1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub Actions × WireGuard VPNでランナーのIPを固定する

1
Posted at

この記事は人間が書きました。

個人の検証雑記です。

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を固定化できることが確認できた。

5.png

OpenVPNとWireGuardの比較

ついでに、OpenVPNとWireGuardを簡単に比較してみた。
両方ともEC2にVPNサーバーを構築し、クライアントから接続した際のパケットをキャプチャしWiresharkでフロー図を見てみることにした。

OpenVPN

1.png

接続確立までの流れは次の通り

TLSをベースにしているため、複数往復のやり取りが必要になる。

WireGuard

4.png

対してWireGuardの流れは非常にシンプルだった。

接続確立までが1RTTで完了している。
WireGuardはNoiseIKというハンドシェイクパターンを利用しているようだ。が...自分ではNoiseIKについて良くわからなかったのでこのURLをNotebookLMに与えて簡単に説明してもらった👇️

NoiseIK(ノイズアイケイ)とは、WireGuardという安全なインターネット通信プログラムの「土台となる、特別な鍵交換の仕組み」です。

簡単に言うと、これは通信相手と安全な「秘密の合言葉(セッションキー)」を素早く決めるためのルールです。

具体的には:

• Diffie-Hellman鍵交換という数学的な方法を使って、安全な秘密の合言葉(セッションキー)を作り出します。

• この合言葉の交換は、たった1往復のメッセージ(1-RTTハンドシェイク)で完了し、すぐに暗号化されたデータのやり取り(トランスポートデータ)を始められます。

• これにより、WireGuardは誰にも秘密を知られることなく、しかも非常に短い時間で、安全な通信を始めることができます。NoiseIKは、「The Noise Protocol Framework」という、安全な通信プロトコルを設計するための大きな枠組みの一部です

さいごに (感想)

まあ、確かにGitHub Actionsのように「短時間でVPNを張って処理を実行する」というようなユースケースにおいて、WireGuardのシンプルさと速さが大きな利点になると感じた。

参考にさせてもらった記事

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?