如何使用 Tap 设备设置使用 IPv4 和 IPv6 的 OpenVPN?

如何使用 Tap 设备设置使用 IPv4 和 IPv6 的 OpenVPN?

我已经成功使用 tap0 设置 OpenVPN 以实现完整的 IPv4 连接。现在我想对 IPv6 执行相同操作。

地址和网络设置(请注意,我的真实前缀被 2001:db8 替换):

2001:db8::100:0:0/96    my assigned IPv6 range
2001:db8::100:abc:0/112 OpenVPN IPv6 range
2001:db8::100:abc:1     tap0 (on server) (set as gateway on client)
2001:db8::100:abc:2     tap0 (on client)
2001:db8::1:2:3:4       gateway for server

 Home laptop   (tap0: 2001:db8::100:abc:2/112 gateway 2001:db8::100:abc:1/112)
  |      | |      (running Kubuntu 10.10; OpenVPN 2.1.0-3ubuntu1)
  | wifi | |
   router  |
      |   OpenVPN
  INTERNET |
eth0  |   /tap0
     VPS        (eth0:2001:db8::1:2:3:4/64    gateway 2001:db8::1)
               (tap0: 2001:db8::100:abc:1/112)
                  (running Debian 6; OpenVPN 2.1.3-2)

服务器具有本机 IPv4 和 IPv6 连接,客户端仅具有 IPv4。

我可以通过 OpenVPN 与我的服务器 ping6,但不能与其他机器(例如ipv6.google.com)ping6。

net.ipv6.conf.all.forwarding设置为,我也1尝试过禁用,但没有成功。net.ipv6.conf.all.accept_ra

在服务器和客户端上使用时tcpdump,我可以看到数据包实际上是通过 tap0 传输到 eth0 的。路由器 (2001:db8::1) 在收到 ICMP6 回显请求后向 eth0 发送针对客户端 (2001:db8::100:abc:2) 的邻居请求。服务器没有响应该请求,这导致 ICMP6 回显请求无法路由到目的地。

我如何使此 IPv6 连接正常工作?

答案1

Timothy Baldwins 的回答让我走上了正确的道路,尽管答案相当隐晦。IPv6 邻居广告/请求就像 IPv6 的 ARP。它用于“查看”网络上的其他机器。路由器发送邻居请求,机器(服务器或客户端)应使用邻居广告进行回复。

即使net.ipv6.conf.all.forwarding设置为1,邻居广告和请求也不会被转发。要使 eth0 转发邻居广告和请求,应将 eth0 设置为 tap0 后面的客户端 IPv6 地址的代理,并为 eth0 启用邻居代理:

echo 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp
/sbin/ip -6 neigh add proxy 2001:db8::100:abc:2 dev eth0

不幸的是,无法检索已添加的代理列表,ip -6重复执行命令时也不会显示错误消息。我也不确定“neigh del proxy”是否有效,它不会给出错误消息,而且C 源代码对我来说没什么意义。


由于我不想手动完成所有工作,因此我创建了一个脚本来为我完成这些工作。

服务器配置

IPv6 地址基于 IPv4 部分(1在 10.8.0 中。1)。前缀和网络掩码存储在中/etc/openvpn/variables

接下来的步骤是通过本机 IPv4 连接设置具有加密 IPv4/IPv6 连接到 Internet 的 OpenVPN。RSA 密钥tls-身份验证用于身份验证和 MITM 预防。

/etc/openvpn/variables包含用于 up 脚本(在启动时运行,创建 tap0 设备后)和客户端连接脚本(在客户端验证后运行)的变量。

# this prefix is handled out by the provider, replace it with your own prefix
prefix=2001:db8::abc
# netmask, 2001:db9::abc:0000 - 2001:db9::abc:FFFF
prefixlen=112

/etc/openvpn/server-clientconnect.sh以 root 身份执行,并通过将 IPv6 地址添加到 eth0 代理来确保 IPv6 正确路由。由于是client-connect在 OpenVPN 切换到设置指定的用户后调用的Usersudo因此需要授予脚本足够的权限以 root 身份运行。当然,在使用之前应该检查变量,数字应该在 2 和 254 之间(包括 2 和 254)。(1 是网关,255 是广播地址)。

#!/bin/sh
. /etc/openvpn/variables
if [ -z "$ifconfig_pool_remote_ip" ]; then
        echo "Missing environment variable."
        exit 1
fi
ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
        echo "Invalid IP part."
        exit 1
fi
hexipp=$(printf '%x' $ipp)
/sbin/ip -6 neigh add proxy $pfx:$hexipp dev eth0

vpn为了实现这一点,应该允许用户运行脚本,同时保留包含远程网络 IPv4 地址的内容。通过执行并附加以下内容$ifconfig_pool_remote_ip将下一行添加到 sudoers 文件中:sudo visudo

Defaults:vpn env_keep=ifconfig_pool_remote_ip
vpn ALL=NOPASSWD: /etc/openvpn/server-clientconnect.sh

/etc/openvpn/server-up.sh启用 IPv4、IPv6 转发(eth0+tap0 不起作用,但必须如此all)和 eth0 上的邻居代理。它还将网关地址添加到服务器tap0

#!/bin/sh
. /etc/openvpn/variables
/sbin/ip -6 addr add $pfx:1/$pfxlen dev $dev
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
echo 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp

最后,OpenVPN 配置文件位于/etc/openvpn/internet.conf

proto udp
dev tap
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 10.8.0.0 255.255.255.0
script-security 2
up /etc/openvpn/server-up.sh
client-connect "/usr/bin/sudo -u root /etc/openvpn/server-clientconnect.sh"
# encrypt all traffic
push "redirect-gateway def1"
# keep the same IP addresses each time
ifconfig-pool-persist ipp.txt
keepalive 10 120
tls-auth ta.key 0
cipher BF-CBC
comp-lzo
# OpenVPN will switch to this user, it is also used for sudo
user vpn
group vpn
persist-key
persist-tun

为了文件的完整性、权限和所有权/etc/openvpn

drwx------  root root  .
-rw-------  root root  ca.crt
-rw-------  root root  dh1024.pem
drwx------  root root  easy-rsa      <-- left from creation of keys
-rw-------  root root  ipp.txt
-rwx------  root root  server-clientconnect.sh
-rw-------  root root  internet.conf
-rw-------  root root  variables
-rwx------  root root  server-up.sh
-rw-------  root root  server.crt
-rw-------  root root  server.key
-rw-------  root root  ta.key
-rwx------  root root  update-resolv-conf <-- this was installed by default

防火墙设置:

itpables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.8.0.0/24 -i tap0 -o eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
ip6tables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -s 2001::db8::abc:0/112 -i tap0 -o eth0 -j ACCEPT

客户端配置

/etc/openvpn/client.conf

client
dev tap
proto udp
remote 178.21.112.251 1194
script-security 2
up /etc/openvpn/client-up.sh
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca ca.crt
cert home.crt
key home.key
ns-cert-type server
tls-auth ta.key 1
cipher BF-CBC
comp-lzo

ta.keyca.key是来自服务器的相同文件。home.keyhome.crt是在服务器上创建的文件。

client-up.sh添加IPv6地址和路由(基于IPv4地址):

#!/bin/sh
pfx='2001:db8::abc'
pfxlen=112
hexippart=`printf '%x' "$(echo $ifconfig_local | cut -d. -f4)"`
/sbin/ip -6 addr add $pfx:$hexippart/$pfxlen dev $dev
/sbin/ip -6 route add default via $pfx:1 dev $dev

指南位于http://www.ipsidixit.net/2010/03/24/239/非常有帮助,OpenVPN 手册页对于有关各种设置的信息很有用。

答案2

上游路由器配置为 2001:db8::100:abc:2 位于直接连接的链路上,设置 net.ipv6.conf.eth0.proxy_ndp = 1 以假装它是。

相关内容