◆ root じゃなくても 80 番ポートにウェブサーバを起動できる
◆ Node.js だと面倒な部分なので助かる
◆ だけど Ubuntu 系だけで CentOS などの rpm は用意されてない

以前書きましたが Linux だと 80 番ポートをリッスンするのに root 権限が必要で Node.js で root 以外のユーザでサーバを起動しようとするとすごく面倒です
リッスン後にプロセスの uid を root 以外のユーザにするのですが リッスン前後で実行ユーザが変わるのと困るところがあります

なので結局 気にせず root を使うか Nginx を前段に置いとくのがいいのかなぁとか思ったり

そんなだったのですが 偶然 authbind というツールを見つけました
root 以外のユーザで 1024 未満のポートをリッスンできるといういかにもなツールです

ソースから

これはよさそうと早速試そうとしたのですが Ubuntu 系のみのようです
https://packages.ubuntu.com/ja/focal/amd64/authbind

Fedora や CentOS の dnf に rpm は見つからず リポジトリの追加や非公式 rpm もそれらしいのはなさそうでした
こんな良さげなツールなのにどうしてないんでしょうね
このまま諦めきれなかったので ソースコードを探すと Ubuntu の公式からダウンロードできたので 自分でビルドすることにしました

先に結果

先に結果ですが 無事インストールできてちゃんと動きました

まずは authbind を使わず一般ユーザで Node.js を使って 80 番ポートにサーバを起動しようとしてみます

[user1@4d8d7daf6d55 authbind]$ node -e "http.createServer((req, res) => res.end('1')).listen(80)"
events.js:174
throw er; // Unhandled 'error' event
^

Error: listen EACCES: permission denied 0.0.0.0:80
at Server.setupListenHandle [as _listen2] (net.js:1263:19)
at listenInCluster (net.js:1328:12)
at Server.listen (net.js:1415:7)
at [eval]:1:47
at Script.runInThisContext (vm.js:122:20)
at Object.runInThisContext (vm.js:329:38)
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at evalScript (internal/bootstrap/node.js:590:27)
at startup (internal/bootstrap/node.js:265:9)
Emitted 'error' event at:
at emitErrorNT (net.js:1307:8)
at process._tickCallback (internal/process/next_tick.js:63:19)
at evalScript (internal/bootstrap/node.js:593:13)
at startup (internal/bootstrap/node.js:265:9)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)

permission denied って言われてますね

次に authbind を使った場合です

[user1@4d8d7daf6d55 ~]$ authbind node -e "http.createServer((req, res) => res.end('1')).listen(80)" &
[1] 328
[user1@4d8d7daf6d55 ~]$ curl http://localhost/
1[user1@4d8d7daf6d55 ~]$

エラーは出ずに起動できています
また 分かりづらい部分に結果が出ていますが curl で http://localhost/ にアクセスすると 1 を正常に取得できています

インストールと設定

今回試すために使った環境は Docker の centos:8 イメージです

まず実行する Node.js やビルドに必要なパッケージをインストールします

dnf install nodejs wget make gcc

適当に /opt にソースファイルをダウンロードしてきて make install します

cd /opt
wget <url>
tar -xf authbind_2.1.2.tar.gz
cd authbind
make install

インストールできたら authbind コマンドが使えるようになって /etc/authbind に設定ファイルが配置されています
今回は 80 番ポートに user1 からアクセスできたらいいので 下のように設定します

cd /etc/authbind/byport
touch 80
chown user1 80
chmod 755 80

ポートで許可するので /etc/authbind/byport にポート番号の空のファイルを作ります
ファイルオーナーを user1 にして パーミッションは 755 にします

[root@4d8d7daf6d55 byport]# ls -al
total 0
drwxr-xr-x 2 root root 16 Nov 20 09:36 .
drwxr-xr-x 5 root root 47 Nov 20 09:35 ..
-rwxr-xr-x 1 user1 root 0 Nov 20 09:36 80

後は user1 で 80 番ポートをリッスンするコマンドに authbind をつけて実行します

authbind node server.js