能書き
私的サーバー構築日誌:仕切り直しからの自宅サーバー構築の続きです。
認証局の構築は以前もやりまして、その焼き直しですが。そのまま再掲でも詰まらないので、関連コマンドをdockerコンテナの中に封じ込めてみます。
概要説明と参考文献
ものすご~く端的に言うと。
周知の通り、証明書はそれだけでは用を為しません。証明書が正しい事を証明する為に電子署名する機関が認証局であり、取り敢えず無条件で信用するのがルート認証局です。全ての署名はこのルート認証局の信用に依って成り立っています。
ルート認証局は、通常は社会的合意に基づいて信用されます。しかしコストなどの問題から私的用途の為にはルート認証局を自分で用意する事があります。これがプライベート認証局、通称オレオレ認証局です。
このような認証基盤の全貌をPKIと呼びます。
これについては下記文献に丁寧な説明があります。
参考文献:認証局(CA)の役割 ~PKI基礎②~ - マイクロソフ党ブログ
参考文献:電子メールのセキュリティ(5) ~ 認証局(CA)とPKI ~ - 基礎からわかる!パソコン入門・再入門
UbuntuにはデフォルトでOpenSSLがインストールされています。これでオレオレ認証局を作る事も出来ますが、手順が少々面倒臭い。
例えば下記の記事が図解も入っていて分かり易い。しかしこの記事はCentOSなんですよね。残念。
参考文献:OpenSSLでプライベート認証局の構築(ルートCA、中間CA) - Qiita
Ubuntuの場合は下記が参考になりそうです。微妙に古くなりかけていますが。
参考文献:Ubuntu 18.04 LTS で OpenSSL を使ったプライベート認証局&証明書を作る - 未完放流
なお、OpenVPNプロジェクトの中でこの手間を軽減するツールが作られているようで、easy-rsaと呼ばれています。easy-rsaを用いた手順は、ちょっとぐぐればそこら中に解説記事があります。例えば下記など。
参考文献:easy-rsaでプライベートCA(認証局)を作ってオレオレ証明書ではないローカル用TLS証明書の管理をする
参考文献:easy-rsa 3 で認証局を構築する - yamata::memo
因みに、認証局なんて面倒臭い事をしないでドカンとオレオレ証明書を作っちまえ!と思ったら、少なくともKerberosではうまくいかないらしい。他にもダメな事例が散見されるようです。
参考文献:KerberosのバックグラウンドにOpenLDAPを使う - Qiita
そういう訳で、この記事ではeasy-rsaを使ってみます。
目標
- easy-rsaを使用してルート認証局を作る所までを実施します。
- Dockerコンテナを作り、一連のコマンド操作はその中で実施します。
easy-rsaのコンテナを作成
スナップショット
スナップショットだいじ。超だいじ。
sudo zfs snapshot tank/root/ubuntu@$(date +%Y%m%d_%H%M%S)_before_easy-rsa
取り扱いユーザー作成
certというユーザーを作成し、ログイン禁止にして、証明書などはこれに扱わせます。
こういう時にどういうユーザーを作成するのがLinux的に一般的なのかわかりません。ログイン禁止という要請からパスワードを設定しないユーザーを作成してみました。
こういう場合の定石を御存知の方がいらっしゃいましたら御教示お願いします
CA_USER=cert
sudo zfs create -o com.ubuntu.zsys:bootfs-datasets=tank/root/ubuntu -o canmount=on -o mountpoint=/home/$CA_USER tank/userdata/$CA_USER
sudo useradd -s /bin/bash $CA_USER
sudo cp -a /etc/skel/. /home/$CA_USER
sudo chown -R $CA_USER:$CA_USER /home/$CA_USER
sudo usermod -aG docker $CA_USER
パスワードを設定していないのでsshログインできません。su
コマンドでも一般ユーザーからcertになる事は出来ません。
$ su $CA_USER
Password:
rootユーザーとしてcertになります。少々面倒ですが。まあ、普段は滅多にやらない操作なので我慢します。セキュリティとはそういう物でしょう。たぶん。
$ sudo su $CA_USER
$ whoami
cert
$ exit
exit
/etc
を確認。
sudo svn di --diff-cmd diff -x -U0 /etc
こうなりました。
$ sudo svn di --diff-cmd diff -x -U0 /etc
Index: /etc/group
===================================================================
--- /etc/group (revision 13)
+++ /etc/group (working copy)
@@ -60 +60,2 @@
-docker:x:999:admin
+docker:x:999:admin,cert
+cert:x:1001:
Index: /etc/gshadow
===================================================================
--- /etc/gshadow (revision 13)
+++ /etc/gshadow (working copy)
@@ -60 +60,2 @@
-docker:!::admin
+docker:!::admin,cert
+cert:!::
Index: /etc/passwd
===================================================================
--- /etc/passwd (revision 11)
+++ /etc/passwd (working copy)
@@ -32,0 +33 @@
+cert:x:1001:1001::/home/cert:/bin/bash
Index: /etc/shadow
===================================================================
--- /etc/shadow (revision 11)
+++ /etc/shadow (working copy)
@@ -32,0 +33 @@
+cert:!:19596:0:99999:7:::
Index: /etc/subgid
===================================================================
--- /etc/subgid (revision 10)
+++ /etc/subgid (working copy)
@@ -1,0 +2 @@
+cert:165536:65536
Index: /etc/subuid
===================================================================
--- /etc/subuid (revision 10)
+++ /etc/subuid (working copy)
@@ -1,0 +2 @@
+cert:165536:65536
Index: /etc/zfs/zfs-list.cache/tank
===================================================================
--- /etc/zfs/zfs-list.cache/tank (revision 12)
+++ /etc/zfs/zfs-list.cache/tank (working copy)
@@ -6,0 +7 @@
+tank/userdata/cert /home/cert on on on on on off on off - none - - - - - - --
コミットします。
sudo svn ci -m"user $CA_USER" /etc
コンテナ作成
まずはcertユーザーになります。
sudo su $CA_USER
認証局の名前は、今回はdemoCA
とします。
CA_NAME=demoCA
cd
mkdir $CA_NAME
docker-compose.yml
ファイルはこうなります。
cat <<___ >docker-compose.yml
version: '3.8'
services:
ca:
build: .
volumes:
- .:/mnt
tty: true
___
そしてDockerfile
です。
cat <<___ >Dockerfile
FROM ubuntu:22.04
RUN groupadd -g $(id -g) $USER \
&& useradd -u $(id -u) -g $(id -g) -s /bin/bash $USER \
&& apt update \
&& apt upgrade -y \
&& apt install -y easy-rsa
___
このDockerfileだと、必要なインストールは起動した時に完了します。
docker compose up -d
dockerコンテナ内でcertユーザーになれる事を確認します。
docker compose exec -e CA_USER=$USER ca /bin/bash
su $CA_USER
whoami
exit
exit
easy-rsaを利用したルート認証局の作成
Dockerコンテナに入る
コンテナに入り、certユーザーになります。
cd
cd $CA_NAME
docker compose exec -e CA_USER=$USER -e CA_NAME=$CA_NAME ca /bin/bash
su $CA_USER
公開鍵インフラストラクチャ(PKI)ディレクトリの準備
cd /mnt/$CA_NAME
ln -s /usr/share/easy-rsa/* .
./easyrsa init-pki
認証局(CA)の作成
まずは所定のディレクトリにvar
ファイルを作成します。
/opt/demoCA/vars.example
というファイルがあるのでこれを編集すれば良さそうですが、ここでは下記のように新規作成します。それぞれの値は自分の状況に応じて修正して下さい。忘れた頃に騒ぎになるのが嫌なので、私は百年認証局にしました。
cat <<___ >pki/vars
set_var EASYRSA_ALGO "ec"
set_var EASYRSA_DIGEST "sha512"
set_var EASYRSA_CA_EXPIRE 36524
___
次に、認証局のルート公開鍵と秘密鍵のペアを作成します。
下記コマンドを実行すると、キーペアのパスフレーズを入力するように求められます。必ず強力なパスフレーズを入力し、安全な場所に書き留めます。
更に、CAの共通名(CN; Common Name)を確認するように求められます。CNは、認証局のコンテキストでこのマシンを参照するために使用される名前です。任意の文字列を入力できますが、インターネット上で使う予定があれば自分の所有しているドメインにするのが良いでしょう。今回はLAN内のDNSサーバで管理しているマシン名にします。
./easyrsa build-ca
.rnd
ファイルを開けないエラーが発生する事がありますが、今回は特に問題無いようです。万が一そのようなエラーが発生したら、以前の記事を参照ください。
パスフレーズとCNを入力して成功すると、下記の2ファイルが生成されます。
- CAの公開鍵
/mnt/demoCA/pki/ca.crt
- CAの秘密鍵
/mnt/demoCA/pki/private/ca.key
秘密鍵は絶対に漏らしてはいけない物になります。
内容確認
作った認証局の内容を確認します。
参考文献:opensslコマンドでサーバーにアクセスして確認する - opensslコマンドを使ったSSL証明書の確認方法 - やさしいopensslコマンドによるSSL証明書の確認方法 - Oji-Cloud
参考文献:証明書の期限確認 - 発行されたSSL証明書の内容 - SSL証明書の内容をopensslで確認する
cd /mnt/$CA_NAME/pki
openssl x509 -text -in ca.crt | grep -E "Issuer:|Subject:"
openssl x509 -dates -noout -in ca.crt
下記の実行例は、作成時にCN(Common Name)としてdemoCA
を指定した場合の結果です。
$ cd /mnt/$CA_NAME/pki
$ openssl x509 -text -in ca.crt | grep -E "Issuer:|Subject:"
Issuer: CN = demoCA
Subject: CN = demoCA
$ openssl x509 -dates -noout -in ca.crt
notBefore=Aug 20 07:52:32 2023 GMT
notAfter=Aug 20 07:52:32 2123 GMT
ホストマシンでも確認できます。
まずはコンテナを抜けます。
exit
exit
それから確認。
cd
cd $CA_NAME/pki
openssl x509 -text -in ca.crt | grep -E "Issuer:|Subject:"
openssl x509 -dates -noout -in ca.crt
Dockerコンテナ内での確認と同じ結果を得られます。
$ openssl x509 -text -in ca.crt | grep -E "Issuer:|Subject:"
Issuer: CN = demoCA
Subject: CN = demoCA
$ openssl x509 -dates -noout -in ca.crt
notBefore=Aug 20 07:52:32 2023 GMT
notAfter=Aug 20 07:52:32 2123 GMT
最後に。certユーザーから抜けて終わりです。
exit
仕舞い
ルート認証局、通称オレオレ認証局を作成しました。役に立つのは証明書を作成した時になりますが、その作成手順はまた後日にします。
利用するマシン全部にインポートが必要なのでちょっと面倒ですが、自分だけの証明書を無料で設定する準備が出来ました。