Aplikasi Node.js tidak dapat berjalan di port 80 meskipun tidak ada proses lain yang memblokir port tersebut

94

Saya menjalankan instans Debian di Amazon EC2 dengan Node.js diinstal. Jika saya menjalankan kode di bawah ini:

http = require('http');

http.createServer(function (request, response){
  response.writeHead(200, {'Content-Type':'text/plain'});
  response.end('Hello World\n');
}).listen(80);
console.log("Running server at port 80");

Saya mendapatkan output di bawah ini yang memberi tahu saya ada proses lain yang mendengarkan di port 80:

Running server at port 80

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: listen EACCES
    at errnoException (net.js:901:11)
    at Server._listen2 (net.js:1020:19)
    at listen (net.js:1061:10)
    at Server.listen (net.js:1127:5)
    at Object.<anonymous> (/home/admin/nodetests/nodetest.js:6:4)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

Sekarang ketika saya memeriksa untuk melihat apakah ada proses (sebagai root jika ada yang tersembunyi) mendengarkan pada port 80 menggunakan:

netstat -tupln

Saya mendapatkan output di bawah ini, yang memberi tahu saya tidak ada yang mendengarkan di port 80:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1667/sshd       
tcp6       0      0 :::22                   :::*                    LISTEN      1667/sshd

Saya harus mencatat bahwa debian memiliki port 80 terbuka sebagai aturan masuk jika itu membuat perbedaan.

Pertanyaan saya adalah: Apa yang saya lakukan salah? Kenapa saya tidak dapat mengidentifikasi proses mendengarkan port 80? Mengapa diblokir di Debian? Langkah apa yang harus saya ambil agar kode berjalan dengan benar?

Brian Yeh
sumber

Jawaban:

197

Kode kesalahan EACCESberarti Anda tidak memiliki izin yang tepat untuk menjalankan aplikasi di porta itu. Pada sistem Linux, port apa pun di bawah 1024 memerlukan akses root.

hexacyanide
sumber
5
dengan demikian, sudo node myapp.js akan melakukannya jika Anda memiliki otorisasi untuk menggunakan sudo (cukup tempelkan untuk pemula mana pun).
AlexMA
21
@AlexMA tetapi menjalankan server sebagai root adalah tidak besar, tidak
Patrick Evans
1
Lalu bagaimana Anda menjalankan node pada port 80? Haruskah Anda ... tidak dan menggunakan proxy?
AlexMA
9
@PatrickEvans Saya kira praktik terbaiknya adalah menjalankan pada port yang berbeda dan hanya menyiapkan aturan penerusan port seperti yang disebutkan di sini: stackoverflow.com/questions/16573668/…
AlexMA
73

Alih-alih berjalan pada port 80, Anda dapat mengalihkan port 80 ke port aplikasi Anda (> 1024) menggunakan

iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000

Ini akan bekerja jika aplikasi Anda berjalan pada port 3000.

Kamrul
sumber
1
melakukan ini. Ketahuilah bahwa Anda harus menjadi root untuk menjalankan iptables di instalasi debian baru, jika tidak, $ PATH tidak akan mengarah ke sana.
Brian Yeh
Ya, ini mungkin cara termudah untuk melakukannya. Saya menggunakan Google Cloud Compute yang memberi saya masalah saat menyentuh Port 80. Ini bagus. Terima kasih.
Andy
Ini harus menjadi solusi yang diterima. Menjalankan server web sebagai sudo berbahaya, berpotensi memberikan akses root pada penyerang jika ada kerentanan dalam aplikasi; juga, jika aplikasi membuat file apa pun, file tersebut tidak dapat diakses oleh pengguna lain, membuat Anda lebih sering menggunakannya sudo.
jesusiniesta
Tidak yakin mengapa, tetapi di Ubuntu 14.04 ini tidak berhasil untuk saya. Saya sekarang menggunakan port forwarding melalui ssh, yang sama mudahnya. Saya memposting jawaban di bawah ini .
panepeter
19

Jawaban singkat: Anda dapat mengizinkan akses node ke port itu menggunakan:

setcap 'cap_net_bind_service=+ep' /path/to/nodejs

jawaban panjang

Edit:

Mungkin tidak berfungsi pada versi node baru

Reut Sharabani
sumber
itu berhasil. @LinuxMint - sudo setcap 'cap_net_bind_service = + ep' / usr / local / bin / node
Gabungkan
Terkadang pembaruan akan mengubah jalur lokasi ke node, dan ini akan berhenti berfungsi. Jadi, Anda harus menjalankannya lagi untuk jalur baru ke node.
steampowered
Sepertinya ini tidak lagi berfungsi setelah node versi 8. github.com/nodejs/node/issues/22648
timaw
6

Perhatikan bahwa jika Anda telah apachemenjalankan, Anda dapat membuat proxy terbalik di vhost. Jika node Anda berjalan di porta 8080:

<VirtualHost 127.0.0.1:80>
        ServerName myLocalServer

        ProxyPass        /  http://localhost:8080/
        ProxyPassReverse /  http://localhost:8080/
</VirtualHost>

Tentu saja, tambahkan server ke /etc/hosts:

127.0.0.1    myLocalServer

Anda perlu mengaktifkan modul apache yang relevan:

sudo a2enmod proxy_html
sudo a2enmod proxy_http
sudo a2enmod proxy_connect
sudo a2enmod proxy_ajp
sudo service apache2 restart

... dan sekarang Anda dapat terhubung ke http://myLocalServer.

Redsandro
sumber
3

Bagi mereka yang mencari solusi cepat dan mudah untuk lingkungan pengembangan , penerusan porta melalui ssh bisa menjadi alternatif yang bagus:

ssh -L 80:localhost:3000 yourusername@localhost -N

Ini meneruskan port 80 di localhost ke port 3000 di localhost.

Ini harus dijalankan sebagai root (port istimewa). Untuk membatalkannya, cukup tekan ctrl-c di terminal. (Anda dapat menambahkan-f bendera untuk menjalankan perintah di latar belakang, tetapi kemudian Anda perlu menemukannya lagi untuk mematikannya).

Solusi ini mengharuskan Anda memiliki server ssh yang berjalan secara lokal . Ini dapat dilakukan dengan cepat , tetapi harap diingat implikasi keamanan jika Anda berada di jaringan bersama. Anda mungkin ingin menerapkan setidaknya beberapa tingkat keamanan tambahan (nonaktifkan kata sandi & login root).

Saya pribadi hanya pernah menggunakan ini di mesin lokal saya. Saya tidak yakin bagaimana pengaruhnya terhadap kecepatan pemrosesan permintaan Anda jika Anda menjalankan ini pada produksi, mungkin seseorang punya ide. Bagaimanapun, Anda perlu memastikan perintah ini terus berjalan sepanjang waktu, yang menyebabkan lebih banyak sakit kepala. Untuk lingkungan produksi , saya sarankan menggunakan proxy terbalik seperti nginx .

panepeter
sumber
2

jawaban heksasiana benar. tetapi apakah ada solusi untuk membuat ini berhasil?

jawabannya iya.

bagaimana?

Anda dapat menggunakan reverse proxymisalnya menjalankan nginx reverse proxydi port 80dan meneruskan proxy ke tujuan ip:portnode yang menggunakannya.

Anda dapat mengaturnya menggunakan docker containeryang membuat hidup lebih mudah. ini adalah versi resmi nginx di hub docker yang dapat Anda tarik.

bahkan ada lebih banyak manfaat dalam menggunakan reverse proxyyang Anda dapat google.

Ali_Hr
sumber
0

Saya mendapatkan kesalahan yang sama dan saya mencoba menjalankan aplikasi saya menggunakan sudo dan itu berhasil untuk saya.

tanpa sudo

mansi@mansi:~/NodePractice$ node myFirst.js 
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES 0.0.0.0:80
    at Object.exports._errnoException (util.js:870:11)
    at exports._exceptionWithHostPort (util.js:893:20)
    at Server._listen2 (net.js:1224:19)
    at listen (net.js:1273:10)
    at Server.listen (net.js:1369:5)
    at Object.<anonymous> (/home/mansi/NodePractice/myFirst.js:6:4)
    at Module._compile (module.js:410:26)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)

dan dengan sudo

mansi@mansi:~/NodePractice$ sudo node myFirst.js 
^C
Parth Pachchigar
sumber
... yang sebenarnya tidak ingin Anda lakukan. Ini menciptakan masalah keamanan.
bvdb
-1

Menggunakan PORT 80 membutuhkan beberapa izin khusus. Menggunakan sudosebelum menjalankan pernyataan aplikasi memecahkan masalah saya. misalnya, jika Anda menggunakan npm untuk menjalankan aplikasi, Anda dapat mengetiksudo npm start

webcrawler
sumber
1
Jawaban ini tidak menambahkan apa pun untuk menjawab konten yang sudah disediakan oleh orang lain. Harap jawab hanya jika Anda menambahkan informasi tambahan.
Brian Yeh
-2

Kode kesalahan EACCESberarti Anda tidak memiliki izin yang tepat untuk menjalankan aplikasi di porta itu. Pada sistem Linux, port apa pun di bawah 1024 memerlukan akses root.

Jalankan program dengan sudoizin. Jalankan sudo superintah sebelum menjalankan program.

akshith ranjan
sumber
Lihat komentar posting di bawah jawaban hexacyanides. Terima kasih.
Brian Yeh