はじめに
SAN付きの localhost
に対する自己証明書について学びたかったため、備忘録として記載する。
環境
Windows 10 Professional
WSL2 - (Ubuntu22.04 LTS)
Docker desktop 4.19.0 (106363)
Docker version 23.0.5
Docker Compose version v2.17.3
準備
まずは、適当なwebサーバを用意したいので、nginx
をDockerで構築する。
nginxをDockerで構築する
ディレクトリ構造
最終的なツリー構造は下記になる。
.
├── compose.yml
└── nginx
├── conf
│ └── certs
│ ├── san.txt
│ ├── server.crt
│ ├── server.csr
│ └── server.key
├── conf.d
│ ├── default.conf
│ └── ssl.conf
└── html
└── index.html
compose.yml の作成
1つずつ作成する。
まずは、 compose.yml
を下記のように作成する。
services:
nginx:
image: nginx:1.25.1
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/conf/certs:/etc/nginx/certs
- ./nginx/html:/usr/share/nginx/html:ro
ports:
- "80:80"
- "443:443"
80
, 443
は空けておきアクセスできるようにする。volume
には、設定ファイル、証明書、確認できるように html
をマウントしておく。
html の作成
次に、確認用の html
を作成する。nginx/html
フォルダを作成し、その中に index.html
を作成する。
中身は下記のようにした。
<p>Hello,World</p>
確認用のため最小限にした。
設定ファイルの作成
次に、設定ファイルを作成する。nginx/conf.d
フォルダを作成し、その中に default.conf
および ssl.conf
を作成する。
まずは、default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
次に、ssl.conf
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
location / {
root /usr/share/nginx/html;
}
}
これでOK。
SAN付き自己証明書の作成
最後に証明書を作成する。nginx/conf/certs
フォルダを作成し、中に移動する。
まずは、 今回の肝である san.txt
を作成する。
san.txt
は下記のように作成。
subjectAltName = DNS:localhost, IP:127.0.0.1
その後、 key
, crt
, csr
を作成するため、下記で証明書を作成するコマンドを実行する。
秘密鍵の作成
openssl genrsa -out server.key 2048
CSRの作成
openssl req -out server.csr -key server.key -new
下記のようにほとんど適当にやった。
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
証明書の作成
openssl x509 -req -days 3650 -signkey server.key -in server.csr -out server.crt -extfile san.txt
最後にSANが付与されているかをチェックする。
openssl x509 -text -in server.crt -noout
下記のような記述があればOK.
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost, IP Address:127.0.0.1
ここまでで準備は完了。
実際に下記のコマンドで立ち上げてみる。
docker compose up -d
↓httpはOKですね!(http://localhost/)
↓httpsもOK! (https://localhost/)
証明書の確認は下記でチェックする。
「鍵マーク」をクリック→鍵のマーク(この接続は~)→「証明書~」
つけたDNS名、IPアドレスがあることを確認できた。
自己証明書をルート証明書としてインポート
先程のセクションで確認したhttps
の表示、
この保護されていない通信
って表示されるのは心理的に嫌な気持ちになる。
なので、下記の手順でブラウザに証明書をインポートし、信頼できる証明書とするようにしてみる。
インストールできているかの確認
「信頼されたルート証明機関」に localhost
が入っていればOK
ブラウザでの確認
※証明書の読み込みにブラウザを再起動する必要があるかもしれない
https://localhost にアクセスすると下記のように鍵マークが割れていないことを確認できる。
ちなみに、ブラウザごとに証明書を管理しているため、Firefox
では信頼されていないことを確認できる。
参考
- OpenSSL で SAN 付きの自己署名証明書を作成する
https://kuttsun.blogspot.com/2020/04/openssl-san.html - サーバ名がIPアドレスの場合の証明書作成 / サブジェクト代替名 (SAN) の設定方法
https://tex2e.github.io/blog/protocol/certificate-with-ip-addr - SSL証明書の内容をopensslで確認する
https://qiita.com/m-chika/items/e4936feb4087b7ddbe8b - イマドキの証明書は全部マルチドメイン証明書
https://qiita.com/testnin2/items/0fb2211dffae2ffaec7a - 証明書の OU(組織単位名)は非推奨へ、来年からは利用禁止に
https://www.cybertrust.co.jp/blog/ssl/regulations/ou-usage-prohibit.html
おわりに
証明書のトレンドはいつの間にか変わっていることが多い。
というのも、証明書の更新は1年に1回だったり、3年に1回だったりで期間が空いてしまい、なおかつ1回だけということもあるからだ。
期間が空く定常したタスクほど調べるのが億劫になってしまうのは嫌だなと思いつつも、やってしまう。
最近だと、Let’s Encryptなどで自分で証明書を発行するということもないので、よりこのあたりの情報がないので定期的に知識をアップデートしないとなと思う。