Ubuntu ServerにOpenVPNをインストール・設定する完全ガイド

Security tutorial - IT technology blog
Security tutorial - IT technology blog

自動スクリプトで5分でOpenVPNをインストール

ステップごとに手動設定することなく、すぐにVPNサーバーを立ち上げたい場合、openvpn-installスクリプトが最速の選択です。私はこのスクリプトをステージングやデモ環境の迅速なデプロイに使用しています。

# 自動インストールスクリプトをダウンロードして実行
wget https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh
chmod +x openvpn-install.sh
sudo bash openvpn-install.sh

スクリプトはサーバーIP、ポート、DNS、クライアント名などの情報を尋ねます。2〜3分後には、インポート可能な.ovpnファイルが準備できています。それだけです。

本番環境では話が違います。どの暗号を使うか、どのサブネットを使うか、ログをどこに出力するかを制御する必要がある場合は、手動インストールが十分な柔軟性をもたらします。以下でステップごとに詳しく説明します。

Ubuntu 22.04へのOpenVPNの手動インストール

ステップ1:パッケージのインストール

sudo apt update
sudo apt install -y openvpn easy-rsa

ステップ2:認証局(CA)の作成

Easy-RSA 3.x(Ubuntu 22.04付属)は便利なPKI管理ツールです。CAを専用ディレクトリに分離しています。後で証明書を失効させたり、新しいクライアントを追加したりする際に、OpenVPNの設定と混在しないため見つけやすくなります。

# PKIディレクトリを作成
make-cadir ~/openvpn-ca
cd ~/openvpn-ca

# PKIを初期化してCAを作成
./easyrsa init-pki
./easyrsa build-ca nopass

build-ca nopassはパスフレーズなしのCAを作成します。サーバーが自動再起動する際にパスワード入力待ちで止まらなくなります。このCAが多くの重要なサービスを管理する場合は、nopassを省略してセキュリティを強化してください。

ステップ3:サーバー証明書の作成

# サーバー証明書と秘密鍵を作成
./easyrsa gen-req server nopass
./easyrsa sign-req server server

# Diffie-Hellmanパラメータを生成(2 vCPU VPSで約30〜60秒かかります)
./easyrsa gen-dh

# TLS Authキーを作成(DDoSとリプレイアタック対策)
openvpn --genkey secret ta.key

ステップ4:ファイルをOpenVPNディレクトリにコピー

sudo cp pki/ca.crt pki/private/server.key pki/issued/server.crt /etc/openvpn/server/
sudo cp pki/dh.pem ta.key /etc/openvpn/server/

ステップ5:サーバー設定ファイルの作成

sudo nano /etc/openvpn/server/server.conf

以下の設定は実際に使用しているバージョンで、複数回のデプロイを経て調整したものです:

port 1194
proto udp
dev tun

ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh.pem
tls-auth /etc/openvpn/server/ta.key 0

server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 8.8.8.8"

keepalive 10 120
cipher AES-256-GCM
auth SHA256

user nobody
group nogroup
persist-key
persist-tun

status /var/log/openvpn-status.log
log-append /var/log/openvpn.log
verb 3

ステップ6:IPフォワーディングを有効化してサービスを起動

# IPフォワーディングを有効化
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# トラフィックをフォワードするiptablesを設定
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE

# OpenVPNを起動
sudo systemctl enable --now openvpn-server@server
sudo systemctl status openvpn-server@server

クライアント証明書の作成

cd ~/openvpn-ca

# クライアント証明書を作成("client1"を実際の名前に変更してください)
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1

次に、クライアントがインポートするためのclient1.ovpnファイルを作成します:

cat > ~/client1.ovpn << EOF
client
dev tun
proto udp
remote YOUR_SERVER_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
verb 3
key-direction 1
<ca>
$(cat ~/openvpn-ca/pki/ca.crt)
</ca>
<cert>
$(cat ~/openvpn-ca/pki/issued/client1.crt)
</cert>
<key>
$(cat ~/openvpn-ca/pki/private/client1.key)
</key>
<tls-auth>
$(cat ~/openvpn-ca/ta.key)
</tls-auth>
EOF

高度な設定

ファイアウォールを回避するためにTCP 443ポートでOpenVPNを実行

企業ネットワーク、ホテル、コワーキングスペースではUDP/1194がブロックされることがあります。TCP/443で実行すると、トラフィックがHTTPSのように見えるため、ほとんどの企業ファイアウォールは通過させます。

# server.confで修正
port 443
proto tcp

トレードオフ:TCP-over-TCPは二重のオーバーヘッドを生じさせ、ルートによってUDPと比べてレイテンシが20〜40ms増加します。UDPが本当にブロックされている場合にのみ有効にしてください。

必要なトラフィックのみをルーティングするクライアント制限(スプリットトンネリング)

フルトンネルはすべてのトラフィックをVPN経由でリダイレクトします。従業員がYouTubeを視聴している時でもです。これはサーバーの帯域幅を無駄にし、不必要にレイテンシを増加させます。スプリットトンネリングは内部サブネットへのトラフィックのみをルーティングし、残りはユーザーのISPを直接通過させます。

# redirect-gatewayの行を削除し、具体的なルートに置き換える
# push "redirect-gateway def1 bypass-dhcp"  # この行を削除
push "route 192.168.1.0 255.255.255.0"  # 内部サブネットのみをルーティング

退職した従業員の証明書を失効させる

cd ~/openvpn-ca
./easyrsa revoke client1
./easyrsa gen-crl

# CRLをOpenVPNにコピー
sudo cp pki/crl.pem /etc/openvpn/server/

# まだなければ/etc/openvpn/server/server.confに追加
echo "crl-verify /etc/openvpn/server/crl.pem" | sudo tee -a /etc/openvpn/server/server.conf

sudo systemctl restart openvpn-server@server

監査経験からの実戦的なヒント

10台以上のサーバーを監査した後、繰り返されるパターンがあります:VPNは動作しているが、設定に最初から脆弱性がある。レビュー時に必ず確認するチェックリスト:

  • 古い暗号を使用しないBF-CBC(Blowfish)やAES-128-CBCは避けてください。AES-256-GCMを使用してください。AEADサイファーは一つのステップでデータの暗号化と認証を同時に行うため、別途authディレクティブは不要です。
  • tls-authまたはtls-cryptを有効化するtls-authはすべてのパケットにHMACシグネチャを追加します。無効なパケットは復号化前にドロップされます。tls-cryptはさらにTLSハンドシェイクも暗号化します。私はtls-cryptを優先しています。
  • tls-version-min 1.2を使用する:server.confにこの行を追加してTLS 1.0と1.1を無効化してください。
  • UFWファイアウォール:ポートを開けてフォワーディングを許可することを忘れないでください:
sudo ufw allow 1194/udp
sudo ufw allow OpenSSH

# /etc/ufw/before.rulesに追加(*filterの行の前に)
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
  • 1証明書1デバイスuser_deviceの命名規則に従ってください。例えばnam_laptopnam_phoneのように。デバイスをブロックする必要がある場合、同じユーザーの他のデバイスに影響を与えずに該当する証明書だけを失効させることができます。
  • ログを定期的に監視する/var/log/openvpn-status.logは誰がどのIPから接続しているかをリアルタイムで表示します。fail2banと組み合わせて、認証失敗が連続して多いIPを自動的にブロックしてください。

クライアントからの接続テスト

# Linux/macOS
sudo openvpn --config client1.ovpn

# 接続後にIPを確認
curl ifconfig.me
# VPNサーバーのIPが表示されるはず

WindowsではOpenVPN Connect(Microsoft Store)、macOSではTunnelblick、iOSとAndroidにもOpenVPN Connectアプリがあります。すべて同様の方法で.ovpnファイルをインポートします。

最もよく忘れること:server.confを修正した後、サービスを再起動してすぐにログを確認し、エラーを早期に発見してください。

sudo systemctl restart openvpn-server@server
sudo journalctl -u openvpn-server@server -f

VPNが動作しているからといって、それで完了というわけではありません。これは多層防御の一つの層に過ぎません。SSHキーのみの認証(パスワードログインを完全に無効化)、VLAN間のネットワークセグメンテーション、そして不審なIPが接続した際のアラートを追加してください。この三つを組み合わせて初めて本当に安心できます。

Share: