OpenWrt+OpenVPN穿透及公司虚拟私有网关搭建

《OpenWrt+OpenVPN穿透及公司虚拟私有网关搭建》

总结

更多实用的案例参考

http://www.linuxfly.org/post/86/ - 客户端权限组及定制配置 - 服务端客户端内网互通 http://blog.ltns.info/linux/connect_two_home_networks_using_openvpn_and_openwrt/ - 内部DHCP及DNS服务 - 服务端代理客户端证书,客户端只需帐号密码 - 代理 - 安全性

http://www.linuxfly.org/post/84/ - Linux做服务端

http://www.linuxfly.org/post/85/ - Windows做客户端

http://blog.jqian.net/post/openwrt-openvpn.html - OpenWRT 做客户端

FAQ1.无法登陆提示TLS错误

客户端、服务端认证cert文件时间不对称,重新生成即可

FAQ2.只能访问VPN Server,不能访问Server外的设备

通过nat解决 虽然有的资料说通过正确设置路由表并打开ip_forward就可以了,但在我的server上,虽然的确是有net:10.7.0.0/24,gw:10.8.1.2这个路由的(默认就有的),却仍然不能正常工作(除非是我的理解有误,需要的是另外一条路由设置),所以最后还是通过nat解决的(毕竟vpn的ip不属于本地子网,单纯的ip转发应该是没有用的)。

FAQ3.可以VPN到Server,但Server和Client互相ping不通。

OpenWRT特殊情况

## FAQ1:端口转发无效
# 1.添加网络-防火墙-通信规则-打开对应路由端口
# 2.防火墙-端口转发-添加转发规则
# 3.配置成功之后仍然无效:开启openwrt系统路由功能
echo "1" > /proc/sys/net/ipv4/ip_forward
#为了让这个设置重启也好用,我们编辑 /etc/sysctl.conf:
vim /etc/sysctl.conf
#编辑这行:
#net.ipv4.ip_forward=1
#把"#"删了:
net.ipv4.ip_forward=1
# 重启network、firewall,然后重启路由器
/etc/init.d/network restart
/etc/init.d/firewall restart
# 4.转发成功,但只可外网访问,内网被拒绝

## FAQ2:登录vpn后ping不通
# 1.(错误,应该新建一个tun接口,无配置协议,物理并入tun0)OpenWrt看看网络接口,lan口的物理设置,其中应该有个“tap0”,有没有打勾,并入lan
# 2./etc/config/network增加内容
config interface 'tun'
        option ifname 'tun0'
        option proto 'none'
# 3./etc/config/firewall增加内容
config zone
        option name 'tun'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'

config forwarding
        option src 'lan'
        option dest 'tun'
        option mtu_fix '0'

config forwarding
        option src 'tun'
        option dest 'lan'
        option mtu_fix '0'
# (确认不必要)4./etc/firewall.user增加内容
iptables -I INPUT -i tun0 -j ACCEPT
iptables -I OUTPUT -o tun0 -j ACCEPT
iptables -I FORWARD -i tun0 -j ACCEPT
iptables -I FORWARD -o tun0 -j ACCEPT

## FAQ3:(FAQ2中出错了,纯净的环境是不存在这个问题的)openwrt可以ping通10.7.0.1,内网其他设备无法ping通,转发端口无法访问
0.关闭防火墙的“启用SYN-flood防御”
# 1.网络-防火墙-转发规则-添加转发到tun的规则
添加tun 192.168.99.1 22,远程SSH可用
添加tun 192.168.99.181 8001,WEB8001仍然出错
# 2.(未验证)真是原因是内网机器上没有返回给vpn的包导致一直不通,在内网被连接的机器上添加如下路由
route add -net 10.7.0.0/24 gw 192.168.99.1 #linux
route add 10.7.0.0 mask 255.255.0.0 192.168.99.1 #win

详细方案

http://blog.csdn.net/zubin006/article/details/4544684 问题排查 1.客户端版本(系统、软件)问题排查:无 2.客户端conf配置排查:无 3.服务端conf配置排查:无 4.C/A问题:无 5.route路由问题,没有通向vpn内网的转发路由: 解决探索 正常与出错的环境,都拨上VPN,route print一看,社区的机是没有10.7.0.0/24(也就是OpenVPN的子网IP)的路由的。 用ipconfig可以看到,获得的IP是 10.7.0.6,网关是10.7.0.5,于是手动执行:

## Linux或OpenWrt
route add -net 10.0.0.0 netmask 255.0.0.0 gw 10.7.0.5
失败:route: SIOCADDRT: File exists,路由已存在
解决:server.conf少了句 push "route 10.7.0.0 255.255.0.0"
## Windows cmd/powershell 管理员模式
route add 10.0.0.0 mask 255.0.0.0 10.7.0.5

再ping 10.7.0.1,已经通了。服务器与社区设备,互相可以ping通,看起来一切都正常了。   

不过到底为什么会出现这样的问题呢?后来仔细看了一下log,看到这3条: Tue Apr 18 19:07:45 2006 route ADD 10.7.0.0 MASK 255.255.0.0 10.7.0.5 Tue Apr 18 19:07:45 2006 ROUTE: route addition failed using CreateIpForwardEntry: 参数不正确。 [if_index=65541] Tue Apr 18 19:07:45 2006 Route addition via IPAPI failed

显然,OpenVPN是有尝试添加这条路由的,但由于某种原因失败了。

在默认设置下,似乎OpenVPN会自动判断添加路由的时机(可能是 TEST ROUTES: 0/0 succeeded len=1 ret=0 a=0 u/d=down…那几条),然后再添加路由。

这种机制在公司的机可以正常工作,但在社区的机却失败了,在OpenVPN认为已经可以添加路由的时候,实际上系统还没做好准备(我后来写了个批处理,先ipconfig/all然后route print然后再route add,在配置文件中使用route-up这个directive来执行它,然后在log中查看结果。可以看到,即使路由表里已经有10.7.0.x的路由,接下来的route add还是加不进去)。

还好,OpenVPN提供了一个route-delay,用这个directive可以强行指定添加路由前的延时。经过实验,在我这里需要设置成route-delay 10(10秒)才可以添加路由。等待时状态窗口会停在”FlushIpNetTable”的状态,这时也可以自己cmd尝试手工添加路由,同样也会受到系统的拒绝。10秒过后,OpenVPN会添加路由,察看log也可以看到已经不会出错了。

但问题没有解决。用route print,还是没看到那条路由,而如果在配置文件中加多一条route 10.7.0.0 255.255.0.0,可以在log中看到OpenVPN连续执行了两次route add,第一次成功,第二次显示路由已存在。

然后连接完成后,route print还是看不到。真是比较奇怪。 最终方案 在server.conf/server.ovpn添加

# 方法一:管理员模式启动
# 方法二:新增route-method exe
## Fix Windows Can't Ping
route-method exe
# 方法三:服务端写ipp固定ip 10.7.0.8,客户端添加永久路由(固定地址+1:10.7.0.9)
route add 10.0.0.0 mask 255.0.0.0 10.7.0.9

遗憾的是,这里必须把10.7.0.5这个VPN Gateway的IP写进去,而在某些情况下,可能没办法是先确定这个IP。

(补充:后来再读了一下manpage,发现有这个directive: –route-method m Which method m to use for adding routes on Windows? adaptive (default) – Try IP helper API first. If that fails, fall back to the route.exe shell command. ipapi – Use IP helper API. exe – Call the route.exe shell command. 也就是说,可以不用route-up那句,改成route-method exe,效果是一样的,而且更具通用性)   总的来说,对于Openvpn,排除防火墙的因素,问题往往很有可能出在路由上,其次就是nat。配置Openvpn必须要对这两个东西保持清醒才行。

FAQ4.SSH免密码,密钥登录

/etc/dropbear/authorized_keys

一、OpenVPN介绍

OpenVPN

VPN即虚拟子网,用于跨越互联网构建虚拟的局域网,普遍用于公司网络管理、跨域设备管理等场景。 Windows自带的pptp更加简易,而跨平台的openvpn更加通用、安全。

openwrt/luci

openwrt用于智能路由器的嵌入式操作系统,用opkg进行包管理,精简功能完善,带有管理的web端。 luci则深度优化了web管理端,实现了Linux软件的web管理工作。 提供多样的模板luci-theme、应用luci-app及定制的规范。

Openwrt下的OpenVPN

openvpn server 参考:http://www.zhihu.com/question/21751217 openwrt 下有2个openvpn server:一个是openvpn-openssl,另一个是openvpn-polarssl,配置方法是通用的。

openvpn client 参考: http://wiki.openwrt.org/doc/howto/vpn.client.openvpn.tun http://blog.jqian.net/post/openwrt-openvpn.html

软件: - openwrt 开源的路由器固件 - openvpn VPN客户端 - obfsproxy 流量混淆工具 - pdnsd 域名解析服务

opkg update
opkg install openvpn openvpn-easy-rsa

二、OpenVPN Server+Client配置实践

参考: http://www.williamlong.info/archives/3814.html http://www.cnblogs.com/sunzhouyi/archive/2010/08/11/1797088.html

0.环境版本

服务端 - Ubuntu 14.10 - openvpn 2.3.2 - dnsmasq DNS服务器

客户端1 - 硬件版本:newifi mini y1 - 固件版本:newifi/openwrt-ramips-mt7620-Lenovo-y1-squashfs-sysupgrade.bin 链接:http://pan.baidu.com/s/1jG308fG 密码:kncx - Openvpn 2.3.6

客户端2 - 系统:Windows 10 - Openvpn 2.3.6

1.认证机构配置

# vars
set HOME=E:\OpenVPN\easy-rsa

set KEY_COUNTRY=CN
set KEY_PROVINCE=HN
set KEY_CITY=SHAOYANG
set KEY_ORG=ZKKJ
set KEY_EMAIL=info@zkkj168.com
set KEY_CN=ZKKJ
set KEY_NAME=ZKKJ
set KEY_OU=ZKKJ
set PKCS11_MODULE_PATH=ZKKJ
set PKCS11_PIN=1234

# ./build-ca
Common Name (eg, your name or your server's hostname) []:ZKKJ-CA

# build-key-server server
Common Name : server
Password : 空

# build-key clientzk
Common Name : clinetzk/clineths/clientzx/clientnc
Password : 空

服务端配置 server.ovpn/server.conf

server.conf(zkkj)

port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 10.8.0.0 255.255.0.0
push "redirect-gateway def1"
;push "dhcp-option DNS 8.8.8.8"
;push "dhcp-option DNS 8.8.4.4"
ifconfig-pool-persist ipp.txt
duplicate-cn
keepalive 10 120
client-to-client
comp-lzo
comp-noadapt
fragment 1300
mssfix 1300
sndbuf 204800
rcvbuf 204800
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3
server 10.7.0.0 255.255.0.0

#如果可以让VPN Client之间相互访问直接通过openvpn程序转发,
#不用发送到tun或者tap设备后重新转发,优化Client to Client的访问效率
client-to-client

#如果Client使用的CA的Common Name有重复了,或者说客户都使用相同的CA

duplicate-cn

#下面表示每10秒通过VPN的Control通道ping对方,如果连续120秒无法ping通,
#认为连接丢失,并重新启动VPN,重新连接
#(对于mode server模式下的openvpn不会重新连接)。
keepalive 10 120

启动服务端 openvpn –config server.conf

DNS配置

为OpenVPN客户端搭建DNS

这就是为什么我们要安装dnsmasq的原因,打开它的配置文件。

root@delta:/etc/openvpn# nano /etc/dnsmasq.conf

定位到这行:

#listen-address=

把它换成下面这样:

listen-address=127.0.0.1,10.8.0.1

然后定位到这行:

#bind-interfaces

把”#“删了:

bind-interfaces

为了让dnsmasq应用这些更改,我们重启它:

root@delta:/etc/openvpn# service dnsmasq restart

开启Linux路由功能

我们希望在一些机器或虚拟机上运行的OpneVPN有路由的功能,这意味着要开启IP转发。

#为了打开它,我们用root账户键入
echo "1" > /proc/sys/net/ipv4/ip_forward
#为了让这个设置重启也好用,我们编辑 /etc/sysctl.conf:
vim /etc/sysctl.conf

#编辑这行:
#net.ipv4.ip_forward=1
#把"#"删了:
net.ipv4.ip_forward=1

还需要激活一些iptables相关的规则(待测试是否必要):

# eth1为服务器外网网卡名称,10.7.0.0是vpn网段
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.7.0.0/24 -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING -s 10.7.0.0/24 -o eth1 -j MASQUERADE

服务器端防火墙设置加入了以下规则(待测试是否必要):

iptables -I INPUT 1 -p udp --dport 443 -j ACCEPT
iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT
iptables -I INPUT   -i tap0 -j ACCEPT
iptables -I FORWARD -i tap0 -j ACCEPT
iptables -I INPUT   -i br-lan -j ACCEPT
iptables -I FORWARD -i br-lan -j ACCEPT

OpenWrt客户端配置

复制openvpn-zkkj.conf到/etc/openvpn/my-vpn.conf
复制ca.crt client.cert client.key到/etc/openvpn

openvpn-zkkj.conf(zkkj)

client
dev tun
comp-lzo
comp-noadapt
fragment 1300
sndbuf 204800
rcvbuf 204800
verb 3

ca /etc/openvpn/ca.ca
cert /etc/openvpn/client.cert
key /etc/openvpn/client.key


comp-lzo yes
;remote 110.52.103.89
remote vpn.zkkj168.com
;route-gateway 192.168.99.1
;redirect-gateway

开机启动

## 常规方式,系统——启动项——openvpn启动
cp /tmp/etc/openvpn-zkkj.conf /etc/openvpn/my-vpn.conf
登录luci后台,服务——openvpn——custom_config启动打勾

## 制定方式,系统——启动项——自定文本
## start openvpn
/usr/sbin/openvpn --cd /etc/openvpn --config my-vpn.conf --daemon
## end

OpenWRT Ping不通问题

iptables -I FORWARD -o br-lan -j ACCEPT # 允许 br-lan 端口流量被转发
iptables -I FORWARD -o tun0 -j ACCEPT # 允许 tun0 端口流量被转发
iptables -t nat -I POSTROUTING -o tun0 -j MASQUERADE #tun0 出口的流量 SNAT 出去

iptables -I FORWARD -o br-lan -j ACCEPT
iptables -I FORWARD -o tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.99.0/24 -j MASQUERADE

OpenWRT端口映射

1.服务UPNP开启 2.网络——防火墙

ipc1

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5540

IP 192.168.99.50, port 1554 位于 lan



ipc1web

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5580

IP 192.168.99.50, port 80 位于 lan



ipc1ser

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5800

IP 192.168.99.50, port 8000 位于 lan



ipc2rtsp

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5541

IP 192.168.99.51, port 1554 位于 lan



ipc2web

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5581

IP 192.168.99.51, port 80 位于 lan



ipc2ser

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5801

IP 192.168.99.51, port 8000 位于 lan



ipc3

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5542

IP 192.168.99.52, port 1554 位于 lan



ipc3web

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5582

IP 192.168.99.52, port 80 位于 lan



ipc3ser

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5802

IP 192.168.99.52, port 8000 位于 lan



ipc4rtsp

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5543

IP 192.168.99.53, port 1554 位于 lan



ipc4web

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5583

IP 192.168.99.53, port 80 位于 lan



ipc4ser

IPv4-TCP, UDP
来自 所有主机 位于 wan
通过 所有路由地址 at port 5803

IP 192.168.99.53, port 8000 位于 lan