IFACE4=`ip route show|grep default|sed -e 's/^default.*dev \([^ ]\+\).*$/\1/'` IP4=`ip addr show dev $IFACE4 | grep -m 1 'inet\ ' | sed -e 's/^.*inet \([^ \\]\+\)\/.*$/\1/'`
sudo ip tunnel del sit1 # 删除已经创建的设备,若没有则忽略 sudo ip tunnel add sit1 mode sit remote $REMOTE_IP4local$IP4 sudo ip linkset dev sit1 up sudo ip -6 addr add $REMOTE_IP6:$IP4/64 dev sit1 sudo ip -6 route add default via $REMOTE_IP6:$REMOTE_IP4 dev sit1
其基本步骤都是:
建立一个 sit 隧道;
为隧道 interface 添加地址;
添加默认路由;
对 NAT 场景的处理的主要区别在第二步。在第二个脚本中,使用的是从本地的 ip route 获取的IP。如果是在路由器场景下,这拿到的是 LAN 地址。而在第一个脚本中,是通过 curl ifconfig.me 来获取的 IP,这拿到的是公网 IP。以同样的精神,我对学校提供的脚本进行了改造:
IFACE4=`ip route show|grep default|grep "192.168"|sed -e 's/^default.*dev \([^ ]\+\).*$/\1/'` IP4=`ip addr show dev $IFACE4 | grep -m 1 'inet\ ' | sed -e 's/^.*inet \([^ \\]\+\)\/.*$/\1/'` PUBLIC_IP=`curl ifconfig.me`
echo"Public: ${PUBLIC_IP}, Local: ${IP4}"
DEFAULT_ROUTE=`ip -6 route show |grep default|sed -e 's/^default via \([^ ]\+\).*$/\1/'|grep fe80`
if [ ! -z "$(ifconfig | grep sit1)" ]; then ip tunnel del sit1 # 删除已经创建的设备,若没有则忽略 echo"Delete old tunnel sit1" fi ip tunnel add sit1 mode sit remote $REMOTE_IP4local$IP4 ip linkset dev sit1 up ip -6 addr add $REMOTE_IP6:$PUBLIC_IP/64 dev sit1 ip -6 route add default via $REMOTE_IP6:$REMOTE_IP4 dev sit1
if [ ! -z "$DEFAULT_ROUTE" ]; then ip -6 route del default via $DEFAULT_ROUTE dev $IFACE4 proto static metric 100 pref medium echo"Remote original gateway" fi
为什么要修改为公网地址呢?这是因为 ISATAP 不支持路由发现,因此需要固定 IP 来指引回溯流量找到客户端。不过这里有一个问题:公网地址实际上是路由器的地址,这意味着 ISATAP 响应是发送给路由器的。路由器如何知道这个响应应该发送给 LAN 的那个地址呢?