vpn-setup について
vpn-setupは、リモートアクセスやネットワーク接続向けの安全なVPNトンネルを設定するスキルです。WireGuard、OpenVPN、Tailscale、AWS Site-to-Site VPNの設定例とトラブルシューティングを扱います。
主な機能
- 01WireGuardサーバーとクライアントの設定
- 02OpenVPN証明書とトンネルの構成
- 03Tailscaleのサブルート設定
- 04AWS Site-to-Site VPNの構成
- 05接続、DNS、性能の問題の調査
活用シーン
- 01従業員や契約者のリモートアクセス設定
- 02オンプレミスネットワークとクラウドの接続
- 03サービスを公開せずに内部サービスへアクセス
- 04データセンターやリージョン間の接続
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill vpn-setupインストール後、Claude Code で/vpn-setupを入力して読み込まれたか確認します。
詳細
VPN のセットアップ
リモートアクセスと拠点間接続のために、安全な VPN トンネルを構成します。
このスキルを使用する場面
次のような場合にこのスキルを使用します。
- 従業員や契約社員向けに、安全なリモートアクセスをセットアップする場合
- オンプレミスネットワークをクラウド環境に接続する場合(拠点間接続)
- データセンターやリージョン間のトラフィックを暗号化する場合
- 分散インフラストラクチャ向けにメッシュ VPN を実装する場合
- 内部サービスをパブリックに公開せず、安全なアクセスを提供する場合
前提条件
- VPN エンドポイント用のパブリック IP を持つ Linux サーバー
- VPN サーバーへの root/sudo アクセス
- VPN トラフィックを許可するファイアウォールルール(WireGuard の場合は UDP 51820、OpenVPN の場合は UDP 1194)
- VPN ホスト名用に構成された DNS(任意ですが推奨)
- IP サブネット化とルーティングに関する知識
WireGuard
サーバーのセットアップ
# Install WireGuard (Ubuntu/Debian)
apt update && apt install -y wireguard
# Generate server keys
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
chmod 600 /etc/wireguard/server_private.key
# Generate pre-shared key (optional, adds post-quantum resistance)
wg genpsk > /etc/wireguard/psk.key
chmod 600 /etc/wireguard/psk.key
サーバーの構成
# /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server-private-key>
# Enable IP forwarding and NAT on startup
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# DNS for clients
DNS = 10.0.0.1
# Peer: Alice (laptop)
[Peer]
PublicKey = <alice-public-key>
PresharedKey = <preshared-key>
AllowedIPs = 10.0.0.2/32
# Peer: Bob (mobile)
[Peer]
PublicKey = <bob-public-key>
PresharedKey = <preshared-key>
AllowedIPs = 10.0.0.3/32
# Peer: Office network (site-to-site)
[Peer]
PublicKey = <office-public-key>
PresharedKey = <preshared-key>
AllowedIPs = 10.0.0.4/32, 192.168.1.0/24
Endpoint = office.example.com:51820
PersistentKeepalive = 25
クライアントの構成
# Client config: alice.conf
[Interface]
Address = 10.0.0.2/24
PrivateKey = <alice-private-key>
DNS = 10.0.0.1
[Peer]
PublicKey = <server-public-key>
PresharedKey = <preshared-key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
スプリットトンネリングの構成
# Client config with split tunnel (only route internal traffic through VPN)
[Interface]
Address = 10.0.0.2/24
PrivateKey = <alice-private-key>
# No DNS override for split tunnel
[Peer]
PublicKey = <server-public-key>
PresharedKey = <preshared-key>
Endpoint = vpn.example.com:51820
# Only route specific subnets through VPN
AllowedIPs = 10.0.0.0/24, 172.16.0.0/16, 192.168.1.0/24
PersistentKeepalive = 25
WireGuard の管理コマンド
# Start/stop interface
wg-quick up wg0
wg-quick down wg0
# Enable on boot
systemctl enable wg-quick@wg0
# Show connection status
wg show
wg show wg0
# Add a new peer dynamically
wg set wg0 peer <new-public-key> allowed-ips 10.0.0.5/32
# Remove a peer
wg set wg0 peer <public-key> remove
# Show transfer statistics
wg show wg0 transfer
# Generate QR code for mobile clients
apt install -y qr-encode
qrencode -t ansiutf8 < alice-mobile.conf
ピア管理スクリプト
#!/bin/bash
# wg-add-peer.sh - Add a new WireGuard peer
set -euo pipefail
PEER_NAME="${1:?Usage: $0 <peer-name>}"
SERVER_CONF="/etc/wireguard/wg0.conf"
CLIENTS_DIR="/etc/wireguard/clients"
SERVER_PUBKEY=$(cat /etc/wireguard/server_public.key)
SERVER_ENDPOINT="vpn.example.com:51820"
PSK=$(cat /etc/wireguard/psk.key)
# Find next available IP
LAST_IP=$(grep -oP 'AllowedIPs = 10\.0\.0\.\K[0-9]+' "$SERVER_CONF" | sort -n | tail -1)
NEXT_IP=$((LAST_IP + 1))
mkdir -p "$CLIENTS_DIR"
# Generate client keys
wg genkey | tee "$CLIENTS_DIR/${PEER_NAME}_private.key" | wg pubkey > "$CLIENTS_DIR/${PEER_NAME}_public.key"
chmod 600 "$CLIENTS_DIR/${PEER_NAME}_private.key"
CLIENT_PRIVKEY=$(cat "$CLIENTS_DIR/${PEER_NAME}_private.key")
CLIENT_PUBKEY=$(cat "$CLIENTS_DIR/${PEER_NAME}_public.key")
# Add peer to server config
cat >> "$SERVER_CONF" << EOF
# Peer: ${PEER_NAME}
[Peer]
PublicKey = ${CLIENT_PUBKEY}
PresharedKey = ${PSK}
AllowedIPs = 10.0.0.${NEXT_IP}/32
EOF
# Generate client config
cat > "$CLIENTS_DIR/${PEER_NAME}.conf" << EOF
[Interface]
Address = 10.0.0.${NEXT_IP}/24
PrivateKey = ${CLIENT_PRIVKEY}
DNS = 10.0.0.1
[Peer]
PublicKey = ${SERVER_PUBKEY}
PresharedKey = ${PSK}
Endpoint = ${SERVER_ENDPOINT}
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF
# Reload WireGuard
wg syncconf wg0 <(wg-quick strip wg0)
echo "Peer ${PEER_NAME} added with IP 10.0.0.${NEXT_IP}"
echo "Client config: ${CLIENTS_DIR}/${PEER_NAME}.conf"
OpenVPN
サーバーのセットアップ
# Install OpenVPN and Easy-RSA
apt install -y openvpn easy-rsa
# Initialize PKI
make-cadir /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-dh
openvpn --genkey secret /etc/openvpn/ta.key
# Generate client certificate
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1
サーバーの構成
# /etc/openvpn/server.conf
port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
tls-auth /etc/openvpn/ta.key 0
server 10.8.0.0 255.255.255.0
# Route client traffic through VPN
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
# Split tunnel: push specific routes instead
# push "route 172.16.0.0 255.255.0.0"
# push "route 192.168.1.0 255.255.255.0"
keepalive 10 120
# Cipher and auth
cipher AES-256-GCM
auth SHA256
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
# Hardening
tls-version-min 1.2
tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384
user nobody
group nogroup
persist-key
persist-tun
# Logging
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
verb 3
# Max clients
max-clients 100
# Client isolation (clients cannot see each other)
client-to-client
クライアントの構成
# client1.ovpn
client
dev tun
proto udp
remote vpn.example.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client1.crt
key client1.key
tls-auth ta.key 1
cipher AES-256-GCM
auth SHA256
verb 3
Tailscale(マネージド WireGuard)
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
# Authenticate and connect
tailscale up
# Advertise subnet routes (act as a gateway)
tailscale up --advertise-routes=192.168.1.0/24,172.16.0.0/16
# Enable as exit node (route all traffic)
tailscale up --advertise-exit-node
# Use an exit node
tailscale up --exit-node=<exit-node-ip>
# Check status
tailscale status
# Access control: tailscale ACL policy (in admin console)
# Example ACL policy
cat << 'EOF'
{
"acls": [
{"action": "accept", "src": ["group:engineering"], "dst": ["tag:servers:*"]},
{"action": "accept", "src": ["group:devops"], "dst": ["*:*"]},
{"action": "accept", "src": ["tag:monitoring"], "dst": ["tag:servers:9100"]}
],
"tagOwners": {
"tag:servers": ["group:devops"],
"tag:monitoring": ["group:devops"]
},
"groups": {
"group:engineering": ["[email protected]", "[email protected]"],
"group:devops": ["[email protected]"]
}
}
EOF
# Enable MagicDNS and set DNS
tailscale up --accept-dns
# SSH via Tailscale (no SSH keys needed)
tailscale up --ssh
AWS 拠点間 VPN
# Create Virtual Private Gateway
VGW_ID=$(aws ec2 create-vpn-gateway --type ipsec.1 --query 'VpnGateway.VpnGatewayId' --output text)
# Attach to VPC
aws ec2 attach-vpn-gateway --vpn-gateway-id "$VGW_ID" --vpc-id vpc-0abc123
# Create Customer Gateway (your on-prem device)
CGW_ID=$(aws ec2 create-customer-gateway \
--type ipsec.1 \
--bgp-asn 65000 \
--public-ip 203.0.113.10 \
--query 'CustomerGateway.CustomerGatewayId' --output text)
# Create VPN connection
VPN_ID=$(aws ec2 create-vpn-connection \
--type ipsec.1 \
--customer-gateway-id "$CGW_ID" \
--vpn-gateway-id "$VGW_ID" \
--options '{"StaticRoutesOnly":false}' \
--query 'VpnConnection.VpnConnectionId' --output text)
# Download configuration for your device
aws ec2 describe-vpn-connections --vpn-connection-ids "$VPN_ID"
# Enable route propagation
aws ec2 enable-vgw-route-propagation \
--gateway-id "$VGW_ID" \
--route-table-id rtb-0abc123
# Monitor VPN tunnel status
aws ec2 describe-vpn-connections \
--vpn-connection-ids "$VPN_ID" \
--query 'VpnConnections[0].VgwTelemetry'
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| WireGuard のハンドシェイクが完了しない | ファイアウォールが UDP 51820 をブロックしている | サーバーのファイアウォールと、経路上にあるすべてのファイアウォールで UDP 51820 を開放します |
| VPN 経由でインターネットに接続できない | IP フォワーディングが無効、または NAT が設定されていない | net.ipv4.ip_forward=1 を有効にし、PostUp の iptables ルールを確認します |
| VPN 経由で DNS 名前解決ができない | DNS が通知されていない、またはローカル DNS と競合している | クライアント構成に DNS = を設定し、/etc/resolv.conf を確認します |
| OpenVPN の TLS ハンドシェイクに失敗する | 証明書が一致しない、または期限切れ | CA 証明書が一致することを確認し、openssl x509 -dates で証明書の日付を確認します |
| スプリットトンネルでトラフィックが漏れる | AllowedIPs の範囲が広すぎる | AllowedIPs に特定のサブネットのみを設定し、traceroute で確認します |
| Tailscale のノードに到達できない | ACL がトラフィックをブロックしている | Tailscale 管理画面の ACL ポリシーを確認し、tailscale status でノードがオンラインであることを確認します |
| AWS VPN トンネルが不安定になる | アイドルタイムアウト、または DPD の設定ミス | カスタマーゲートウェイで DPD を有効にし、定期的にキープアライブトラフィックを送信します |
| VPN のパフォーマンスが低い | MTU の問題によりフラグメンテーションが発生している | WireGuard の構成で MTU = 1420 を設定し、ping -M do -s 1400 でテストします |
ベストプラクティス
- 最新の導入では WireGuard を使用します(よりシンプルで高速、攻撃対象領域も小さくなります)
- 可能な場合は VPN アクセスに MFA を導入します
- キーを定期的にローテーションします(WireGuard は四半期ごと、OpenVPN 証明書は年次)
- VPN 接続を監視し、異常があればアラートを送信します
- スプリットトンネリングまたは ACL を使用して、役割ごとに VPN アクセスを分離します
- 量子コンピューター耐性を高めるため、WireGuard で事前共有鍵を使用します
- セキュリティ脆弱性に対処するため、VPN ソフトウェアを常に最新の状態に保ちます
- 監査のため、すべての VPN 接続イベントを記録します
- 従業員の退職時には、VPN アクセスを直ちに無効にします
- 拠点間 VPN 接続のフェイルオーバーをテストします
関連スキル
- ゼロトラスト - 最新のアクセスパターン
- SSL/TLS 管理 - 証明書の管理
- ファイアウォール構成 - ネットワークアクセス制御
コメント
Markdown 対応