Express サーバを80番ポートで動かすには

Express サーバを80番ポートで動かそうとした。

const express = require('express');
const app = express();

router.get('/', (req, res) => {
  res.send('Hello World');
});

app.listen(80, () => {
  console.log('Server Started');
});

実行してみたら、以下のようなエラーが出た。

$ node index.js

events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES 0.0.0.0:80
    at Server.setupListenHandle [as _listen2] (net.js:1343:19)
    at listenInCluster (net.js:1401:12)
    at Server.listen (net.js:1485:7)
    at Function.listen (/Users/Neo/express-test/node_modules/express/lib/application.js:618:24)
    at Object.<anonymous> (/Users/Neo/express-test/index.js:48:5)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)

コレを解決する方法。

ウェルノウンポート番号

そもそも、普段 URL を書く時にポート番号を書かなくても通信できるのは何故か。それは、

といった一般的な決まりがあって、ブラウザ等がポート情報を自動補完してくれているからだ。コレを Well-known Port (ウェルノウンポート番号) という。

ウェルノウンポートで動かすにはスーパーユーザ権限が必要

1024番未満のウェルノウンポートで動かすには、スーパーユーザ権限、つまり sudo で実行することが必要になる。

ということで、サーバの起動の仕方を以下のようにするだけでも、一応解消する。

$ sudo node index.js

プロセスの所有権がルートユーザになる

ただ、このままだと、プロセスの所有権がルートユーザになるので、少々怖い。

そこで、サーバを起動した後に uid を変更することで、一般ユーザの所有権に設定する。

const http = require('http');  // Node.js 組み込みの http モジュール
const express = require('express');
const app = express();

router.get('/', (req, res) => {
  res.send('Hello World');
});

// app.listen() は使わず、以下のように設定する
const httpServer = http.Server(app);
httpServer.listen(80, () => {
  process.setuid(501);  // ID を変更する
  console.log('Server Started');
});

コレで OK。process.setuid() の引数にしている 501 は、$ id 【ユーザ名】 と入力すると確認できる値。テキトーに。