OpenVPN 証明書の作成と管理

2015年4月20日

前回までに以下の様なディレクトリ構成が出来上がりました。
[tvoncmeta {animated: “fast"} ]

  • etc
    • openvpn
      • easy-rsa ——-| 証明書作業ディレクトリ
        • keys ——-| 証明書管理ディレクトリ
      • keys ——-| 証明書設置ディレクトリ
      • server.conf ——-| OpenVPN設定ファイル

[/tvoncmeta]

OpenVPNサーバーを立ち上げるにあたり、各証明書と鍵の作成を行います。

マスタCA証明書と鍵の生成

証明書の作業は/etc/openvpn/easy-rsaディレクトリで行うので移動しておきましょう。
各ビルドスクリプトで参照される環境変数が、varsファイルに記述されているので必要な項目を編集します。

# 国
export KEY_COUNTORY="JP"
# 都道府県
export KEY_PROVINCE="Saitama"
# 市町村
export KEY_CITY="Unknown"
# 組織名
export KEY_ORG="planetleaf.com"
# e-mail
export KEY_EMAIL="hoge@hoge.jp"
# 以下は使用しないのでコメント
#export KEY_CN=
#export KEY_NAME=
#export KEY_OU=
#export PKCS11_MODULE_PATH=
#export PKCS11_PIN=

 以下は証明局、サーバー証明書等、最初のOpenVPN起動に必要なファイルを用意するための作業です。なお、最初からやり直したければ./clean-allで証明書管理ディレクトリがクリアされます。

cd /etc/openvpn/easy-rsa
# 環境変数設定
. ./vars

# keysディレクトリ初期化
./clean-all

# CA(認証局)作成 (ca.crt ca.key) 問い合わせは設定済みなので全てenter
./build-ca

# dh(Diffie Hellman)キー生成 (dh1024.pem)
./build-dh

# サーバーキー生成 (server.crt server.csr server.key)
# パスワードは空で問い合わせはyes
./build-key-server server
 
# tls-authで使用する共有静的鍵の生成 (ta.key)
openvpn --genkey --secret ta.key

# crl-verifyを設定するための初期CRL(廃止証明書リスト)ファイルの生成
# CRLファイルは運用中に修正可能だが、ヌルファイルを使用する事が出来ないため
# ダミー証明を作成、廃止して初期ファイルを作成する。
# 空パス、応答はyes
./build-key dmy
./revoke-full dmy
# revoke-full実行後に出てくる"error 23 at~"は廃止された事の証明
# (使えないのでエラーになっている)

 サーバー側に必要なファイルを上位ディレクトリにコピーします。

mkdir /etc/openvpn/keys
cp /etc/openvpn/easy-rsa/keys/ca.crt /etc/openvpn/keys/
cp /etc/openvpn/easy-rsa/keys/server.crt /etc/openvpn/keys/
cp /etc/openvpn/easy-rsa/keys/server.key /etc/openvpn/keys/
cp /etc/openvpn/easy-rsa/keys/dh1024.pem /etc/openvpn/keys/
cp /etc/openvpn/easy-rsa/keys/crl.pem /etc/openvpn/
cp /etc/openvpn/easy-rsa/ta.key /etc/openvpn/
chown nobody:nobody /etc/openvpn/crl.pem

 続いて一人のユーザー分の証明書を作成し、専用の作業ディレクトリへ格納します。
あとはユーザーが増えるたびにbuild-keyを繰り返せばOK。(build-key-passの場合はパスワード付きの証明書が作成できます)

# ユーザー証明書生成、homeuser1はそのままcommon nameの初期値に設定されるので
# 証明書名=ユーザー名という管理の仕方でいいかも
# パスワードは空、応答はyes
./build-key homeuser1

# ファイルを纏めるためにディレクトリを用意
# この中のファイルをUSBメモリ等、安全な手段でユーザーに渡せばよい。
mkdir -p ~/crt-temp
cp keys/ca.crt ~/crt-temp/
cp keys/homeuser1.crt ~/crt-temp/
cp keys/homeuser1.key ~/crt-temp/
cp ta.key ~/crt-temp/

流石に数をこなしていくと、証明書の管理と発行がずさんになったり、ファイルが散乱しそうなので、OpenVPN限定という事で、証明書埋め込みタイプのコンフィグレーションを出力するスクリプトを作成しました。

#!/bin/sh
outname=$1.ovpn

echo '
tls-client
dev tun
tls-client
nobind
pull
float
proto udp
remote home.planetleaf.com 1194
resolv-retry infinite
persist-key
persist-tun
# askpass password.cfg
key-direction 1
comp-lzo
verb 3
' > $outname

cafile=keys/ca.crt
certfile=keys/$1.crt
keyfile=keys/$1.key
tafile=ta.key

if [ ! -e $cafile ]; then
  echo 'error: '$cafile' is not found.'
  rm -f $outname
  exit
fi
echo '<ca>' >> $outname
sed -n -e "/-----BE.*$/,/-----EN.*$/p" $cafile >> $outname
echo '</ca>' >> $outname
echo $cafile' was embedded.'

if [ ! -e $certfile ]; then
  echo 'error: '$certfile' is not found.'
  rm -f $outname
  exit
fi
echo '<cert>' >> $outname
sed -n -e "/-----BE.*$/,/-----EN.*$/p" $certfile >> $outname
echo '</cert>' >> $outname
echo $certfile' was embedded.'

if [ ! -e $keyfile ]; then
  echo 'error: '$keyfile' is not found.'
  rm -f $outname
  exit
fi
echo '<key>' >> $outname
sed -n -e "/-----BE.*$/,/-----EN.*$/p" $keyfile >> $outname
echo '</key>' >> $outname
echo $keyfile' was embedded.'

if [ ! -e $tafile ]; then
  echo 'error: '$tafile' is not found.'
  rm -f $outname
  exit
fi
echo '<tls-auth>' >> $outname
sed -n -e "/-----BE.*$/,/-----EN.*$/p" $tafile >> $outname
echo '</tls-auth>' >> $outname
echo $tafile' was embedded.'
echo 'successful!'
echo 'output '$outname

 証明書コモンネーム.ovpnというファイルが作成されます。パスワード付きの物を配布すると少しは安心できるかもしれません。

次回、サーバーの設定と起動へ続きます。