フレッツ光クロス固定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プレフィックス変更に対応する為の記事はほぼみあたらなかったのですが、ご参考になれば幸いです。
今回は以上です。それでは。
コメント
コメントを投稿