OnionドメインのウェブサイトをDockerで構築して公開したいこと、ありますよね。
僕はあるので自分用にメモです。
なお、このレポートを書くにあたってO'Reilly Dockerを参考にしました。
構築の土台となる部分を最小構成で作成します。
最小構成で一旦動かしてみることで動きなども理解できます。
まずcompose.yaml
を作ります。
version: '3.8'
services:
nginx:
image: nginx:alpine
networks:
- tor_network
volumes:
- ./htdocs:/usr/share/nginx/html:ro
restart: unless-stopped
tor:
build:
dockerfile: ./tor/Dockerfile
networks:
- tor_network
- front
volumes:
- ./data:/var/lib/tor
- ./tor/settings:/etc/tor
restart: unless-stopped
networks:
front:
tor_network:
internal: true
ネットワークは、外部に接続するためのfront
ネットワークと、外部とつながっていない内部だけで独立したネットワークのtor_network
を作成します。
tor
コンテナだけ外部と接続し、nginx
コンテナを外部と遮断し、そしてtor
コンテナとnginx
コンテナをtor_network
ネットワークでつなげることにします。
ネットワーク図に表すと以下のようになります。
nginx
コンテナは、余計なものが入っていないnginx:alpine
を使用します。
tor
コンテナは、後述のDockerfile
を使用します。
また、どちらもrestart: unless-stopped
で、落ちたら再起動するようにしています。不要だったかもしれません。
tor
コンテナのDockerfileは、alpine:latest
にtorを追加して起動するだけのものです。
FROM alpine:latest
RUN apk update
RUN apk add tor
CMD ["tor", "-f", "/etc/tor/torrc"]
torの設定ファイルであるtorrc
で、80ポートへの接続をnginx
コンテナに向けています。
※Dockerネットワーク内ではコンテナ名で名前解決をすることができる
SocksPort 0
HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 nginx:80
誰かの踏み台にされるのだけは防ぐためにSocksPort 0
の設定をしていますが、自分でもTorプロクシとして利用したい場合はここをSocksPort 0.0.0.0:9150
として、Dockerfile
でEXPOSE 9150
をしてからcompose.yaml
でtorのportsに"9150:9150"
を追加することでSOCKSホストとして利用できます。
Nginxはnginx:alpine
イメージをそのまま使います。
なにも表示されないと動いているかどうかわかりにくいのでindex.html
を配置しておきます。
<!DOCTYPE html>
<html>
<head>
<title>docker hidden service test title</title>
</head>
<body>
<div>docker hidden service test body div</div>
</body>
</html>
以上で最小構成は作成完了です。
Dockerは普通にdocker-compose up -d
コマンドで起動します。
正常に起動すると、data/hidden_service/hostname
に以下のようなファイルが出力されています。
data/hidden_service/hostname
kxal3j4zblhjt4jinnbly6icciqbh2ihq4u2opsu4qhqyqazwsgaq3ad.onion
このアドレスにTorブラウザなどで接続し、作成したindex.htmlが表示されていることを確認します。
WindowsでDockerを立てている場合、ここで既にdata/hidden_service
が存在すると、以下のようなエラーメッセージが出て終了してしまいます。
[notice] Tor 0.4.7.13 running on Linux with Libevent 2.1.12-stable, OpenSSL 3.0.7, Zlib 1.2.13, Liblzma 5.2.9, Libzstd 1.5.2 and Unknown N/A as libc.
[notice] Tor can't help you if you use it wrong! Learn how to be safe at https://support.torproject.org/faq/staying-anonymous/
[notice] Read configuration file "/etc/tor/torrc".
[warn] Permissions on directory /var/lib/tor/hidden_service/ are too permissive.
[warn] Failed to parse/validate config: Failed to configure rendezvous options. See logs for details.
[err] Reading config failed--see warnings above.
既にWindows側の既存のディレクトリをDockerでマウントするとディレクトリのパーミッションが777になります。
そのためSSH接続時の証明書と同様に、パーミッションがあまりにもオープンすぎるとTorが判断するとエラーで止まるようです。
なので既存のhidden_service
を使用したい場合は、tor/Dockerfile
内でCOPY
したりchmod -R 700 /var/lib/tor/hidden_service/
を叩く必要がありそうですが、今回は最小構成だけ作りたいのでここでは説明を省きます。
無事に動いていることが確認できました。
nginx
コンテナは外部に接続できないようになっていますから、セキュリティは高いです。
もし更にセキュリティを向上させるのであれば、nginx
コンテナやtor
コンテナをdistroless
やscratch
でマルチステージビルドで組み立てると良いでしょう。その方法についてはまた後日投稿します。