perlでIO::Socketを使う時に「permission deny」と言うエラーが出た時の対処法

perlで以下の様なコードを書いた時に、permission denyと言うエラーが出てきた。

use IO::Socket;
$sock0 = new IO::Socket::INET(
Listen    => 5,
LocalAddr => 'localhost',
LocalPort => 80,
Proto     => 'tcp',
Reuse     => 1
);

原因は単純で、ポート番号を80としてローカル立ち上げようとしたのが問題。

上記コードでは、1024番以上のポート番号を指定してあげれば上手くいく。

LocalPort => 3000,

これでhttp://localhost:3000のurlでローカルサーバーにアクセスできるようになる。

なぜ、ポート番号80だとpermission denyのエラーが出るのか?

では、なぜポート番号80だとpermission denyのエラーが出たかと言うと、1023番以下のポート番号を使う場合は、rootユーザーでなければいけないからだ。

ちなみに、これはperl特有の現象ではなく、Rubyやphpでローカルサーバーを立てる時でも起こることだ。

1,024番ポート以前のポート番号は、開放時にroot権限が必要です。なので(通常80番ポートを設定している)Apacheの起動にはroot権限が必要ですが、(通常8080番ポートを設定している)Tomcatの起動は一般ユーザーで行うことができるわけです。
開放時にroot権限が必要なポート番号 – くろのまったりシステム開発日記。

また、stackoverflowでも以下のような回答がされている。

Short answer: you can’t. Ports below 1024 can be opened only by root. As per comment – well, you can, using CAP_NET_BIND_SERVICE, but that approach, applied to java bin will make any java program to be run with this setting, which is undesirable, if not a security risk.
How to run a server on port 80 as a normal user on Linux? – Server Fault

上記の記事では、どうしても80番のポート番号を使いたい場合は、以下のようにできると紹介している。(ただ8080番にリダイレクトしているだけですけど)

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

ReratedPosts

PerlのDBIで新規レコードを作成(INSERT)した時にレコードのIDを取得する方法
Mojoliciousで文字化けが起こった時の対処法2つ
Mojoliciousで「[error] Role::Tiny 2.000001+ is required for roles」のエラーが出た時の対処法
perlで正規表現で文字列を置換したり、新しい変数に格納する方法
perl(Mojolicious)をレンタルサーバーXserverを使って公開する手順まとめ
perlでファイルの読み込みとか作成とか削除のまとめ