云服务器组建公司和家庭局域网
前言
最近不满足frp的内网映射,因为frp只能单独的将某个端口映射出来,需要多个端口就需要映射多个,很是麻烦,所以研究了一下open组建,从晚上9点一直研究到凌晨4点愣是没研究透彻,只能做到客户端和客户端之间的通行,无法在一个客户端访问另一个客户端内网的其他机器,第二天不甘心,又研究了大半天,终于研究透彻了,核心概念就是路由需要配置好,需要理解了路由的走向,才能正确配置,下面记录一下
组建条件
- 家庭V客户端,以下统称C1
- 云服务器V服务端,以下统称S
- 公司内网服务器,以下统称C2
脚本
openVPN 手工搭建非常复锁,所以可以采用脚本快速搭建,以下推荐两个脚本
脚本1下载地址
脚本2下载地址(推荐)
安装
1 | #下载 |
或者clone代码
1 | #下载 |
安装过程如下
安装完再次运行脚本,可选择
- 添加用户
- 移除已存在的用户
- 卸载软件
- 退出
启动服务(默认已经启动)
1 | sudo systemctl start openvpn-server@server.service |
客户端下载
开放端口
如果用的云服务器,记得放行默认进出端口1194,如果更改了端口,就开放更改后的端口
以上配置完成后,打开客户端导入配置即可开始用了
优化
服务端配置需要进行一些修改,因为默认全部流量走VPN,但是我们一般不需要所有流量走VPN,只需要内网IP就可以,所以需要分流,再服务端配置即可
1 | # 配置文件位置 |
修改完服务端配置后,重启服务端和客户端
注意点
服务端开启路由转发
1
2
3
4
5sysctl -a | grep forward
#显示结果如下:net.ipv4.ip_forward的值为1则表示路由转发功能开启
net.ipv4.ip_forward = 1C2客户端开启路由转发(如果是linux则开启方法同上,如果是windows)
1
2
3
4#1、 需要修改注册表 将以下值设为1
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRoute
#2、将Routing and Remote Access 服务的启动类型更改为自动并启动服务至此,客户端之间已经可以相互访问了,并且不仅可以访问10.8开头的虚拟专用网IP,也可以访问C2客户端所在内网的IP,比如C2内网IP 192.168.1.3,但是还无法访问C2所在内网的其他机器,还需要再C2所在内网的路上配置一下静态路由
1
2
3
4
5
6
7目标地址:10.8.0.0
子网掩码 :255.255.255.0
下一跳(网关):192.168.1.3(C2机器内网IP)
出口:LAN
经过以上配置后,C1就完全可以访问C2机器以及C2机器所在的内网,同理,如果想双网互通,比如C2访问C1所在内网,也是同样的配置一下即可
其他
1 | #以下配置是服务段未作路由的情况下,让10.8网段的IP走VPN,其他不走VPN |
1 | # windows查看路由 |
路由详解(由此启发)
理解 VPN 路由(以及任何网络路由)配置的关键是认识到一个 IP packet 如何被传输,以下描述的是极度简化后的单向传输过程:
- 机器 A (
192.168.0.2
) 发送了一个目标地址为172.29.1.4
的 IP packet. - 根据本地路由规则,
172.29.1.0/24
的下一跳是虚拟网卡 tun0, 由 VPN 客户端接管。 - VPN 客户端将这个 packet 的来源地址从
192.168.0.2
改为10.8.0.123
, 转发给 VPN 服务端。 - VPN 服务端收到 packet. 根据本地路由规则,
172.29.1.0/24
的下一跳是默认网关172.29.0.1
. - 默认网关找到在同一个局域网内的机器 B (
172.29.1.4
).
客户端 -> 内网
为什么机器 A 的本地路由表里会有 172.29.1.0/24
这个网段的路由规则?通常情况下,这是 VPN 服务端推送给客户端,由客户端在建立 VPN 连接时自动添加的。例如 push "route 172.30.0.0 255.255.0.0"
的作用就是将 172.30.0.0/16
网段的路由推送给客户端。
内网 -> 客户端
这个时候,如果机器 B 想要回复 A(比如发个 ACK),就会出问题,因为 packet 的来源地址还是 10.8.0.123
, 而 10.8.0.0/24
网段并不属于当前局域网,是 VPN 服务端私有的——机器 B 往 10.8.0.123
发送的 ACK 会在某个位置(比如默认网关)遇到 “host unreachable” 而被丢弃。对于机器 A 来说,表面现象可能是连接超时或 ping 不通。
解决方法是,在 packet 离开 VPN 服务端时,将其「伪装」成来自 172.29.0.3
(VPN 服务端的局域网地址),这样机器 B 发送的 ACK 就能顺利回到 VPN 服务端,然后发给机器 A. 这就是所谓的 SNAT, 在 Linux 系统中由 iptables 来管理,具体命令是:iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
.
客户端 -> 另一个客户端的内网
连接 OpenVPN 的两个 client 之间可以互相通信,这是因为服务端推送的路由里包含了对应的网段。但是想从 Client A 到达 Client B 所在局域网的其他机器,还需要额外的配置。因为 OpenVPN 服务端缺少 Client B 局域网相关的路由规则。
配置示例:
1 | # server.conf |
内网与内网互访
在前两节所给的配置基础上,只需要再加一点配置,就能实现 OpenVPN 服务端所在局域网与客户端所在局域网的互访。配置内容是,在各自局域网的默认网关上添加路由,将对方局域网网段的下一跳设为 OpenVPN 服务端 / 客户端所在机器,同时用 iptables 配置相应的 SNAT 规则。
例如:
- Cluster A 的路由表里添加
172.31.0.0/16
, 下一跳为172.30.0.16
(cluster-a-relay). - Cluster B 路由表里添加
172.30.0.0/16
, 下一跳为172.31.1.2
(cluster-b-relay).
延伸
本文的配置适合大部分场景,因为公司没有公网IP,所以配置略繁琐,如果公司有公网Ip,那就省去了云服务器,直接将服务端部署在服务器上,配置转发路由即可,速度提升的同时,配置也会比较简单
还有一种是ipspec的V服务,配置也很简单,重点是windows本身支持,不需要下载客户端,连接比较方便,这种的适合我刚才说的服务端部署在公司内网,且有公网Ip,安装方式参考
注意
server.conf每次安装里面的证书名称是随机的,所以如果之前备份的记住不要直接覆盖,把需要的替换进去就行