腾讯云自定义镜像配置IPv6

生成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 &

发表评论

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理