スキップしてメイン コンテンツに移動

フレッツ光クロス(コラボ)でDHCPv6 Reconfigure messageが繰り返し送信される件について

先日(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が飛んできます。何か他のやり取りや設定が必要なようなので継続調査が必要そうです。)
# 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が再送されて二か月程再送されてきていて冗長が過ぎると思うのですが、どうなんでしょう。非効率的だと筆者もそう思いますが、他にも何かあるかもしれないので念のため引き続き継続調査としておきたいと思います。

基、まず、起動時の設定です。当初は、/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は以下のようにしました。
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.sh
gw23.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ネットワーク共に疎通できるか確認してください。
今回は以上です。それでは。

コメント

このブログの人気の投稿

wsdd を使ってSamba サーバをネットワークに表示

Windows 10のアップデートで、セキュリティー対応のため、smbv1がデフォルトではインストールされなくなり、Samba serverがエクスプローラーのネットワークに表示されなくなってしまいました。そこで、いくつか方法を調べたのですが、linuxでwsdの実装がないか探したところ、 https://github.com/christgau/wsdd が、見つかりましたので、さっそくインストールしてみました。まだパッケージにはないようですが、インストール自身は簡単です。wsdd自体は以下のように取得し、linkを張っておきます。 cd /usr/local/bin/ sudo wget https://raw.githubusercontent.com/christgau/wsdd/master/src/wsdd.py sudo chmod 755 wsdd.py sudo ln -sf wsdd.py wsdd こちらのsambaサーバはDebianなので、/etc/systemd/system/wsdd.serviceは以下のようにしました。 [Unit] Description=Web Services Dynamic Discovery host daemon Requires=network-online.target After=network.target network-online.target multi-user.target [Service] Type=simple ExecStart=/usr/local/bin/wsdd -d MYDOMAIN [Install] WantedBy=multi-user.target wsdd -d MYDOMAINのところを、環境にあわせて書き換えてください。 次に、systemdに登録・起動テストを行います。 systemctl enable wsdd systemctl start wsdd 起動に成功すると、エクスプローラーのネットワークに表示されます。  なおこのwsddはpython3が必要です。一度試してみてください。SMBv1/CIFSを停止していても、大丈夫です。 cで書かれたほかのwsddの実装もあるようなので、いずれパッケージになるかも...

Windows デバイス暗号化 のサポートで "許可されていない dma 対応バス/デバイスが検出されました"の対処

Windows でセキュリティー関係を見ているのですが、とあるPCでmsinfo32で確認すると"デバイス暗号化のサポート"で"許可されていない dma 対応バス/デバイスが検出されました"と出ていました。このPCの場合、それ以外はOK(なにも表示されない)だったのですが、ネットでしらべるとMSのドキュメントではハードウェアベンダーに問い合わせるなどと敷居が高く具体的にどこが引っかかっているかわかりません。そこでほかに方法はないかとしらべやってみたところ、"前提条件をみたしています"まで持って行けたので、本稿を挙げた次第です。 具体的には、以下のようにします。 1-a. 許可するDMA対応バス・デバイスを指定するレジストリの所有権と書き込み設定をおこなう。 以下のレジストリキーの所有者を自分自身(管理ユーザ)のものにし、フルコントロール権を付与する。 HKLM\SYSTEM\CurrentControlSet\Control\DmaSecurity\AllowedBuses もしくは 1-b. MicrosoftよりPsExecをダウンロードし、System権限でRegeditを立ち上げ編集する。 Microsoftより、https://docs.microsoft.com/en-us/sysinternals/downloads/psexec にある こちら をダウンロードし、解凍する。解凍すると、x64の場合、PsExec64.exeがあるので、管理者権限で以下を実行し、システム権限でregeditを立ち上げることが出来るようになる。 cd Downloads\PSTools .\PsExec64.exe -sid C:\Windows\regedit.exe 2-a. パワーシェルスクリプトを実行し、PnPデバイスのうちインスタンスがPCIで始まるものを"AllowedBuses"に追加する。 以下のパワーシェルスクリプトを作成する。たとえばDocuments\allow-dma-bus-device.ps1として作成する。( こちらの記事のものを使用させていただきました: Thank you! ) $tmpfile = "$($env:T...

フレッツ光クロス:MAP-E ROUTER by Debian Box (iptables)

フレッツ光クロスがようやく開通したので、Debianにてrouterを構成し接続してみました。なお、プロバイダーを選ぶにあたっては、IPoE方式がそれぞれ異なるため検討したところ、IPoEでは、MAP-Eでもv6plusとocnバーチャルコネクトがあり、前者がポート数240なのに対し、後者は約4倍のポート数が使えるようなネットの情報をみて、OCNバーチャルコネクトを選択しました。(プロバイダーとしてはぷららです。なおDS-LiteはCE側でのNATではないので今回は見送りました。)そこで、OCN バーチャルコネクトをDebian(iptables)で実現するとどうなるかと思い、ネットの情報を頼りにしつつ、設定した次第です。 実際に試した結果、とりあえず通信できていますが、MAP-Eは本来マッピングルールをマップサーバから取得するはずなので、今回のやり方が正解とはいえませんし、仕様変更されると通信できなくなる可能性があります。あくまでも参考程度ですが、本稿をUPしてみました。 2023/03/16追記: こちら にゲームコンソールNAT越え(Nintendo Switch ナットタイプ A判定)対応版を投稿しました。 2023/03/28追記:※1の記述および3行無効化によりNAT越え(Nintendo Switch ナットタイプ B判定)できるようになりました。 構成は以下の通りです。 ルーターがDebianで回線がOCNバーチャルコネクトであること以外はなにも特別なところはない構成です。 さて、いきなり設定ですが、まず、割り当てられたプレフィックスを確認します。 確認は、 dhclient -6 -d -P enp2s0 とします。出力の中に 前略 RCV: | | X-- IAPREFIX 2400:4050:5c71:af00::/56 後略 このようにプレフィックスが表示されるので、その確認したプレフィックスを書き留めておきます。これを こちらで 入力します。すると、 CE: 2400:4050:5c71:af00:99:f171:c600:2f00 IPv4 アドレス: 153.241.113.198 ポート番号:(1776-1791 2800-2815 3824-3839) 4848-4863 5872-5887 6896-...