Onion ServiceのWebサイトをHTTPSに対応させる

記事
プライバシーTor

Onion Serviceは、HTTPSを利用しなくても通信は暗号化されていますし、.onionドメイン自体が公開鍵であるため、通信先のサーバーが本物であることも保証されています。

一方で、Onion ServiceはTorクライアント同士の通信のみ暗号化しています。真にE2EEであるためには、Onion Serviceを実行しているサーバーとWebサイトのサーバーが同一であり、かつ閲覧者のTorクライアントとブラウザが同じ機器で動作している必要があります。

例えばTorルーターを使用している閲覧者が、Wi-Fiで接続したデバイスからOnion ServiceのWebサイトを閲覧する場合、ルーターで一度復号された通信がデバイスに転送されるため、E2EEは成立しません。Wi-Fiのパスワードが漏洩していたりすると、攻撃者は通信内容を盗聴できる可能性があるわけです。

証明書の入手

残念ながら、記事作成時点ではLet’s Encryptは.onionドメインに対応していません。それどころか、対応しているCAは以下の2つしかなく、いずれも有料です。

Digicertは組織向けの高額なEV証明書を発行するので非常に高価です。なので特に個人の場合はHARICAでDV証明書を取得することになります。

なお、暗号通貨による支払いは不可能なため、HTTPS化をすれば、Webサイトの運営者の身元は司法機関によって特定される可能性があります。(特にHARICAはギリシャのCAなのでEU圏内です)

各サービスから証明書を購入する方法は、それぞれ丁寧に説明してくれているので割愛します。

証明書を設定

.onionのWebサイトでもtorrcを少し編集すれば、あとは通常のものとほぼ同じように証明書を設定できます。

以下ではHARICAから入手した証明書をNginxで設定する例を示します。

まずtorrcを以下のように少し変更して、HTTPS用のポートを設定します。
これはNginx側が認識するための仮のローカルのポートです。
Onion Serviceではポート解放をする必要はありません。

HiddenServiceDir /etc/tor/hidden_service/
HiddenServicePort 80 127.0.0.1:80
HiddenServicePort 443 127.0.0.1:443

次にHARICAからPKCS#7 (chain)の証明書をダウンロードして、これをOpenSSLでPEM形式に変換します。

$ openssl pkcs7 -in Cert_chain.p7b -out onion.pem

続いてNginxの設定ファイルを以下のように設定します。

server {
    listen 443 ssl;

    server_name examplexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxd.onion;
    
    ssl_certificate /etc/nginx/cert/onion.pem;
    ssl_certificate_key /etc/nginx/cert/onion.key;
}

listenには先ほどtorrcで設定したSSL用のポート(ここでは443)を指定します。

ssl_certificatessl_certificate_keyには先ほど変換したPEM形式の証明書と、証明書の発行時に作成した秘密鍵のパスをそれぞれ指定します。

ちなみに、SSLでない方のポート(ここでは80)に来たリクエストをSSLのポート(443)にリダイレクトさせることも普通にできます。

設定が終わったらtorとNginxを再起動します。

$ sudo systemctl restart tor
$ sudo systemctl restart nginx

しばらくしてから、Tor Browser等でサイトにアクセスしてみてください。

Tor BrowserではOnion ServiceのWebサイトにアクセスすると、必ず玉ねぎの鍵アイコンが出るので、そこから証明書の情報を確認してください。

情報が正しければ設定は完了です。おつかれさまでした。

おまけ: Onion-Location

Onion ServiceのWebサイトが普通のWebのサイトのミラーである場合、Tor BrowserにOnion ServiceのWebサイトが利用可能であることを示すことができます。

Tor Project | Onion-Location

アドレスバーの横に「.onion available」というボタンが表示されて簡単にOnion Service版のサイトにアクセスできるようになるので、設定しておいて損はないはずです。

なおOnion Serviceでなく、HTTPSに対応しているサイトでのみ有効です。

<meta>タグを追加して設定

<head>内に以下のようなタグを追加するだけです。

<meta http-equiv="Onion-Location" content="https://examplexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxd.onion/">

HTTPヘッダーを追加して設定

Onion-Locationヘッダーを送信することもできます。

例えばNginxで設定する場合は以下のようにします。

server {
    listen 443 ssl;
    server_name example.com;
    add_header Onion-Location "https://examplexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxd.onion$request_uri";
}