cfsslを用いたオレオレ証明書作成

# Motivation
kubernetesを自分で構築する場合に証明書の作成を避けては通れないため、証明書作成の方法をまとめる。
証明書作成といえばopensslが有名どこと思うが、何度やっても何をしてるかわけわからなくなることが多々あるかと思う(
そこでopensslに代わり、cfsslを用いることで実際に行いたいことにフォーカスして整理する。
下記のcoreos社の記事がとても参考になるので、下記のページの内容を読みメモを補足していく。
https://coreos.com/os/docs/latest/generate-self-signed-certificates.html

# 事前準備
cfsslのインストール

```
brew install cfssl
```

## cfsslを用いた証明書作成

cfsslでcsrとca関連設定の雛形作成

```
cfssl print-defaults config > ca-config.json
cfssl print-defaults csr > ca-csr.json
```



Ca-cong.jsonを下記のように書き換え

証明書の種類には、client certificate, server certificate, peer certificateの3つがあり、それぞれの有効期限や証明書の用途などを設定する。下記の例では43800h(5年)を設定している。

```
{
    "signing": {
        "default": {
            "expiry": "43800h"
        },
        "profiles": {
            "server": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            },
            "peer": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}
```



ca-csr.jsonを下記のように編集

```
{
    "CN": "My CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "JP",
            "OU": "Kubernetes"
        }
    ]
}
```



### 認証局の生成

```
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
```

cfsslを用いてgencert(証明書作成)を行う。 ca-csr.json(CSR)の内容を基に認証局を初期化(initca)

cfssljsonでcaと指定することで、出力するファイルの頭文字にプレフィクスが付与される。

caと指定した場合は下記の通り

```
ca-key.pem
ca.csr
ca.pem
```



### サーバ証明書要求の雛形を生成

雛形をserver.jsonとして生成

```
cfssl print-defaults csr > server.json
```

Server.jsonを下記のように書き換え

hosts内は証明書を適用するサーバ群

```
...
"CN": "myserver",
    "hosts": [
        "192.168.0.1",
        "myserver.local",
        "myserver"
    ],
...    
```



### サーバ証明書を作成

認証局の秘密鍵 ca-key.pem

認証局の証明書 ca.pem 

認証局の設定  ca-config.json

-profile: ca-config.json内のプロファイル一覧から使用するプロファイルを指定

```
cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile server server.json | cfssljson -bare server -
```

下記3ファイル作成される

Server-key.pem: サーバの秘密鍵

server.csr: 証明書要求(CSR)

server.pem: サーバ証明書

````
server-key.pem
server.csr
server.pem
````





### 上記の雛形なしで一発で証明書作成する方法

```
echo '{"CN":"coreos1","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server -hostname="192.168.122.68,ext.example.com,coreos1.local,coreos1" - | cfssljson -bare server
```





## 証明書の内容確認

### hash確認

証明書と公開鍵、秘密鍵のハッシュが一致することを確認して検証できる。

証明書のハッシュ確認

```
cat cert.pem| openssl x509 -modulus -noout | openssl md5
93c7aea0b0180dac57e13cfa1c426cdc
```



秘密鍵のハッシュ確認

```
cat key.pem | openssl rsa -modulus -noout | openssl md5
93c7aea0b0180dac57e13cfa1c426cdc
```



### 証明書の中身確認

証明書の発行者や有効期限、用途やSAN(Subject Alternative Name)などを確認可能

```
cat server.pem | openssl x509 -text -noout
```