strongSwan 用の証明書を作成する
strongSwan で使用可能なサーバ証明書やクライアント証明書の作成方法について書きます。基本的には、strongSwan を使って作成するのが簡便ですが、それでもいちいち覚えてられないので、認証局に関する一連の運用を Makefile
にまとめました。気に入っていただけたら、ご利用ください。
認証局の設定
/etc/pki/myCA
を作成し、その中に Makefile
を配置します。
# mkdir -p /etc/pki/myCA # cd /etc/pki/myCA # curl -O "https://raw.githubusercontent.com/seinolab/simple-ca-with-strongswan/main/Makefile" ... #
Makefile
の設定部分を編集します。各自の環境や好みに合わせて設定してください。RSA の証明書も使えますので、その場合は TYPE
に rsa
を、SIZE
に 2048
か 4096
を指定してください。
CA_ROOT=/etc/pki/myCA # information of your Certificate Authority COUNTRY=JP STATE=Niigata ORGANIZATION=My Great Company CA_NAME=ca.example.com # lifetime of certificates EXPIRE_CERT=366 # サーバ/クライアント証明書の有効期限(単位: 日) EXPIRE_CA=3660 # 認証局証明書の有効期限(単位: 日) EXPIRE_CRL=10 # CRLの有効期限(単位: 日) # Type of certificates TYPE=ecdsa # 証明書の cipher(rsa|ecdsa|ed25519|ed448) SIZE=256 # 鍵のサイズ(単位: bit) # default destination MAILTO=root
認証局の作成
make
すると認証局が作成されます。認証局は明示的に作成しなくとも、最初のサーバ証明書またはクライアント証明書を発行する時に、Makefile
の依存関係の解決の仕組みにより、必要な場合は自動的に作成されます。
# cd /etc/pki/myCA # make ... #
ルート証明書は /etc/pki/myCA/cacerts/
以下に作成されます。配布用の .der
ファイルも作成されます。
# ls cacerts/ root.cert.der root.cert.pem root.key.pem # ls crls/ crl.pem #
root.cert.der
(公開鍵)はメール送付されますので、クライアント側へインストールし、「常に信頼する」に設定してください。
期限切れなどで認証局を破棄する場合は、make clean
します。認証局を破棄すると、/etc/pki/myCA
以下の発行済みの各種証明書も削除されます。
# make clean ... #
何をやっているか知りたい方は、以下をクリックしてください。
認証局の秘密鍵 ${CA_KEY}
を生成します。パーミッションは 600
にしておきます。
mkdir -p ${CA_CERT_DIR} strongswan pki --gen --type ${TYPE} --size ${SIZE} --outform pem > ${CA_KEY} chmod 600 ${CA_KEY}
認証局の公開鍵 ${CA_PUB}
を生成します。自身の秘密鍵で署名します。
strongswan pki --self --ca --lifetime ${EXPIRE_CA} \ --in ${CA_KEY} --type ${TYPE} \ --san "${CA_CERT_DN}" \ --dn "${CA_CERT_DN}" --outform pem \ --flag crlSign \ > ${CA_PUB}
strongSwan 5.9.11 以降、crlSign
フラグが設定されていない認証局の証明書は使用不可になりました。現状、明示的に指定しなくてもデフォルトで設定されるのですが、念のため付けておきます。
配布用の .der
形式のファイルを作成します。
openssl x509 -in ${CA_PUB} -outform DER -out ${CA_CERT_DIR}/root.cert.der
CRL ${CRL}
を作成します。
mkdir -p ${CRL_DIR} strongswan pki --signcrl --cacert ${CA_PUB} --cakey ${CA_KEY} \ --lifetime=${EXPIRE_CRL} --outform pem \ > ${CRL}
サーバ証明書の発行
サーバ example.com
用のサーバ証明書を発行します。ワイルドカード証明書(*.example.com
)が発行されます。
# cd /etc/pki/myCA # make SERVER=example.com server ... #
サーバ証明書は /etc/pki/myCA/servers/
以下に作成されます。
# ls servers/ example.com.cert.pem example.com.key.pem #
.cert.pem
の方が公開鍵、.key.pem
の方が秘密鍵です。
何をやっているか知りたい方は、以下をクリックしてください。
サーバ証明書の秘密鍵 ${SKEY}
を生成します。パーミッションは 600
にしておきます。
mkdir -p ${SERVER_CERT_DIR} strongswan pki --gen --type ${TYPE} --size ${SIZE} --outform pem > ${SKEY} chmod 600 ${SKEY}
サーバ証明書の秘密鍵 ${SKEY}
の鍵ペアとなる公開鍵 ${SPUB}
を作成し、認証局の秘密鍵 ${CA_KEY}
で署名します。
strongswan pki --pub --in ${SKEY} --type ${TYPE} \ | strongswan pki --issue --lifetime ${EXPIRE_CERT} \ --cacert ${CA_PUB} --cakey ${CA_KEY} \ --dn "C=${COUNTRY}, O=${ORGANIZATION}, CN=${SERVER}" \ --san ${SERVER} --san *.${SERVER} \ --flag serverAuth --flag ikeIntermediate --outform pem \ > ${SPUB}
SAN を設定することで、ワイルドカード証明書にしています。サーバ証明書の場合、serverAuth
フラグを設定します。
クライアント証明書の発行
vpnuser@example.com
用のクライアント証明書を発行します。途中でクライアント証明書をインポートする際のパスワードを聞かれますので、入力します。発行したクライアント証明書は、delivery-to@example.com
へメール送付されます。
# cd /etc/pki/myCA # make USER=vpnuser@example.com MAILTO=delivery-to@example.com issue ... Enter Export Password: Verifying - Enter Export Password: ... #
証明書のコモンネームは vpnuser@example.com
の形式はダメで、vpnuser
としなければならない、という情報もありますが、そのような制限は確認できませんでした。
クライアント証明書は /etc/pki/myCA/clients/
以下に作成されます。
# ls clients/ vpnuser@example.com.cert.pem vpnuser@example.com.key.pem vpnuser@example.com.p12 #
クライアント側にインストール後、これらのファイルは削除してしまっても認証できますが、クライアント証明書を失効させる際に必要になるので、残しておきましょう。
PKCS12(.p12
ファイル)には、クライアント証明書の鍵ペアに加えて、認証局のルート証明書(公開鍵)を含めることもできます。
何をやっているか知りたい方は、以下をクリックしてください。
クライアント証明書の秘密鍵 ${CKEY}
を生成します。パーミッションは 600
にしておきます。
mkdir -p ${CLIENT_CERT_DIR} strongswan pki --gen --type ${TYPE} --size ${SIZE} --outform pem > ${CKEY} chmod 600 ${CKEY}
クライアント証明書の秘密鍵 ${CKEY}
に対する鍵ペアとまる公開鍵 ${CPUB}
を生成します。認証局の秘密鍵 ${CA_KEY}
で署名します。
strongswan pki --pub --in ${CKEY} --type ${TYPE} \ | strongswan pki --issue --lifetime ${EXPIRE_CERT} \ --cacert ${CA_PUB} --cakey ${CA_KEY} \ --dn "C=${COUNTRY}, O=${ORGANIZATION}, CN=${USER}" \ --flag clientAuth \ --san ${USER} --outform pem \ > ${CPUB}
クライアント証明書の秘密鍵 ${CKEY}
と公開鍵 ${CKEY}
をまとめて、配布用に .p12 形式で出力します。
openssl pkcs12 -export -legacy \ -inkey ${CKEY} -in ${CPUB} \ -name "${ORGANIZATION} client certificate" \ -out ${CLIENT_CERT_DIR}/${USER}.p12
macOS や iOS が対応していないので、-legacy
オプションを付けています。
クライアント証明書を失効させる
vpnuser@example.com 用のクライアント証明書を失効させます。無効化する際は、理由を指定します。理由には key-compromise
、 ca-compromise
、affiliation-changed
、superseded
、cessation-of-operation
、certificate-hold
のいずれか一つが設定できます)。
# cd /etc/pki/myCA # make USER=vpnuser@example.com REASON=key-compromise revoke ... #
クライアント証明書 ${CPUB}
を理由 ${REASON}
により失効させます。その後、古い CRL を新しい CRL で、atomic な操作で置き換えます。
strongswan pki --signcrl --lifetime=${EXPIRE_CRL} --basecrl=${CRL} \ --cacert ${CA_PUB} --cakey ${CA_KEY} \ --reason ${REASON} --cert ${CPUB} --outform pem \ > ${CRL}.new \ && mv -f ${CRL}.new ${CRL}
サーバ証明書も失効させられるのですが、面倒なのでそこまでは対応していません。--cert
にサーバ証明書の公開鍵のパスを渡せば、失効させられます。
CRL を更新する
CRL の有効期限を更新します。CRL のチェックを有効にしている場合、CRL の有効期限が切れると、すべての証明書が無効扱いになりますので、ご注意ください。CRL をチェックしない設定の場合は、CRL を更新しなくても問題ないですが、証明書を失効させることができません(認証局から証明書のファイルを削除しても失効になりませんのでご注意ください)。
# cd /etc/pki/myCA # make update ... #
何をやっているか知りたい方は、以下をクリックしてください。
CRL ${CRL}
を認証局の秘密鍵 ${CA_KEY}
で署名し、CRL の有効期限を ${EXPIRE_CRL}
日後に再設定します。その後、古い CRL を新しい CRL で、atomic な操作で置き換えます。
strongswan pki --signcrl --lifetime=${EXPIRE_CRL} --basecrl=${CRL} \ --cacert ${CA_PUB} --cakey ${CA_KEY} --outform pem \ > ${CRL}.new \ && mv -f ${CRL}.new ${CRL}
通常は、systemd
や cron
で定期的に実行します。以下は systemd
で自動更新する場合の設定例です。週次で更新されます。
# mkdir -p /usr/local/systemd/system # cd /usr/local/systemd/system # curl -O "https://raw.githubusercontent.com/seinolab/simple-ca-with-strongswan/main/pki-update-crl.service" # curl -O "https://raw.githubusercontent.com/seinolab/simple-ca-with-strongswan/main/pki-update-crl.timer" # systemctl start pki-update-crl.timer # systemctl enable pki-update-crl.timer
おわりに
シンプルな Makefile
ですので、各自の環境に合わせてカスタマイズしていただけると幸いです。