非 root ユーザとして Node.js を実行する
一段落説明
「最小権限の原則」によれば、ユーザ/プロセスは必要な情報やリソースにだけアクセスできるようにしなければならない。攻撃者にルートアクセスを与えることは、他のサービスにトラフィックをルーティングしたりするような、ありとあらゆる悪意のあるアイデアを試せる環境を与えてしまうことになります。実際には、ほとんどの Node.js アプリケーションは root アクセスを必要とせず、そのような特権とともに実行することはありません。しかし、root ユーザを使わなければならない 2 つのシナリオがあります:
- 特権ポート(例:80番ポート)へのアクセスを得るために、Node.js を root として実行する
- Docker コンテナはデフォルトで root として実行します(!)。Node.js ウェブアプリケーションは非特権ポートをリッスンし、受け付けるトラフィックを 80 番ポートから Node.js アプリケーションにリダイレクトするために nginx のようなリバースプロキシを利用することが推奨されます。Docker イメージをビルドする際は、安全性の高いアプリケーションは代理の非 root ユーザでコンテナを実行するべきです。多くの Docker クラスタ(例:Swarm、Kubernetes)は宣言的にセキュリティコンテキストを設定することが可能です。
コード例 - 非 root ユーザとして Docker イメージを構築する
FROM node:latest
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
USER node
CMD ["node", "server.js"]
ブログ引用: "By default, Docker runs container as root"(デフォルトでは、Docker は root でコンテナを実行します)
eyalzek による docker-node リポジトリより:
デフォルトでは、Docker はコンテナを root で実行しますが、コンテナ内部ではセキュリティ上の問題が発生する可能性があります。可能な限り、非特権ユーザとしてコンテナを実行したいと思うでしょう。そのために、node イメージは node ユーザを提 供しています。よって、Docker イメージは次のようにして node ユーザとして実行することができます: "-u 'node'"
ブログ引用: "The attacker will have total control over your machine"(攻撃者はマシンのすべての権限を得るでしょう)
Olivier Lalonde のブログ Don't run Node.js as root より:
実際、もし root でサーバを稼働させていて、コードの脆弱性からハッキングされた場合、攻撃者はマシンのすべての権限を得るでしょう。これは、潜在的に攻撃者がディスク全体を削除したり、さらに悪いことを行うことができるということを意味します。一方で、一般ユーザーの権限でサーバを実行していた場合、攻撃者はそれらの権限に制限されます。