mcpField
V
vpn-setup

vpn-setup

github.com/bagelholeクラウド・DevOps1.2k402 回インストール23 週間前に更新
リポジトリ

vpn-setup について

vpn-setupは、リモートアクセスやネットワーク接続向けの安全なVPNトンネルを設定するスキルです。WireGuard、OpenVPN、Tailscale、AWS Site-to-Site VPNの設定例とトラブルシューティングを扱います。

主な機能

  1. 01WireGuardサーバーとクライアントの設定
  2. 02OpenVPN証明書とトンネルの構成
  3. 03Tailscaleのサブルート設定
  4. 04AWS Site-to-Site VPNの構成
  5. 05接続、DNS、性能の問題の調査

活用シーン

  1. 01従業員や契約者のリモートアクセス設定
  2. 02オンプレミスネットワークとクラウドの接続
  3. 03サービスを公開せずに内部サービスへアクセス
  4. 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 接続のフェイルオーバーをテストします

関連スキル

コメント