この記事は人間が書きました。
個人の検証雑記です。
GitHubホステッドランナーを使用していて、ランナーのグローバルIPを固定したい場合、いくつかの対処手段がある。その中の一つとして、以下のドキュメントを「こんな方法もあるよ」と教えてもらったので試してみた。
内容としては「WireGuardを使えば、GitHub Actionsのワークフローの中で簡単にVPNを張れる」というもの。
WireGuardとは最新のVPNプロトコルで、現時点で最速だとか。
簡単にVPN環境が構築できるTraiscaleなどでも使用されているらしい。
WireGuardサーバーの構築
まずはWireGuardサーバーの構築。今回はEC2 (Ubuntu24.04) で構築をおこなった。
WireGuardサーバーの構築方法については多くの記事があるため詳細は割愛。
一応、検証で構築した際のAnsible Playbookを書いておいたので、置いておく。
GitHub Actionsから接続
GitHub Actions用にWireGuardのキーペアを生成する。
# プライベートキーを生成
wg genkey > private.key
# パブリックキーを生成
cat private.key | wg pubkey > public.key
生成した公開鍵はサーバー側のPeer設定に追加しておく。
次にワークフローは以下のように書いてみた。
ドキュメントの内容からの変更点として、wg-quickでより簡潔に接続設定をおこなうようにしてみた。
name: WireGuard VPN Connection
on:
workflow_dispatch:
jobs:
wireguard_connection:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install WireGuard
run: sudo apt update && sudo apt install -y wireguard
- name: Setup WireGuard configuration
run: |
# Create WireGuard config file
sudo tee /etc/wireguard/wg0.conf > /dev/null <<EOF
[Interface]
PrivateKey = ${{ secrets.WIREGUARD_PRIVATE_KEY }}
Address = ${{ secrets.WG_CLIENT_IP }}/32
[Peer]
PublicKey = ${{ secrets.WG_SERVER_PUBLIC_KEY }}
Endpoint = ${{ secrets.WG_SERVER_ENDPOINT }}
AllowedIPs = 0.0.0.0/0
EOF
- name: Start WireGuard with wg-quick
run: sudo wg-quick up wg0
- name: Test VPN connection
run: |
# Wait for connection to establish
sleep 5
echo "Test connection to private network"
ping -c 3 ${{ secrets.WG_SERVER_IP }}
echo "Show routing table"
ip route show
echo "Show WireGuard status"
sudo wg show
- name: Run your private network tests here
run: |
curl http://ifconfig.io
- name: Cleanup
if: always()
run: |
sudo wg-quick down wg0 2>/dev/null || true
sudo rm -f /etc/wireguard/wg0.conf
Secretsに設定するのは以下の項目。
• WIREGUARD_PRIVATE_KEY: Actions用のWireGuard秘密鍵
• WG_SERVER_PUBLIC_KEY: サーバーの公開鍵
• WG_SERVER_ENDPOINT: サーバーのエンドポイント(例: xx.xx.xx.xx:51820)
• WG_CLIENT_IP: クライアント側に割り当てるVPN内アドレス
• WG_SERVER_IP: サーバーのVPN内アドレス
この設定で実行するとすぐにVPNが確立され、GitHub ActionsのグローバルIPを固定化できることが確認できた。
OpenVPNとWireGuardの比較
ついでに、OpenVPNとWireGuardを簡単に比較してみた。
両方ともEC2にVPNサーバーを構築し、クライアントから接続した際のパケットをキャプチャしWiresharkでフロー図を見てみることにした。
OpenVPN
接続確立までの流れは次の通り
TLSをベースにしているため、複数往復のやり取りが必要になる。
WireGuard
対してWireGuardの流れは非常にシンプルだった。
接続確立までが1RTTで完了している。
WireGuardはNoiseIKというハンドシェイクパターンを利用しているようだ。が...自分ではNoiseIKについて良くわからなかったのでこのURLをNotebookLMに与えて簡単に説明してもらった👇️
NoiseIK(ノイズアイケイ)とは、WireGuardという安全なインターネット通信プログラムの「土台となる、特別な鍵交換の仕組み」です。
簡単に言うと、これは通信相手と安全な「秘密の合言葉(セッションキー)」を素早く決めるためのルールです。
具体的には:
• Diffie-Hellman鍵交換という数学的な方法を使って、安全な秘密の合言葉(セッションキー)を作り出します。
• この合言葉の交換は、たった1往復のメッセージ(1-RTTハンドシェイク)で完了し、すぐに暗号化されたデータのやり取り(トランスポートデータ)を始められます。
• これにより、WireGuardは誰にも秘密を知られることなく、しかも非常に短い時間で、安全な通信を始めることができます。NoiseIKは、「The Noise Protocol Framework」という、安全な通信プロトコルを設計するための大きな枠組みの一部です
さいごに (感想)
まあ、確かにGitHub Actionsのように「短時間でVPNを張って処理を実行する」というようなユースケースにおいて、WireGuardのシンプルさと速さが大きな利点になると感じた。
参考にさせてもらった記事


