containerlabとstepcaを使ってLet’s Encryptのようなサーバー証明書の自動発行をローカル環境で実験する方法

# はじめに

Let’s Encrypt

https://letsencrypt.org/ja/

を使ったサーバー証明書の自動発行をローカルのテスト環境で体験する方法を紹介します。

# テストネットワーク環境

containerlab

https://containerlab.dev/

を使います。

containerlabの環境は

https://note.com/twsnmp/n/n654b27d0b25e

を参照してください。


# ACME対応の認証局（CA)

stepca

https://smallstep.com/docs/step-ca/#introduction-to-step-ca

のDokcer版


https://hub.docker.com/r/smallstep/step-ca

を使います。




# 必要なディレクトリーの作成

```terminal
#cd /root
#mkdir stepca_clab
#cd stepca_clab
#mkdir step
#chmod a+w step
```

/root/stepca_clabに、トポロジーファイルとDockerfileを作成します。


# トポロジーファイル

認証局(ca)と証明書を取得するクライアント(cli)を設置したトポロジーファイルを作成します。

```yaml:stepca.clab.taml
name: step-ca

topology:
  nodes:
    ca:
      kind: linux
      image: smallstep/step-ca
      binds:
        - /root/stepca_clab/step:/home/step
      ports:
        - 9000:9000
      env:
        DOCKER_STEPCA_INIT_NAME: ca
        DOCKER_STEPCA_INIT_DNS_NAMES: localhost,ca
        DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT: true
        DOCKER_STEPCA_INIT_ACME: true
    cli:
      kind: linux
      image: cli

```

step-caのDockerイメージは、DockerHUBからダウンロードします。


# クライントのDockerイメージ

クライントは、step-caやstep-cliのイメージは使わずに自分でビルドします。

Dockerfileは

```Dockerfile
FROM debian
ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update -qy \
   && apt-get upgrade -qy \
   && apt-get install -y \
   certbot \
   wget \
   && rm -rf /var/lib/apt/lists/*
RUN wget https://dl.smallstep.com/cli/docs-cli-install/latest/step-cli_amd64.deb &&  dpkg -i step-cli_amd64.deb

```

です。

```terminal
#cd /root/stepca_clab
#docker build -t cli .
```
でビルドします。

# containerlabの起動

準備ができたら

```terminal
#clab deploy
```
を実行します。

# CAのパスワードとフィンガープリントを確認

CAのコンテナのログを表示します。

```terminal
#docker logs clab-step-ca-ca
|
👉 Your CA administrative username is: step
👉 Your CA administrative password is: <パスワード>
🤫 This will only be displayed once.
|
2025/02/23 06:54:19 Additional configured hostnames: ca
2025/02/23 06:54:19 X.509 Root Fingerprint: <フィンガープリント>

|

```
のようにCAのパスワードとフィンガープリントがあるので、コピーしておきます。
フィンガープリントは、

```terminal
cat step/config/defaults.json
{
	"ca-url": "https://localhost:9000",
	"ca-config": "/home/step/config/ca.json",
	"fingerprint": "<フィンガープリント>",
	"root": "/home/step/certs/root_ca.crt"
}
```

でも確認できます。

# クライアンでstep caコマンドの初期化

```terminal
#docker exec -it  clab-step-ca-cli /bin/bash
```

でクライアントコンテナ内のシェルに接続します。
```terminal
root@cli:/#step ca bootstrap --ca-url https://ca:9000 --fingerprint <確認したフィンガープリント>  --install
```

成功すれば、必要な設定ファイルとCAの証明書がインストールされます。

# step caコマンドで証明書の発行

step ca certificateを実行すると

```terminal
root@cli:/# step ca certificate cli  cli.crt cli.key
Use the arrow keys to navigate: ↓ ↑ → ←
What provisioner key do you want to use?
  ▸ acme (ACME)
    admin (JWK) [kid: Uqxu8jPb1z0JplP_yW8WDIFcqB3gn4IYNef4uRYw2Dw]
```

のようになります。ACMEを選択すれば、証明書と秘密鍵のファイルが作成されます。
JWKを選択した場合は、パスワードを聞かれるので、先程ログで確認したパスワードを入力すれば、
発行されます。

# Certbotで証明書を取得する

クライアントのコンテナには、Certbot

https://certbot.eff.org/

もインストールされています。
certbotで証明書を取得するには、

```terminal
root@cli:/#  REQUESTS_CA_BUNDLE=$(step path)/certs/root_ca.crt     certbot certonly -n --standalone -d cli     --server https://ca:9000/acme/acme/directory --agree-tos --email test@example
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for cli

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/cli/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/cli/privkey.pem
This certificate expires on 2025-02-24.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

```

のようにします。



# 自動作成された証明書を確認してみる

opensssl x509コマンドで確認できます。

```terminal

root@cli:/# openssl x509 -in /etc/letsencrypt/live/cli/fullchain.pem -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            c4:68:fa:98:08:4d:09:32:fd:04:35:4d:99:d4:e7:90
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: O = ca, CN = ca Intermediate CA
        Validity
            Not Before: Feb 23 08:30:33 2025 GMT
            Not After : Feb 24 08:31:33 2025 GMT
        Subject:
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:3b:3e:72:da:c5:5c:03:7e:07:50:38:00:19:63:
                    59:f8:f8:f1:42:bf:52:8b:d7:c0:50:64:f6:92:38:
                    06:e8:ef:ee:ba:79:4a:7d:22:2b:a2:10:27:c2:26:
                    92:57:3a:ab:3b:c4:02:56:77:02:dc:35:d8:f5:d6:
                    ad:a8:3c:c2:23
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Key Identifier:
                FC:62:54:43:E7:4C:C5:49:E4:F6:F5:3C:42:4E:3C:A4:60:2F:69:AE
            X509v3 Authority Key Identifier:
                CC:F2:F5:31:FF:15:B1:8E:BC:92:92:D8:55:F0:6D:34:BD:E7:29:12
            X509v3 Subject Alternative Name: critical
                DNS:cli
            1.3.6.1.4.1.37476.9000.64.1:
                0......acme..
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:44:02:20:3d:83:5f:82:95:de:09:67:51:de:8a:05:61:d2:
        5f:b7:b1:19:cb:28:03:58:17:75:63:7d:79:3f:ae:72:2a:94:
        02:20:2f:a4:e6:c8:ed:47:ac:20:fc:58:92:8a:c7:8e:e1:c0:
        02:95:66:6a:cf:a8:94:c2:82:8d:d1:86:83:bc:c7:6c

```


# 余談

この記事は、

https://note.com/twsnmp/n/n94746187a3e1

の学習の副産物として書いています。

PKI機能を

https://note.com/twsnmp/n/na5c62f59833d

に追加しようと思って調べています。