Cloudflare Zero TrustのPrivate Networkでpingを通すのにハマった話

Cloudflare Zero TrustのPrivate Networkを作った際、pingを通すのに結構ハマったので、そのハマりどころを紹介します。

# Cloudflare Zero Trustとは

[Cloudflare Zero Trust](https://www.cloudflare.com/ja-jp/zero-trust/)は、企業レベルのゼロトラストネットワークアクセスのソリューションです。大盤振る舞いなことに50ユーザーまで無料なので、従来のVPNの代替としてご家庭や小規模オフィスなどで便利に使うことができます。

記事タイトルの「Private Network」はCloudflare Zero Trustの用語で、別ネットワークをVPN的に接続する設定のことを指します。これを使うことで、例えば自宅外から自宅のマシン群にアクセスすることができます。

# pingが通らなくてハマった

私はCloudflare Zero TrustのPrivate Networkの設定を行い、WARP ClientをインストールしたPCから自宅ネットワークが見えるようにしました。ここまではネット上に資料がたくさんあるので誰でも設定できると思います。

ところが、自宅に接続したとき、pingはデフォルトでは通りません。やればできるでしょ、と思っていたのですが、3個もハマりどころがあって意外と苦労しました。ハマりどころを順に説明します。

## ハマりどころ1：cloudflaredがQUICで接続していないといけない

Private Networkの接続の際、Zero Trustで接続するネットワーク内のcloudflaredクライアントがCloudflareのエッジと通信する必要があります。

cloudflaredはまずQUICで通信を試み、失敗した場合はHTTP/2にフォールバックして通信します。このとき、QUICで通信できていれば全てのプロトコルを通せますが、HTTP/2で通信しているとTCPしか通せず、UDPとICMPは通せません。

私はOpenWrtのcloudflaredパッケージを使おうとしていたのですが、現状OpenWrt環境だと必要な暗号スイートのサポートがなくQUICで通信できないため、起動オプションでHTTP/2が指定されています。

他の環境でも、ファイアウォールでアウトバウンドに通信制限をしているとQUICで通信できず、HTTP/2にフォールバックすることがあるようです。

- 参考URL
  - [Cloudflare Tunnel 経由で自前のDNSリゾルバーを利用する
](https://zenn.dev/hiroe_orz17/articles/0d71bf6789635d)
  - [cloudflared: Needs to be built via Go with Cloudflare experimental patches #23596
](https://github.com/openwrt/packages/issues/23596)
  - [cloudflared: Makefile does not use correct toolchain (no support for post quantum curves) #23852
](https://github.com/openwrt/packages/issues/23852)

## ハマりどころ2：Cloudflareの設定でICMPのProxyを有効にしないといけない

Cloudflare Zero Trustでpingを通したい場合、Zero Trustのダッシュボードにアクセスし、ICMPプロトコルのプロキシ設定を有効にする必要があります。手順は以下の通りです。

1. [Cloudflare Zero Trustのダッシュボード](https://one.dash.cloudflare.com/)にログインします
2. 「Settings」「Network」「Firewall」「Proxy」から「ICMP」を有効にします

この設定を行うことで、pingなどのICMPトラフィックがPrivate Networkにプロキシされます。

## ハマりどころ3：Linuxの設定によってはroot権限でもICMP Echoパケットが作れない

cloudflaredを動かしているOSの設定次第で、cloudflaredがICMP Echoパケットを作れないことがあります。

私はcloudflaredを古いRaspberry Pi OS上で利用していたのですが、起動時に下記のようなログが出力されていました。
```
Oct 13 18:39:24 raspberrypi2 cloudflared[21808]: 2024-10-13T09:39:24Z WRN The user running cloudflared process has a GID (group ID) that is not within ping_group_range. You might need to add that user to a group within that range, or instead update the range to encompass a group the user is already in by modifying /proc/sys/net/ipv4/ping_group_range. Otherwise cloudflared will not be able to ping this network error="Group ID 0 is not between ping group 1 to 0"
Oct 13 18:39:24 raspberrypi2 cloudflared[21808]: 2024-10-13T09:39:24Z WRN ICMP proxy feature is disabled error="cannot create ICMPv4 proxy: Group ID 0 is not between ping group 1 to 0 nor ICMPv6 proxy: socket: permission denied"
```

Linuxの場合、ICMP Echoパケットを作ることが可能なグループIDはカーネルパラメータで制御されています。この設定がデフォルトで全ユーザー不可能になっている環境があります。現在の設定は以下のように確認できます。

```
$ sysctl net.ipv4.ping_group_range
net.ipv4.ping_group_range = 1	0
```

このように`1 0`となっている場合、root権限でもICMP Echoパケットを作ることができません。私は次のようにrootグループのみ許可するようにしました。

```
$ sudo sysctl -w net.ipv4.ping_group_range="0 0"
net.ipv4.ping_group_range = 0 0
```

# まとめ

以上3つの問題を解決することでcloudflaredがICMPパケットをproxyできるようになり、Cloudflare Zero Trustで接続しているPrivate Networkにpingが通るようになりました。

Cloudflare Zero Trustでpingを通すのに苦労している人は私以外にもいるようです。もし諦めている人がいたら参考にしてみてください。