首页 > Linux, OpenWrt > 通过OpenWrt路由器和OpenVPN实现两地局域网互联

通过OpenWrt路由器和OpenVPN实现两地局域网互联

2015年3月7日 LTNS     访问次数 381 发表评论 阅读评论

之前一直 通过Tomato路由器和OpenVPN实现两地局域网互联 [以下简称 前文],现在两地的路由器已换成(或只有一个路由器换) OpenWrt固件,于是继续通过 OpenVPNOpenWrt 路由器实现两地局域网互联。

拓扑示意图如下

出于安全性和可管理性,根据 OpenVPN官网的HOWTO,决定采用 tun方式,除了 VPN主网段(10.8.1.0/24),还设置了一个 10.8.2.0/24的 VPN网段,以便通过 iptables命令实现不同的访问权限。

 
准备条件:
1. 路由器刷 OpenWrt BB 14.07固件,或者 Gargoyle(OpenWrt 的web前端之一)1.7.x固件;
2. OpenVPN相关证书的制作请参考 OpenWrt Wiki;另外,通过 OpenWrt trunk 里的 luci-app-openvpn程序,或者 Gargoyle固件 的 openvpn web管理插件也可以制作相关证书;
3. 分别在 A路由器和 B路由器上设置好上网功能,同时 A路由器还需要启用 DDNS动态域名(比如 xxx.3322.org,以便接受来自外网的 VPN客户端的访问)和 SSH Server,详请自行网上搜索,本文只涉及 OpenVPN相关的配置。

 
A路由器 VPN Server端的设置

通过比如 Putty 软件登录路由器后,安装 openvpn

opkg update
opkg install openvpn-openssl openvpn-easy-rsa
/etc/init.d/openvpn enable     #设置随路由器开机自启动
ln -s /usr/sbin/openvpn /etc/openvpn/ovpnsvrtun   #创建一个软链接文件

虽然 OpenWrt trunk 版本里有 luci-app-openvpn,Gargoyle固件 也提供了 openvpn的web管理插件,但试用下来感觉都不是很方便(比如GUI界面可供选择的参数不够全,可自定义的配置只能一个,等等),于是决定还是手工配置。

通过比如 WinSCP 软件登录路由器,新建一个服务端配置文件,比如 /etc/openvpn/svrtun.conf

daemon
dev tun21     #tun设备编号可自定义
port 1194     #端口号可自定义
proto udp     #建议使用udp协议
server 10.8.1.0 255.255.255.0     #VPN主网段
comp-lzo yes
keepalive 10 60
verb 3
ca /etc/openvpn/ca.crt     #相关证书需上传至相应的目录下
dh /etc/openvpn/dh1024.pem
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key

ifconfig-pool-persist /etc/openvpn/ipp.txt     #记录客户端虚拟ip地址
ccd-exclusive
client-config-dir /etc/openvpn/ccd     #客户配置文件目录
status-version 2
status status

# Custom Configuration
push "route 192.168.1.0 255.255.255.0"     #把A路由器内网的路由推送给VPN客户端

# 把两条客户端网段的路由告知服务端,默认已有 10.8.1.0的所以无需再指定了
route 10.8.2.0 255.255.255.0
route 192.168.2.0 255.255.255.0

# 如下三行启用客户端相互可见功能和相关的路由
#push "route 10.8.2.0 255.255.255.0"
#push "route 192.168.2.0 255.255.255.0"
#client-to-client

注:各项参数的说明详请见 OpenVPN官网

然后在自定义防火墙文件 /etc/firewall.user 中添加如下四行内容

iptables -I INPUT 1 -p udp --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun21 -s 10.8.1.0/24 -d 192.168.1.0/24 -j ACCEPT
iptables -A FORWARD -i tun21 -s 10.8.2.0/24 -d 192.168.1.0/24 -j ACCEPT
iptables -A FORWARD -i tun21 -s 192.168.2.0/24 -d 192.168.1.0/24 -j ACCEPT

#如果OpenWrt/Gargoyle固件默认禁止了跨网段访问,则需要增加一行
#iptables -A FORWARD -o tun21 -s 192.168.1.0/24 -j ACCEPT

注:这里的设置允许两个 VPN网段和 B路由器内网访问 A路由器内网,请根据实际情况自行修改访问权限。另,修改完成后须执行命令 /etc/init.d/firewall restart 以重启防火墙

针对 client这个客户端(即,B路由器),还要创建对应的配置文件 /etc/openvpn/ccd/client(文件名必须和客户端证书名一致),内容如下

ifconfig-push 10.8.1.5 10.8.1.6     #指定虚拟ip地址为 10.8.1.5
iroute 192.168.2.0 255.255.255.0    #B路由器向 VPN主网段通告自己内网的路由

 
同样的,还可以创建 /etc/openvpn/ccd/client2

ifconfig-push 10.8.2.1 10.8.2.2

 
最后修改启动脚本 /etc/init.d/openvpn 末尾的 start_service函数的内容

start_service() {
#	config_load 'openvpn'
#	config_foreach start_instance 'openvpn'
#注释掉如上两行并添加如下的一行
/etc/openvpn/ovpnsvrtun --syslog "openvpn(svrtun)" --cd /etc/openvpn --config svrtun.conf &
}

注:修改完成后须执行命令 /etc/init.d/openvpn start 以启动 openvpn服务

 

B路由器 VPN Client端的设置

同样需要安装 openvpn

opkg update
opkg install openvpn-openssl openvpn-easy-rsa
/etc/init.d/openvpn enable
ln -s /usr/sbin/openvpn /etc/openvpn/ovpnclient

新建一个客户端配置文件,比如 /etc/openvpn/client.conf,内容如下

daemon
client     #这个不能改,不是client客户端证书名
dev tun11
proto udp
remote xxx.3322.org 1194
resolv-retry 30
nobind
persist-key
persist-tun
comp-lzo yes
verb 3
ca /etc/openvpn/ca.crt     #相关证书需上传至相应的目录下
cert /etc/openvpn/client.crt
key /etc/openvpn/client.key
status-version 2
status status

 
然后在自定义防火墙文件 /etc/firewall.user 中添加如下二行内容

iptables -A FORWARD -i tun11 -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT
#iptables -I INPUT -i tun11 -s 192.168.1.0/24 -j ACCEPT   #允许A路由器内网访问B路由器本身

#如果OpenWrt/Gargoyle固件默认禁止了跨网段访问,则需要增加一行
#iptables -A FORWARD -o tun11 -s 192.168.2.0/24 -j ACCEPT

注:修改完成后须执行命令 /etc/init.d/firewall restart 以重启防火墙

还要修改启动脚本 /etc/init.d/openvpn 末尾的 start_service函数的内容

start_service() {
#	config_load 'openvpn'
#	config_foreach start_instance 'openvpn'
/etc/openvpn/ovpnclient --syslog "openvpn(client)" --cd /etc/openvpn --config client.conf &
}

注:修改完成后须执行命令 /etc/init.d/openvpn start 以启动 openvpn服务

 
这时 B路由器作为 VPN客户端就会自动登录 A路由器(VPN服务端),这样就实现了 A、B这两个路由器内网的互访了。另外,VPN客户端 client2通过移动互联网登录 VPN服务端,可获取 10.8.2.1这个ip地址并可访问 A路由器的内网(192.168.1.0/24)。

顺便提一下,通过 OpenVPN 还可以让 Tomato路由器和 OpenWrt路由器互联,Tomato的相关设置(无论是配置为服务端还是客户端)可参考 前文

 

补充1:
如果想要让不同 VPN网段的客户端相互访问,比如允许 10.8.2.1访问 192.168.2.0/24,除了需要在 VPN Server端的配置中启用 client-to-client及相关路由(见前述内容),还需要在 B路由器的防火墙中添加

iptables -A FORWARD -i tun11 -s 10.8.2.0/24 -d 192.168.2.0/24 -j ACCEPT

 
然后重启两个路由器即可。

 

补充2:
参考 TomatoVPN作者的 脚本,可分别在 A路由器和 B路由器上新建一个检查用脚本(防止 openvpn进程意外被杀),比如 /root/ovpnup.sh

#!/bin/sh
killall -0 ovpn$1 2> /dev/null
if [ $? != 0 ]
then
	logger \"$0: Starting ovpn$1\"
	/etc/openvpn/ovpn$1 --syslog "openvpn($1)" --cd /etc/openvpn --config $1.conf &
else
	logger \"$0: ovpn$1 already running: $(pidof ovpn$1)\"
fi

注:新建后需执行 chmod +x /root/ovpnup.sh,以添加可执行属性。

然后把该脚本添加到定时任务 /etc/crontabs/root

4 */2 * * * /root/ovpnup.sh svrtun     #每两小时检查一次,针对A路由器

#针对B路由器则需改成如下一行
4 */2 * * * /root/ovpnup.sh client

 
 

补充3:
可以添加更多的 VPN配置,比如在 A路由器上新建一个 bridge模式(相比tun设备的route模式,安全性差一点但更方便) VPN Server的配置文件 /etc/openvpn/svrtap.conf

daemon
dev tap11     #需在A路由器的LAN网络设置里绑定 tap11设备,以使桥接生效
port 1194
proto tcp
server-bridge 192.168.1.1 255.255.255.0 192.168.1.101 192.168.1.105   #和A路由器内网桥接,ip地址池范围101~105要避免跟A路由器的DHCP Server冲突

comp-lzo yes
keepalive 10 60
verb 3
ca /etc/openvpn/ca.crt
dh /etc/openvpn/dh.pem
cert /etc/openvpn/svr.crt
key /etc/openvpn/svr.key

ifconfig-pool-persist /etc/openvpn/ipp.txt
ccd-exclusive
client-config-dir /etc/openvpn/ccd
client-to-client

status-version 2
status status 
# Custom Configuration

注:对应的 VPN客户端(比如安装了 openvpn-2.0.9-gui-1.0.3 的WinXP笔记本电脑)可用如下配置

client
dev tap
proto tcp
remote xxx.3322.org 1194
ca ca.crt
cert client2.crt
key client2.key
resolv-retry infinite
nobind
mute-replay-warnings
comp-lzo
verb 4

 
然后在 A路由器上创建一个软链接文件

ln -s /usr/sbin/openvpn /etc/openvpn/ovpnsvrtap

修改启动脚本 /etc/init.d/openvpn 末尾的 start_service函数的内容

start_service() {
#	config_load 'openvpn'
#	config_foreach start_instance 'openvpn'
/etc/openvpn/ovpnsvrtun --syslog "openvpn(svrtun)" --cd /etc/openvpn --config svrtun.conf &

/etc/openvpn/ovpnsvrtap --syslog "openvpn(svrtap)" --cd /etc/openvpn --config svrtap.conf &
}

 
还要在 A路由器的防火墙里添加一行

iptables -I INPUT 1 -p tcp --dport 1194 -j ACCEPT

 
最后在定时任务 /etc/crontabs/root 中添加一行

...
5 */2 * * * /root/ovpnup.sh svrtap

 
完成后重启路由器A,至此,安装了 openvpn-2.0.9-gui-1.0.3 的WinXP笔记本电脑就可以登录VPN服务端,获取地址 192.168.1.101并可访问 A路由器的内网了。

 

 

参考文章
http://bbs.chinaunix.net/thread-830695-1-1.html

 

分类: Linux, OpenWrt 标签: , , , , ,
  1. amoboy
    2015年6月4日21:59 | #1

    大大,我几乎按照您的教程做了一遍,但是不知道为什么,连接上一直出错.
    read UDPv4: Connection reset by peer (WSAECONNRESET) (code=10054)
    一直是这个错误,好像是说有防火墙..不知道为什么?

    iptables -I INPUT 1 -p udp –dport 1194 -j ACCEPT
    是不是这行有问题,我看input 后面是1…?

  2. amoboy
    2015年6月4日22:42 | #2

    Thu Jun 04 22:41:37 2015 OpenVPN 2.3.6 x86_64-w64-mingw32 [SSL (OpenSSL)] [LZO] [PKCS11] [IPv6] built on Mar 19 2015
    Thu Jun 04 22:41:37 2015 library versions: OpenSSL 1.0.1m 19 Mar 2015, LZO 2.08
    Enter Management Password:
    Thu Jun 04 22:41:37 2015 MANAGEMENT: TCP Socket listening on [AF_INET]127.0.0.1:25342
    Thu Jun 04 22:41:37 2015 Need hold release from management interface, waiting...
    Thu Jun 04 22:41:37 2015 MANAGEMENT: Client connected from [AF_INET]127.0.0.1:25342
    Thu Jun 04 22:41:37 2015 MANAGEMENT: CMD 'state on'
    Thu Jun 04 22:41:37 2015 MANAGEMENT: CMD 'log all on'
    Thu Jun 04 22:41:37 2015 MANAGEMENT: CMD 'hold off'
    Thu Jun 04 22:41:37 2015 MANAGEMENT: CMD 'hold release'
    Thu Jun 04 22:41:38 2015 Socket Buffers: R=[65536->65536] S=[65536->65536]
    Thu Jun 04 22:41:38 2015 MANAGEMENT: >STATE:1433428898,RESOLVE,,,
    Thu Jun 04 22:41:38 2015 Attempting to establish TCP connection with [AF_INET]121.204.185.26:21194 [nonblock]
    Thu Jun 04 22:41:38 2015 MANAGEMENT: >STATE:1433428898,TCP_CONNECT,,,
    Thu Jun 04 22:41:48 2015 TCP: connect to [AF_INET]121.204.185.26:21194 failed, will try again in 5 seconds: 系统试图将驱动器合并到合并驱动器上的目录。
    Thu Jun 04 22:41:53 2015 MANAGEMENT: >STATE:1433428913,RESOLVE,,,
    Thu Jun 04 22:41:53 2015 MANAGEMENT: >STATE:1433428913,TCP_CONNECT,,

  3. amoboy
    2015年6月4日22:42 | #3

    改成tcp连接,关掉客户端的防火墙变成这样...@amoboy

  4. Niclau
    2015年8月16日13:35 | #4

    我让B路由器(client端10.168.1.6,没公网IP,移动宽带)连接A路由器(server端10.168.1.1)。现在B路由能ping通A,也能访问A的ssh(使用10.168.1.1来访问),但A不能ping通B,也不能连接B的ssh。这是我的设置问题,还是openvpn没有这样的功能?我的目的让B做中转然后连接海外vps。

  5. Niclau
    2015年8月16日20:26 | #5

    @Niclau
    可以了,已成功。

  6. Carson
    2015年9月14日13:51 | #6

    楼主,我的做法和你差不多,但是不知道为什么,client如果是linux系统,服务端就不能访问客户端路由

  7. 焓冰
    2015年12月20日14:52 | #7

    博主 ,你好,最近刚玩openwrt 看了你这篇帖子 也想像你这样的vpn网,但有些不明白的地方想请教你,能否加我qq,虚心像您请教,我电子邮箱留的就是我的qq 麻烦你了

  8. LTNS
    2015年12月22日12:49 | #8

    @焓冰
    有什么问题这里留言吧,最近比较忙,很少用qq

  9. jimo
    2016年7月1日05:37 | #9

    ifconfig-push 10.8.1.5 10.8.1.6 #指定虚拟ip地址为 10.8.1.5
    iroute 192.168.2.0 255.255.255.0 #B路由器向 VPN主网段通告自己内网的路由

    博主,如果我想让B路由动态分配到ip地址,而不是固定,上面2行怎么修改?

  10. LTNS
    2016年7月20日16:33 | #10

    @jimo
    我没试过,不过可以参考官网wiki
    https://community.openvpn.net/openvpn/wiki/Concepts-Addressing

    比如在A路由器的配置文件 /etc/openvpn/svrtun.conf 里添加如下一行
    --ifconfig-pool 10.8.1.100 10.8.1.199

    而且 /etc/openvpn/ccd/ 目录下不能有对应客户端证书名的文件(或者文件里不要有 ifconfig-push 这一行),这样,VPN服务端应该就会用上面的ip池来给该客户端动态分配ip了

  11. 88922
    2016年8月30日09:37 | #11

    我想让openvpn管理更多的路由器,LAN的ip与掩码该怎么规划?

    本来以为只能管理10.8.1.0/24 下面的60多个路由器(192.168.X.0/24). 后来再回来看你的教程,每个10.8.X.0下面可以有60多个路由器,也就是说这种配法,共能连接约254*60个路由器。那么对应的LAN 的ip应该怎么规划?(我原来用的是192.168.x.0/24这种,最多只能有254个LAN。 怎么才能更多一些,比如说管理1000个路由器(每个路由器下面最多只有10个ip)。lan之间不交换数据。只是用openvpn来管理路由器而已)

  12. LTNS
    2016年8月31日02:15 | #12

    @88922
    理论上 OpenVPN 可以连接254*60多个路由器(用 A类私有ip应该还可以连接更多,比如254*254*60多个),为了避免这些路由器的LAN IP冲突,除了你提到的C类私有ip(192.168.0.0/16),还可以用A类(10.0.0.0/8)和B类(172.16.0.0/12),当然要避开 OpenVPN 已占用的网段。

    另外,如果其中的某些路由器无需内网之间互访(只需远程访问管理路由器本身)的话,那么它们的LAN IP网段设置成一样也无所谓,反正通过 OpenVPN 分配的ip地址就可以远程管理路由器了。

  1. 2017年4月22日21:58 | #1
32 / 8 = (必填)