在 dist-upgrade 之后,我无法让旧脚本在 16.04 中再次运行,之前的安装是 14.04。此脚本设置了一个网络命名空间,以将程序与主网络接口隔离开来。
简要概述一下应该发生的事情:
- 创建网络命名空间,命名为
ns1
。 - 创建一对 veth 接口,分别命名为
veth1
和vpeer1
- 将接口移至
vpeer1
网络命名空间ns1
- 为接口分配 IP 地址
veth1
并将其启动 - 为接口分配 IP 地址
vpeer1
,并将其启动。 lo
在网络命名空间上启动接口ns1
- 在 veth 对之间创建默认路由。
- 更改
ip_forwarding
为 1 - 将iptables改为
FORWARD
并DROP
flush,flush iptables nat。 - 创建后路由(MASQUERADE)条目并创建两个 FORWARD 条目,这允许在网络命名空间内部和外部之间转发流量。
#!/usr/bin/env bash
set -x
NS="ns1"
VETH="veth1"
VPEER="vpeer1"
VETH_ADDR="10.200.1.1"
VPEER_ADDR="10.200.1.2"
if [[ $EUID -ne 0 ]]; then
echo "You must be root to run this script"
exit 1
fi
# Remove namespace if it exists.
ip netns del $NS &>/dev/null
# Create namespace
ip netns add $NS
# Create veth link.
ip link add ${VETH} type veth peer name ${VPEER}
# Add peer-1 to NS.
ip link set ${VPEER} netns $NS
# Setup IP address of ${VETH}.
ip addr add ${VETH_ADDR}/24 dev ${VETH}
ip link set ${VETH} up
# Setup IP ${VPEER}.
ip netns exec $NS ip addr add ${VPEER_ADDR}/24 dev ${VPEER}
ip netns exec $NS ip link set ${VPEER} up
ip netns exec $NS ip link set lo up
ip netns exec $NS ip route add default via ${VETH_ADDR}
# Enable IP-forwarding.
echo 1 > /proc/sys/net/ipv4/ip_forward
# Flush forward rules.
iptables -P FORWARD DROP
iptables -F FORWARD
# Flush nat rules.
iptables -t nat -F
# Enable masquerading of 10.200.1.0.
iptables -t nat -A POSTROUTING -s ${VPEER_ADDR} -o p119p1 -j MASQUERADE
iptables -A FORWARD -i p119p1 -o ${VETH} -j ACCEPT
iptables -A FORWARD -o p119p1 -i ${VETH} -j ACCEPT
p119p1 是我的以太网适配器,请将其更改为您的适配器以进行测试。
测试此连接,当其运行时,ip netns exec ns1 ping 8.8.8.8
如果它能 ping 出去,就表示它正常工作。
当以 root 身份运行脚本时yourscript.sh
,这在 16.04 上不起作用。在 14.04 上这确实有效。当以 root 身份逐行手动输入时(在需要时替换 ${variables}),这在 16.04 上确实有效。
我确信我没有遇到重大系统缺陷,与旧发行版相比,我做的有些不对。我在以脚本形式运行时出错,基本上它会抱怨“目标主机无法访问”,出于某种原因,它在以脚本形式运行时跳过了为 veth1 分配 IP。原因我自己也不知道。
当可以在命名空间内启动工作程序时。使用ip netns exec ns1 <command>
。如果在命名空间内也使用 VPN,则允许将各个程序分离到自己的 VPN 网络上。