初代OpenBlockSでvtunを利用した設定については昔のOpenBlocksのおと参照。 OpenBlockSSでも構築していてバイナリも置いてありますが、設定方法については詳しく述べられていません。 vtunのencryptオプションによる暗号化は弱いので定常的なVPNとして利用するには別途暗号化に関して工夫をする必要があります。
OpenVPN公式サイトをまず訪れて下さい。
以下の例では、OpenBlockSSにつながったネットワークのグローバルIPが1.2.3.4であるとし、
FreeBSDにつながったネットワークのグローバルIPが5.6.7.8、DMZでのIPが10.20.30.40という環境であるとします。
セキュア Web サーバ構築(+SSL)や
googleでの検索結果
を参照して下さい。
セキュリティの観点から言うと、認証局の秘密鍵が奪われるとその認証局で発行された全ての証明書の信頼性がなくなってしまうので
認証局(CA)自体はVPNを張るマシンとは別になっていて、可能であればnetworkから到達できないぐらい方が望ましいです。
が、双方固定IPという環境であれば証明書を認証手段として使うのではなくIPアドレスを信じるという手もあります。その辺は一口で語れないのでとりあえず省略します。
認証局の証明書はcacert.pemとして作成されますが、他のメジャーな認証局証明書のかたまり ca-bundle.crt に同じフォーマットで埋め込むための
ファイルをついでに作ります。ca.hoge.com.pem
という感じのファイル名にした後、以下のシェルスクリプトを実行すると
ca.hoge.com.crt
の出来上がりです。
#!/bin/sh HOST=ca.hoge.com cp /dev/null ${HOST}.crt echo >> ${HOST}.crt echo Hoge CA >> ${HOST}.crt echo ========================================= >> ${HOST}.crt openssl x509 -fingerprint -noout -in ${HOST}.pem >> ${HOST}.crt echo PEM Data: >> ${HOST}.crt cat ${HOST}.pem >> ${HOST}.crt openssl x509 -noout -text -in ${HOST}.pem >> ${HOST}.crt
OpenVPNで利用する証明書は大雑把に言ってapache用の証明書と同じものです。
うちでは通常以下のようなMakefileを作成して、env HOST=vpn.hoge.com make csr
とやってCSR(証明書要求)を作成し、
秘密鍵ファイルをvpn.hoge.com.key
、
CAにて署名。
してもらった証明書をvpn.hoge.com.pem
として保存しています。
CSRの作成途中色々パラメーターを聞かれますが、OpenVPNで利用する限りどんな文字列でもかまいません。
csr:: openssl req -new -nodes -newkey rsa:1024 -sha1 -keyform PEM -keyout ${HOST}.key -outform PEM -out ${HOST}.csr chmod 600 ${HOST}.key dertopem:: openssl x509 -inform der -outform pem -in ${HOST}.cer -out ${HOST}.pem
CSRをCAで署名してもらった結果がDERフォーマットのvpn.hoge.com.cer
ファイルの場合は、env HOST=vpn.hoge.com make dertopem
として変換することもありますが、この作業は多分不要です。
以下のような感じのスクリプトを /usr/local/etc/rc.d/ に置きます。ログはsyslogに書き込まれますが、daemon facilityを取るようにしていないとダメかもしれません。
/usr/local/sbin/openvpn --remote 1.2.3.4 --dev tun1 \ --ifconfig 192.168.255.1 192.168.255.2 \ --tls-server --dh /etc/ssl/certs/dh1024.pem --ca /etc/ssl/certs/ca.hoge.com.crt \ --cert /usr/local/etc/openvpn/vpn.hoge.com.cer --key /usr/local/etc/openvpn/vpn.hoge.com.key \ --reneg-sec 3600 --udp-mtu 1400 \ --verb 3 \ --up /usr/local/etc/openvpn/zebrarestart.sh \ --down /usr/local/etc/openvpn/zebrarestart.sh \ --daemon --writepid /var/run/openvpn.pid
dh1024.pemはopenssl dhparam -out dh1024.pem 1024
で作成したファイルです。
/usr/local/etc/openvpn/zebrarestart.shの中身は/usr/local/sbin/zebractl restart
です。
OpenVPNを動かしているサーバがファイアウォールの後ろにある場合、UDPのポート5000に対するパケットを転送する必要があります。 ipfilterを使っている場合はipnat.confに以下のような感じのエントリになります。
rdr tun0 5.6.7.8/32 port 5000 -> 10.20.30.40 port 5000 udp
上記の設定でも利用可能ですが、 --chrootを使うと、chrootしたディレクトリ以下しかアクセスできなくなるため、万一openvpnにセキュリティホールがあっても問題が起きにくくなります。 以下のコマンドを使って、chroot後のディレクトリ構成を作成。
# CHROOT=/local/chroot/vpn # mkdir -p $CHROOT # mkdir -p $CHROOT/etc # mkdir -p $CHROOT/var/run # (cd /; ls -1 bin/sh sbin/ifconfig dev/null dev/random dev/tun0 dev/tun1 dev/tun2 dev/tun3 dev/tun4 dev/urandom dev/zero | cpio -pdm $CHROOT) # echo 'openvpn:*:122:' > $CHROOT/etc/group # echo 'openvpn:*:122:122::0:0:OpenVPN:/:/nonexistent' > $CHROOT/etc/master.passwd # /usr/sbin/pwd_mkdb -p -d $CHROOT/etc $CHROOT/etc/master.passwd # mkdir -p $CHROOT/certs
syslogdの起動時に-l /local/chroot/vpn/var/run/log オプションを追加して、chroot後に /var/run/log となる位置にソケットを作っておきます。 また、以下のopenvpn起動時に指定する証明書等のファイルを $CHROOT/certs に移動します。
/usr/local/sbin/openvpn --remote 1.2.3.4 --dev tun1 \ --port 5000 \ --ifconfig 192.168.255.1 192.168.255.2 \ --chroot /local/chroot/vpn \ --tls-server --dh /certs/dh1024.pem --ca /certs/ca.hoge.com.crt \ --cert /certs/vpn.hoge.com.cer --key /certs/vpn.hoge.com.key \ --reneg-sec 3600 --udp-mtu 1400 \ --verb 3 \ --daemon --writepid /var/run/openvpn.pid \ --ping 30 --ping-restart 90 \ --single-session \ --user openvpn --group openvpn \ --persist-key --persist-tun --persist-local-ip --persist-remote-ip
--user, --group を指定した場合は --persist-??? を指定しないとセッションの再接続がうまくいかないようです。 また、--single-session を指定した場合は、--ping, --ping-restart を指定して自動的にセッションの再接続をするようにしないと、 クライアント側からのセッションの再接続の要求に応じられなくなります。
OpenSSL付属の verify-cn はperlですが、shだけで動いてくれないとchroot環境の整備が大変なので $CHROOT/sbin/verify-cn として以下のようなスクリプトを作成しました。
#!/bin/sh # Verify X509 Common Name # # Return 0 if cn matches the common name component of X509_NAME_oneline, # 1 otherwise. # # For example in openvpn, you could use the option: # --tls-verify "./verify-cn Test-Client" # check number of arguments case $# in 3) ;; *) exit 1; ;; esac cn=$1 depth=$2 x509="$3/" case $depth in 0) case $x509 in */CN=$cn/* ) exit 0; ;; *) exit 1; ;; esac ;; *) exit 0; ;; esac exit 0;
openvpnの起動は以下のようになります。--tls-verifyの引数で、カンマの後に続ける文字列はクライアント用証明書作成の時に指定したCommonNameです。
/usr/local/sbin/openvpn --remote 1.2.3.4 --dev tun1 \ --port 5000 \ --ifconfig 192.168.255.1 192.168.255.2 \ --chroot /local/chroot/vpn \ --tls-server --dh /certs/dh1024.pem --ca /certs/ca.hoge.com.crt \ --cert /certs/vpn.hoge.com.cer --key /certs/vpn.hoge.com.key \ --tls-verify /sbin/verify-cn,openblockss.hoge.com \ --reneg-sec 3600 --udp-mtu 1400 \ --verb 3 \ --daemon --writepid /var/run/openvpn.pid \ --ping 30 --ping-restart 90 \ --single-session \ --user openvpn --group openvpn \ --persist-key --persist-tun --persist-local-ip --persist-remote-ip
昔のOpenBlocksのおと参照。ファームウェア自体も置いてあります。
将来的にはopenvpnをramdiskに置いたバージョンを作ってここに置きたいところ。そうなればCFカードも不要になるので。
バイナリをそのまま置いておきます。圧縮もしていません。コンパイルはHDD付OpenBlockSSで行いました。(2002.8.13: OpenSSL 0.9.6g に更新)
openvpn 1.2.1 実行ファイル本体 MD5 (openvpn) = b8ebdbfdc1bcf74b487d887c7661cdc5
libcrypto.so.0.9.6 OpenSSL ダイナミックリンクライブラリ MD5 (libcrypto.so.0.9.6) = 31940a2f74064b78dd615923363220f2
libssl.so.0.9.6 OpenSSL ダイナミックリンクライブラリ MD5 (libssl.so.0.9.6) = 05dc6cbd21c100eb7e3a6c42372494d8
openssl-0.9.6g-openblocks.tar.gz ソース+コンパイル結果 MD5 (openssl-0.9.6g-openblocks.tar.gz) = a36b72e006a90ef77acea3a0ede272d0
ldconfig ダイナミックリンクライブラリ設定ツール MD5 (ldconfig) = dfc2ccb02bc1f115a9661f486e09b1da
うちの openvpn でlddを取った結果は以下の通りです。
[root@openblocks sbin]# ldd openvpn libssl.so.0.9.6 => /local/lib/libssl.so.0.9.6 (0x0ffad000) libcrypto.so.0.9.6 => /local/lib/libcrypto.so.0.9.6 (0x0fe99000) libc.so.6 => /lib/libc.so.6 (0x0fd81000) libdl.so.2 => /lib/libdl.so.2 (0x0fd5e000) /lib/ld.so.1 => /lib/ld.so.1 (0x30000000)
/local/lib においてシンボリックリンクを作成します。リンク作成後の状態は以下の通りです。
[root@openblocks sbin]# ls -l /local/lib total 1569 lrwxrwxrwx 1 root root 14 Dec 26 2001 libcrypto.so -> libcrypto.so.0 lrwxrwxrwx 1 root root 18 Dec 26 2001 libcrypto.so.0 -> libcrypto.so.0.9.6 -r-xr-xr-x 1 root root 1111432 Dec 25 2001 libcrypto.so.0.9.6 lrwxrwxrwx 1 root root 11 Dec 26 2001 libssl.so -> libssl.so.0 lrwxrwxrwx 1 root root 15 Dec 26 2001 libssl.so.0 -> libssl.so.0.9.6 -r-xr-xr-x 1 root root 230800 Dec 25 2001 libssl.so.0.9.6
ld.so.confを以下のようにした後、起動時にldconfig /etc/ld.so.conf
が実行されるようにします。
/usr/lib /lib /local/lib /usr/local/lib
FreeBSDのサーバ用証明書とほぼ同様ですが、パラメータのうちCN(=CommonName)と生成されるファイル名だけ変えたものを作成します。
サーバ側の--tls-verifyの引数で指定するCN(=CommonName)はここで指定した文字列ですなので、必要な場合はメモを取って下さい。
env HOST=openblockss.hoge.com make csr
とやってCSR(証明書要求)を作成して、
CAにて署名。
出来上がった秘密鍵ファイルopenblockss.hoge.com.key
と証明書openblockss.hoge.com.pem
をOpenBlockSSに転送しますが、
特に秘密鍵ファイルについては盗聴されないことが確実な環境で行って下さい。普通はscpを利用することになるでしょう。
また、CA証明書ca.hoge.com.crt
も同様に転送して下さい。
以下のような感じのスクリプトを /etc/rc.d/rc.local に追加します。うちのOpenBlockSSはsyslogを動かしていないためログは取っていません。 --mktunでtun0を作成していますが、実際に利用しているのはtun1のため不要かもしれません。
/local/sbin/openvpn --mktun --dev tun0 /local/sbin/openvpn --dev tun --remote 5.6.7.8 \ --ifconfig 192.168.255.2 192.168.255.1 --tls-client \ --ca /local/etc/openvpn/ca.hoge.com.crt \ --cert /local/etc/openvpn/openblockss.hoge.com.cer \ --key /local/etc/openvpn/openblockss.hoge.com.key \ --udp-mtu 1400 \ --reneg-sec 3600 \ --up /local/etc/zebraall.sh \ --down /local/etc/zebrakill.sh \ --daemon
/local/etc/zebraall.sh
は以下のようにzebraを起動するスクリプトです。
#!/bin/sh /local/sbin/zebra -k -d -f /local/etc/zebra.conf /local/sbin/ospfd -d -f /local/etc/ospfd.conf /local/sbin/ripd -d -f /local/etc/ripd.conf
/local/etc/zebrakill.sh
は以下のようにzebraを終了するスクリプトです。
#!/bin/sh kill `cat /var/run/ripd.pid /var/run/ospfd.pid /var/run/zebra.pid`
/local/etc/zebra.conf, /local/etc/ospfd.conf, /local/etc/ripd.conf
については昔のOpenBlocksのおとを参照して下さい。
OpenBlockS初代と同じです。
OpenBlockSSがブロードバンドルータの後ろにある場合、UDPのポート5000に対するパケットを転送する必要があります。 静的NATの設定を行って下さい。
OpenVPNのオプションについて詳しい説明は、マニュアルを日本語訳するべきなんでしょうけど…現在発展途上なのでちと悩ましいです。