生成IPv6配置脚本的脚本 ipv6config.sh
if [ ! -f "/etc/tencentcloud_ipv6_base.sh" ]; then
cat <<'EOF' > '/etc/tencentcloud_ipv6_base.sh'
#!/bin/bash
## support ipv6 eip config from TAT
## Version:1.0
DEFAULTMODE=$1
DEFAULTADDR=$2
DEFAULTULA=$3
DEFAULTISP=$4
DEFAULTDEV="eth0"
DEVCOUNT=0
ADDRCOUNT=0
MODE=""
ADDR=""
ULA=""
ISP="" # XXX not used yet
DEV=""
sync_config_from_meta()
{
MODE=$DEFAULTMODE
ADDR=$DEFAULTADDR
ULA=$DEFAULTULA
ISP=$DEFAULTISP
DEV=$DEFAULTDEV
# TODO
DEVCOUNT=1
ADDRCOUNT=1
}
setup_dhcpclient_dhclient()
{
local dev=$1
if [[ $MODE == "PASSTHROUGH" ]]; then
# stop client
pid=`cat /var/run/dhclient6.pid`
if [[ -n $pid ]]; then
/usr/bin/kill -9 `cat /var/run/dhclient6.pid`
fi
else
# start client
if [[ ! -f /var/run/dhclient6.pid ]]; then
/sbin/dhclient -6 -nw $dev
fi
fi
}
setup_dhcpclient_systemd()
{
local dev=$1
local profile="/run/systemd/network/10-netplan-$dev.network"
local disabled=`/usr/bin/grep "IPv6AcceptRA=false" $profile; echo $?`
sed -i "/\[Network\]/aGateway=fe80::feee:ffff:feff:ffff" $profile
if [[ $MODE == "PASSTHROUGH" ]]; then
if [[ $disabled == "1" ]]; then
# stop client
sed -i "/\[Network\]/aIPv6AcceptRA=false" $profile
sed -i "/\[Network\]/aAddress=${ADDR}" $profile
networkctl reload
sleep 1
fi
# XXX persistent config causes cloud-init not bringing up $dev
# /usr/bin/sed -i "/eth0:/a\ accept_ra: false" /etc/netplan/00-installer-config.yaml
else
if [[ $disabled == "0" ]]; then
# start client
sed -i "/IPv6AcceptRA=false/d" $profile
sed -i '/^Address=\([0-9a-fA-F]\{1,4\}:\)\{7\}[0-9a-fA-F]\{1,4\}/d' $profile
networkctl reload
sleep 1
fi
# persistent config
# /usr/bin/sed -i "/accept-ra: false/d" /etc/netplan/00-installer-config.yaml
fi
}
setup_dhcpclient_nm()
{
local dev=$1
local connection="System $1"
local method=`/usr/bin/nmcli c s "$connection" | grep ipv6.method | awk '{print $2}'`
if [[ $MODE == "PASSTHROUGH" ]]; then
if [[ $method == "auto" ]]; then
# stop client
/usr/bin/nmcli c m "$connection" ipv6.method ignore
fi
else
if [[ $method == "ignore" ]]; then
# start client
/usr/bin/nmcli c m "$connection" ipv6.method auto
/usr/bin/nmcli c up "$connection"
fi
fi
}
setup_dhclient()
{
if [[ -f /etc/opencloudos-release ]]; then
setup_dhcpclient_nm $1
return
fi
/usr/bin/ps -elF | /usr/bin/grep -w NetworkManager | /usr/bin/grep -v grep >/dev/null
if (( $? == 0 )); then
setup_dhcpclient_nm $1
return
fi
/usr/bin/ps -elF | /usr/bin/grep -w systemd-networkd | /usr/bin/grep -v grep >/dev/null
if (( $? == 0 )); then
setup_dhcpclient_systemd $1
return
fi
setup_dhcpclient_dhclient $1
}
setup_route()
{
if (( $DEVCOUNT == 1 && $ADDRCOUNT == 1 )); then
/sbin/ip -6 route replace default dev $DEV via fe80::feee:ffff:feff:ffff
fi
# TODO policy route
}
# remove wrong addresses and config needed address
# PASSTHROUGH mode: remove ULA and other GUA, config right GUA
# NAT mode: do nothing
# DUAL mode: remove other GUA, config right GUA
setup_addr()
{
local dev=$1
local addr=$2
local ula=$3
local old=
if [[ $MODE == "PASSTHROUGH" ]]; then
old=`/sbin/ip -6 addr show dev $dev | grep inet6 | grep -v 'inet6 fe80' | grep -v "inet6 $addr" | awk '{print $2}'`
elif [[ $MODE == "DUAL" ]]; then
old=`/sbin/ip -6 addr show dev $dev | grep inet6 | grep -v 'inet6 fe80' | grep -v "inet6 $ula" | grep -v "inet6 $addr" | awk '{print $2}'`
else
return 0
fi
for o in $old; do
echo "removing $o"
/sbin/ip -6 addr del dev $dev $o
done
/sbin/ip -6 addr add dev $dev $addr
}
sync_config_from_meta
setup_dhclient $DEV
setup_addr $DEV $ADDR $ULA
setup_route
EOF
fi
mode={{mode}}
gua={{gua}}
ula={{ula}}
DEV="eth0" # default device
rclocal=1
config_rclocal()
{
local conf="/etc/rc.local"
if (( $rclocal != 1 )); then
return
fi
if [[ -h $conf ]]; then
conf="/etc/rc.d/rc.local"
fi
grep -w tencentcloud_ipv6_base $conf | grep "$gua $ula"
if (( $? == 1 )); then
echo "bash /etc/tencentcloud_ipv6_base.sh $mode $gua $ula CAP" >> $conf
fi
chmod +x $conf
}
config_sysconfig()
{
local conf="/etc/sysconfig/network-scripts/init.ipv6-global"
local key="Add some routes which should never appear on the wire"
if [[ -f $conf ]]; then
# duplicate check
grep -w tencentcloud_ipv6_base $conf | grep "$gua $ula"
if (( $? == 1 )); then
lb=`grep -n "$key" $conf | awk -F: '{print $1}' | head -1`
if [[ -n $lb ]]; then
sed -i "${lb} i bash /etc/tencentcloud_ipv6_base.sh ${mode} ${gua} ${ula} CAP" $conf
else
# cannot config
return
fi
fi
rclocal=0
fi
}
config_systemd_networking()
{
local conf="/lib/systemd/system/networking.service"
local key="ExecStart"
if [[ -f $conf ]]; then
# duplicate check
grep -w tencentcloud_ipv6_base $conf | grep "$gua $ula"
if (( $? == 1 )); then
lb=`grep -n $key $conf | awk -F: '{print $1}' | tail -1`
if [[ -n $lb ]]; then
sed -i "${lb} a ExecStartPost=/bin/sh -c 'bash /etc/tencentcloud_ipv6_base.sh ${mode} ${gua} ${ula} CAP'" $conf
systemctl daemon-reload
else
# cannot config
return
fi
fi
rclocal=0
fi
}
config_systemd_NetworkManager()
{
local conf="/lib/systemd/system/NetworkManager.service"
local key="ExecStart"
if [[ -f $conf ]]; then
# duplicate check
grep -w tencentcloud_ipv6_base $conf | grep "$gua $ula"
if (( $? == 1 )); then
lb=`grep -n $key $conf | awk -F: '{print $1}' | tail -1`
if [[ -n $lb ]]; then
sed -i "${lb} a ExecStartPost=/bin/sh -c 'bash /etc/tencentcloud_ipv6_base.sh ${mode} ${gua} ${ula} CAP'" $conf
systemctl daemon-reload
else
# cannot config
return
fi
fi
rclocal=0
fi
}
config_sysconfig
config_systemd_networking
config_systemd_NetworkManager
config_rclocal
# generic config
bash /etc/tencentcloud_ipv6_base.sh $mode $gua $ula CAP
执行该脚本,会自动配置开机启动脚本,并立即执行一次配置脚本。
bash ipv6config.sh
#输出为 ExecStartPost=/bin/sh -c 'bash /etc/tencentcloud_ipv6_base.sh {{mode}} {{gua}} {{ula}} CAP'
如果默认网卡不是eth0,修改DEFAULTDEV变量为网卡设备名称。
增加RC-LOCAL开机执行命令
setipv6.sh
#!/bin/bash
sleep 15 && /bin/sh -c 'bash /etc/tencentcloud_ipv6_base.sh {{mode}} {{gua}} {{ula}} CAP' && /etc/init.d/networking restart
rc.local
在/etc/rc.local最后添加一行
nohup bash /root/setipv6.sh > setipv6.log 2>&1 &