Lego selfdns Provider を作ってみた
サーバ
Published: 2023-02-16

Legoを使って、Let’s EncryptのSSL証明書を取得する際に、legoコマンド自体がDNSサーバとなり、DNS-01の認証を行うためのプロバイダを作ってみました。

はじめに

Legoはgoで書かれた、ACMEクライアントでLet’s EncryptなどのSSL証明書を取得するためのコマンドラインツールです。

何をしたの?

LegoのDNS-01認証は、様々なDNSプロバイダに対応していますが、「APIが使えるDNSサーバなんてないよ!」というときのために、自分自身をDNSとして動かしDNS-01認証でSSL証明書を発行してしまうselfdnsプロバイダを作ってみたという話。

さすがに、Lego自体をサーバとして動かすことは、本家では想定されてないと思うので、Pullリクはせずに 個人的なFork版という位置づけでテストコードも書かずに、自分用に作って見ました。

これで、APIの使えないDNSサービス(ドメイン付属のDNS)でも、NSレコードを向けることで、DNS-01認証でSSL証明書を取得できるようになります。

Lego自体をDNSサーバとして動かすため、外部からDNSサーバとしてアクセスできるようにする必要があります。

免責事項

ここにありますが個人で使う想定でしか作ってないので動作保証はないので悪しからず。
また、ACMEの仕様を確認せず、動けばいいやぐらいの感じで作ってます。

使い方

発行したいDNSにNSレコードを向ける

  • とあるVPSサーバ(hoge)サーバで証明書を発行したいので、hogeサーバのDNSにNSレコードを向けます。

    hoge            60  IN A  XXX.XXX.XXX.XXX
    _acme-challenge 60  IN NS hoge.example.jp.
    
  • 期待した結果になっているか確認するために、digコマンドで確認します。

    $ dig _acme-challenge.example.jp -t ns
    ;; AUTHORITY SECTION:
    _acme-challenge.example.jp. 60 IN  NS      hoge.example.jp.
    
    ;; ADDITIONAL SECTION:
    hoge.example.jp.   60      IN      A       XXX.XXX.XXX.XXX
    

legoを実行するグローバルIPのサーバの準備をします

  • iptablesのポートを開放します。 DNSサーバとして動作するため、UDP/TCPの53番ポートを開放します。

    # iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
    # iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
    
  • 改造版 Legoをダウンロードします。

    # wget https://github.com/masa23/lego/releases/download/v4.10.0/lego_v4.10.0-1_linux_amd64.tar.gz
    # tar zxvf lego_v4.10.0_linux_amd64.tar.gz
    
  • legoを実行して証明書を発行します。
    DNSサーバとして動作させるため、--dns selfdnsを指定します。
    53番ポートを使うためroot権限が必要です。

    # SELFDNS_LISTEN_ADDRESS=XXX.XXX.XXX.XXX SELFDNS_SERVER_HOSTNAME=hoge.example.jp ./lego --email <メールアドレス> --domains="*.example.jp" --accept-tos --dns=selfdns run 
    

    SELFDNS_LISTEN_ADDRESSには、legoを実行するサーバのグローバルIPを指定します。 SELFDNS_SERVER_HOSTNAMEには、legoを実行するサーバのホスト名を指定します。
    こちらは、応答時のSOAレコードに使われます。

問題がなければ、証明書が発行されます。

.lego/certificates/

追記(2023/02/17)

SELFDNS_LISTEN_ADDRESS にIPv6アドレスを指定すると、IPv6アドレスでDNSサーバが起動するようにしました。 なんと、これでIPv6のグローバールIPアドレスがあればLet’s EncryptのSSL証明書を取得できるようなりました。

  • DNS登録
    hoge            60  IN AAAA  20XX:XX:...
    _acme-challenge 60  IN NS hoge.example.jp.
    
  • lego実行
    # SELFDNS_LISTEN_ADDRESS=20XX:XX:... SELFDNS_SERVER_HOSTNAME=hoge.example.jp ./lego --email <メールアドレス> --domains="*.example.jp" --accept-tos --dns=selfdns run
    

これで、貴重なIPv4アドレスのグローバルIPアドレスが無くても気軽にLet’s EncryptのSSL証明書を取得できます! 自宅のフレッツのIPv6アドレスで発行で来た。超便利。