Amazon EC2 と WireGuard で軽量 VPN サーバーを構築する -アクセスログ編-

こんにちは、広野です。

本記事は以下の続編記事です。実装編で紹介した内容のうち、アクセスログの実装にフォーカスして説明します。実装については前回記事を参照ください。

 

前提

WireGuard はネイティブなアクセスログ機能は持っていません。そのため、OS やクラウドの機能を組み合わせてアクセスログを取得する必要があります。

軽量、高速を求めるためにそのようにしたのではないかと考えられます。とは言え、ログのレベルはピンキリだとしても必ず必要だと思いますので、今回実装を試みました。

 

検討した仕様

  • どのクライアントがどのリソースにアクセスしたか、記録したい。→ 実装は IP アドレスレベルの記録が現実的。フォーマット例は以下。
May  8 18:30:01 example-dev-wg kernel: WG_ACCESS IN=wg0 SRC=172.16.179.1 DST=192.168.102.58 PROTO=TCP DPT=443
  • OS 内でログを保存したくない。→ Amazon CloudWatch Logs への転送が AWS では最適。本記事では紹介しませんが CloudWatch Logs Insight で検索が容易になる利点もあります。

何をもってアクセスログとするか、は議論があると思いますがここではこのように定義したと思ってください。

前述の通り、WireGuard はアクセスログ機能を持っていないため、作り込む必要があります。以下のアーキテクチャを考えました。OS 内の動きです。

  • wg0 は、VPN 接続するクライアントと WireGuard の間で使用するネットワークです。本記事の構成では、172.16.179.0/24 を使用しています。
  • クライアントは WireGuard から 172.16.179.0/24 の中から IP アドレスを割り当てられます。動的ではなく、設定ファイルで固定になるため、設定ファイルを誰に渡したか管理していれば、その限りでは人を特定できますし、不正なアクセスが疑われればその設定を削除することになります。
  • ただし、クライアントの IP アドレスは、あくまでも WireGuard の EC2 インスタンスの中でしかわかりません。例えば、VPC フローログで VPC のネットワークトラフィックをロギングしたとしても、VPN の暗号化通信の中にカプセルされているため、クライアントを特定できません。EC2 インスタンスが持つ ENI (OS 上では ens5) では、通信が iptables により NAT されクライアント PC の IP アドレスが一律 EC2 インスタンスのプライベート IP アドレスに変換されます。そのため、EC2 インスタンス内部の仮想インターフェースである、wg0 のトラフィックをログとして取得する必要があります。
  • wg0 のログは、iptables によりカーネルログに送ります。そのような設定をします。
  • rsyslog は、カーネルログから WireGuard のログ (特定の文字列で認識) をログファイルに保存します。
  • Amazon CloudWatch Agent がログファイルを監視し、新しいログが書き込まれると Amazon CloudWatch Logs、つまり OS の外部にログを転送します。CloudWatch Logs の保存期間は本記事の設定では 365 日にしています。
  • わざわざ rsyslog を使用してログをログファイルに落とし込んでいる理由は、Amazon CloudWatch Agent が直接カーネルログや journald を読み込めないためです。
  • ログが Amazon CloudWatch Logs に転送されれば、OS 上にログを残しておく理由はありません。logrotate を使用して、本記事の設定では2日分だけログファイルを保持して削除するようにしています。
  • iptables、rsyslog、Amazon CloudWatch Agent は OS (Amazon Linux 2023 ARM64) のデフォルトではインストールされていないため、dnf でインストールする必要があります。設定コマンドも含め、前回記事のユーザーデータスクリプト内に書いてあります。

必要な設定コマンドは次章で説明します。

設定コマンド

iptables

iptables -I FORWARD 1 -i wg0 -p tcp -m conntrack --ctstate NEW -j LOG --log-prefix "WG_ACCESS " --log-level 4
iptables -I FORWARD 2 -i wg0 -p icmp -j LOG --log-prefix "WG_ACCESS " --log-level 4
  • 1, 2 の数字は重要で、iptables で処理される順番が重要です。他の処理が先に行われるとロギングされなくなってしまうため、最初にロギングを設定しています。
  • conntrack で新規接続のみをロギングします。肥大化防止のため。
  • udp を設定していないのも肥大化防止のためです。本来は udp も取得すべきとは思いますが、やってみると膨大になるのであきらめました。特定の要件があれば設定しましょう。

rsyslog

mkdir -p /var/log/wireguard
cat <<'RSYSLOG' > /etc/rsyslog.d/wireguard.conf
:msg, contains, "WG_ACCESS" /var/log/wireguard/access.log
& stop
RSYSLOG
systemctl enable rsyslog
systemctl start rsyslog
  • /etc/rsyslog.d/wireguard.conf を作成し、WG_ACCESS を含むログを access.log に落とし込む設定をしています。

logrotate

cat <<'LOGROTATE' > /etc/logrotate.d/wireguard
/var/log/wireguard/access.log {
    daily
    rotate 2
    compress
    missingok
    notifempty
    copytruncate
}
LOGROTATE
  • 日次ローテーション、2世代、圧縮です。

Amazon CloudWatch Agent

cat <<CWAGENT > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
{
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/wireguard/access.log",
            "log_group_name": "/wireguard/example-dev-wg/accesslog",
            "log_stream_name": "{instance_id}",
            "timezone": "Local"
          }
        ]
      }
    }
  }
}
CWAGENT
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
  • rsyslog が書き出したログを Amazon CloudWatch Logs に転送します。
  • あらかじめ CloudWatch ロググループの作成や、EC2 インスタンスにアタッチする IAM ロールにログ書き込みの権限が必要です。前回記事の CloudFormation テンプレートに記載されています。

 

実際の動作

実際に、以下の図のような VPN 接続をしたときに、どのようなログが記録されるか確認します。ping 実行です。

クライアント PC からの ping

WireGuard クライアントソフトを Windows PC にインストールして、クライアント設定ファイルをインポートすると VPN 接続ができます。その後、ping を実行します。

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows

PS C:\Users\hiron> ping 192.168.102.58

192.168.102.58 に ping を送信しています 32 バイトのデータ:
192.168.102.58 からの応答: バイト数 =32 時間 =14ms TTL=126
192.168.102.58 からの応答: バイト数 =32 時間 =13ms TTL=126
192.168.102.58 からの応答: バイト数 =32 時間 =14ms TTL=126
192.168.102.58 からの応答: バイト数 =32 時間 =13ms TTL=126

192.168.102.58 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 13ms、最大 = 14ms、平均 = 13ms

OS 上のログファイル

/var/log/wireguard/access.log にログが残りました。

[root@ip-192-168-1-57 wireguard]# tail -4 access.log
May  9 21:36:39 ip-192-168-1-57 kernel: WG_ACCESS IN=wg0 OUT=ens5 MAC= SRC=172.16.179.3 DST=192.168.102.58 LEN=60 TOS=0x00 PREC=0x00 TTL=127 ID=51627 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=298
May  9 21:36:40 ip-192-168-1-57 kernel: WG_ACCESS IN=wg0 OUT=ens5 MAC= SRC=172.16.179.3 DST=192.168.102.58 LEN=60 TOS=0x00 PREC=0x00 TTL=127 ID=51628 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=299
May  9 21:36:41 ip-192-168-1-57 kernel: WG_ACCESS IN=wg0 OUT=ens5 MAC= SRC=172.16.179.3 DST=192.168.102.58 LEN=60 TOS=0x00 PREC=0x00 TTL=127 ID=51629 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=300
May  9 21:36:42 ip-192-168-1-57 kernel: WG_ACCESS IN=wg0 OUT=ens5 MAC= SRC=172.16.179.3 DST=192.168.102.58 LEN=60 TOS=0x00 PREC=0x00 TTL=127 ID=51630 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=301
[root@ip-192-168-1-57 wireguard]#

Amazon CloudWatch Logs

CloudWatch Logs にもログが転送されていることが確認できました。画像は小さいのでお手数ですが拡大してください。

ソースがクライアント PC (172.16.179.3) で、デストが 192.168.102.58 であることがわかります。プロトコルは今回 ICMP でしたが、TCP であればポート番号も記録されます。

 

まとめ

いかがでしたでしょうか。

今回作成したアクセスログがすべてではなく、やはり VPC フローログも併せて取得は必要です。また、不正アクセスを追究するためにはさらに他のログも必要になるでしょう。パケットキャプチャツールほどではないですが、何らかの調査用にすべての通信を取得することもできますがログの量とのトレードオフになります。とりあえず WireGuard のログとしてはここまでは軽量にできそうだ、という感じです。

本記事が皆様のお役に立てれば幸いです。

著者について
広野 祐司

AWS サーバーレスアーキテクチャと React を使用して社内向け e-Learning アプリ開発とコンテンツ作成に勤しんでいます。React でアプリを書き始めたら、快適すぎて他の言語には戻れなくなりました。近年は社内外への AWS 技術支援にも従事しています。AWS サービスには AWS が考える IT 設計思想が詰め込まれているので、いつも AWS を通して勉強させて頂いてまます。
取得資格:AWS 認定は15資格、IT サービスマネージャ、ITIL v3 Expert 等
2020 - 2025 Japan AWS Top Engineer 受賞
2022 - 2025 AWS Ambassador 受賞
2023 当社初代フルスタックエンジニア認定
好きなAWSサービス:AWS AppSync Events / AWS Step Functions / AWS CloudFormation

広野 祐司をフォローする

クラウドに強いによるエンジニアブログです。

SCSKクラウドサービス(AWS)は、企業価値の向上につながるAWS 導入を全面支援するオールインワンサービスです。AWS最上位パートナーとして、多種多様な業界のシステム構築実績を持つSCSKが、お客様のDX推進を強力にサポートします。

AWSクラウド
シェアする
×
タイトルとURLをコピーしました