我有两个 VPS,其中一个安装了 OpenVPN Access Server,另一个安装了 vpn 客户端。当我将客户端连接到 OpenVPN AS 时,我无法从其公共 IP 地址访问安装在客户端上的 apache。我希望在客户端服务器上从公共互联网提供一些服务,如 apache 和 postfix,同时为机器上安装的其他服务建立隧道。我该怎么做?
以下是我的/etc/iproute2/rt_tables
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
1 inet
当客户端断开连接时,ip route show
给出:
default via <router_ip> dev <ext_if>
<netw_addr> via <router_ip> dev <ext_if>
<netw_addr> dev <ext_if> proto kernel scope link src <public_ip>
当客户端连接时,ip route show
给出:
0.0.0.0/1 via <private_router_ip> dev <vpn_if>
default via <router_ip> dev <ext_if>
128.0.0.0/1 via <private_router_ip> dev <vpn_if>
<vpn_addr> dev <vpn_if> proto kernel scope link src <private_ip>
<vpn_server_public_ip> via <router_ip> dev <ext_if>
<netw_addr> via <router_ip> dev <ext_if>
<netw_addr> dev <ext_if> proto kernel scope link src <public_ip>
当客户端连接时,ip addr show
给出
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: <ext_if>: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether XX:XX:XX:XX:XX:XX brd ff:ff:ff:ff:ff:ff
inet <public_ip>/<netmask> brd <ext_broadcast_ip> scope global <ext_if>
valid_lft forever preferred_lft forever
inet6 XXXX:XXXX:XXXX:XXXX::XX scope global
valid_lft forever preferred_lft forever
inet6 XXXX::XX:XXXX:XXXX:XXXX/XX scope link
valid_lft forever preferred_lft forever
18: <vpn_if>: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
link/none
inet <private_ip>/<netmask> brd <private_broadcast_ip> scope global <vpn_if>
valid_lft forever preferred_lft forever
答案1
在客户端使用策略路由来执行此操作。
策略路由
通过互联网的策略路由 http 服务(端口 80)的示例:
echo "1 inet" >> /etc/iproute2/rt_tables
将默认路由添加到inet
路由表
ip route add default via <router_ip> dev <if> table inet
<if>
:替换为接口名称,直接连接到互联网(即eth0
)<router_ip>
:替换为 Internet 侧子网中的路由器(网关)的 IP。这是定义为默认网关的路由器,而客户端服务器未通过 VPN 连接。要获取此 IP,请断开/关闭 VPN 客户端并输入:ip route show | grep default
添加路由规则,将标记为的所有内容发送fwmark 0x1
到路由表inet
ip rule add from all fwmark 0x1 table inet
iptables
使用策略路由标记数据包
在表中标记具有端口80
作为目的地的数据包MANGLE
(... --dport 80 ...
对任何其他服务/端口重复该行)。
iptables -t mangle -F
iptables -t mangle -A PREROUTING -i <if> -p tcp --dport 80 -j MARK --set-mark 0x1
iptables -t mangle -A PREROUTING -j CONNMARK --save-mark
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m connmark --mark 0x1 -j MARK --set-mark 0x1
<if>
:替换为接口名称,直接连接到互联网(即eth0
)
这些规则执行以下操作:
- 刷新
mangle
表格(仅需要清除任何先前定义的规则) MARK
外部接口上的传入数据包到特定端口 (80)MARK
将初始数据包(先前的规则)的设置为该连接的所有数据包的CONNMARK
( )的值。conntrack mark
- 恢复链
CONNMARK
中的OUTPUT
。 MARK
OUTPUT
连接所在的链CONNMARK
中的传出数据包0x1
。这MARK
可用于将策略路由中的数据包与 进行匹配fwmark 0x1
。
答案2
我终于解决了我的问题。以下是我的方法。在 OpenVPN Access Server Web 管理设置中,在 VPN 设置的路由部分下,我检查了
不
提问
“客户端互联网流量是否应该通过 VPN 路由?”
然后,我回到客户端并刷新了 mangle 表中添加的所有先前规则。然后,奇迹出现了!我现在能够连接到我的 VPN,而我的 apache 仍然可供公众使用。