他のプロセスがポートをブロックしていないにもかかわらず、Node.jsアプリはポート80で実行できません


94

Node.jsがインストールされたAmazon EC2でDebianのインスタンスを実行しています。以下のコードを実行すると:

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");

以下の出力が表示され、ポート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)

ここで、ポート80でリッスンしているプロセス(何かが隠されている場合はrootとして)があるかどうかを確認すると、次のようになります。

netstat -tupln

以下の出力が表示され、ポート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

違いがある場合、debianはインバウンドルールとしてポート80を開いていることに注意してください。

私の質問は、次のとおりです。ポート80をリッスンしているプロセスを識別できないのはなぜですか?Debianでブロックされるのはなぜですか?コードを正しく実行するには、どのような手順を踏む必要がありますか?

回答:


197

エラーコードEACCESは、そのポートでアプリケーションを実行するための適切な権限がないことを意味します。Linuxシステムでは、1024未満のポートにはrootアクセスが必要です。


5
したがって、sudoノードmyapp.jsは、sudoを使用する権限がある場合にそれを行います(初心者のためにsudoを追加するだけです)。
AlexMA 2013年

20
@AlexMAですが、サーバーをrootとして実行するのは大したことではありません
Patrick Evans

1
では、どのようにしてポート80でノードを実行しますか?プロキシを使用しないでください。
AlexMA 2013年

9
:@PatrickEvansは、私がここに述べたように、ベストプラクティスが別のポート上で実行し、ちょうどポート転送ルールを設定することであろうと仮定stackoverflow.com/questions/16573668/...
AlexMA

73

ポート80で実行する代わりに、ポート80をアプリケーションのポート(> 1024)にリダイレクトできます。

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

これは、アプリケーションがポート3000で実行されている場合に機能します。


1
これをしました。新規のDebianインストールでiptablesを実行するにはrootでなければならないことがわかりました。そうでない場合、$ PATHはそれをポイントしません。
Brian Yeh 2013

うん、これはおそらくそれを行う最も簡単な方法だった。私はGoogle Cloud Computeを使用していますが、ポート80に触れると問題が発生しました。ありがとう。
アンディ

これは受け入れられる解決策です。Webサーバーをsudoとして実行することは危険であり、アプリケーションに脆弱性がある場合、攻撃者にrootアクセスを与える可能性があります。また、アプリケーションがファイルを作成する場合、他のユーザーがアクセスできなくなり、sudoさらに多くのファイルを使用できるようになります。
jesusiniesta 2017年

理由は定かではありませんが、Ubuntu 14.04では、これは機能しませんでした。これで、sshによるポート転送を使用できるようになりました。これも同じくらい簡単です。以下に回答を掲載しまし
ペインピーター2018

19

短い答え:以下を使用して、そのポートへのノードアクセスを許可できます。

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

長い答え

編集:

新しいノードバージョンでは機能しない可能性があります


それはトリックをしました。@LinuxMint -須藤setcap 'cap_net_bind_service = + EP'は/ usr / local / binに/ノード
コンバイン

更新によってノードへの場所のパスが変更されることがあり、これが機能しなくなります。そのため、ノードへの新しいパスに対して再度実行する必要があります。
18

これはノードバージョン8を過ぎると機能しなくなるようです 。github.com
nodejs /

6

apache実行している場合は、仮想ホスト上にリバースプロキシを作成できることに注意してください。ノードがポートで実行されている場合8080

<VirtualHost 127.0.0.1:80>
        ServerName myLocalServer

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

もちろん、サーバーを追加します/etc/hosts

127.0.0.1    myLocalServer

関連するApacheモジュールを有効にする必要があります。

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

...これでに接続できますhttp://myLocalServer


3

開発環境のための迅速で簡単なソリューションを探している人にとって、sshを介したポート転送は良い代替手段となり得ます:

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

これにより、localhostのポート80がlocalhostのポート3000に転送されます。

root(特権ポート)として実行する必要があります。キャンセルするには、ターミナルでctrl-cを押します。(-fフラグを追加して、コマンドをバックグラウンドで実行させることもできますが、それを終了するには、もう一度見つける必要があります)。

このソリューションでは、sshサーバーをローカルで実行する必要があります。すぐ実行できますが、共有ネットワークを使用している場合は、セキュリティへの影響に注意してください。少なくともある程度の追加のセキュリティを適用することをお勧めします(パスワードの無効化とrootログイン)。

私は個人的にこれを私のローカルマシンでのみ使用します。これを本番環境で実行した場合、リクエストの処理速度にどのように影響するのかはわかりません。とにかく、このコマンドを常に実行し続けることを確認する必要があります。これにより、頭痛の種が増えます。以下のために生産環境、私が使用することをお勧めnginxのようなリバースプロキシを


2

ヘキサシアニドの答えは正しいです。しかし、これを機能させるための解決策はありますか?

答えはイエスです。

どうやって?

reverse proxyたとえば、nginx reverse proxyonポート80を実行して、ip:portそのノードが使用する宛先にプロキシを渡すことができます。

あなたはこれを使っdocker containerてこれを設定することができます。これはあなたがそれを引っ張ることができるDockerハブのnginx公式ビルドです

reverse proxyあなたがそれをググることができることを使用してさらに多くの利点があります。


0

同じエラーが発生し、sudoを使用してアプリケーションを実行しようとしましたが、うまくいきました。

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)

とsudoで

mansi@mansi:~/NodePractice$ sudo node myFirst.js 
^C

...これはまさにあなたがしたくないことです。セキュリティ上の問題が発生します。
bvdb

-1

PORT 80を使用するには、いくつかの特別な権限が必要です。sudoアプリの実行前のステートメントを使用すると、問題が解決しました。たとえば、npmを使用してアプリを実行している場合は、次のように入力できます。sudo npm start


1
この回答は、他の人がすでに提供しているコンテンツに回答するために何も追加しません。追加情報を追加する場合のみ回答してください。
ブライアンイェ

-2

エラーコードEACCESは、そのポートでアプリケーションを実行するための適切な権限がないことを意味します。Linuxシステムでは、1024未満のポートにはrootアクセスが必要です。

sudo権限を持ってプログラムを実行します。実行sudo suプログラムを実行する前にコマンドを。


hexacyanidesの回答の下の投稿コメントを参照してください。ありがとう。
Brian Yeh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.