現実の問題:チームのリモートアクセスはどうなっていますか?
さまざまなプロジェクトの10台以上のサーバーに対してセキュリティ監査を行った結果、ほぼすべてに共通の問題があることがわかりました:VPNがない、またはVPNを「なんとなく」使っているかのどちらかです。具体的には:
- SSHポート22をそのままインターネットに公開しており、ボットにすぐスキャンされてしまう
- OpenVPNを使っているものの設定が煩雑で、エンドユーザーが
.ovpnファイルをあれこれとコピーしなければならない - 一部のチームはTeamViewerやngrokを使っており、「暫定」のはずの解決策が永続的になってしまっている
結果は想像に難くありません:昼夜問わずボットがポートをスキャンし、深夜3時にSSHブルートフォースが走り、サーバーのログがゴミであふれます。あるステージングサーバーのauth.logを確認したことがあるのですが、24時間で中国やロシアのIPから15,000件ものログイン試行がありました。そのサーバーはdev環境を動かしているだけでしたが、侵害されることは不要なトラブルでしかありません。
答えは明らかです:パブリックポートをすべて閉じて、VPN経由でのみアクセスを許可する。しかし、使いやすく、高速で、設定に半日もかからないVPNはどれでしょうか?
なぜOpenVPNが常に答えではないのか?
OpenVPNが悪いと言っているわけではありません。実績があり、安定していて、長年使われてきました。ただ、新しいセットアップをする際に気になる点がいくつかあります:
- 必要以上に遅い:OpenVPNはユーザースペースで動作するため、各パケットがkernel → userspace → kernelと移動しなければなりません。実際のベンチマークでは、OpenVPNは通常100〜200Mbpsしか出ないのに対し、WireGuardは同じハードウェアで1Gbpsの回線を使い切れます。この差は、VPN越しにデータベースやファイルサーバーにアクセスする際に顕著に現れます
- 設定が複雑:PKIインフラ、CA、証明書、
.ovpnファイル — 新しいクライアントを追加するたびに一連の手順が必要です - デバッグが難しい:問題が発生した際、OpenVPNのログがあまり役に立たないことがあります
すでに安定して動いているOpenVPNインフラがあれば、移行する必要はありません。ただし、新しくセットアップするならWireGuardを真っ先に提案します。
WireGuard:次世代VPN、驚くほど小さなコードベース
Jason DonenfeldはWireGuardをわずか約4,000行のコードで書きました。OpenVPNの約70,000行と比べると一目瞭然です。コードが少ない = 攻撃面が小さい = 監査しやすい。Linus Torvaldsはこれを「a work of art」と称し、Linux kernelバージョン5.6から直接統合されました。つまりUbuntu 20.04以降では最初から使えて、追加モジュールのインストールは不要です。
以下がWireGuardをすべての新規セットアップで使う理由です:
- kernel内で動作:OpenVPNのようなユーザースペースのオーバーヘッドがなく、スループットが格段に高い
- 超高速ハンドシェイク:接続確立まで約100ms — OpenVPNは通常1〜2秒かかります
- 最新の暗号技術:ChaCha20、Poly1305、Curve25519 — 古いRSA/AESではありません
- シンプルな設定:各ピアに必要なのはpublic keyだけ — CAも証明書も不要
- デフォルトでステルス:WireGuardは不正なパケットに応答せず、ポートスキャンでは閉じているように見えます
WireGuardのインストールと設定:ステップバイステップ
セットアップ構成:Ubuntu Server 1台をVPNゲートウェイ(パブリックIPあり)とし、Nクライアント(開発用ノートPC、オフィスPC等)を接続します。テスト環境:Ubuntu 22.04 LTS。
ステップ1:WireGuardのインストール
sudo apt update
sudo apt install wireguard -y
Ubuntu 20.04以降では、WireGuardは公式リポジトリに含まれているため、PPAの追加は不要です。
ステップ2:サーバーの鍵ペアを生成する
WireGuardはpublic/private keyを使用します — ユーザー名やパスワードは不要です。各ピア(サーバーまたはクライアント)はそれぞれ独自の鍵ペアを持ちます。
sudo mkdir -p /etc/wireguard
cd /etc/wireguard
# 秘密鍵を生成し、そこから公開鍵を導出する
wg genkey | sudo tee server_private.key | wg pubkey | sudo tee server_public.key
# 鍵の内容を確認する
sudo cat server_private.key
sudo cat server_public.key
重要:秘密鍵は誰とも共有してはいけません。公開鍵は自由に共有できます — これが非対称暗号の原則です。
ステップ3:サーバー設定ファイルを作成する
sudo nano /etc/wireguard/wg0.conf
設定ファイルの内容:
[Interface]
# server_private.keyの内容をここに貼り付ける
PrivateKey = <SERVER_PRIVATE_KEY>
# トンネルインターフェースのIPアドレス(VPN内部IP、パブリックIPではない)
Address = 10.0.0.1/24
# WireGuardがリッスンするポート(UDP)
ListenPort = 51820
# トンネル起動時にIPフォワーディングとNATを有効にする
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# クライアントごとに[Peer]ブロックを追加する
[Peer]
# クライアント1の公開鍵
PublicKey = <CLIENT1_PUBLIC_KEY>
# このクライアントに割り当てるトンネル内IPアドレス
AllowedIPs = 10.0.0.2/32
注意:eth0はサーバーの実際のネットワークインターフェース名に置き換えてください。事前にip aで確認しましょう — VPSプロバイダーによってens3、enp0s3、eth0などの場合があります。推測せず、必ず確認してください。
ステップ4:IPフォワーディングを有効にする
# 即時に有効化する
sudo sysctl -w net.ipv4.ip_forward=1
# 永続的に有効化する(再起動後も維持)
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
ステップ5:クライアントの鍵ペアを生成する
Linuxクライアントマシンで:
sudo apt install wireguard -y
wg genkey | tee client_private.key | wg pubkey | tee client_public.key
クライアントがWindowsまたはmacOSの場合は、公式のWireGuardアプリを使用します — アプリのUIに「Generate keypair」ボタンがあるので、ターミナルは不要です。
ステップ6:クライアントを設定する
クライアントにこの設定ファイルを作成します(またはWindows/macOSのWireGuardアプリにインポートします):
[Interface]
# client_private.keyの内容をここに貼り付ける
PrivateKey = <CLIENT_PRIVATE_KEY>
# クライアントに割り当てられるVPNトンネル内のIPアドレス
Address = 10.0.0.2/24
# VPN接続時に使用するDNS(任意)
DNS = 1.1.1.1
[Peer]
# サーバーの公開鍵
PublicKey = <SERVER_PUBLIC_KEY>
# サーバーのパブリックIPとポート
Endpoint = <SERVER_PUBLIC_IP>:51820
# VPN経由でルーティングするトラフィック:
# 0.0.0.0/0 = すべてのトラフィック(フルトンネル)
# 10.0.0.0/24 = VPN内部トラフィックのみ(スプリットトンネル)
AllowedIPs = 10.0.0.0/24
# NAT(家庭用ルーター、4G等)の背後にいる場合の接続維持
PersistentKeepalive = 25
ステップ7:サーバーでWireGuardを起動する
# トンネルを起動する
sudo wg-quick up wg0
# 起動時に自動的に開始するよう設定する
sudo systemctl enable wg-quick@wg0
# 状態を確認する
sudo wg show
wg showの出力にはトンネル情報とピアの一覧が表示されます。ピアのセクションにlatest handshakeの行が表示されれば、クライアントが正常に接続されています。
ステップ8:サーバーのファイアウォールでポートを開放する
# UFWを使用している場合
sudo ufw allow 51820/udp
sudo ufw reload
# iptablesを直接使用している場合
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
実際の接続を確認する
クライアントが接続したら、ターミナルからすばやくテストします:
# VPN IP経由でサーバーにpingする(パブリックIPではない)
ping 10.0.0.1
# VPN IP経由でサーバーにSSH接続する
ssh [email protected]
10.0.0.1へのpingとSSHが成功すれば、VPNは正常に動作しています。ハンドシェイクは通常1秒以内に完了します — 初めて接続したとき、その速さに驚くはずです。これでSSHポート22をファイアウォールで閉じることができます — WireGuardの鍵を持つ人だけがサーバーにアクセスできるようになります。
新しいクライアントを追加する:サービスの再起動不要
これがWireGuardで最も気に入っているところです。新しいクライアントを追加する際に、証明書に署名したりトンネルを再起動する必要はありません:
# 新しいピアを即時追加する(再起動なしで有効になる)
sudo wg set wg0 peer <CLIENT2_PUBLIC_KEY> allowed-ips 10.0.0.3/32
# 再起動後も維持するため、/etc/wireguard/wg0.confにも追記する:
# [Peer]
# PublicKey = <CLIENT2_PUBLIC_KEY>
# AllowedIPs = 10.0.0.3/32
よくあるトラブルのトラブルシューティング
- 10.0.0.1にpingできるがインターネットにアクセスできない:
cat /proc/sys/net/ipv4/ip_forwardを実行して、出力が1であることを確認してください。正しくてもまだ問題がある場合は、PostUpのインターフェース名がip aの出力と一致しているか確認してください - 何も接続できない:
sudo wg showを実行して、latest handshakeが表示されなければ、UDPポート51820がブロックされています。UFWまたはVPSのセキュリティグループを確認してください - 数分後に接続が切れる:クライアント設定に
PersistentKeepalive = 25を追加してください — NATの背後にいるクライアントでは必須です - 「invalid key」エラー:設定ファイルには実際の鍵の内容(base64文字列)を記述する必要があります。ファイル名
server_private.keyではありません
チーム全体のセットアップが完了すると、サーバーのログはすっきりします。SSHブルートフォースも、毎日何千件もの失敗したログイン試行もなくなります。サーバーのパブリックポートはほぼすべて閉じられ、51820/UDPと443/TCPだけが開いています — 最初から目指していたセキュリティの形です。
