网站首页 文章专栏 树莓派搭建docker openvpn以及ipv6隧道
openvpn可以方便地穿越nat,是替代pptp的好工具。但是openvpn也有配置证书的步骤繁多的难点,本文主要介绍几种安装openvpn的方法,以及ipv6 in ipv4的方法(客户端通过openvpn获取ipv6地址并上网)
本文介绍的方法同样适用于x86 amd64设备。
最简单的方法当然是docker,在树莓派中先安装docker,然后下载openvpn的镜像
docker pull giggio/openvpn-arm
OVPN_DATA="/home/wenfeng/ovpn-data"
VPN.SERVERNAME.COM
是你的服务器域名或者ip地址
docker run -v $OVPN_DATA:/etc/openvpn --rm giggio/openvpn-arm ovpn_genconfig -u udp://VPN.SERVERNAME.COM docker run -v $OVPN_DATA:/etc/openvpn --rm -it giggio/openvpn-arm ovpn_initpki nopass
docker run -v $OVPN_DATA:/etc/openvpn -d --name openvpn -p 1194:1194/udp --cap-add=NET_ADMIN giggio/openvpn-arm
CLIENTNAME
是自定义的客户端名称。
docker run -v $OVPN_DATA:/etc/openvpn --rm -it giggio/openvpn-arm easyrsa build-client-full CLIENTNAME nopass
将证书从container中取出
docker run -v $OVPN_DATA:/etc/openvpn --rm giggio/openvpn-arm ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
如果不出意外,openvpn服务端已经搭建起来了
手工安装即不借助docker,在裸机上安装openvpn服务器。可以参考ubuntu安装openvpn的方法,在树莓派上安装openvpn(这篇文章中很多都在讲证书的生成,openvpn的配置倒是很少)。
所以我们可以考虑使用docker openvpn中生成的ca与证书,以及配置文件来启动本地的openvpn server,可以省很多力气。
使用下面的脚本将docker的配置文件放到本地
sudo rm /etc/openvpn sudo ln -s /home/wenfeng/ovpn-data /etc/openvpn
其实就是做了个软连接,配置文件通用。
系统启动时使用sudo systemctl start openvpn@openvpn
的方法,这个@
挺特别,后面跟着自己的配置文件名称(去除后缀)。这意味着我们可以有很多配置文件,通过@setting_name
来选择。
如果出错,建议用sudo /usr/sbin/openvpn --status /run/openvpn/openvpn.status 10 --cd /etc/openvpn --config /etc/openvpn/openvpn.conf
,观察输出log
因为docker container中没有ipv6地址(应该没有),ipv6 in ipv4 只能在裸机上进行。
修改/etc/sysctl.conf
文件
net.ipv4.ip_forward=1 ... net.ipv6.conf.all.forwarding=1 net.ipv6.conf.all.proxy_ndp = 1
注意修改为你自己的ip地址
iptables -t nat -A POSTROUTING -s 10.11.0.0/16 -j SNAT --to 172.16.8.1
服务器端server.conf中的相关配置: # Server mode and client subnets server 10.8.0.0 255.255.255.0 server-ipv6 aaaa:bbbb:cccc:dddd:80::/112 topology subnet # IPv6 routes push "route-ipv6 aaaa:bbbb:cccc:dddd::/64" push "route-ipv6 2000::/3"
修改aaaa:bbbb:cccc:dddd
为你的真实网址前缀。
ipv4包由iptables 进行nat,ipv6包是proxy。 先在客户端查看ipv6地址,然后运行下面命令。
sudo /sbin/ip -6 neigh add proxy aaaa:bbbb:cccc:dddd:80::1002 dev eth0
aaaa:bbbb:cccc:dddd:80::1002
修改为你自己的ip地址,eth0
修改为你自己的网卡。
客户端ping通openvpn服务器网关
ping6 aaaa:bbbb:cccc:dddd:80::1
用curl测试ipv6网站
curl -g -6 https://www.google.com.hk
服务器端server.conf配置
# Run client-specific script on connection and disconnection script-security 2 client-connect "/etc/openvpn/up.sh" client-disconnect "/etc/openvpn/down.sh"
这里的script-security 2
很重要,不设置会出现WARNING: External program may not be called unless '--script-security 2' or higher is enabled.
这里的up.sh
和down.sh
可以在这里找到,但是我试了之后缺少环境变量,所以目前仍是手工设置ipv6 proxy,研究中。
系统一般提示通过journalctl -xe
或者systemctl status
来排错,但是这两项并不能给出有效信息。
server端无法启动服务,又找不到出错信息 启动服务时出现错误:
pi@raspberrypi:~ $ sudo service openvpn@server start Job for openvpn@server.service failed because the control process exited with error code. See "systemctl status openvpn@server.service" and "journalctl -xe" for details.
journalctl -xe
返回的结果
<pre>- The unit openvpn@server.service has entered the 'failed' state with result 'exit-code'. Jul 26 17:27:15 raspberrypi systemd[1]: <font color="#EF2929"><b>Failed to start OpenVPN connection to server.</b></font> -- Subject: A start job for unit openvpn@server.service has failed </pre>
systemctl status openvpn@server.service
返回的结果,都没有有效的错误信息,只是告诉你出错了。
● openvpn@server.service - OpenVPN connection to server Loaded: loaded (/lib/systemd/system/openvpn@.service; disabled; vendor preset: enabled) Active: activating (auto-restart) (Result: exit-code) since Fri 2019-07-26 17:28:21 CST; 509ms ago Docs: man:openvpn(8) https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage https://community.openvpn.net/openvpn/wiki/HOWTO Process: 13082 ExecStart=/usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openv Main PID: 13082 (code=exited, status=1/FAILURE)
所以我想可以将后台程序变成前台方式,来查看log排错。
将下面命令中的--config
换为自己的配置文件即可
sudo /usr/sbin/openvpn --status /run/openvpn/openvpn.status 10 --cd /etc/openvpn --config /etc/openvpn/openvpn.conf
发现在./build-ca
时报错
no such openssl.cnf
查看脚本发现,easy-rsa自己带了三个不同版本的openssl.cnf,唯独没有系统中的1.1.0版本的,无奈打算将树莓派的openssl降级到1.0.0
使用apt-cache madison openssl
发现没有低版本的,只能自己手动编译。
树莓派编译openssl, 源码下载地址下载地址
现象: 客户端正常连接服务端,并且两者互相可以ping通,客户端甚至可以请求服务端自己的http服务数据,但就是无法请求其他数据,例如www.baidu.com
测试1: 使用下面的命令请求数据:
curl www.baidu.com --interface tun0
会在很长时间后显示time out
测试2: 使用下面的命令ping外网主机
ping 220.181.38.149 -I tun0
没有响应,100% loss
用下面的命令对tun0抓包(客户端运行)
sudo tcpdump -v -i tun0
抓包结果如下:
22:28:14.638190 IP (tos 0x0, ttl 64, id 35007, offset 0, flags [DF], proto ICMP (1), length 84) 10.8.0.6 > 220.181.38.149: ICMP echo request, id 18716, seq 1, length 64 22:28:14.645933 IP (tos 0x0, ttl 52, id 35007, offset 0, flags [DF], proto ICMP (1), length 84) 220.181.38.149 > 10.8.0.6: ICMP echo reply, id 18716, seq 1, length 64 22:28:15.643038 IP (tos 0x0, ttl 64, id 35227, offset 0, flags [DF], proto ICMP (1), length 84) 10.8.0.6 > 220.181.38.149: ICMP echo request, id 18716, seq 2, length 64 22:28:15.650823 IP (tos 0x0, ttl 52, id 35227, offset 0, flags [DF], proto ICMP (1), length 84) 220.181.38.149 > 10.8.0.6: ICMP echo reply, id 18716, seq 2, length 64 22:28:16.667028 IP (tos 0x0, ttl 64, id 35436, offset 0, flags [DF], proto ICMP (1), length 84) 10.8.0.6 > 220.181.38.149: ICMP echo request, id 18716, seq 3, length 64 22:28:16.677797 IP (tos 0x0, ttl 52, id 35436, offset 0, flags [DF], proto ICMP (1), length 84) 220.181.38.149 > 10.8.0.6: ICMP echo reply, id 18716, seq 3, length 64 22:28:17.691232 IP (tos 0x0, ttl 64, id 35689, offset 0, flags [DF], proto ICMP (1), length 84) 10.8.0.6 > 220.181.38.149: ICMP echo request, id 18716, seq 4, length 64 22:28:17.701566 IP (tos 0x0, ttl 52, id 35689, offset 0, flags [DF], proto ICMP (1), length 84) 220.181.38.149 > 10.8.0.6: ICMP echo reply, id 18716, seq 4, length 64 22:28:18.715232 IP (tos 0x0, ttl 64, id 35725, offset 0, flags [DF], proto ICMP (1), length 84) 10.8.0.6 > 220.181.38.149: ICMP echo request, id 18716, seq 5, length 64 22:28:18.723667 IP (tos 0x0, ttl 52, id 35725, offset 0, flags [DF], proto ICMP (1), length 84) 220.181.38.149 > 10.8.0.6: ICMP echo reply, id 18716, seq 5, length 64 22:28:19.716722 IP (tos 0x0, ttl 64, id 35833, offset 0, flags [DF], proto ICMP (1), length 84) 10.8.0.6 > 220.181.38.149: ICMP echo request, id 18716, seq 6, length 64 22:28:19.731483 IP (tos 0x0, ttl 52, id 35833, offset 0, flags [DF], proto ICMP (1), length 84) 220.181.38.149 > 10.8.0.6: ICMP echo reply, id 18716, seq 6, length 64
可知对方主机正常响应,openvpn服务器正常,但是客户端主机自己不正常,无法将网络层的数据反馈到应用层。怀疑是iptables有误,全部清空后错误照常。
使用命令ip route show
查看网关
修改前的网关
default via 10.135.0.1 dev wlp4s0b1 proto static metric 600 10.8.0.1 via 10.8.0.5 dev tun0 10.8.0.5 dev tun0 proto kernel scope link src 10.8.0.6 10.134.118.131 via 10.135.0.1 dev wlp4s0b1 src 10.135.80.126 10.135.0.0/16 dev wlp4s0b1 proto kernel scope link src 10.135.80.126 metric 600 169.254.0.0/16 dev wlp4s0b1 scope link metric 1000 192.168.19.0/24 dev enp3s0 proto kernel scope link src 192.168.19.1 metric 100 192.168.194.0/24 dev ztyourshd4 scope link 192.168.194.0/24 dev ztyourshd4 proto kernel scope link src 192.168.194.5
查看tun0配置 ifconfig
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:10.8.0.6 P-t-P:10.8.0.5 Mask:255.255.255.255 inet6 addr: fe80::15d6:6be6:afbd:cb5/64 Scope:Link UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:625 errors:0 dropped:0 overruns:0 frame:0 TX packets:3293 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:114339 (114.3 KB) TX bytes:445127 (445.1 KB)
新增网关
sudo route add default gw 10.8.0.5
这里不能用10.8.0.1
做网关,如果添加该地址为网关,会有如下错误:
SIOCADDRT: Network is unreachable
(可选)如果域名服务不正常,需要手动更改
修改这个文件即改即用
vim /etc/resolv.conf cat /etc/resolv.conf
修改后
nameserver 8.8.8.8
参考https://blog.csdn.net/u012732259/article/details/76502231
设置好默认网关后,ping正常,网络访问正常。