LANのマシン用にLet’s encryptのサーバー証明書を取得する方法について考えてみた

かなりレアケースですが、普段はインターネットから参照できるようにしたくないけど、Let’s encryptのサーバー証明書を取得したいときだけLANで使っているWebサーバーを公開したいときがあります。こういった手間をかけるなら、LAN用にプライベート認証局を用意して自動更新する仕組みを作ったほうが楽かもしれませんが、技術的に設置できるということを知っているということに意味がある気がするので、備忘録として書いておきます。

こういうことをすると、そもそも、名前解決のところで少し面倒なことをしないといけないですし、インターネット上で利用できるサーバーが必要だということで、LAN内にプライベート認証局を用意するよりもハードルは高いです。

目次

前提

前提がいくつかあります。まず、ドメインはとってあるものを使います。ここでは、example.jpだとします。LAN内でしか使わないlan.example.jpというホスト名があったとして、これの名前解決については、DNSへAレコードを追加します。

また、VPSなどでSSHログインできるサーバーを用意します。これは普段は別ドメインでWebサイトを公開するのに利用ものだとします。せっかく用意するのなら、サーバー証明書取得用だけに利用するのはもったいなくて、有効に活用したいですからね。これはwww.example.orgだとします。

lan.example.jp用のマシンは自宅のLANに用意するとします。ブロードバンドルーターを接続してSSHでwww.example.orgへアクセスできる環境にあるとします。マシン名はubuntu.localとしておきましょう。

さて、インターネットからlan.example.jpからアクセスするときは、www.example.orgのIPアドレス、LAN内でlan.example.jpへアクセスするときは、ubuntu.localのIPアドレスとなるように名前解決を設定する必要があります。方法はいくつかありますが、lan.example.jpへアクセスするマシンのhostsファイルへ名前解決のための情報を記述するのが簡単です。他にはLAN内のネームサーバーとしてdnsmasqを用意して、これを使って名前解決をするというのも良いでしょう。

なお、複数のマシンからアクセスが必要なubuntu.localのIPアドレスは固定したいので、DHCPサーバーへMACアドレスに対してIPアドレスを固定する設定をして運用するとします。

ubuntu.local 構築手順

構築手順上の重要な点だけ書いておきます。普通にhttp, httpsに対応したWebサーバーを用意します。

  • ubuntu.localでhttp://lan.example.jp、https://lan.example.jpが動作するようにWebサーバーを構築
  • リバースSSHポートフォワードを使ってubuntu.localの80, 443をwww.example.orgの8080, 8443とつなげる

www.example.org 構築手順

ubuntu.localで動作するWebサーバーとの連携を設定します。リバースSSHポートフォワードで127.0.0.1:8080、127.0.0.1:8443でubuntu.localとつながっている点がポイントです。なお、「Let’s encryptのサーバー証明書を取得する」だけなら、www.example.orgでhttps://lan.example.jpは必要ありません。

  • www.example.orgではhttp://www.example.org, https://www.example.org, http://lan.example.jp, https://lan.example.jpが動作するようにWebサーバーを構築
  • www.example.orgの/etc/hostsに「127.0.0.1 lan.example.jp」を登録
  • www.example.orgのWebサーバーでは名前ベースのバーチャルホストを用意してhttp://lan.example.jp, https://lan.example.jpはリバースプロキシーでそれぞれlan.example.jp:8080(これは127.0.0.1:8080と同じ)、lan.example.jp:8443(これは127.0.0.1:8443と同じ)へ転送
  • www.example.orgでSELinuxを有効にしている場合は、「/usr/sbin/setsebool -P httpd_can_network_connect 1」を実行

少し気になるのは/etc/hostsにlan.example.jpを登録しているところです。lan.example.jpがwww.example.orgと違うIPアドレスへ移動することになったときに、このファイルを更新する必要があるので忘れないようにしないといけません。

/etc/hostsを書き換えないで、リバースプロキシーの設定時にhttp://localhost:8080、https://localhost:8443を指定して、ubuntu.localのWebサーバーでhttp://localhost、https://localhostでも接続できるようにしておく方法もあります。

どちらが良いのかは、公開したいWebアプリに依存します。Webアプリがリダイレクトやレスポンスヘッダーにいろいろ情報を追加するタイプの場合はlocalhostを使うと、ヘッダー情報の書き換えなどの処理が動くように設定を追加する必要が出てくるはずです。その手間を考えると/etc/hosts書き換えが楽なはずです。

他の方法

まぁ、www.example.orgでLet’s encryptのスクリプトを使って証明書を更新するようにして、取得した証明書をubuntu.localへ転送するという方法もあって、そっちの方が簡単だったりします。

今回、上記の方法を考えたのは、あるWebアプリでSSLの設定をするためのコマンドがあって、それがLet’s encryptを使っていてLANのマシンで実行する必要があったからです。www.example.orgのマシンで、そのWebアプリを動かすための環境を構築して動かして証明書を取得しても良かったのですが、既存の環境に影響が出そうなのでやめました。

最近は、こういう設定に時間をかけるより、他のことに時間をかけた方がいいような場面も多いですが、なんとなくやってみたくなるのですよね。

同じタグの記事: Let's Encrypt
同じカテゴリの記事: Linux