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