WireGuard
WireGuardは、現代的な暗号技術で低遅延・高スループットを実現した、次世代の軽量なOSS VPNプロトコルです。
最新の暗号アルゴリズムを採用していながら低遅延であり、またコードベースが小さいためカーネルで動作する軽量な点が特徴としてあります。
この記事ではWireGuardのホストサーバをAWSのEC2で作ります。シェルスクリプト1つで世界中のリージョンにサーバを立てれるようにしました。またソースコードはAIと作りました。
準備
IAMからEC2インスタンスを作るユーザーとそれにアタッチするロールを作成します。
EC2インスタンスにアタッチするロールvpn_launch_roleにはAmazonSSMManagedInstanceCoreを付与します。SSMで手元と通信してコンフィグのダウンロードとハートビードを送ります
実行ユーザーにはAmazonEC2FullAccess, AmazonSSMFullAccessとロールvpn_launch_roleをパスするためのインラインポリシーをアタッチします。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::829282863407:role/vpn_launch_role" } ]}実行ユーザを実行するCLIにaws configureで設定しましょう。
実行
適当にコピーとかして実行します。Bashで作ってます。 引数にリージョン名を追加してリージョンを指定します。
実行するとカレントディレクトリにvpn-{region}.confファイルが作成されます。それをクライアントアプリに投げ込めば接続できます!
:::message インスタンス消すの忘れないでねー :::
# generated by Gemini
#!/bin/bash
# --- 設定項目 ---REGION=$1SG_NAME="WireguardSG"ROLE_NAME="vpn_launch_role"INSTANCE_TYPE="t3.nano"
# リージョン指定の確認if [ -z "$REGION" ]; then echo "Usage: ./vpn.sh <region-name>" echo "Example: ./vpn.sh us-west-2" exit 1fi
echo "=================================================="echo " Wireguard All-in-One Deployer: ${REGION}"echo "=================================================="
# 1. セキュリティグループの確認と自動作成echo "[1/5] Checking Security Group in ${REGION}..."SG_ID=$(aws ec2 describe-security-groups \ --region "$REGION" \ --filters "Name=group-name,Values=$SG_NAME" \ --query 'SecurityGroups[0].GroupId' \ --output text 2>/dev/null)
if [ "$SG_ID" == "None" ] || [ -z "$SG_ID" ]; then echo "Creating new Security Group: ${SG_NAME}..." SG_ID=$(aws ec2 create-security-group \ --group-name "$SG_NAME" \ --description "Wireguard VPN Group" \ --region "$REGION" \ --query 'GroupId' \ --output text)
# UDP 51820番ポートを解放 aws ec2 authorize-security-group-ingress \ --group-id "$SG_ID" \ --protocol udp \ --port 51820 \ --cidr 0.0.0.0/0 \ --region "$REGION" echo "Security Group created: ${SG_ID}"else echo "Using existing Security Group: ${SG_ID}"fi
# 2. EC2インスタンスの起動echo "[2/5] Launching EC2 instance with Docker..."USER_DATA=$(cat <<EOF#!/bin/bashdnf update -ydnf install -y dockersystemctl start dockersystemctl enable dockerdocker run -d \ --name=wireguard \ --cap-add=NET_ADMIN \ --cap-add=SYS_MODULE \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=Asia/Tokyo \ -e SERVERURL=auto \ -e PEERS=1 \ -e PEERDNS=auto \ -p 51820:51820/udp \ -v /config:/config \ --restart unless-stopped \ linuxserver/wireguardEOF)
INSTANCE_ID=$(aws ec2 run-instances \ --region "$REGION" \ --image-id resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 \ --count 1 \ --instance-type "$INSTANCE_TYPE" \ --security-group-ids "$SG_ID" \ --iam-instance-profile Name="$ROLE_NAME" \ --user-data "$USER_DATA" \ --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=Wireguard-$REGION}]" \ --query 'Instances[0].InstanceId' \ --output text)
if [ -z "$INSTANCE_ID" ] || [ "$INSTANCE_ID" == "None" ]; then echo "ERROR: Failed to launch instance. Check your IAM permissions (PassRole etc.)." exit 1fi
echo "Instance ID: ${INSTANCE_ID}"
# 3. SSM AgentがOnlineになるのを待機echo "[3/5] Waiting for SSM Agent to come online..."while true; do # インスタンスがSSM一覧に現れ、かつPingStatusがOnlineになるのを待つ STATUS=$(aws ssm describe-instance-information \ --region "$REGION" \ --filters "Key=InstanceIds,Values=$INSTANCE_ID" \ --query "InstanceInformationList[0].PingStatus" \ --output text 2>/dev/null)
if [ "$STATUS" == "Online" ]; then echo -e "\nSSM Agent is Online." break fi printf "." sleep 10done
# 4. 設定ファイルの生成待ちと取得コマンド発行echo "[4/5] Retrieving Wireguard config (waiting for generation)..."# コンテナ内でファイルができるまでループし、できたらcatするスクリプトをSSMで送るCOMMAND_ID=$(aws ssm send-command \ --region "$REGION" \ --instance-ids "$INSTANCE_ID" \ --document-name "AWS-RunShellScript" \ --parameters 'commands=["for i in {1..30}; do if [ -f /config/peer1/peer1.conf ]; then docker exec wireguard cat /config/peer1/peer1.conf && exit 0; fi; sleep 5; done; echo \"Timeout waiting for config\"; exit 1"]' \ --query "Command.CommandId" \ --output text)
# AWS側でコマンドが完了するのを待機aws ssm wait command-executed \ --region "$REGION" \ --command-id "$COMMAND_ID" \ --instance-id "$INSTANCE_ID"
# 5. ローカルファイルへの保存echo "[5/5] Downloading configuration file..."OUT_FILE="vpn-${REGION}.conf"aws ssm list-command-invocations \ --region "$REGION" \ --command-id "$COMMAND_ID" \ --details \ --query "CommandInvocations[0].CommandPlugins[0].Output" \ --output text > "$OUT_FILE"
# ファイルが空でないか、"None"などのエラーメッセージでないか確認if [ -s "$OUT_FILE" ] && ! grep -q "Timeout" "$OUT_FILE"; then echo "==================================================" echo " SUCCESS!" echo " Region: ${REGION}" echo " Config: ${OUT_FILE}" echo "=================================================="else echo "ERROR: Config retrieval failed. The file is empty or timed out." rm -f "$OUT_FILE"fiあとがき
AIに作らせたものって創造性が無くてあまり好きではないのですが(特に絵)、こうして実用的なものができた時、思わず共有したくなります。 大方ブラックボックス化してしまっていますが、何とかAWS CLIができるようにしたいなーと所感。
本当はNetflixでジブリが見たかったんですけど、もう少し何か対策が必要そうです。 とりあえず学校からマイクラできて神✨✨