Windows nginx + .NET8 Blazor & Flask アプリ + certbot Let's Encrypt 証明書  *.exaple.com https(TLS/SSL) 公開するメモ。

# 環境
Windows 11 Pro 23H2
Python  3.12.5
pyenv   3.1.1
pip     24.2
certbot 2.11.0
flask   2.1.5

# 証明書があるフォルダ

```bat
*.pem証明書があるフォルダ
C:/Certbot/live/example.com/
```

# certbot インストール
```bat
> pip install certbot
> where certbot
C:\Users\admin\.pyenv\pyenv-win\shims\certbot
C:\Users\admin\.pyenv\pyenv-win\shims\certbot.bat
```

# DNS-01チャレンジでワイルドカード証明書を取得する
`*example.com` のようなワイルドカード証明書を取得するには [DNS-01チャレンジ](https://letsencrypt.org/ja/docs/challenge-types/) を使用する必要があるようだ。
この記事を参考にやってみる。
[Let's EncryptのDNS-01チャレンジでのSSL証明書更新（手動）](https://qiita.com/gbgb-ojisan/items/be8a35270a84b6b7ca2e)

```管理者権限のDOS窓で.bat
> certbot certonly --manual --server https://acme-v02.api.letsencrypt.org/directory --preferred-challenges dns -d *.example.com -d example.com -m bakabon.oop@gmail.com --agree-to

Saving debug log to C:\Certbot\log\letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N ← 入力

Account registered.
Requesting a certificate for *.example.com and example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

_acme-challenge.example.com.

with the following value:

LKnLeYiTe3Kq_G0eRCAMxguvumYh6Xyl3vAQIjO0k3M

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue ← ★
```
★ Enter 押しちゃダメ！

**DNS設定**
onamae https://www.onamae.com/domain/navi/dns_manage で
ホスト名 ： _acme-challenge
TYPE : TXT
VALUE : LKnLeYiTe3Kq_G0GRTfdxguvumYh6Xyl3vAQIjOddr 指定された値

数分？待つ

https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.example.com
にアクセスして値が反映されているか確認する。
反映されていれば **Enter**

```bat
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

_acme-challenge.example.com.

with the following value:

gSPCf0ahlz5Qn9K7YdtjbqDNyQddJlbLq-XAWc_FXss

(This must be set up in addition to the previous challenges; do not remove,
replace, or undo the previous challenge tasks yet. Note that you might be
asked to create multiple distinct TXT records with the same name. This is
permitted by DNS standards.)

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.example.com.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
```
もう1度★を繰り返す。
以前登録した値は<font color="#ff0000">**消さないで追加**</font>する。

https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.example.com
にアクセスして値が 【２つ】反映されているか確認する。
反映されていれば **Enter**

```bat
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Successfully received certificate.
Certificate is saved at: C:\Certbot\live\example.com\fullchain.pem
Key is saved at:         C:\Certbot\live\example.com\privkey.pem
This certificate expires on 2024-12-29.
These files will be updated when the certificate renews.

NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
```

証明書取得成功！


```証明書取得確認コマンド.bat
> certbot certificates
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: example.com
    Serial Number: 4b83c3a61bdb516f37Hgatce74853f89505
    Key Type: ECDSA
    Domains: example.com
    Expiry Date: 2024-12-17 02:13:45+00:00 (VALID: 78 days)
    Certificate Path: C:\Certbot\live\example.com\fullchain.pem
    Private Key Path: C:\Certbot\live\example.com\privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
```

# 証明書の手動更新
[証明書取得制限](https://letsencrypt.org/ja/docs/rate-limits/)があるのでまずテストで実行するのが吉
```【テスト】証明書更新コマンド.bat
> certbot renew --dry-run
```
```証明書更新コマンド.bat
> certbot renew
```
※ renew 実行すると有効期限まで残り30日以下なら更新する。
```強制的に証明書更新コマンド.bat
> certbot --force-renewal
```
※ [証明書取得制限](https://letsencrypt.org/ja/docs/rate-limits/)があるので乱用注意

# タスクスケジューラーに登録して毎日実行
<font color="#ff0000">**管理者権限で実行するように登録**</font>
```update_ca.bat
certbot renew
```

# Windows版 nginx インストール
[nginx 公式 ダウンロード](https://nginx.org/en/download.html)
nginx/Windows-1.27.1 をダインロードzip解凍して`c:\nginx`に配置
```管理者権限DOS窓.bat
> cd c:\nginx
> .\nginx

ブラウザで localhost 確認
```

# nginx リバースプロキシとして設定
- ドメイン : *.example.com
- Blazorアプリ : blazor.example.com
- Flaskアプリ : flask.example.com
※ `C:\nginx\conf\nginx.conf` はバックアップする
```C：\nginx\conf\nginx.conf
http {
    # HTTPS (blazoe.example.com - Blazorアプリ)
    server {
        listen 443 ssl;
        server_name blazoe.example.com;

        ssl_certificate C:/Certbot/live/example.com/fullchain.pem;
        ssl_certificate_key C:/Certbot/live/example.com/privkey.pem;

        location / {
            proxy_pass http://localhost:5000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    # HTTPS (flask.example.com - Flaskアプリ)
    server {
        listen 443 ssl;
        server_name flask.example.com;

        ssl_certificate C:/Certbot/live/example.com/fullchain.pem;
        ssl_certificate_key C:/Certbot/live/example.com/privkey.pem;

        location / {
            proxy_pass http://localhost:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}
```

# nginx 基本コマンド & 証明書適用確認コマンド
`C:\nginx` パスは通っていない
```bat
サーバー開始
> .\nginx  

サーバー停止
> .\nginx -s stop

設定再読み込み
> .\nginx -s reload

証明書が適用されているか確認
> openssl s_client -connect example.com:443 -showcerts
```

# Flask + waitress WEBアプリ
フォルダはどこでもよい。
nginx のリバースプロキシはアクセスしたFQDNを nginx.conf で設定した<font color="#ff0000">ローカルポートに転送</font>する。
```flask.py

from flask import Flask
from waitress import serve

app = Flask(__name__)


@app.route("/")
def hello():
    return "こんにちは nginx portfolio. waitress + flask 8080"


if __name__ == "__main__":
    serve(app, host='0.0.0.0', port=8000)
```

# .NET8 Blazor WEBアプリ
Visual Studio 2022 で期待通りに動くMyAppを発行して、コマンドラインから IIS Express で起動しようと何パターンもチャレンジしたが失敗が続いてる orz
お預け

# ポート開放
※ 注意はまった部分
- ESET ポート開放
- Windows Defender ポート開放
- ルーター ポート開放

<font color="#ff0000">**ポート開放確認コマンド**</font>
```powershell
PS Test-NetConnection -ComputerName example.com -Port 443
```