FreeBSD 12.0 に OpenVPN をインストールして証明書認証で構成する方法

FreeBSD 12.0 上に OpenVPN サーバーを構築し、証明書ベースの認証で安全な VPN を提供する手順をステップごとに解説します。パッケージのインストール、easy-rsa による CA/サーバ/クライアント証明書の作成、OpenVPN 設定、pf ファイアウォールとポートフォワード設定、クライアント構成と接続テストまで網羅します。
重要: 本ガイドは FreeBSD 12.0 を想定しています。他のバージョンやディストリビューションでは一部コマンドやパスが異なる場合があります。
定義と前提条件
- OpenVPN: 公衆ネットワーク上で安全なプライベートネットワークを構築するためのオープンソース VPN ソフトウェア。暗号化には OpenSSL を使用します。
- easy-rsa: OpenVPN と一緒に使われる小型の PKI 管理ツール。簡易に CA、証明書、CRL、DH パラメータを作成できます。
前提条件
- FreeBSD 12.0 が稼働していること(最小 512MB RAM、1 vCPU 推奨)。
- root 権限(または sudo)。
- pf ファイアウォールの基本的な理解。必要に応じて pf の導入手順は公式ドキュメントを参照してください。
用語一行定義
- CA: 証明書を発行する認証局。署名によりサーバ/クライアント証明書を信頼させます。
目次
- Step 1: OpenVPN をインストールする
- Step 2: easy-rsa の変数を設定する
- Step 3: 証明書を生成する(CA, サーバ, クライアント, DH, CRL)
- Step 4: OpenVPN サーバーを構成する
- Step 5: pf ファイアウォールを設定する
- Step 6: IP フォワーディングを有効にする
- Step 7: クライアント設定を作成する
- Step 8: 接続テスト
- セキュリティ強化と運用上の注意点
- トラブルシューティング
- 役割別チェックリスト
- 受け入れ基準
- 参考
Step 1 - OpenVPN をインストールする
まずパッケージリポジトリを更新してから OpenVPN をインストールします。
pkg update
pkg install openvpn
インストール後、OpenVPN サービスをブート時に自動起動するように設定し、トンネル用インターフェースを定義します。
sysrc openvpn_enable="YES"
sysrc openvpn_if="tun"
これで FreeBSD 12.0 に OpenVPN がインストールされました。サンプルスクリーンショット:
Step 2 - 証明書変数の設定
easy-rsa の vars を編集して、PKI を生成する際に使うデフォルト値を設定します。
ディレクトリを準備して easy-rsa をコピーします。
mkdir -p /usr/local/etc/openvpn/
cp -R /usr/local/share/easy-rsa /usr/local/etc/openvpn/
ディレクトリに移動して vars を編集します。
cd /usr/local/etc/openvpn/easy-rsa/
vim vars
vars ファイルにあなたの組織情報や鍵サイズ、アルゴリズムなどを設定します。例:
set_var EASYRSA "$PWD"
set_var EASYRSA_PKI "$EASYRSA/pki"
set_var EASYRSA_DN "cn_only"
set_var EASYRSA_REQ_COUNTRY "DE"
set_var EASYRSA_REQ_PROVINCE "Frankfurt"
set_var EASYRSA_REQ_CITY "Frankfurt"
set_var EASYRSA_REQ_ORG "hakase-labs CERTIFICATE AUTHORITY"
set_var EASYRSA_REQ_EMAIL "[email protected]"
set_var EASYRSA_REQ_OU "HAKASE-LABS EASY CA"
set_var EASYRSA_KEY_SIZE 2048
set_var EASYRSA_ALGO rsa
set_var EASYRSA_CA_EXPIRE 7500
set_var EASYRSA_CERT_EXPIRE 365
set_var EASYRSA_NS_SUPPORT "no"
set_var EASYRSA_NS_COMMENT "HAKASE-LABS CERTIFICATE AUTHORITY"
set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types"
set_var EASYRSA_SSL_CONF "$EASYRSA/openssl-1.0.cnf"
set_var EASYRSA_DIGEST "sha256"
編集後、vars を実行可能にします。
chmod +x vars
準備が整いました。
Step 3 - 証明書を生成する
PKI を初期化して、CA、サーバー証明書、クライアント証明書、DH、CRL を作成します。
cd /usr/local/etc/openvpn/easy-rsa/
./easyrsa.real init-pki
CA を生成する
./easyrsa.real build-ca
プロンプトで CA キー用のパスフレーズを入力します。完了後、pki/ に ca.crt と private/ca.key が生成されます。
サーバー証明書を生成して署名する
サーバー用のリクエストを作成します(ここでは openvpn-bsd という名前を使用)。
./easyrsa.real gen-req openvpn-bsd nopass
CA でサーバー証明書に署名します。
./easyrsa.real sign-req server openvpn-bsd
CA のパスフレーズを入力すると署名が完了します。
検証:
openssl verify -CAfile pki/ca.crt pki/issued/openvpn-bsd.crt
エラーが出なければ成功です。
クライアント証明書を生成して署名する
クライアント用に client01 を作成します。
./easyrsa.real gen-req client01 nopass
署名:
./easyrsa.real sign-req client client01
CA のパスフレーズを入力して署名完了。検証:
openssl verify -CAfile pki/ca.crt pki/issued/client01.crt
DH-PARAM と CRL を生成する
追加セキュリティ用に DH パラメータと CRL を生成します。CRL は後で失効リストとして使用します。
./easyrsa.real gen-crl
./easyrsa.real gen-dh
生成後、出力ファイルを OpenVPN 用ディレクトリに配置します。
mkdir -p /usr/local/etc/openvpn/{server,client}
cp pki/ca.crt /usr/local/etc/openvpn/server/
cp pki/issued/openvpn-bsd.crt /usr/local/etc/openvpn/server/
cp pki/private/openvpn-bsd.key /usr/local/etc/openvpn/server/
cp pki/ca.crt /usr/local/etc/openvpn/client/
cp pki/issued/client01.crt /usr/local/etc/openvpn/client/
cp pki/private/client01.key /usr/local/etc/openvpn/client/
cp pki/dh.pem /usr/local/etc/openvpn/server/
cp pki/crl.pem /usr/local/etc/openvpn/server/
完了の確認:
Step 4 - OpenVPN サーバーを構成する
OpenVPN のメイン設定を作成します。
cd /usr/local/etc/openvpn/
vim openvpn.conf
以下は基本的な openvpn.conf の例です。必要に応じてパラメータを調整してください。
# OpenVPN Port, Protocol, and the Tun
port 1194
proto udp
dev tun
# OpenVPN Server Certificate - CA, server key and certificate
ca /usr/local/etc/openvpn/server/ca.crt
cert /usr/local/etc/openvpn/server/openvpn-bsd.crt
key /usr/local/etc/openvpn/server/openvpn-bsd.key
#DH and CRL key
dh /usr/local/etc/openvpn/server/dh.pem
crl-verify /usr/local/etc/openvpn/server/crl.pem
# Network Configuration - Internal network
# Redirect all Connection through OpenVPN Server
server 10.5.5.0 255.255.255.0
push "redirect-gateway def1"
# Using the DNS from https://dns.watch
push "dhcp-option DNS 84.200.69.80"
push "dhcp-option DNS 84.200.70.40"
#Enable multiple clients to connect with the same certificate key
duplicate-cn
# TLS Security
cipher AES-256-CBC
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
auth SHA512
auth-nocache
# Other Configuration
keepalive 20 60
explicit-exit-notify 1
persist-key
persist-tun
comp-lzo yes
daemon
user nobody
group nobody
# OpenVPN Log
log-append /var/log/openvpn.log
verb 3
設定を保存したらサービスを起動して状態を確認します。
service openvpn start
service openvpn status
ソケットをリッスンしているプロセスを確認します。
sockstat -l4
例: UDP 1194 で待ち受けていることを確認します。
Step 5 - pf ファイアウォールを設定する
pf を使って VPN トラフィックの NAT と許可ルールを設定します。ここでは VPN インターフェースを tun0
、外部インターフェースを $ext_if
(例: vtnet0)とします。
pf.conf の例:
# vpn interface
vpn_if="tun0"
vpn_net = "10.5.5.0/24"
# reassemble all fragmented packets before filtering them
scrub in on $ext_if all fragment reassemble
# route traffic from VPN interface out to the internet
nat on ! $vpn_if from $vpn_net to any -> $ext_ip
# Allow Connection to VPN Server
pass in on $ext_if proto udp from any to ($ext_if) port 1194 keep state
# Pass all connection on the VPN Interface
pass in on $vpn_if from any to any
設定をチェックしてリロードします。
service pf check
service pf reload
ルール確認:
pfctl -sr
pfctl -sn
画面例:
Step 6 - IP フォワーディングを有効にする
カーネルでの IP フォワーディングを有効にします。
vim /etc/sysctl.conf
以下を追加:
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
設定を反映してゲートウェイ有効化:
sysctl -f /etc/sysctl.conf
sysrc gateway_enable="YES"
reboot
再起動後、ルーティングと転送が有効になっていることを確認してください。
Step 7 - クライアント設定を作成する
クライアント側で使用する .ovpn 設定を作成します。サーバーの公開 IP に合わせて remote を変更してください。
cd /usr/local/etc/openvpn/client/
vim client01.ovpn
client01.ovpn の例:
client
dev tun
proto udp
remote xxx.xxx.xxx.xxx 1194
ca ca.crt
cert client01.crt
key client01.key
cipher AES-256-CBC
auth SHA512
auth-nocache
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
resolv-retry infinite
compress lzo
nobind
persist-key
persist-tun
mute-replay-warnings
verb 3
作成した client ディレクトリにある ca.crt, client01.crt, client01.key と client01.ovpn をローカル端末に安全な方法でダウンロードします。
転送には scp や SFTP、あるいはセキュアな USB を利用してください。鍵ファイルは特に安全に扱ってください。
Step 8 - 接続テスト
ダウンロードしたクライアント設定と証明書を配置した後、クライアントで次のように接続します。
openvpn --config client01.ovpn
接続確立後、サーバーから割り当てられた仮想インターフェースを確認します。
ifconfig tun0
割り当てられた内部 IP(例: 10.5.5.6)が表示されれば成功です。
サーバーの内部 IP に ping を打ちます。
ping -c3 10.5.5.1
外部 IP がサーバー側に見えるか確認します。
curl ipinfo.io
接続成功の例:
セキュリティ強化と運用上の注意点
- CA キーの保護: private/ca.key は厳重に保護し、可能ならオフラインで保管します。
- 鍵長とアルゴリズム: RSA 2048 は一般的ですが、セキュリティ要件が高い場合は 3072/4096 や EC(ECDSA)検討を推奨します。
- TLS つまり脆弱性対策: tls-version-min 1.2 以上、強力な tls-cipher を指定する。
- CRL 管理: クライアント失効時は CRL を更新し OpenVPN サーバーで再読み込みする。失効操作:
./easyrsa.real revoke client01
./easyrsa.real gen-crl
cp pki/crl.pem /usr/local/etc/openvpn/server/
service openvpn restart
- ログ管理: /var/log/openvpn.log をローテーションし、不要なログ肥大化を防止します。
- コンフィグ管理: 設定や証明書の変更はバージョン管理し、変更履歴を残します。
運用上のチェックリスト(役割別)
管理者チェックリスト
- OpenVPN サービスが自動起動するか確認
- pf で UDP 1194 を許可しているか確認
- /etc/sysctl.conf で IP フォワーディングが有効か確認
- 定期的に CRL を更新する手順を確立
セキュリティ担当者チェックリスト
- CA キー保管ポリシーを定義
- 鍵長と暗号スイートが組織基準に合致しているか確認
- 監査ログの保存期間を決定
サポート担当チェックリスト
- クライアント接続手順をドキュメント化
- よくある障害と対応手順をまとめる
- 失効リストの更新手順を把握
トラブルシューティング
接続できない場合に確認する項目
- サーバー側で OpenVPN がリッスンしているか
sockstat -l4
で UDP 1194 を確認
- pf でポートがブロックされていないか
pfctl -sr
とpfctl -sn
でルール確認
- 証明書の検証に失敗していないか
openssl verify -CAfile pki/ca.crt pki/issued/client01.crt
- クライアントの .ovpn のパス指定が正しいか(ca, cert, key)
- ログを確認する:
/var/log/openvpn.log
(verb レベルを上げて詳細を確認)
よくあるエラーと対処
- TLS handshake failed: サーバー・クライアントの時刻ずれ、証明書不一致、TLS バージョンの不整合を確認
- AUTH_FAILED: 認証方式が合っているか、鍵ファイルが破損していないかを確認
受け入れ基準
- サーバーが UDP 1194 で待ち受け、クライアントが internal ネットワーク(例 10.5.5.0/24)を取得できること
- クライアントからサーバー内のリソースに ICMP や TCP で到達できること
- インターネット接続がサーバー経由で行われ、外部 IP がサーバーの IP に変わること
- CRL を使って失効したクライアントが接続できないこと
追加の設計選択肢と代替案
- 認証方式: 証明書ベースの他に、事前共有鍵(PSK) やユーザー名/パスワード(さらに PAM/LDAP 連携)も可能。証明書はスケールとセキュリティの面で有利。
- 暗号化アルゴリズム: OpenVPN 2.5+ では AEAD(例: AES-GCM)を使うとパフォーマンスとセキュリティが向上します。
- コンテナ化: OpenVPN をコンテナで運用する場合はネットワーク命名やホスト側の pf 設定に注意が必要です。
テストケースと受け入れテスト(抜粋)
- 新規クライアントが証明書で接続できること
- 失効済みクライアントが接続できないこと
- サーバー再起動後に自動でサービスが立ち上がること
- pf の NAT によってクライアントの外向きトラフィックがインターネットに出ること
参考
まとめ
このガイドでは FreeBSD 12.0 上に OpenVPN をインストールし、easy-rsa で CA/証明書を構築、OpenVPN サーバー設定、pf による NAT/ファイアウォール、IP フォワーディング有効化、クライアント構成、接続テストまでを一通り説明しました。運用段階では CA キーの厳格な管理、CRL の適切な運用、ログと監視の継続的な実施を強く推奨します。