Armbian に sing-box TUN をデプロイした後、少し分かりにくい問題が発生しました:IPv6 の ping は通るのに、auto_redirect を有効化すると IPv6 の HTTPS 接続がタイムアウトする的情况です。
调查结果、障害の原因は IPv6 の公網ルートやプロキシノードではなく、Linux のループバックインターフェース lo に ::1/128 アドレスが存在しないことでした。本稿では、その切り分け Processes .Ordinal and 修正方法を記録します。
環境
- Linux:Armbian、ARM64、6.18 系カーネル
- sing-box:1.14.x
- ネットワーク管理:Netplan + NetworkManager
- 透過プロキシ:TUN、
auto_route: true、auto_redirect: true - IPv6:上位ネットワークから自動設定され、インターフェースにはグローバル IPv6 アドレスと RA によるデフォルトルートが設定済み
プライバシーを保護するため、実際の公衆アドレス、MAC アドレス、ルーターアドレス、ドメイン名、およびカスタム内部ルーティングテーブル番号は省略しています。以下の例にある ULA アドレスとテスト対象は説明용です。
障害的现象
IPv6 HTTPS を直接テストします。
curl --noproxy '*' -6 -v --connect-timeout 5 \
--resolve 'cloudflare.com:443:[2606:4700::6810:85e5]' \
https://cloudflare.com/
sing-box を有効化した後:
* Trying [2606:4700::6810:85e5]:443...
* Connection timed out after 5002 milliseconds
curl: (28) Connection timed out
比較テスト:
| 状態 | IPv6 HTTPS |
|---|---|
| sing-box 停止中 | 正常 |
auto_redirect: true | タイムアウト |
auto_redirect: false | 正常 |
ただし、単純な ping -6 テストは成功する場合があります。ICMP の疎通確認だけでは、TCP/HTTPS のテストを代替できません。
切り分け Processes.Ordinal
1. IPv6 アドレスとデフォルトルートの問題を排除
ip -6 addr show dev eth0 scope global
ip -6 route show default
インターフェースにはすでにグローバル IPv6 アドレスがあり、デフォルトルートは RA によって学習されています。形式は次のとおりです。
default via fe80::... dev eth0 proto ra
NetworkManager が IPv6 を管理している場合、net.ipv6.conf.eth0.accept_ra の値だけで RA が正常に機能しているかを判断してはいけません。実際のアドレスとルートを併せて確認する必要があります。
2. TCP が tun0 または eth0 に直接現れないことを 발견
HTTPS 対象をパケットキャプチャで確認します。
sudo tcpdump -ni tun0 'ip6 and tcp port 443'
sudo tcpdump -ni eth0 'ip6 and tcp port 443'
auto_redirect を有効化している場合、想定される宛先への IPv6 TCP SYN が確認できませんでした。これは必ずパケット損失を意味しません。sing-box の nftables ルールが、TCP をまずローカルポートへリダイレクトしている可能性があります。
3. nftables のローカル REDIRECT を確認
sudo nft -a list table inet sing-box
ルールには次のような内容が存在しました。
meta l4proto tcp ... queue flags bypass to 100
meta l4proto tcp ... redirect to :23457 return
ここでのポートは、今回の切り分け環境における内部リスニングポートです。別のバージョンや設定では異なる場合があります。IPv6 のリスニング状態を確認します。
sudo ss -6 -lntp '( sport = :23457 )'
確かに sing-box はそのポートをリスニングしていました。
続いてループバックインターフェースもキャプチャします。
sudo tcpdump -ni lo -vv 'tcp port 23457'
このとき、重要なパケットは次の形式でした。
IP6 2001:db8::1234.4210 > ::1.23457: Flags [S]
IP6 2001:db8::1234.4210 > ::1.23457: Flags [S]
IP6 2001:db8::1234.4210 > ::1.23457: Flags [S]
上記の
2001:db8::/32は文書専用の IPv6 プレフィックスであり、実際の公衆アドレスではありません。
SYN が繰り返し再送され、SYN-ACK が返っていません。これは、接続がローカル ::1 へリダイレクトされているものの、ローカル TCP ハンドシェイクが完了していないことを示しています。
4. 根本原因を特定:ループバックインターフェースに IPv6 アドレスがない
ip -6 addr show dev lo
出力は驚くほど空でした。正常な場合、ループバックインターフェースには次が存在するはずです。
inet6 ::1/128 scope host
::1/128 が存在しないため、IPv6 TCP REDIRECT でローカル ::1 を指定しても、接続を正常に確立できませんでした。これは、繰り返し送信された SYN と SYN-ACK がない現象と一致しています。
修正方法
まず lo の IPv6 状態を確認します。
ip link show lo
sysctl net.ipv6.conf.lo.disable_ipv6
ip -6 addr show dev lo
IPv6 が無効になっている場合:
sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0
ループバックインターフェースが有効になっていることを確認します。
sudo ip link set lo up
::1/128 がまだ表示されない場合は、手動で追加します。
sudo ip -6 addr add ::1/128 dev lo
検証します。
ip -6 addr show dev lo
ping -6 -c 2 ::1
curl --noproxy '*' -6 --connect-timeout 5 https://api6.ipify.org
auto_redirect: true の状態でも HTTPS が正常であることを確認して、ようやく障害が解決したといえることになります。
問題が再起動後に発生する場合は、/etc/sysctl.d/ に lo の IPv6 を無効化する設定が存在しないか確認し、sysctl 設定ファイルで明示的に次のように設定できます。
net.ipv6.conf.lo.disable_ipv6 = 0
注意点として、この設定は lo の IPv6 が無効化されていないことを保証するだけにすぎ、::1/128 が常に存在することを自動的に保証するわけではありません。再起動後にアドレスが再び消えた場合は、起動順序や lo を管理するサービスの調査を継続する必要があります。
まとめ
- IPv6 の
pingが成功しても、IPv6 TCP プロキシが正常であるとは限らないため、実際の HTTPS リクエストで検証する必要があります。 - sing-box の
auto_redirectを有効化すると、一部の TCP トラフィックが nftables によってローカルポートへリダイレクトされます。eth0またはtun0だけをキャプチャしても、想定した宛先へのトラフィックを確認できない場合があります。 ssでリスニング状態を確認し、tcpdump -i loで SYN の再送信 발견することが、今回の切り分けにおける鍵となりました。- 最終的な障害点は、
loに IPv6 ループバックアドレス::1/128が欠落していたことでした。 auto_redirectを一時的に無効化すれば問題を回避できますが、今回の障害に対する本来の実質的な修正は、ループバックインターフェースを修正することです。
診断コマンド早見表
ip -6 addr show dev lo
sysctl net.ipv6.conf.lo.disable_ipv6
ip -6 route show default
sudo nft -a list table inet sing-box
sudo ss -6 -lntp '( sport = :23457 )'
sudo tcpdump -ni lo 'tcp port 23457'
補足:UFW を有効化した後、下流デバイスからインターネットに接続できない問題
IPv6 のループバック問題륧解決した後、Armbian で UFW を有効化したところ、新たな現象が発生しました:Armbian 本体はネットワークへ正常にアクセスできるのに、Armbian を経由している下流デバイスからはネットワークへ正常にアクセスできないという問題です。
まず、UFW のブロックログを確認します。
sudo ufw logging medium
sudo journalctl -k -f -o cat | grep --line-buffered 'UFW BLOCK'
以下は匿名化済みの代表的なログです。IP アドレスには RFC 5737 の文書用サンプルアドレスを使用しているため、実際のネットワーク設定へそのまま転用することはできません。
[UFW BLOCK] IN=eth0 OUT= SRC=192.0.2.20 DST=192.0.2.254 PROTO=TCP DPT=9091 SYN
[UFW BLOCK] IN=eth0 OUT= SRC=192.0.2.20 DST=192.0.2.254 PROTO=TCP DPT=22703 SYN
ここで OUT= が空で、宛先がローカルアドレスになっているため、これらのリクエストは通常の FORWARD ではなく、**INPUT(Armbian 本体へのアクセス)**として识别されています。之前に deny routed を直接疑っただけでは、説明が完全ではありませんでした。
続いて、次のコマンドでリスニングプロセスを確認します。
sudo ss -lntup | grep -E ':(9091|22703)\b'
結果では、2 つの TCP ポートのいずれも sing-box がリスニングしており、一方は LAN の IPv4 アドレス、もう一方はワイルドカードアドレスにバインドされていました。該当する inbound ポートを許可すると、下流デバイスからインターネットへ接続 Again became possible. ただし強調すべき点があります。これはポートの到達可能性と障害が関係することを証明しますが、リスニング結果だけから、これらが TUN ポートや特定機能のものであるとは推定できません。sing-box の設定を確認して、具体的な用途を特定する必要があります。
サービスが LAN 内でのみ使用される場合、UFW のルール在实际の LAN アドレスとサブネットに限定するようにできます。以下は RFC 5737 のサンプルサブネットを使用するルールテンプレートであり、実際の値に置き換える必要があります。
sudo ufw allow in on eth0 from 192.0.2.0/24 to 192.0.2.254 port 9091 proto tcp
sudo ufw allow in on eth0 from 192.0.2.0/24 to 192.0.2.254 port 22703 proto tcp
セキュリティ上の注意:送信元を制限していない ufw allow 22703/tcp の直接実行は推奨しません。ポートがワイルドカードアドレスでリスニングされている場合には、公衆 IPv6 へ意図せず公開されていないか特に確認してください。また、下流デバイスからインターネットへ接続できない状態を解消するため、すべての routed トラフィックを恒久的にデフォルト許可にするのも 바람직하지 않습니다。
今回の補足における切り分けの要点は、まず IN / OUT で INPUT と FORWARD を区別し、次にリスニングプロセスを確認し、最後に実際の送信元に基づいて精密に許可することです。UFW のステータスページは nft list ruleset の代替にはなりません。sing-box の auto_redirect には 별도의 nftables ルールが存在するためです。