自宅サーバー構築譚：オレオレ認証局

# 能書き

[自宅サーバー構築譚：基本構想](https://qiita.com/katz_engineer/items/cb592be44daa28a51d9b)に基づく自宅サーバー構築、[Ubuntu22.04LTSインストールその2](https://qiita.com/katz_engineer/items/033471b69143bf76650e)の続きです。

[以前](https://qiita.com/katz_engineer/items/afd9435bb8a04e33ee8b)もやりまして、その焼き直しです。

ものすご～く端的に言うと。

周知の通り、証明書はそれだけでは用を為しません。証明書が正しい事を証明する為に電子署名する機関が認証局であり、取り敢えず無条件で信用するのがルート認証局です。全ての署名はこのルート認証局の信用に依って成り立っています。

ルート認証局は、通常は社会的合意に基づいて信用されます。しかしコストなどの問題から私的用途の為にはルート認証局を自分で用意する事があります。これがプライベート認証局、通称オレオレ認証局です。

このような認証基盤の全貌を PKI と呼びます。

これについては下記文献に丁寧な説明があります。

参考文献：[認証局（CA）の役割　～PKI基礎②～ - マイクロソフ党ブログ](https://microsoftou.com/role-of-ca/)
参考文献：[電子メールのセキュリティ（5） ～ 認証局（CA）とPKI ～ - 基礎からわかる！パソコン入門・再入門](https://www.yamanjo.net/knowledge/internet/internet_20.html)

Ubuntu にはデフォルトで OpenSSL がインストールされています。これでオレオレ認証局を作る事も出来ますが、手順が少々面倒臭い。 
例えば下記の記事が図解も入っていて分かり易い。しかしこの記事は CentOS なんですよね。残念。

参考文献：[OpenSSLでプライベート認証局の構築（ルートCA、中間CA） - Qiita](https://qiita.com/bashaway/items/ac5ece9618a613f37ce5)

Ubuntu の場合は下記が参考になりそうです。微妙に古くなりかけていますが。

参考文献：[Ubuntu 18.04 LTS で OpenSSL を使ったプライベート認証局＆証明書を作る - 未完放流](https://idwonder21.hatenablog.com/entry/2019/03/03/123510)

なお、 OpenVPN プロジェクトの中でこの手間を軽減するツールが作られているようで、 easy-rsa と呼ばれています。 easy-rsa を用いた手順は、ちょっとぐぐればそこら中に解説記事があります。例えば下記など。

参考文献：[easy-rsaでプライベートCA(認証局)を作ってオレオレ証明書ではないローカル用TLS証明書の管理をする](https://r-o-head.tk/post/private-ca-with-easy-rsa/)
参考文献：[easy-rsa 3 で認証局を構築する - yamata::memo](https://yamatamemo.blogspot.com/2014/01/easy-rsa-3.html)

因みに、認証局なんて面倒臭い事をしないでドカンとオレオレ証明書を作っちまえ！と思ったら、少なくとも Kerberos ではうまくいかないらしい。

参考文献：[KerberosのバックグラウンドにOpenLDAPを使う - Qiita](https://qiita.com/kanatatsu64/items/ec50707002c5dbd7330d#tls%E3%81%AE%E6%9C%89%E5%8A%B9%E5%8C%96)

そういう訳で、この記事では easy-rsa を使ってみます。使わない場合も考えたんですが、心が折れました。

追伸。LDAP も TLS とかで証明書が活躍する使い方があります。それで、LDAPのインストールよりも先に認証局を作る事にしました。

参考文献：[LDAP & TLS - Ubuntu Server](https://ubuntu.com/server/docs/service-ldap-with-tls)

# ssh で接続

OpenSSH サーバを設定してあるので、ログインして root になっておきます。

```console
sudo -i
```

# easy-rsa のインストール

## スナップショット

[スナップショットだいじ。超だいじ。](https://qiita.com/katz_engineer/items/f3bd2f7af2ba49db156c#%E3%82%B9%E3%83%8A%E3%83%83%E3%83%97%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90)

```console
zfs snapshot tank/ROOT/ubuntu@$(date +%Y%m%d_%H%M%S)_before_OpenSSL
zfs snapshot tank/ROOT/ubuntu/var/lib/apt@$(date +%Y%m%d_%H%M%S)_before_OpenSSL
zfs snapshot tank/ROOT/ubuntu/var/lib/dpkg@$(date +%Y%m%d_%H%M%S)_before_OpenSSL
```

## インストール

```console
apt-get install -y easy-rsa
```

ただ、なぜかOpenSCのパッケージが同時にインストールされます。ICカードリーダのライブラリのようですが、理由の見当が付きません。ぐぐっても解説記事が無いようですし。よくわかりません。

```console
The following NEW packages will be installed:
  easy-rsa libccid libpcsclite1 opensc opensc-pkcs11 pcscd
```

## /etc バージョン管理

インストール直後の /etc をバージョン管理します。まずは確認。

```console
svn st /etc
```

こう表示されました。

```console
?       /etc/init.d/pcscd
M       /etc/ld.so.cache
?       /etc/libccid_Info.plist
?       /etc/opensc
?       /etc/rc0.d/K01pcscd
?       /etc/rc1.d/K01pcscd
?       /etc/rc2.d/K01pcscd
?       /etc/rc3.d/K01pcscd
?       /etc/rc4.d/K01pcscd
?       /etc/rc5.d/K01pcscd
?       /etc/rc6.d/K01pcscd
?       /etc/reader.conf.d
?       /etc/systemd/system/sockets.target.wants/pcscd.socket
```

pcscd関係のみの模様ですが、これをcommitします。

```console
svn st /etc | grep "^?" | cut -b9- | xargs -I{} find {} -type f -or -type d -or -type l | xargs -t svn add
svn ci /etc -m"installed Easy RSA"
```

## 専用ユーザは作りません

本当はここでCA管理用ユーザを作るのですが。このサーバ構築では、後に LDAP を利用したユーザ管理を導入しようと考えてますので、新規ユーザはそれまでお預けにします。今回は root ユーザでCAを管理する事にします。


# easy-rsa を利用したルート認証局の作成

##  公開鍵インフラストラクチャ(PKI)ディレクトリの準備

root のホームディレクトリではなく ```/opt/CA``` ディレクトリに作成します。

```console
mkdir -p /opt/CA
chmod 700 /opt/CA/
cd /opt/CA/
mkdir demoCA
cd demoCA/
ln -s /usr/share/easy-rsa/* .
./easyrsa init-pki
```

## 認証局(CA)の作成

まずは所定のディレクトリに```vars```ファイルを作成します。
```/opt/CA/demoCA/vars.example```というファイルがあるのでこれを編集すれば良さそうですが、ここでは下記のように新規作成します。
それぞれの値は自分の状況に応じて修正して下さい。

```console
cat <<___ >vars
set_var EASYRSA_ALGO      "ec"
set_var EASYRSA_DIGEST    "sha512"
set_var EASYRSA_CA_EXPIRE "36524"
___
```

次に、認証局のルート公開鍵と秘密鍵のペアを作成します。

下記コマンドを実行すると、キーペアのパスフレーズを入力するように求められます。必ず強力なパスフレーズを入力し、安全な場所に書き留めます。

更に、CAの共通名(CN; Common Name)を確認するように求められます。CNは、認証局のコンテキストでこのマシンを参照するために使用される名前です。任意の文字列を入力できますが、インターネット上で使う予定があれば自分の所有しているドメインにするのが良いでしょう。今回はLAN内のDNSサーバで管理しているマシン名にします。

```console
./easyrsa build-ca
```

もしも下記のように```.rnd```ファイルを開けないエラーが発生したら。

```console
Can't load /opt/CA/demoCA/pki/.rnd into RNG
```

放っておいても良さそうです。
参考文献：[/root/.rndをRNGにロードできません。どこにありますか、またはどのように作成しますか？ -  web-development-kb-ja.site](https://www.web-development-kb-ja.site/ja/openssl/rootrnd%E3%82%92rng%E3%81%AB%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82%E3%81%A9%E3%81%93%E3%81%AB%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B%E3%80%81%E3%81%BE%E3%81%9F%E3%81%AF%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E4%BD%9C%E6%88%90%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F/944616827/)

手当をしたいなら、下記コマンドを実行します。
参考文献：[1. 公開鍵を作る - ファイルの暗号化ならopenssl smimeだ！ - ファイルをお手軽に暗号化したい！ – openssl cms のススメ - IIJ Engineers Blog](https://eng-blog.iij.ad.jp/archives/9268#%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%ae%e6%9a%97%e5%8f%b7%e5%8c%96%e3%81%aa%e3%82%89openssl_smime%e3%81%a0%ef%bc%81)


```console
openssl rand -writerand /opt/CA/demoCA/pki/.rnd
```

根本解決の為には```/etc/ssl/openssl.cnf```を修正しろ、と下記参考文献には書いてあります。しかし```RANDFILE```なるキーワードが存在しません。実際には```/usr/share/easy-rsa/openssl-easyrsa.cnf```に```RANDFILE```の記述があるようですが、ちょっと怖いのでこのファイルの修正は諦めました。
参考文献：[OpenSSLでCSRを発行したときに”.rnd”が開けないというエラーが出た - memo.](https://www.xenos.jp/~zen/blog2/index.php/2021/12/22/post-6209/)

パスフレーズとCNを入力して成功すると、下記の2ファイルが生成されます。

- CAの公開鍵 ```/opt/CA/demoCA/pki/ca.crt```
- CAの秘密鍵 ```/opt/CA/demoCA/pki/private/ca.key```

秘密鍵は絶対に漏らしてはいけない物になります。```/opt/CA```ディレクトリも権限設定に注意しましょう。

## 内容確認

作った認証局の内容を確認します。下記の実行例は、作成時にCN(Common Name)として```demoCA```を指定した場合の結果です。

参考文献：[opensslコマンドでサーバーにアクセスして確認する - opensslコマンドを使ったSSL証明書の確認方法 - やさしいopensslコマンドによるSSL証明書の確認方法 - Oji-Cloud](https://oji-cloud.net/2020/07/15/post-5114/)
参考文献：[証明書の期限確認 - 発行されたSSL証明書の内容 - SSL証明書の内容をopensslで確認する](https://qiita.com/m-chika/items/e4936feb4087b7ddbe8b#%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%AE%E6%9C%9F%E9%99%90%E7%A2%BA%E8%AA%8D)

```console
# cd 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=Nov 20 07:38:39 2022 GMT
notAfter=Nov 17 07:38:39 2032 GMT
```

# 各端末にCAの公開鍵(ca.crt)をコピーしルート証明書としてインポート

## 公開鍵(ca.crt)の送付

これについては[次回](https://qiita.com/katz_engineer/items/8c0dcbb985d4493200d2)詳しく述べます。今回は省略。

## 公開鍵(ca.crt)をルート証明書としてインポート

やり方はOSによって異なります。それぞれの手順で実施して下さい。
UbuntuとAndroidの場合は参考文献を参照。

参考文献：[使用する各端末にCAの公開鍵(ca.crt)をルート証明書としてインポート - easy-rsaでプライベートCA(認証局)を作ってオレオレ証明書ではないローカル用TLS証明書の管理をする - R O HEAD -yajiri-](https://r-o-head.tk/post/private-ca-with-easy-rsa/#%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E5%90%84%E7%AB%AF%E6%9C%AB%E3%81%ABca%E3%81%AE%E5%85%AC%E9%96%8B%E9%8D%B5-ca-crt-%E3%82%92%E3%83%AB%E3%83%BC%E3%83%88%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%A8%E3%81%97%E3%81%A6%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88)

# 仕舞い

ルート認証局、通称オレオレ認証局を作成し、クライアントマシンへ送付する手順を確立しました。役に立つのは証明書を作成した時になりますが、その作成手順は[次回](https://qiita.com/katz_engineer/items/1bb165f5f59c43c0ab6a)にします。

利用するマシンすべてへインポートが必要なのでちょっと面倒ですが、自分だけの証明書を無料で設定する準備が出来ました。やったね:thumbsup_tone2: