フレッツ光クロス固定IP(enひかりクロス+V6プラス固定IP)でDebianを使ったLinuxルータを運用し、本稿執筆時点で一年2か月ほど使っているのですが、二か月ほど前(ちょうど一年たったころ)IPv6プレフィックスが変更され通信できなくなった経験がありました。
当初は何が起こったのか分からなかったのですが、その時はdhclientを使っていてデバッグモードで立ち上げると新しいプレフィックスが降りてきたことが確認できました。半固定というより、突然だったので動的だよなこれ、と思ったのは言うまでもありません。
その後、スクリプトなどを順に追っていって無事IPv6/IPv4ともに通信できましたが、今後もIPv6プレフィックスが変更されうると想定しておく方がよいと思い、サーバにはGUAを割り当てずULAのみにし、また、dhclientでは対応が難しい(dhcpv6サーバからのReconfigure messageに対してlogにメッセージを吐くだけ)ので、Reconfigure messageに対してリアクションができるdhcpcdに切り替えました。
ただ、プレフィックスの変更があった場合、このルータ上ではdhcpcdがルータのIPv6設定を更新しIPv6通信はできるのですが、IPv4通信などはプレフィックスが変更されるのでIP4IP6トンネルが無効になり、IPv4での通信ができなくなります。
他にも、dhcpサーバも配布するGUAが変更されるので、設定ファイルの書き換え・再起動が必要になります。/etc/radvd.confも同じで書き換えてradvdを再起動させる必要があります。また、ULAを使っている場合は、nftablesのルールも書き換える必要があります。さらにサブルータを使っている場合は、サブルータの設定も変更しなければなりません。
このようにIPv6 GUAプレフィックス変更時の対応は思った以上に大変で、手動で変更するには時間的にも手数的にも限界があると思います。
そこでIPv6プレフィックスの変更について、dhcpcdには色々なreasonのeventをhookで処理できるのでどのような対応ができるか調べたところ、RECONFIGURE6はlogにメッセージを吐くだけですが、RECONFIGURE6が発生した直後にreason=RENEW6でアドレスの更新が行われることがわかりました。(RFC3315のReconfigure については、本来ならもう少し異なる状況があり得るのですが、とりあえずRENEW6に着目することにしました。)この場合、新プレフィックスと旧プレフィックスが異なるとこれはRECONFIGURE6に対応したRENEW6だったという事がわかり、プレフィックスの変更処理をすることが出来そうなので本稿を挙げた次第です。
なお、ルータの再起動時はBOUND6というイベントでアドレスを取得できているので、まずは、以下の様な方針で処理することにしました。
1. 起動時、dhcpcd イベント発生時、reason="BOUND6"の場合、hookスクリプトで対応する処理を記述する。
2. 起動後、dhcpcd イベント発生時、reason="RENEW6"の場合でかつ new_dhcp6_ia_pd1_prefix1とold_dhcp6_ia_pd1_prefix1が異なる場合、プレフィックス変更が行われたとみなし、hookスクリプト内で対応する処理を記述する。
また、検討したところ、hookスクリプト自身は最小限に近い処理をし、対応するスクリプトを呼び出す方法をとることにしました。
まず、dhcpcdのインストールと設定です。dhcpcdのインストールは、以下の様にしました。
dhcpcdの設定は以上ですが、現在のIPv6プレフィックス情報を記述しておきます。systemctl で dhcpcdを呼び出すとjournalctl -u dhcpcdでプレフィックス情報がわかるのですが、直接以下の様 dhcpcd を単独で呼び出しても、プレフィックス情報がわかります。(どちらでも構いません。)
続いてBOUND6とRENEW6で共通使用するスクリプトです。/usr/local/sbin/renew-conf-prefix.sh として保存します。(chmod +x 要)
まずは、dhcpcdでのhookを記述しておきます。
IPv6プレフィックス変更に対応する為の記事はほぼみあたらなかったのですが、ご参考になれば幸いです。
今回は以上です。それでは。
当初は何が起こったのか分からなかったのですが、その時はdhclientを使っていてデバッグモードで立ち上げると新しいプレフィックスが降りてきたことが確認できました。半固定というより、突然だったので動的だよなこれ、と思ったのは言うまでもありません。
その後、スクリプトなどを順に追っていって無事IPv6/IPv4ともに通信できましたが、今後もIPv6プレフィックスが変更されうると想定しておく方がよいと思い、サーバにはGUAを割り当てずULAのみにし、また、dhclientでは対応が難しい(dhcpv6サーバからのReconfigure messageに対してlogにメッセージを吐くだけ)ので、Reconfigure messageに対してリアクションができるdhcpcdに切り替えました。
ただ、プレフィックスの変更があった場合、このルータ上ではdhcpcdがルータのIPv6設定を更新しIPv6通信はできるのですが、IPv4通信などはプレフィックスが変更されるのでIP4IP6トンネルが無効になり、IPv4での通信ができなくなります。
他にも、dhcpサーバも配布するGUAが変更されるので、設定ファイルの書き換え・再起動が必要になります。/etc/radvd.confも同じで書き換えてradvdを再起動させる必要があります。また、ULAを使っている場合は、nftablesのルールも書き換える必要があります。さらにサブルータを使っている場合は、サブルータの設定も変更しなければなりません。
このようにIPv6 GUAプレフィックス変更時の対応は思った以上に大変で、手動で変更するには時間的にも手数的にも限界があると思います。
そこでIPv6プレフィックスの変更について、dhcpcdには色々なreasonのeventをhookで処理できるのでどのような対応ができるか調べたところ、RECONFIGURE6はlogにメッセージを吐くだけですが、RECONFIGURE6が発生した直後にreason=RENEW6でアドレスの更新が行われることがわかりました。(RFC3315のReconfigure については、本来ならもう少し異なる状況があり得るのですが、とりあえずRENEW6に着目することにしました。)この場合、新プレフィックスと旧プレフィックスが異なるとこれはRECONFIGURE6に対応したRENEW6だったという事がわかり、プレフィックスの変更処理をすることが出来そうなので本稿を挙げた次第です。
なお、ルータの再起動時はBOUND6というイベントでアドレスを取得できているので、まずは、以下の様な方針で処理することにしました。
1. 起動時、dhcpcd イベント発生時、reason="BOUND6"の場合、hookスクリプトで対応する処理を記述する。
2. 起動後、dhcpcd イベント発生時、reason="RENEW6"の場合でかつ new_dhcp6_ia_pd1_prefix1とold_dhcp6_ia_pd1_prefix1が異なる場合、プレフィックス変更が行われたとみなし、hookスクリプト内で対応する処理を記述する。
また、検討したところ、hookスクリプト自身は最小限に近い処理をし、対応するスクリプトを呼び出す方法をとることにしました。
まず、dhcpcdのインストールと設定です。dhcpcdのインストールは、以下の様にしました。
apt-get install dhcpcd dpkg -P isc-dhcp-client参考までに、必要最小限の/etc/apt/sources.listは以下の通りです。この場合、IPv4での通信ができなくてもipv6でパッケージを取得できます。
deb http://deb.debian.org/debian bookworm main non-free-firmware non-free contribまた/etc/resolv.confも下記の様に最小限にしておけば、IPv6で名前解決できますので、nameserverを取得できなかった場合などの参考にしてください。
nameserver 2606:4700:4700::1111 nameserver 2606:4700:4700::1001/etc/dhcpcd.confは以下の通りで、enp1s0f0がLAN側でenp1s0f1がWAN側です。
duid ll noipv6rs noipv4ll denyinterfaces enp1s0f0 option dhcp6_reconfigure_msg, dhcp6_reconfigure_accept, dhcp6_name_servers, dhcp6_domain_search nooption dhcp6_sol_max_rt, dhcp6_inf_max_rt, dhcp6_vivco interface enp1s0f1 ipv6rs ia_pd 0/::/56 enp1s0f0/0/56つづいてkea-dhcp6.confやradvd.confといった変更対象ファイルに対しdhcpcdが読み書きできるようにしておきます。
ReadWritePaths=/var/lib/dhcpcd /run/dhcpcd /etc/wpa_supplicant /etc/dhcpcd.conf /etc/resolv.conf /etc/kea/kea-dhcp6.conf /etc/radvd.conf許可を与えたら、 systemctl daemon-reload としてサービス内容を更新します。
dhcpcdの設定は以上ですが、現在のIPv6プレフィックス情報を記述しておきます。systemctl で dhcpcdを呼び出すとjournalctl -u dhcpcdでプレフィックス情報がわかるのですが、直接以下の様 dhcpcd を単独で呼び出しても、プレフィックス情報がわかります。(どちらでも構いません。)
dhcpcd -k dhcpcd dhcpcd-9.4.1 starting dev: loaded udev DUID 00:03:00:01:0c:11:22:33:44:25 enp3s0: waiting for carrier enp1s0f1: IAID aa:bb:cc:dd enp1s0f1: IA type 25 IAID 00:00:00:00 enp1s0f1: adding address fe80::e22:22ff:fe33:4425 enp1s0f1: soliciting an IPv6 router enp1s0f1: soliciting a DHCPv6 lease enp1s0f0: activating for delegation enp1s0f0: IAID aa:bb:cc:dd enp1s0f1: Router Advertisement from fe80::16aa:bbff:fecc:dd8a enp1s0f1: adding default route via fe80::16aa:bbff:fecc:dd8a enp1s0f1: soliciting a DHCP lease enp1s0f1: ADV 2xxx:yyyy:zzzz:1600::/56 from fe80::16aa:bbff:fecc:dd8a (以下略)ADV 2xxx:yyyy:zzzz:1600::/56が降りてきたPDです。これを今回は以下の様にして/var/lib/dhcpcd/prefix.confに保存してください。
dhcp6_ia_pd1_prefix1=2xxx:yyyy:zzzz:1600:: dhcp6_ia_pd1_prefix1_length=56つづいて前述の起動時のreason="BOUND6"の場合の処理です。これは、これまで/etc/rc.localで呼び出していた処理をほぼそのまま呼び出すhookで良いので以下の様にしてみました。
######## /lib/dhcpcd/dhcpcd-hooks/10-boot-time case "$reason" in BOUND6) /usr/local/sbin/init-v6p-static.sh $new_dhcp6_ia_pd1_prefix1 $new_dhcp6_ia_pd1_prefix1_length ;; esac呼び出されるスクリプトは init-v6p-static.sh (chmod 700) で以下の通りです。
######## /usr/local/sbin/init-v6p-static.sh #!/bin/sh if [ $# -ne 2 ];then echo "Usage: $0 NEW_PREFIX NEW_PREFIX_LEN"; exit 1 fi NEW_PREFIX=$1 NEW_PREFIX_LEN=$2 ULA=fd98:1:1::/56 ULA_PFX=`echo $ULA | awk -F'::' '{print $1}'` PREFIX_CONF=/var/lib/dhcpcd/prefix.conf # get last prefix from $PREFIX_CONF OLD_PREFIX=`cat $PREFIX_CONF | grep dhcp6_ia_pd1_prefix1= | awk -F'=' '{print $2}'` OLD_PREFIX_LEN=`cat $PREFIX_CONF | grep dhcp6_ia_pd1_prefix1_length | awk -F'=' '{print $2}'` # OLD_PREFIXを/$OLD_PREFX_LENで表記した場合、たとえば、2111:2222:3333:4444::/56は2111:2222:3333:4400::/56と訂正し比較する # また、2111:2222:3333:4444:5555::/80の場合でも2111:2222:3333:4400::/56と訂正し比較する。(サブルータでの対応の為) OLD_GUA=$OLD_PREFIX HEXTET_3RD_OLD=`echo $OLD_GUA | awk -F':' '{print $3}'` HEXTET_4TH_OLD=`echo $OLD_GUA | awk -F':' '{print $4}'` if [ "" = "$HEXTET_3RD_OLD" ]; then OLD=`echo $OLD_GUA | awk -F'::' '{print $1}'` else OLD_GUA_48=`echo $OLD_GUA | awk -F":" '{print $1 ":" $2 ":" $3}'` case $HEXTET_4TH_OLD in ????) TMP=`echo $HEXTET_4TH_OLD | cut -c 1-2` OLD=$OLD_GUA_48:$TMP OLD_ZZ=00 ;; ???) TMP=`echo $HEXTET_4TH_OLD | cut -c 1` OLD=$OLD_GUA_48:$TMP OLD_ZZ=00 ;; "") OLD=$OLD_GUA_48 OLD_ZZ= ;; esac fi OLD_PREFIX=$OLD$OLD_ZZ:: if [ "$OLD_PREFIX" != "$NEW_PREFIX" ]; then prefix_has_been_changed=1 else prefix_has_been_changed=0 fi ###### 以下、プロバイダからの設定情報を代入 UPDT_URL=http://xxx.enabler.ne.jp/update USER=username PASS=password IFID=0011:2233:4400:0000 IP4=1.1.1.1 BR=2111:2222:3333:4400::55 ###### プロバイダからの設定情報は以上 WANDEV=enp1s0f1 LANDEV=enp1s0f0 TUNDEV='tun0' TUN_MTU=1460 PFX=$1/$2 PREFIX=`echo $PFX | awk 'BEGIN{FS="::"}{print $1}'` GW_PLEN=$2 GW=23 CE=$PREFIX:$IFID CE_PLEN=$GW_PLEN 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 $TUN_MTU 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 nft add table ip6 nat66 nft add chain ip6 nat66 PREROUTING { type nat hook prerouting priority dstnat\; policy accept\; } nft add chain ip6 nat66 INPUT { type nat hook input priority 100\; policy accept\; } nft add chain ip6 nat66 OUTPUT { type nat hook output priority -100\; policy accept\; } nft add chain ip6 nat66 POSTROUTING { type nat hook postrouting priority srcnat\; policy accept\; } nft insert rule ip6 nat66 PREROUTING iifname "${WANDEV}" oifname "${LANDEV}" dnat ip6 prefix to ip6 daddr map { "${PFX}" : "${ULA}" } nft insert rule ip6 nat66 POSTROUTING iifname "${LANDEV}" oifname "${WANDEV}" snat ip6 prefix to ip6 saddr map { "${ULA}" : "${PFX}" } if [ "$prefix_has_been_changed" = "1" ];then # 最初に /var/lib/dhcpcd/prefix.confを更新しておく /usr/local/sbin/renew-conf-prefix.sh $OLD_PREFIX $NEW_PREFIX /var/lib/dhcpcd/prefix.conf # /etc/radvd.confを更新し、radvdをリスタート /usr/local/sbin/renew-conf-prefix.sh $OLD_PREFIX $NEW_PREFIX /etc/radvd.conf systemctl restart radvd # /etc/kea/kea-dhcp6.confを更新し、kea-dhcpcd-confをリスタート /usr/local/sbin/renew-conf-prefix.sh $OLD_PREFIX $NEW_PREFIX /etc/kea/kea-dhcp6.conf systemctl restart kea-dhcp6-server fiルータ起動後のDHCPCDイベントBOUND6時のスクリプトは以上です。
続いてBOUND6とRENEW6で共通使用するスクリプトです。/usr/local/sbin/renew-conf-prefix.sh として保存します。(chmod +x 要)
#!/bin/sh if [ $# -ne 3 ];then echo "Usage: $0 OLD_GUA NEW_GUA TARGET_CONF"; exit 1 fi replace_file() { if [ -e "$1" ]; then if comp_file "$1" "$2"; then echo comp_file "$1" "$2" same > /var/lib/dhcpcd/msgs.txt rm -f "$2" return 1 fi fi cat "$2" > "$1" rm -f "$2" return 0 } OLD_GUA=$1 NEW_GUA=$2 TARGET_CONF=$3 # backup TARGET_CONF before processing. FILENAME=$(basename $TARGET_CONF) cp -a $TARGET_CONF /var/lib/dhcpcd/$FILENAME.`date '+%Y_%m_%d-%H:%M:%S'` # copy $TARGET_CONF /var/lib/dhcpcd/$FILENAME cp -a $TARGET_CONF /var/lib/dhcpcd/$FILENAME TARGET_WRK=/var/lib/dhcpcd/$FILENAME HEXTET_1ST_NEW=`echo $NEW_GUA | awk -F':' '{print $1}'` HEXTET_1ST_OLD=`echo $OLD_GUA | awk -F':' '{print $1}'` HEXTET_2ND_NEW=`echo $NEW_GUA | awk -F':' '{print $2}'` HEXTET_2ND_OLD=`echo $OLD_GUA | awk -F':' '{print $2}'` HEXTET_3RD_NEW=`echo $NEW_GUA | awk -F':' '{print $3}'` HEXTET_3RD_OLD=`echo $OLD_GUA | awk -F':' '{print $3}'` HEXTET_4TH_NEW=`echo $NEW_GUA | awk -F':' '{print $4}'` HEXTET_4TH_OLD=`echo $OLD_GUA | awk -F':' '{print $4}'` if [ "" = "$HEXTET_3RD_NEW" ];then NEW=`echo $NEW_GUA | awk -F'::' '{print $1}'`:0:0: else NEW_GUA_48=`echo $NEW_GUA | awk -F":" '{print $1 ":" $2 ":" $3}'` case $HEXTET_4TH_NEW in ????) TMP=`echo $HEXTET_4TH_NEW | cut -c 1-2` NEW=$NEW_GUA_48:$TMP NEW_ZZ=00 ;; ???) TMP=`echo $HEXTET_4TH_NEW | cut -c 1` NEW=$NEW_GUA_48:$TMP NEW_ZZ=00 ;; "") NEW=$NEW_GUA_48 NEW_ZZ= ;; esac fi if [ "" = "$HEXTET_3RD_OLD" ]; then OLD=`echo $OLD_GUA | awk -F'::' '{print $1}'` else OLD_GUA_48=`echo $OLD_GUA | awk -F":" '{print $1 ":" $2 ":" $3}'` case $HEXTET_4TH_OLD in ????) TMP=`echo $HEXTET_4TH_OLD | cut -c 1-2` OLD=$OLD_GUA_48:$TMP OLD_ZZ=00 ;; ???) TMP=`echo $HEXTET_4TH_OLD | cut -c 1` OLD=$OLD_GUA_48:$TMP OLD_ZZ=00 ;; "") OLD=$OLD_GUA_48 OLD_ZZ= ;; esac fi TMP2=:0:0: TMP1=:0: sed -i "s/$OLD$TMP2/$NEW/g" $TARGET_WRK sed -i "s/$OLD$TMP1/$NEW/g" $TARGET_WRK if [ "$HEXTET_1ST_OLD" = "$HEXTET_1ST_NEW" ] && [ "$HEXTET_2ND_OLD" = "$HEXTET_2ND_NEW" ];then if [ "$HEXTET_3RD_OLD" != "" ]; then if [ "$HEXTET_4TH_OLD" != "" ]; then if [ "$HEXTET_3RD_NEW" != "" ];then if [ "$HEXTET_4TH_NEW" != "" ];then #echo DL1aa HEXTET_4TH_NEW:$HEXTET_4TH_NEW $OLD $NEW sed -i "s/$OLD/$NEW/g" $TARGET_WRK else #echo DL1ab HEXTET_4TH_NEW:$HEXTET_4TH_NEW $OLD $NEW sed -i "s/$OLD/$NEW:/g" $TARGET_WRK fi else #echo DL1b sed -i "s/$OLD/$NEW/g" $TARGET_WRK fi else #echo DL2 # 2111:2222:3333:40:: to 2aaa:bbbb:cccc:dd40:: sed -i "s/$OLD:/$NEW/g" $TARGET_WRK # correct 2aaa:bbbb:cccc:dd: to 2aaa:bbbb:cccc:dd00:: ZZ=00 sed -i "s/$NEW:/$NEW$ZZ::/g" $TARGET_WRK fi else #echo DL3 sed -i "s/$OLD::/$NEW$NEW_ZZ::/g" $TARGET_WRK fi else if [ "$HEXTET_3RD_OLD" = "" ];then if [ "$HEXTET_4TH_OLD" = "" ];then if [ "$HEXTET_3RD_NEW" != "" ];then if [ "$HEXTET_4TH_NEW" != "" ];then #echo DL4a sed -i "s/$OLD$OLD_ZZ/$NEW$NEW_ZZ/g" $TARGET_WRK sed -i "s/$OLD/$NEW/g" $TARGET_WRK else #echo DL4b $OLD $NEW sed -i "s/$OLD/$NEW:/g" $TARGET_WRK # correct 2111:2222:3333110:: to 2111:2222:3333:110:: sed -i "s/$NEW/$NEW:/g" $TARGET_WRK fi else #echo DL4c $OLD $NEW sed -i "s/$OLD::/$NEW::/g" $TARGET_WRK fi else : #echo DL4d: $OLD_GUA $NEW_GUA fi else if [ "$HEXTET_4TH_OLD" = "" ];then if [ "$HEXTET_3RD_NEW" != "" ];then if [ "$HEXTET_4TH_NEW" != "" ];then #echo DL5a $OLD $NEW sed -i "s/$OLD/$NEW/g" $TARGET_WRK # correct 2111:2222:3333:16:: to 2111:2222:3333:1600:: ZZ=00 sed -i "s/$NEW/$NEW$ZZ/g" $TARGET_WRK # ocrrect 2111:2222:3333:1600:10:: 2111:2222:3333:1610:: sed -i "/$NEW$ZZ::/!s/$NEW$ZZ:/$NEW/g" $TARGET_WRK else #echo DL5b # ex "2111:2222:0":10: to "2aaa:bbbb:cccc:dd"10: sed -i "s/$HEXTET_1ST_OLD:$HEXTET_2ND_OLD:$HEXTET_3RD_OLD:/$NEW/g" $TARGET_WRK # correct 2aaa:bbbb:cccc:dd: to 2aaa:bbbb:cccc:dd00:: ZZ=00 sed -i "s/$NEW:/$NEW$ZZ::/g" $TARGET_WRK fi else #echo DL5c # 2111:2222:3333 2aaa:bbbb sed -i "s/$OLD/$NEW/g" $TARGET_WRK fi else #echo DL6 sed -i "s/$OLD$OLD_ZZ/$NEW$NEW_ZZ/g" $TARGET_WRK sed -i "s/$OLD/$NEW/g" $TARGET_WRK fi fi fi sed -i "/duid\|hw-address/!s/:00:/:/g" $TARGET_WRK sed -i "s/:0:0::/::/g" $TARGET_WRK sed -i "s/:0::/::/g" $TARGET_WRK sed -i "s/:::/::/g" $TARGET_WRK if replace_file $TARGET_CONF "$TARGET_WRK"; then chmod 644 $TARGET_CONF fi exit 0次はルーター起動中のDHCPCDイベントRENEW時でprefixの変更があった場合(つまりRECONFIGURE6でプレフィックスの変更があった場合)の処理です。
まずは、dhcpcdでのhookを記述しておきます。
######## /lib/dhcpcd/dhcpcd-hooks/15-reconfigure6 case "$reason" in RENEW6) if [ "$new_dhcp6_ia_pd1_prefix1" != "$old_dhcp6_ia_pd1_prefix1" ];then p1=$new_dhcp6_ia_pd1_prefix1 p2=$new_dhcp6_ia_pd1_prefix1_length p3=$old_dhcp6_ia_pd1_prefix1 p4=$old_dhcp6_ia_pd1_prefix1_length /usr/local/sbin/reconfigure-v6p-static.sh $p1 $p2 $p3 $4 fi ;; esac続いて呼び出される /usr/local/sbin/reconfigure-v6p-static.sh (chmod 700) です。
######## /usr/local/sbin/reconfigure-v6p-static.sh #!/bin/sh if [ $# -ne 4 ];then echo "Usage: $0 NEW_PREFIX NEW_PREFIX_LEN OLD_PREFIX OLD_PREFIX_LEN"; exit 1 fi NEW_PREFIX=$1 NEW_PREFIX_LEN=$2 ULA=fd98:1:1::/56 ULA_PFX=`echo $ULA | awk -F'::' '{print $1}'` # ULA address for LANDEV to restore. LANDEV_ULA=fd98:1:1::23/56 ###### 以下、プロバイダからの設定情報を代入 UPDT_URL=http://xxx.enabler.ne.jp/update USER=username PASS=password IFID=0011:2233:4400:0000 IP4=1.1.1.1 BR=2111:2222:3333:4400::55 ###### プロバイダからの設定情報は以上 WANDEV=enp1s0f1 LANDEV=enp1s0f0 TUNDEV='tun0' TUN_MTU=1460 GW_PLEN=$2 GW=23 PFX=$1/$2 PREFIX=`echo $PFX | awk 'BEGIN{FS="::"}{print $1}'` CE=$PREFIX:$IFID CE_PLEN=$GW_PLEN OLD_PFX=$3/$4 OLD_PREFIX=`echo $OLD_PFX | awk 'BEGIN{FS="::"}{print $1}'` OLD_CE=$OLD_PREFIX:$IFID OLD_CE_PLEN=$GW_PLEN # delete old tunnel ip -6 tunnel del $TUNDEV # delete old CE address ip -6 addr del $OLD_CE/$OLD_CE_PLEN dev $LANDEV # add new CE address ip -6 addr add $CE/$CE_PLEN dev $LANDEV # add new tunnel ip -6 tunnel add $TUNDEV mode ip4ip6 remote $BR local $CE dev $LANDEV encaplimit none ip link set dev $TUNDEV mtu $TUN_MTU 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 nft delete table ip6 nat66 nft add table ip6 nat66 nft add chain ip6 nat66 PREROUTING { type nat hook prerouting priority dstnat\; policy accept\; } nft add chain ip6 nat66 INPUT { type nat hook input priority 100\; policy accept\; } nft add chain ip6 nat66 OUTPUT { type nat hook output priority -100\; policy accept\; } nft add chain ip6 nat66 POSTROUTING { type nat hook postrouting priority srcnat\; policy accept\; } nft insert rule ip6 nat66 PREROUTING iifname "${WANDEV}" oifname "${LANDEV}" dnat ip6 prefix to ip6 daddr map { "${PFX}" : "${ULA}" } nft insert rule ip6 nat66 POSTROUTING iifname "${LANDEV}" oifname "${WANDEV}" snat ip6 prefix to ip6 saddr map { "${ULA}" : "${PFX}" } # 最初に /var/lib/dhcpcd/prefix.confを更新しておく /usr/local/sbin/renew-conf-prefix.sh $OLD_PREFIX $NEW_PREFIX /var/lib/dhcpcd/prefix.conf # /etc/radvd.confを更新し、radvdをリスタート /usr/local/sbin/renew-conf-prefix.sh $OLD_PREFIX $NEW_PREFIX /etc/radvd.conf systemctl restart radvd # /etc/kea/kea-dhcp6.confを更新し、kea-dhcpcd-confをリスタート /usr/local/sbin/renew-conf-prefix.sh $OLD_PREFIX $NEW_PREFIX /etc/kea/kea-dhcp6.conf systemctl restart kea-dhcp6-server/var/lib/dhcpcd/以下に/etc/radvd.confと/etc/kea/kea-dhcp6.confをバックアップする処理を入れたので、これで何かあっても対応できそうです。
IPv6プレフィックス変更に対応する為の記事はほぼみあたらなかったのですが、ご参考になれば幸いです。
今回は以上です。それでは。
コメント
コメントを投稿