先日(2024/05/02)フレッツ光クロス(コラボ、enひかりクロス v6プラス 固定IP)でIPv6プレフィックスが突然変更され新しいプレフィックスに変更されたのですが、スクリプトの見直しで対応し、何とかインターネットに接続できる環境にはできていました。
しかし、2024/05/19現在まで、さらに新しいアドレスが割り当てられるわけでもないのに、プロバイダー側からはプレフィックス変更メッセージ(DHCPv6 Reconfigure Message)が繰り返し送信され続けています。
そこでDHCPv6 Reconfigure Messageがきても、さらに新しいプレフィックスが提示されていない場合は無視するようにしました。そうでないと、通信が一時的に途絶えてしまうためです。具体的には下記の様にしましたが、今回はdhclientから、dhcpcdに変更して対応してみました。というのもdhclientはReconfigure Messageを受け取ってもログを吐くだけですがdhcpcdはrenewメッセージを返すからです。(tcpdumpで確認しました。しかし、reconfigure-message for renewに対しrenewを返しているにもかかわらず相変わらず対向ルータからはReconfigure Messageが飛んできます。何か他のやり取りや設定が必要なようなので継続調査が必要そうです。)
The server can discontinue retransmission of Reconfigure messages to the client once the server receives the Renew or Information-request message from the client.
ややこしいのですが”中止しなければならないという事ではない”ようです。つまり、サーバ側が中止せずに冗長的に再構成メッセージを送っているのだろうと筆者は考えています。こちらも、RFC3315 19.4.1. に以下のような記載がありました。
"It might be possible for a duplicate or retransmitted Reconfigure to be sufficiently delayed (and delivered out of order) to arrive at the client after the exchange (initiated by the original Reconfigure) has been completed. In this case, the client would initiate a redundant exchange. The likelihood of delayed and out of order delivery is small enough to be ignored. The consequence of the redundant exchange is inefficiency rather than incorrect operation."
"(元の再構成によって開始された後に開始された後)の交換が完了した後に、重複または再送信された再構成を十分に遅延させる(および順序から順に配信される)ことが可能であるかもしれません。この場合、クライアントは冗長交換を開始します。遅延および遅延配信の遅延の可能性は無視するのに十分小さい。冗長交換の結果は、誤った操作ではなく効率的です。"
https://tex2e.github.io/rfc-translater/html/rfc3315.htmlより引用
拙訳:(大元のReconfigureによって開始された)メッセージ交換の後、つまり、メッセージ交換が完了した後に、重複または再送されたReconfigureメッセージがクライアントに到着するのが十二分に遅延されること(もしくは無秩序に送信されること)は可能であるかもしれません。この場合、クライアントは冗長的にメッセージ交換を開始するでしょう。遅延または無秩序なメッセージ送信の可能性は、無視するのに十分小さいのです。冗長メッセージ交換の結果は誤った操作というよりも非効率的なものになります。
つまり、Reconfigureに応答した後も再送することは、誤った操作ではないが、非効率的だ、という事をRFC3315では言及しているようです(間違っていたらすいません)。それにしてもReconfigure Messageが再送されて二か月程再送されてきていて冗長が過ぎると思うのですが、どうなんでしょう。非効率的だと筆者もそう思いますが、他にも何かあるかもしれないので念のため引き続き継続調査としておきたいと思います。
基、まず、起動時の設定です。当初は、/etc/dhcpcd.exit-hookに記述をまとめたかったのですが、こちらからの呼び出しの場合、スクリプト内でsedが正常にしませんでした。sedはiptablesのルールの書き換えに使うので、sedが使えないと面倒なので違う方法で対応するしかありません。
(2024/06/26追記/lib/systemd/system/dhcpcd.serviceでファイルやディレクトリのRWを制御している様なので、そこを書き換えるとsedやファイル作成なども正常に動作しましたのでいずれ別稿にしてまとめたいとおもっています。)
本稿ではsyslogに吐き出されたメッセージをもとに、rsyslogでスクリプトを起動させる方法をとってみました。
なお、WAN側インターフェースはenp1s0f0で、LAN側インターフェースはenp1s0f1です。また、LANではGUAではなくULAを割り当てip6tablesにてNETMAPでGUA/ULA変換をしています。
まず、/etc/dhcpcd.confは以下のようにしました。
続いて、rsyslogの設定は以下のようにしました。
呼び出されるスクリプトは以下のようになります。まず、起動時に呼び出されるスクリプトは以下の様になります。
今回は以上です。それでは。
しかし、2024/05/19現在まで、さらに新しいアドレスが割り当てられるわけでもないのに、プロバイダー側からはプレフィックス変更メッセージ(DHCPv6 Reconfigure Message)が繰り返し送信され続けています。
そこでDHCPv6 Reconfigure Messageがきても、さらに新しいプレフィックスが提示されていない場合は無視するようにしました。そうでないと、通信が一時的に途絶えてしまうためです。具体的には下記の様にしましたが、今回はdhclientから、dhcpcdに変更して対応してみました。というのもdhclientはReconfigure Messageを受け取ってもログを吐くだけですがdhcpcdはrenewメッセージを返すからです。(tcpdumpで確認しました。しかし、reconfigure-message for renewに対しrenewを返しているにもかかわらず相変わらず対向ルータからはReconfigure Messageが飛んできます。何か他のやり取りや設定が必要なようなので継続調査が必要そうです。)
# tcpdump -nev -i enp1s0f0 port 546 or port 547 #以下適当に改行を入れています。 17:47:04.315069 ROUTER_MAC_ADDR > ENP1F0F0_MAC_ADDR, ethertype IPv6 (0x86dd), length 137: (class 0xb8, hlim 255, next-header UDP (17) payload length: 83) ROUTER_MAC_ADDR.547 > ENP1F0F0_MAC_ADDR.546: [udp sum ok] dhcp6 reconfigure (xid=0 (client-ID hwaddr type 1 0cc47abd2a24) (server-ID hwaddr type 1 001122334455) (option-request IA_PD) (authentication proto: reconfigure, alg: HMAC-MD5, RDM: mono, RD: aaaa bbbb cccc dddd type: HMAC-MD5 value: aaaabbbb ccccdddd eeeeffff 11112222) (reconfigure-message for renew)) 17:47:04.315514 ENP1F0F0_MAC_ADDR > 33:33:00:01:00:02, ethertype IPv6 (0x86dd), length 165: (flowlabel 0x678ad, hlim 1, next-header UDP (17) payload length: 111) ENP1F0F0_MAC_ADDR.546 > ff02::1:2.547: [udp sum ok] dhcp6 renew (xid=83d478 (client-ID hwaddr type 1 aabbccddeeff) (server-ID hwaddr type 1 001122334455) (IA_PD IAID:0 T1:0 T2:0 (IA_PD-prefix 2400:aaaa:bbbb:cc00::/56 pltime:12600 vltime:14400)) (option-request vendor-specific-info reconfigure-message reconfigure-accept SIP-servers-address DNS-server DNS-search-list) (elapsed-time 0) (reconfigure-accept)) 17:47:04.318905 ROUTER_MAC_ADDR > ENP1F0F0_MAC_ADDR, ethertype IPv6 (0x86dd), length 208: (class 0xb8, hlim 255, next-header UDP (17) payload length: 154) ROUTER_MAC_ADDR.547 > ENP1F0F0_MAC_ADDR.546: [udp sum ok] dhcp6 reply (xid=83d478 (client-ID hwaddr type 1 aabbccddeeff) (server-ID hwaddr type 1 001122334455) (reconfigure-accept) (DNS-server 2001:aaaa:bb01::a 2001:aaaa:bb01:1::a) (DNS-search-list flets-xxxx.jp. yyyy.jp.) (IA_PD IAID:0 T1:7200 T2:10800 (IA_PD-prefix 2400:aaaa:bbbb:cc00::/56 pltime:12600 vltime:14400)))2024/06/26 追記:Reconfigureが完了したら何か通知をするのかどうか調べるため、RFC3315(フレッツ光クロス IPv6 DHCP仕様書)の 19.4.1. Receipt of Reconfigure Messages を読んだところ、クライアントからRenweまたはInformation-requestを受け取るとサーバはReconfigureメッセージを再送することを中止することが”出来る”とあります。
The server can discontinue retransmission of Reconfigure messages to the client once the server receives the Renew or Information-request message from the client.
ややこしいのですが”中止しなければならないという事ではない”ようです。つまり、サーバ側が中止せずに冗長的に再構成メッセージを送っているのだろうと筆者は考えています。こちらも、RFC3315 19.4.1. に以下のような記載がありました。
"It might be possible for a duplicate or retransmitted Reconfigure to be sufficiently delayed (and delivered out of order) to arrive at the client after the exchange (initiated by the original Reconfigure) has been completed. In this case, the client would initiate a redundant exchange. The likelihood of delayed and out of order delivery is small enough to be ignored. The consequence of the redundant exchange is inefficiency rather than incorrect operation."
"(元の再構成によって開始された後に開始された後)の交換が完了した後に、重複または再送信された再構成を十分に遅延させる(および順序から順に配信される)ことが可能であるかもしれません。この場合、クライアントは冗長交換を開始します。遅延および遅延配信の遅延の可能性は無視するのに十分小さい。冗長交換の結果は、誤った操作ではなく効率的です。"
https://tex2e.github.io/rfc-translater/html/rfc3315.htmlより引用
拙訳:(大元のReconfigureによって開始された)メッセージ交換の後、つまり、メッセージ交換が完了した後に、重複または再送されたReconfigureメッセージがクライアントに到着するのが十二分に遅延されること(もしくは無秩序に送信されること)は可能であるかもしれません。この場合、クライアントは冗長的にメッセージ交換を開始するでしょう。遅延または無秩序なメッセージ送信の可能性は、無視するのに十分小さいのです。冗長メッセージ交換の結果は誤った操作というよりも非効率的なものになります。
つまり、Reconfigureに応答した後も再送することは、誤った操作ではないが、非効率的だ、という事をRFC3315では言及しているようです(間違っていたらすいません)。それにしてもReconfigure Messageが再送されて二か月程再送されてきていて冗長が過ぎると思うのですが、どうなんでしょう。非効率的だと筆者もそう思いますが、他にも何かあるかもしれないので念のため引き続き継続調査としておきたいと思います。
基、まず、起動時の設定です。
(2024/06/26追記/lib/systemd/system/dhcpcd.serviceでファイルやディレクトリのRWを制御している様なので、そこを書き換えるとsedやファイル作成なども正常に動作しましたのでいずれ別稿にしてまとめたいとおもっています。)
本稿ではsyslogに吐き出されたメッセージをもとに、rsyslogでスクリプトを起動させる方法をとってみました。
なお、WAN側インターフェースはenp1s0f0で、LAN側インターフェースはenp1s0f1です。また、LANではGUAではなくULAを割り当てip6tablesにてNETMAPでGUA/ULA変換をしています。
まず、/etc/dhcpcd.confは以下のようにしました。
duid ll noipv6rs ipv6only noipv4ll denyinterfaces enp1s0f1 option dhcp6_reconfigure_msg, dhcp6_reconfigure_accept, dhcp6_name_servers, dhcp6_domain_search, dhcp6_sip_servers_addresses, dhcp6_vivso nooption dhcp6_sol_max_rt, dhcp6_inf_max_rt, dhcp6_vivco interface enp1s0f0 ipv6rs ia_pd 0/::/56 enp1s0f1/0/56また、/etc/network/interfaces.d以下は以下のようにしています。
#/etc/network/interfaces.d/enp1s0f0 auto enp1s0f0 iface enp1s0f0 inet manual #/etc/network/interfaces.d/enp1s0f1 auto enp1s0f1 iface enp1s0f1 inet static address 10.1.1.23 netmask 255.255.255.0 iface enp1s0f1 inet6 static address fd98:1:1:1::23/64/etc/radvd.confは以下の通りです。
interface enp1s0f1 { AdvSendAdvert on; AdvManagedFlag on; AdvOtherConfigFlag on; MaxRtrAdvInterval 180; prefix fd98:1:1:1::/64 { }; };/etc/dhcp/dhcpd6.confの一部は以下の通りです。
subnet6 fd98:1:1:1::/64 { range6 fd98:1:1:1::100 fd98:1:1:1::ffff; option dhcp6.name-servers 2606:4700:4700::1111, 2606:4700:4700::1001; }ここまでの設定で起動すると、GUAがLAN側インターフェースenp1s0f1に割り当てられるので、ip aなどで確認してから、/etc/iptables/rules.v6 (iptables-persistentパッケージが必要) の設定(一部)をしておきます。
*nat :PREROUTING ACCEPT [770:64947] :INPUT ACCEPT [6:766] :OUTPUT ACCEPT [18:2308] :POSTROUTING ACCEPT [227:20024] -A PREROUTING -d 240b:aabb:ccdd:ee01::/64 -i enp1s0f0 -j NETMAP --to fd98:1:1:1::/64 -A POSTROUTING -s fd98:1:1:1::/64 -o enp1s0f0 -j NETMAP --to 240b:aabb:ccdd:ee01::/64 COMMIT次に、/etc/dhcpcd.exit-hookは以下のようにしました。
#!/bin/bash LANDEV=enp1s0f1 if [ "$reason" = "DELEGATED6" ]; then logger dhcpcd: new_delegated_dhcp6_prefix for $LANDEV: $new_delegated_dhcp6_prefix old_delegated_dhcp6_prefix=`ip -6 addr show dev $LANDEV | grep $new_delegated_dhcp6_prefix | awk '{print $2}'` if [ "$old_delegated_dhcp6_prefix" = "" ];then # ipv6 address has been changed or not assigned. logger dhcpcd: ipv6 address for $LANDEV has been changed or not assigned: $new_delegated_dhcp6_prefix else logger dhcpcd: ipv6 address for $LANDEV is same as old one or has been newly assinged. fi fiやっていることは非常にシンプルで、変数$new_delegated_dhcp6_prefixのアドレスがLAN側に既に割り振られているか否かでログメッセージを変えているだけです。
続いて、rsyslogの設定は以下のようにしました。
#/etc/rsyslog.d/gw23.conf if ($hostname == "gw23" and $msg contains "enp1s0f0: delegated prefix") then \ ^/usr/local/sbin/ipt-v6p-static.sh #/etc/rsyslog.d/gw23-reconfigure6.conf if ($hostname == "gw23" and $msg contains "dhcpcd: ipv6 address for enp1s0f1 has been changed or not assigned:") then \ ^/usr/local/sbin/ipt-v6p-static-reconfigure6.shgw23.confは起動時のdhcpcdのログを基に/usr/local/sbin/ipt-v6p-static.shをキックするようにしています。また、gw23-reconfigure6.confは、前述のIPv6アドレス/プレフィックスの変更があった場合(変数$new_delegated_dhcp6_prefixのアドレスがLAN側に割り当てられていない場合)に、/usr/local/sbin/ipt-v6p-static-reconfigure6.shが呼び出されるようにしています。
呼び出されるスクリプトは以下のようになります。まず、起動時に呼び出されるスクリプトは以下の様になります。
#/usr/local/sbin/ipt-v6p-static.sh ---------------------------------- #!/bin/bash UPDT_URL=http://xxx.enabler.ne.jp/update USER=UserName PASS=PassWord IFID=0011:2233:4400:0000 IP4=10.11.22.33 BR=2001:1111:2222:3333::44 WANDEV=enp1s0f0 LANDEV=enp1s0f1 TUNDEV='tun0' sleep 10 PFX=`grep "$WANDEV: delegated prefix" /var/log/syslog | tail -n 1 | awk -F"prefix" '{print $2}' | tr -d ' '` PREFIX=`echo $PFX | awk 'BEGIN{FS="::"}{print $1}'` GW_PLEN=`echo $PFX | awk 'BEGIN{FS="/"}{print $2}'` GW=23 CE=$PREFIX:$IFID CE_PLEN=$GW_PLEN if [ "$PFX" = "" ];then logger dhcpcd: $0: PFX is null. exit 1 else logger dhcpcd: $0: PFX=$PFX fi ip -6 addr add $PREFIX::$GW/$GW_PLEN dev $LANDEV ip -6 addr add $CE/$CE_PLEN dev $LANDEV ip -6 tunnel add $TUNDEV mode ip4ip6 remote $BR local $CE dev $LANDEV encaplimit none ip link set dev $TUNDEV mtu 1460 ip link set dev $TUNDEV up ip -4 addr add $IP4/32 dev $TUNDEV ip route delete default ip route add default dev $TUNDEV curl "$UPDT_URL?user=$USER&pass=$PASS" iptables -t nat -F iptables -t mangle -F iptables -t mangle -o $TUNDEV -I FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu # MASQUERADEを使う場合 iptables -t nat -A POSTROUTING -o $TUNDEV -j MASQUERADE # FULLCONENATを使う場合 #iptables -t nat -A PREROUTING -i $TUNDEV -j FULLCONENAT #iptables -t nat -A POSTROUTING -o $TUNDEV -j FULLCONENAT updt_rules_v6() { PREFIX_CHANGED="no" RULES_V6="/etc/iptables/rules.v6" IF1PREFIX_ULA=fd98:1:1:1 IF1PREFIX_NEW=`echo $PREFIX | awk -F":" '{ val1="0x"$1; printf "%x", val1; printf ":"; val2="0x"$2; printf "%x", val2; printf ":"; val3="0x"$3; printf "%x", val3; printf ":"; val4="0x"$4; val4=val4+"0x1"; printf "%x", val4; }'` IF1PREFIX_OLD=`grep $IF1PREFIX_ULA /etc/iptables/rules.v6 | grep PREROUTING | awk -F"-d" '{print $2}' | awk '{print $1}' | awk 'BEGIN{FS="::"}{print $1}'` if [ "$IF1PREFIX_OLD" != "$IF1PREFIX_NEW" ]; then if [ -f "$RULES_V6" ]; then sed -i "s/$IF1PREFIX_OLD/$IF1PREFIX_NEW/g" "$RULES_V6" PREFIX_CHANGED="yes" fi fi if [ "$PREFIX_CHANGED" = "yes" ]; then ip6tables-restore < "$RULES_V6" fi } updt_rules_v6続いて、実際に新しいプレフィックスが配布された場合(dhcpcdがDELGATED6をexit-hookで出力し、IPv6アドレス/プレフィックスの変更があった場合)に呼び出されるスクリプトはこちらです。
#/usr/local/sbin/ipt-v6p-static-reconfigure6.sh ---------------------------------- #!/bin/bash #ipt-v6p-static-reconfigure6.sh logger dhcpcd: running $0 UPDT_URL=http://xxx.enabler.ne.jp/update USER=UserName PASS=PassWord IFID=0011:2233:4400:0000 IP4=10.11.22.33 BR=2001:1111:2222:3333::44 WANDEV=enp1s0f0 LANDEV=enp1s0f1 TUNDEV='tun0' LANDEV_ULA=fd98:1:1:1::23/64 PFX=`grep "dhcpcd: ipv6 address for $LANDEV has been changed or not assigned:" /var/log/syslog | tail -n 1 | awk '{print $NF}'` PREFIX=`echo $PFX | awk 'BEGIN{FS="::"}{print $1}'` GW_PLEN=`echo $PFX | awk 'BEGIN{FS="/"}{print $2}'` GW=23 CE=$PREFIX:$IFID CE_PLEN=$GW_PLEN if [ "$PFX" = "" ];then logger dhcpcd $0: PFX is not available. exit 1 else logger dhcpcd $0: PFX: $PFX fi # delete tunnel and flush addresses ip -t tunnel del $TUNDEV ip -6 addr flush dev $LANDEV # restore ll and ula addresses sysctl -w net.ipv6.conf.$LANDEV.addr_gen_mode=1 sysctl -w net.ipv6.conf.$LANDEV.addr_gen_mode=0 ip -6 addr add $LANDEV_ULA dev $LANDEV # restore addresses and tunnel ip -6 addr add $PFX dev $LANDEV ip -6 addr add $PREFIX::$GW/$GW_PLEN dev $LANDEV ip -6 addr add $CE/$CE_PLEN dev $LANDEV ip -6 tunnel add $TUNDEV mode ip4ip6 remote $BR local $CE dev $LANDEV encaplimit none ip link set dev $TUNDEV mtu 1460 ip link set dev $TUNDEV up ip -4 addr add $IP4/32 dev $TUNDEV ip route delete default ip route add default dev $TUNDEV curl "$UPDT_URL?user=$USER&pass=$PASS" iptables -t nat -F iptables -t mangle -F iptables -t mangle -o $TUNDEV -I FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu # MASQUERADEを使う場合 iptables -t nat -A POSTROUTING -o $TUNDEV -j MASQUERADE # FULLCONENATを使う場合 #iptables -t nat -A PREROUTING -i $TUNDEV -j FULLCONENAT #iptables -t nat -A POSTROUTING -o $TUNDEV -j FULLCONENAT updt_rules_v6() { PREFIX_CHANGED="no" RULES_V6="/etc/iptables/rules.v6" IF1PREFIX_ULA=fd98:1:1:1 IF1PREFIX_NEW=`echo $PREFIX | awk -F":" '{ val1="0x"$1; printf "%x", val1; printf ":"; val2="0x"$2; printf "%x", val2; printf ":"; val3="0x"$3; printf "%x", val3; printf ":"; val4="0x"$4; val4=val4+"0x1"; printf "%x", val4; }'` IF1PREFIX_OLD=`grep $IF1PREFIX_ULA /etc/iptables/rules.v6 | grep PREROUTING | awk -F"-d" '{print $2}' | awk '{print $1}' | awk 'BEGIN{FS="::"}{print $1}'` if [ "$IF1PREFIX_OLD" != "$IF1PREFIX_NEW" ]; then if [ -f "$RULES_V6" ]; then sed -i "s/$IF1PREFIX_OLD/$IF1PREFIX_NEW/g" "$RULES_V6" PREFIX_CHANGED="yes" fi fi if [ "$PREFIX_CHANGED" = "yes" ]; then ip6tables-restore < "$RULES_V6" fi } updt_rules_v6設定は以上です。設定が済んだら再起動してIPv6/IPv4ネットワーク共に疎通できるか確認してください。
今回は以上です。それでは。
コメント
コメントを投稿