🧺

Cloudflare WARP Client のネットワーク関連設定まとめ

2024/07/28に公開

Cloudflare WARP Client のネットワーク関連の設定をマトメます。
今回の対象はダッシュボードの Settings > WARP Client から設定する部分になります。

Device settings > Profile settings

Device Profiles でWARP 端末の設定を特定の条件でグループ化することができます。
そのグループごとに設定できるネットワーク関連の項目を記載します。

Split Tunnels

Split Tunnels では WARP 端末がどの IP Domain(host) を WARP トンネルに転送するかを指定します。

* IP 指定の場合は宛先 IP を元にインターフェースを選択
* Domain 指定の場合は宛先 Domain(host)を元にインターフェースを選択
  ** 実際には当該 Domain の DNS 検索後の IP を動的に Split Tunnels に登録

Split Tunnels の mode

modeExclude Include どちらかに指定します。デフォルトは Exclude

mode default 設定する IP Domain
Exclude すべて WARP インターフェースへ ローカルインターフェースへ送信する宛先を指定
Include すべてローカルインターフェースへ WARP インターフェースへ送信する宛先を指定

Allow users to enable local network exclusion

Allow users to enable local network exclusion は WARP 端末が WARP インターフェース経由で接続できるプライベートネットワークに対して、WARP インターフェースではなく、ローカルインターフェースから直接接続するオプションを一時的に提供します。

下記のようなケースで候補になります。

* リモートから事務所のプライベートネットワークに接続していた WARP 端末が事務所に帰還し、同一サブネット内での通信を試みる
* WARP 端末を自宅で利用し、事務所のプライベートネットワークに接続できるが、事務所の IP と家の IP が重複しており、家のプリンターに繋がらない

前提

リモートの WARP 端末(CGNAT IP 100.96/12)が RFC 1918 プライベートネットワーク(例 172.16.x/24)に通信できている環境を前提にします。

* WARP 端末 100.96/12 はプライベートネットワーク 172.16.x/24 に接続可能
* Split Tunnel 設定は Exclude IPs and domains を指定

ユースケース

WARP 端末がプライベートネットワーク配下に移動し、その中の宛先と通信する場合を考えます。

* WARP 端末がプライベートネットワーク 172.16.x/24 に移動
* ローカルインタフェース 172.16.x/24 のプリンターに印刷

ルーティング(デフォルト)

リモートにいる場合と同じ通信経路になります。

* 100.96/12 から Cloudflare を通じてセキュリティ機能を経て 172.16.x/24 にルーティング
* リモートからの接続と同じ通信経路 (100.96/12 --> 172.16.x/24)

ルーティング(Allow users to enable local network exclusion を On)

WARP 端末のローカルインターフェースに関して、一時的な直接接続を可能とします。

* 一時的な同一サブネット内通信(172.16.1/24 <--> 172.16.1/24)
* 管理者は有効時間 Timeout を指定(セキュリティ面を考慮)
* Timeout 0 に設定すると常に有効

ユーザーが各自で直接接続を有効にします。
Access local network を☑。

注意書きが出たら OK

Access local network 有無での TTL の違い

Magic WAN 配下の 172.16.1/24

ubuntu@oym2:~$ ip addr |grep 172.16
    inet 172.16.1.243/24 metric 100 brd 172.16.1.255 scope global ens3

デフォルト Access local network オフ
1.243 ←→ 1.254 PING
RTT 6 msec。

ubuntu@oym2:~$ ping -c 5 172.16.1.254
PING 172.16.1.254 (172.16.1.254) 56(84) bytes of data.
64 bytes from 172.16.1.254: icmp_seq=1 ttl=63 time=6.01 ms
64 bytes from 172.16.1.254: icmp_seq=2 ttl=63 time=6.45 ms
64 bytes from 172.16.1.254: icmp_seq=3 ttl=63 time=5.96 ms
64 bytes from 172.16.1.254: icmp_seq=4 ttl=63 time=7.61 ms
64 bytes from 172.16.1.254: icmp_seq=5 ttl=63 time=6.43 ms

--- 172.16.1.254 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 5.962/6.492/7.605/0.592 ms

Access local network オン

ubuntu@oym2:~$ warp-cli override local-network --help
Override settings to access the local area network

Usage: warp-cli override local-network <COMMAND>

Commands:
  allow  Allow access to the local network, if permitted by settings
  show   Return information about any currently applied local network access
  stop   Stop any current local network access
  help   Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help

ubuntu@oym2:~$ warp-cli override local-network show
No current access to local network

ubuntu@oym2:~$ warp-cli override local-network allow
Success

ubuntu@oym2:~$ warp-cli override local-network show
Local Network access ends after the next reconnection

直接接続で RTT が 6 msec 短くなる。

ubuntu@oym2:~$ ping -c 5 172.16.1.254
PING 172.16.1.254 (172.16.1.254) 56(84) bytes of data.
64 bytes from 172.16.1.254: icmp_seq=1 ttl=64 time=0.245 ms
64 bytes from 172.16.1.254: icmp_seq=2 ttl=64 time=0.381 ms
64 bytes from 172.16.1.254: icmp_seq=3 ttl=64 time=0.395 ms
64 bytes from 172.16.1.254: icmp_seq=4 ttl=64 time=0.414 ms
64 bytes from 172.16.1.254: icmp_seq=5 ttl=64 time=0.522 ms

--- 172.16.1.254 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4086ms
rtt min/avg/max/mdev = 0.245/0.391/0.522/0.088 ms
ubuntu@oym2:~$

Global settings

グローバルで共通の設定になります。

Override local interface IP

Override local inteface IP では WARP インターフェースに対する IP(IPv4)アドレスの付与のされ方が変わります。IPv6 は変わりません。

WARP インターフェース IPv4 アドレス(デフォルト)

プライベートネットワークの端末から見ると、WARP 端末の IPv4 は 100.96/12 のレンジになります。ただ、WARP 端末で自身の WARP インターフェース IP を見ると 172.16.0.2 です。

* WARP インターフェースに付与される IPv4 アドレスは `172.16.0.2/32` で共通
* Cloudflare Gateway を通過する際に `100.96/12` のレンジでアドレス変換
ipconfig
PS C:\Users\AdeleVance> ipconfig | Select-String "(アダプタ|IPv4|マスク|IPv6)"

不明なアダプター CloudflareWARP:
   IPv6 アドレス . . . . . . . . . . . .: 2606:4700:110:..
   リンクローカル IPv6 アドレス. . . . .: fe80::83b:d647:4bed:d388%14
   IPv4 アドレス . . . . . . . . . . . .: 172.16.0.2
   サブネット マスク . . . . . . . . . .: 255.255.255.255
イーサネット アダプター イーサネット:
   リンクローカル IPv6 アドレス. . . . .: fe80::ece3:a379:fbd5:7fa8%3
   IPv4 アドレス . . . . . . . . . . . .: 172.16.143.130
   サブネット マスク . . . . . . . . . .: 255.255.255.0

WARP インターフェース IPv4 アドレス(Override local interface IP を On)

WARP インターフェースに直接 100.96/12 のレンジから IP 付与されます。

ipconfig
PS C:\Users\AdeleVance> ipconfig | Select-String "(アダプタ|IPv4|マスク|IPv6)"

不明なアダプター CloudflareWARP:
   IPv6 アドレス . . . . . . . . . . . .: 2606:4700:110:..
   リンクローカル IPv6 アドレス. . . . .: fe80::83b:d647:4bed:d388%14
   IPv4 アドレス . . . . . . . . . . . .: 100.96.0.88
   サブネット マスク . . . . . . . . . .: 255.255.255.255
イーサネット アダプター イーサネット:
   リンクローカル IPv6 アドレス. . . . .: fe80::ece3:a379:fbd5:7fa8%3
   IPv4 アドレス . . . . . . . . . . . .: 172.16.143.130
   サブネット マスク . . . . . . . . . .: 255.255.255.0

ユースケース

Dev docs にあるように WARP Connector や MASQUE を使うときや、172.16.0.2 がローカルと重複する場合に使えます。

その他のユースケースとして、Magic WAN や WARP Connector でサーバー発の通信を考えます。

アプリケーションによってはデータ部分でクライアントの IP を通知し、その IP に対してサーバー側から接続をかけるものがあります。そのような場合は Override local interface IP を有効にすると、アプリが使えるようになります。
たとえば FTP の PORT コマンドがつながるようになります。

Override local interface IP を On
ftp PORT command 成功
PS C:\Users\AdeleVance> ftp 172.16.1.243
172.16.1.243 に接続しました。
220 (vsFTPd 3.0.5)
200 Always in UTF8 mode.
ユーザー (172.16.1.243:(none)): ubuntu
331 Please specify the password.
パスワード:
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
cloudflared-stable-linux-amd64.deb
226 Directory send OK.
ftp: 39 バイトが受信されました 0.00秒 39.00KB/秒。
ftp>

FTP サーバー、WARP 端末どちらで見ても、FTP サーバー 172.16.1.243:20 から WARP インターフェース  100.96.0.88:52565 に対する通信が同じ内容で見られます。

Pcap WARP 端末
PS C:\Program Files\Wireshark> .\tshark.exe -i5 port 20
Capturing on 'CloudflareWARP'

    1   0.000000 172.16.1.243 → 100.96.0.88  TCP 60 20 → 52565 [SYN] Seq=0 Win=62720 Len=0 MSS=1396 SACK_PERM TSval=2396960097 TSecr=0 WS=128
    2   0.000258  100.96.0.88 → 172.16.1.243 TCP 60 52565 → 20 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1240 WS=256 SACK_PERM TSval=10645459 TSecr=2396960097
    3   0.025711 172.16.1.243 → 100.96.0.88  TCP 52 20 → 52565 [ACK] Seq=1 Ack=1 Win=62720 Len=0 TSval=2396960121 TSecr=10645459
    4   0.025888 172.16.1.243 → 100.96.0.88  FTP-DATA 88 FTP Data: 36 bytes
    5   0.025907 172.16.1.243 → 100.96.0.88  TCP 52 20 → 52565 [FIN, ACK] Seq=37 Ack=1 Win=62720 Len=0 TSval=2396960121 TSecr=10645459
    6   0.025923  100.96.0.88 → 172.16.1.243 TCP 52 52565 → 20 [ACK] Seq=1 Ack=38 Win=12583168 Len=0 TSval=10645485 TSecr=2396960121
    7   0.030003  100.96.0.88 → 172.16.1.243 TCP 52 52565 → 20 [FIN, ACK] Seq=1 Ack=38 Win=12583168 Len=0 TSval=10645485 TSecr=2396960121
    8   0.061881 172.16.1.243 → 100.96.0.88  TCP 52 20 → 52565 [ACK] Seq=38 Ack=2 Win=62720 Len=0 TSval=2396960158 TSecr=10645485
8 packets captured
Pcap FTP サーバー
ubuntu@oym2:~$ sudo tshark -i2 port 20

    1 0.000000000 172.16.1.243 → 100.96.0.88  TCP 76 20 → 52565 [SYN] Seq=0 Win=62720 Len=0 MSS=8960 SACK_PERM=1 TSval=2396960097 TSecr=0 WS=128
    2 0.023603203  100.96.0.88 → 172.16.1.243 TCP 76 52565 → 20 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1240 WS=256 SACK_PERM=1 TSval=10645459 TSecr=2396960097
    3 0.023674869 172.16.1.243 → 100.96.0.88  TCP 68 20 → 52565 [ACK] Seq=1 Ack=1 Win=62720 Len=0 TSval=2396960121 TSecr=10645459
    4 0.024029278 172.16.1.243 → 100.96.0.88  FTP-DATA 104 FTP Data: 36 bytes
    5 0.024063322 172.16.1.243 → 100.96.0.88  TCP 68 20 → 52565 [FIN, ACK] Seq=37 Ack=1 Win=62720 Len=0 TSval=2396960121 TSecr=10645459
    6 0.048195264  100.96.0.88 → 172.16.1.243 TCP 68 52565 → 20 [ACK] Seq=1 Ack=38 Win=12583168 Len=0 TSval=10645485 TSecr=2396960121
    7 0.060297507  100.96.0.88 → 172.16.1.243 TCP 68 52565 → 20 [FIN, ACK] Seq=1 Ack=38 Win=12583168 Len=0 TSval=10645485 TSecr=2396960121
    8 0.060325350 172.16.1.243 → 100.96.0.88  TCP 68 20 → 52565 [ACK] Seq=38 Ack=2 Win=62720 Len=0 TSval=2396960158 TSecr=10645485
Override local interface IP を Off

PORT コマンドは通信できません。

WARP 端末 172.16.0.2 の Pcap を見ると PORT コマンドが 500 で切られています。

   15   9.527414   172.16.0.2 → 172.16.1.243 FTP 65 Request: PORT 172,16,0,2,205,245
   16   9.555079 172.16.1.243 → 172.16.0.2   FTP 67 Response: 500 Illegal PORT command.

FTP サーバー( vsftpd )を見ると、PORT コマンドの IP 172.16.0.2 と送信元 IP アドレス 100.96.0.88 が異なっています。このような状況で接続を切るのは bounce attack 対策でしょうか。

   15 9.529159576  100.96.0.88 → 172.16.1.243 FTP 81 Request: PORT 172,16,0,2,205,245
   16 9.529422793 172.16.1.243 → 100.96.0.88  FTP 83 Response: 500 Illegal PORT command.

とは言え、仮にこれが受け入れられたとして 172.16.0.2 に接続しようとしても、WARP 端末には届きません。

余談 vsftpd

port_promiscuous を YES に変えたらイケるかと思いましたが、違うエラーが出たので追うのをやめました。
他の FTP サーバーなら 172.16.0.2 にデータコネクションを仕掛ける挙動を見れるかもしれません。

   18 11.379906355  100.96.0.88 → 172.16.1.243 FTP 81 Request: PORT 172,16,0,2,206,181
   19 11.380152099 172.16.1.243 → 100.96.0.88  FTP 107 Response: 200 PORT command successful. Consider using PASV.
   20 11.412476958  100.96.0.88 → 172.16.1.243 FTP 62 Request: NLST
   21 11.413094404 172.16.1.243 → 100.96.0.88  FTP 66 Response: 500 OOPS:
   22 11.413131253 172.16.1.243 → 100.96.0.88  FTP 72 Response: vsf_sysutil_bind

なお FTP サーバーが 172.16.0.2 の代わりに 100.96.0.88 に接続すれば、 Cloudflare Gateway で宛先 NAT されて WARP 端末 172.16.0.2 に届きます。

ping でサーバー発の NAT を確認

サーバーからの PING

ubuntu@oym2:~$ ping 100.96.0.88
PING 100.96.0.88 (100.96.0.88) 56(84) bytes of data.
:
64 bytes from 100.96.0.88: icmp_seq=9 ttl=126 time=43.0 ms
64 bytes from 100.96.0.88: icmp_seq=10 ttl=126 time=28.0 ms

WARP 端末での Pcap

PS C:\Program Files\Wireshark> .\tshark.exe -i5 icmp
Capturing on 'CloudflareWARP'
    1   0.000000 172.16.1.243 → 172.16.0.2   ICMP 84 Echo (ping) request  id=0x525d, seq=9/2304, ttl=62
    2   0.000174   172.16.0.2 → 172.16.1.243 ICMP 84 Echo (ping) reply    id=0x525d, seq=9/2304, ttl=128 (request in 1)
    3   1.000189 172.16.1.243 → 172.16.0.2   ICMP 84 Echo (ping) request  id=0x525d, seq=10/2560, ttl=62
    4   1.000526   172.16.0.2 → 172.16.1.243 ICMP 84 Echo (ping) reply    id=0x525d, seq=10/2560, ttl=128 (request in 3)

Network locations

グローバルで共通の設定になります。

Managed networks

Managed networks を使うと Device profile を場所に応じて切り替えることができます。場所の特定には TLS サーバーとその証明書を利用します。

* 何をもって場所を判断するか?

WARP 端末が自身のいる場所から特定の証明書を提示する TLS エンドポイントにアクセスできるか。

ネットワーク接続時に、TLS エンドポイントを探し、接続できれば、その TLS エンドポイントが紐付けられた Device profile で動作します。

Managed networks の登録には TLS エンドポイントの接続先とその証明書のハッシュを指定します。この TLS エンドポイントのリストが WARP 端末に同期され、WARP 端末はネットワーク接続時にどれかつながるか探索をします。

* Managed networks に設定された `IP` `Host名` (IP 推奨)は自動的に WARP トンネルから除外されます。(Split Tunnel には表示されず暗黙的に)
* TLS エンドポイントは WARP 端末がリモートから接続する必要のないものを設定します。
* あるロケーションから疎通できる TLS エンドポイントは一つだけになるようにします。

WARP トンネルから除外された TLS エンドポイントの IP アドレスにそのロケーションから疎通ができれば、その WARP 端末は当該のプロファイルで動作します。(例えば下記の Configure settings にある Captive portal detection がその拠点では Off になる、など)

Managed networks の配下にいるかは下記の要領で確認することができます。

PS C:\Users\AdeleVance> warp-cli debug  alternate-network
拠点 A にいるかのチェック
PS C:\Users\AdeleVance>

Virtual networks

Virtual networks を使うと、異なる cloudflared トンネルの先の同じ IP アドレスに対し、WARP 端末がどちらを使うか選択して通信することができます。

Dev docs の例ではプロダクションとステージングなど、IP アドレスの重複が発生しそうなケースをいくつかあげています。

Virtual networks を作成し、

cloudflared の Private network( Networks >Tunnels > トンネル名 > Private Network )を Virtual networks と紐つけます。


設定されると WARP 端末では Virtual networks(仮想ネットワーク)を選択する画面が出てくるので、切り替えて利用します。

warp-cli vnet コマンドでの切り替え例

aws-1 が選ばれている(Currently selected を見る)

PS C:\Users\AdeleVance> warp-cli vnet
Virtual Networks:
Currently selected: e422e876-a778-470a-8391-431c965a71ab
ID: e422e876-a778-470a-8391-431c965a71ab
Name: aws-1
Comment: aws tokyo
Default: false

ID: 43a057d2-05e0-459b-8ca2-a21da1ddbc71
Name: default
Comment: This network was autogenerated because this account lacked a default one
Default: true

ID: 096faa6e-bb89-4f5a-946c-4ac01d558cd1
Name: oci-1
Comment: oracle tokyo
Default: false

curl

PS C:\Users\AdeleVance> curl 172.31.0.1 | Select-String "DOCTYPE"
:
<title>AWS!</title>
:

oci-1 に変える

PS C:\Users\AdeleVance> warp-cli vnet 096faa6e-bb89-4f5a-946c-4ac01d558cd1
Success

curl

PS C:\Users\AdeleVance> curl 172.31.0.1 | Select-String "DOCTYPE"
:
<title>OCI!</title>
:

以上です。
2024年7月時点のメモになります。
Beta のものもあるので、その時点の最新の公式ドキュメントを参照しましょう。

Discussion