« NginxをWindowsのコマンドラインから操作するバッチファイル | トップページ | Celeron N5095搭載のミニPCを購入 »

2022年4月18日 (月)

Windowsでnginxとlegoを用いてLet's Encryptからhttp方式によるSSL証明書の発行を行う

Linuxでの解説記事は結構見つかるがWindows版での記事はほとんどなかったので。
ついでにnginxで発行された証明書を使用してSSLオフロードまでテスト。

Let's Encryptからの証明書取得に04WebServerとwin-acmeの組み合わせで失敗して行き詰ったので、試しにIISとwin-acmeの組み合わせでやったらあっけなく成功した。

2022/06/14追記:
04WebServerとwin-acmeの組み合わせでの失敗原因が判明。
ルーターでマルチホーミングの設定をしている為、インターネット側からサーバーへのSYNパケットに対するサーバーのSYN/ACK応答パケットがルーターで別セッション扱いとなって接続してきたWANと違うWANから返信されていた。
その為、クライアントから見たとき接続先のIPと違うIPから応答が返ってくるために異常と判断されてコネクションが確立出来ていなかった。
ルーターのforward Filterに新しくTcp.Port80を特定WANへ転送する様に定義して問題は解決した。
IISとwin-acmeの組み合わせで問題なかったのはIISサーバーから接続するコネクションですべての処理が実施され、WAN側からサーバーへコネクションを新規に接続する動作がなかった為ではないかと思われる。
追記終わり

しかしIISを使うと証明書がpfx形式で直接IISに取り込まれてしまう。
最終的な目的はメールサーバをnginxでSSLオフロードしてTLSv1.2で動かすことなので証明書はpem形式で自動更新していきたい。
だがIISで証明書を取得すると証明書更新の度にIISから手動でpem形式を指定して証明書をExportしなければならない。

と言う訳で色々調べた結果、nginxとlegoを用いてLet's Encryptから証明書を取得する方式で再度チャレンジすることに。

・nginx設定
# HTTP SERVER
http {
  include mime.types;
  default_type application/octet-stream;
  keepalive_timeout 65;
  server {
    listen 80;
    server_name xxx-xxx.iobb.net;
    location / {
      root html;
    index index.html index.htm;
    }
    location ^~ /.well-known/acme-challenge/ {
      root cert; # http方式の認証で使用するフォルダ名、nginx実行ファイル直下に同名のフォルダを作成する
    ndex index.html index.htm;
    }
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root html;
    }
  }
}

・lego実行コマンド
lego --accept-tos --http --http.webroot d:\Service\nginx\cert --domains xxx-xxx.iobb.net --path d:\Service\lego\ssl --email xxx@xxx-xxx.iobb.net run

・環境によって変更するコマンド部分の解説
--http.webroot d:\Service\nginx\cert
http方式での認証に使用するWebサーバのフォルダ、ローカルPC上の実際の場所を指定。
nginxの設定でnginx実行ファイルのあるフォルダ直下のcertフォルダを指定しているのでそれに合わせる。
このフォルダ内にLet’s Encryptからのドメイン認証に必要なフォルダやファイルが作成される。

--domains xxx-xxx.iobb.net
Let’s Encryptからアクセスしてくるドメイン名。
このドメインにアクセスしてドメイン認証用のファイルが確認できれば証明書が発行されれる。

--path d:\Service\lego\ssl
発行された証明書を保存するフォルダ。
このフォルダ内に認証関連のフォルダが作成されて証明書や秘密鍵などのファイルが保存されれる。

--email xxx@xxx-xxx.iobb.net
Let’s Encryptから証明書発行・更新時に使用されれるアカウント名となる。
その他証明書の有効期限が近づくとこのメールアドレスにアラートメッセージが来たりする。

・実行結果
PowerShellのコマンドラインからlego実行コマンドを実行した際の出力ログ

PS D:\Service\lego> .\lego --accept-tos --http --http.webroot d:\Service\nginx\cert --domains xxx-xxx.iobb.net --path d:\Service\lego\ssl --email xxx@xxx-xxx.iobb.net run

2022/04/17 19:37:05 [INFO] [xxx-xxx.iobb.net] acme: Obtaining bundled SAN certificate
2022/04/17 19:37:06 [INFO] [xxx-xxx.iobb.net] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/99166025460
2022/04/17 19:37:06 [INFO] [xxx-xxx.iobb.net] acme: Could not find solver for: tls-alpn-01
2022/04/17 19:37:06 [INFO] [xxx-xxx.iobb.net] acme: use http-01 solver
2022/04/17 19:37:06 [INFO] [xxx-xxx.iobb.net] acme: Trying to solve HTTP-01
2022/04/17 19:37:14 [INFO] [xxx-xxx.iobb.net] The server validated our request
2022/04/17 19:37:14 [INFO] [xxx-xxx.iobb.net] acme: Validations succeeded; requesting certificates
2022/04/17 19:37:15 [INFO] [xxx-xxx.iobb.net] Server responded with a certificate.
PS D:\Service\lego>

・実行失敗例
nginxの認証に使用するフォルダ指定を間違えて最初に実行したときのログ
認証用ファイルは作成されたがWeb上からアクセスできなかったので失敗した。
これは04WebServerとWin-acmeから実施した際も同様のエラーログが出ていたのだが結局解決できなかった。

PS D:\Service\lego> .\lego --accept-tos --http --http.webroot d:\Service\nginx\html --domains xxx-xxx.iobb.net --path d:\Service\lego\ssl --email xxx@xxx-xxx.iobb.net run
2022/04/17 19:35:42 No key found for account xxx@xxx-xxx.iobb.net. Generating a P256 key.
2022/04/17 19:35:42 Saved key to d:\Service\lego\ssl\accounts\acme-v02.api.letsencrypt.org\xxx@xxx-xxx.iobb.net\keys\xxx@xxx-xxx.iobb.net.key
2022/04/17 19:35:42 [INFO] acme: Registering account for xxx@xxx-xxx.iobb.net
!!!! HEADS UP !!!!

Your account credentials have been saved in your Let's Encrypt
configuration directory at "d:\Service\lego\ssl\accounts".

You should make a secure backup of this folder now. This
configuration directory will also contain certificates and
private keys obtained from Let's Encrypt so making regular
backups of this folder is ideal.
2022/04/17 19:35:43 [INFO] [xxx-xxx.iobb.net] acme: Obtaining bundled SAN certificate
2022/04/17 19:35:43 [INFO] [xxx-xxx.iobb.net] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/99165718980
2022/04/17 19:35:43 [INFO] [xxx-xxx.iobb.net] acme: Could not find solver for: tls-alpn-01
2022/04/17 19:35:43 [INFO] [xxx-xxx.iobb.net] acme: use http-01 solver
2022/04/17 19:35:43 [INFO] [xxx-xxx.iobb.net] acme: Trying to solve HTTP-01
2022/04/17 19:35:47 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz-v3/99165718980
2022/04/17 19:35:47 Could not obtain certificates:
error: one or more domains had a problem:
[xxx-xxx.iobb.net] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Invalid response from http://xxx-xxx.iobb.net/.well-known/acme-challenge/QZR0-_8U8NRJ7_jT93NVm4fYcvTwwzz_F_DEgb663YU [49.135.46.198]: 404

・発行された証明書ファイル関連
無事証明書が発行されるとlegoで指定したフォルダに各種フォルダとファイルが作成されれる。
作成されるフォルダのうちcertificatesフォルダ内に
証明書:xxx-xxx.iobb.net.crt
秘密鍵:xxx-xxx.iobb.net.key
がpem形式で作成される。

・SSLオフロードの試験
証明書と秘密鍵が取れたのでそれを使用してSSLオフロードが正常に機能するかテストを実施。
SSLオフロード自体は自己証明書を用いて既に試験済み。

・nginx設定
冒頭のnginxのHTTP SERVER設定ファイルに以下の設定を追加。
# SSL OFFLOAD
stream {
  server {
    listen 443 ssl;
    ssl_certificate D:/Service/lego/ssl/xxx-xxx.iobb.net.crt;
    ssl_certificate_key D:/Service/lego/ssl/xxx-xxx.iobb.net.key;
    proxy_connect_timeout 10s;
    proxy_timeout 10s;
    proxy_pass 127.0.0.1:80;
  }
}

・Webサーバアクセス確認
WEBブラウザからHTTPSでURLへアクセスを実施しnginxのWeb用ページを表示。
2204179001
SSLオフロードが有効に機能し取得した証明書を用いてコネクションがTLSv1.2で暗号化出来ていることを確認できた。

一応WebサーバのTLSv1.2対応はおまけでメインはメールサービスをTLSv1.2に対応させるのが目的なので、今後は証明書の自動更新テストを行い問題無ければ本番ドメインでの証明書取得と自動更新及びnginxでpop3とsmtpのSSLオフロード設定を行う予定。
テスト環境では自己証明書を用いての一連のテストは実施済みなので証明書の自動更新さえ上手くいけば運用に問題はなさそうである。

|

« NginxをWindowsのコマンドラインから操作するバッチファイル | トップページ | Celeron N5095搭載のミニPCを購入 »

パソコン・インターネット」カテゴリの記事

ソフトウェア」カテゴリの記事

ネットワーク」カテゴリの記事

nginx」カテゴリの記事

lego」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




« NginxをWindowsのコマンドラインから操作するバッチファイル | トップページ | Celeron N5095搭載のミニPCを購入 »