Dockerfile内でオレオレ認証局を作成する話

# dockerさん、オレだよ！オレオレ！！

あまり関係ない始まりですが、Dockerfile内でオレオレ認証局を作成する話をします。
もっと簡単な方法はあると思いますが、レッツトライ。

といってもめんどうだからとりあえずババンとDockerfileの必要部分を抜き出して書いちゃいます。

```dockerfile:Dockerfile
FROM rockylinux/rockylinux:8


COPY certs/ca.key /etc/pki/CA/private/
RUN  mkdir -p /selfcerts/;
COPY files/self-certs-settings/openssl-ca.cnf /selfcerts/
RUN  openssl req -new -x509 -days 3650 -sha256 -key /etc/pki/CA/private/ca.key -subj "/C=JP/ST=prefecture/L=city/O=companyname/CN=server.name" -out /etc/pki/CA/ca.crt -config /selfcerts/openssl-ca.cnf
RUN  cp /etc/pki/CA/ca.crt /usr/share/pki/ca-trust-source/anchors/
RUN  update-ca-trust extfile
RUN  openssl x509 -inform pem -in /etc/pki/CA/ca.crt -outform der -out /selfcerts/ca.der
COPY certs/server.key /selfcerts/server.key
COPY files/self-certs-settings/openssl-server.cnf /selfcerts/openssl-server.cnf
COPY files/self-certs-settings/sans_temp.cnf /selfcerts/sans_temp.cnf
RUN  openssl req -new -key /selfcerts/server.key -sha256 -subj "/C=JP/ST=prefecture/L=city/O=companyname/CN=server.name" -config /selfcerts/openssl-server.cnf -out /selfcerts/server.csr
RUN  mkdir -p /etc/pki/CA/newcerts ; touch /etc/pki/CA/index.txt ; echo '0001' >> /etc/pki/CA/serial
RUN  yes| openssl ca -in /selfcerts/server.csr -keyfile /etc/pki/CA/private/ca.key -cert /etc/pki/CA/ca.crt -config /selfcerts/openssl-server.cnf -extfile /selfcerts/sans_temp.cnf -out /selfcerts/server.crt
RUN sed -i "s/#ServerName www\.example\.com/ServerName server.name/g" /etc/httpd/conf.d/ssl.conf
```

では、分割してみていきましょう。
```dockerfile:Dockerfile
COPY certs/ca.key /etc/pki/CA/private/
```
あれ、もう既にCAのキーを作ってありますね、キーの作り方は

```bash:make_keys.sh
#!/bin/bash
mkdir -p ./certs/
sudo rm -f ./certs/server.key ./certs/ca.key
sudo openssl genrsa -des3 -out ./certs/ca.key 2048 -config ./files/self-certs-settings/openssl-ca.cnf
sudo openssl rsa -in ./certs/ca.key -out ./certs/ca.key
sudo openssl genrsa 2048 > ./certs/server.key
sudo openssl rsa -in ./certs/server.key -out ./certs/server.key
sudo chown ${USER}:${USER} ./certs/server.key ./certs/ca.key
sudo chmod 400 ./certs/server.key ./certs/ca.key
```

`./files/self-certs-settings/openssl-ca.cnf`は設定ファイルです、適切な値を入れて置いてください。

```dockerfile:Dockerfile
RUN  mkdir -p /selfcerts/;
```
は良いですね？

```dockerfile:Dockerfile
COPY files/self-certs-settings/openssl-ca.cnf /selfcerts/
```
これもOKですね？

```dockerfile:Dockerfile
RUN  openssl req -new -x509 -days 3650 -sha256 -key /etc/pki/CA/private/ca.key -subj "/C=JP/ST=prefecture/L=city/O=companyname/CN=server.name" -out /etc/pki/CA/ca.crt -config /selfcerts/openssl-ca.cnf
```
ここが第一関門です、国名やサーバ名をここで指定します。


```dockerfile:Dockerfile
RUN  cp /etc/pki/CA/ca.crt /usr/share/pki/ca-trust-source/anchors/
RUN  update-ca-trust extfile
```
これも良いですね？

```dockerfile:Dockerfile
RUN  openssl x509 -inform pem -in /etc/pki/CA/ca.crt -outform der -out /selfcerts/ca.der
COPY certs/server.key /selfcerts/server.key
COPY files/self-certs-settings/openssl-server.cnf /selfcerts/openssl-server.cnf
```
これも問題ないないと思います。`openssl-server.cnf`も設定しておいてください。

```dockerfile:Dockerfile
COPY files/self-certs-settings/sans_temp.cnf /selfcerts/sans_temp.cnf
```

これなんですが、この`sans_tmp.cnf`は

```text:sans_temp.cnf
subjectAltName=@subject_alt_names
[ subject_alt_names ]
DNS.1 = server.name
```

のように書いておきます。これは結構苦労しました。


```dockerfile:Dockerfile
RUN  openssl req -new -key /selfcerts/server.key -sha256 -subj "/C=JP/ST=prefecture/L=city/O=companyname/CN=server.name" -config /selfcerts/openssl-server.cnf -out /selfcerts/server.csr
```
これもOKですよね？

```dockerfile:Dockerfile
RUN  mkdir -p /etc/pki/CA/newcerts ; touch /etc/pki/CA/index.txt ; echo '0001' >> /etc/pki/CA/serial
```
この`serial`はDokcerfileを使用してビルドするたびにインクリメントしないといけません。ご注意を。
でないとFirefoxでエラーになります。

```dockerfile:Dockerfile
RUN  yes| openssl ca -in /selfcerts/server.csr -keyfile /etc/pki/CA/private/ca.key -cert /etc/pki/CA/ca.crt -config /selfcerts/openssl-server.cnf -extfile /selfcerts/sans_temp.cnf -out /selfcerts/server.crt
```
ここもかなり苦労しましたが、yesを入力しないと先に進まないのでyesコマンドを使います。

```dockerfile:Dockerfile
RUN sed -i "s/#ServerName www\.example\.com/ServerName server.name/g" /etc/httpd/conf.d/ssl.conf
```
と、apacheの設定も変えないといけません。

これで動くはずです。

お試しあれ！！