远程 SSH 登录不起作用

远程 SSH 登录不起作用

我有一台电脑在路由器后面,端口转发设置为 SSH 端口 22,运行完美 - 我可以登录和执行所有操作。我想做的是让这台电脑连接到 VPN,并且只允许本地网络或通过 VPN 连接(用于互联网访问)的流量。这也很有效。一旦 VPN 连接断开,PC 就无法连接到互联网。现在我正在使用 IPTABLES 执行此操作,问题是我似乎无法通过路由器端口转发从外部源获取传入的 SSH。我可以从本地网络内通过 SSH 连接到电脑。

这是我尝试过的:

# Allow traffic to VPN SERVER
sudo iptables -A INPUT -s $REMOTE_IP -j ACCEPT

# Allow ssh traffic
iptables -A INPUT -i eth1 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT    
iptables -A OUTPUT -o eth1 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

# Allow local traffic.
sudo iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT
sudo iptables -A INPUT -s 172.16.0.0/12 -j ACCEPT
sudo iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT

# Disallow everything else.
sudo iptables -A INPUT ! -i tun+ -j DROP

# Allow traffic from VPN SERVER.
sudo iptables -A OUTPUT -d $REMOTE_IP -j ACCEPT

# Allow local traffic.
sudo iptables -A OUTPUT -d 10.0.0.0/8 -j ACCEPT
sudo iptables -A OUTPUT -d 172.16.0.0/12 -j ACCEPT
sudo iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT

# Disallow everything else.
sudo iptables -A OUTPUT ! -o tun+ -j DROP

sudo openvpn --config client.cfg --auth-user-pass client.cred --daemon

这是我的 iptables -vL -n 输出:(用 XX.XX.XX.XX 替换 vpn 服务器)

Chain INPUT (policy ACCEPT 25674 packets, 4792K bytes)
 pkts bytes target     prot opt in     out     source               destination         
78848   11M ACCEPT     all  --  *      *       XXX.XXX.XXX.XXX      0.0.0.0/0           
 3176  318K ACCEPT     tcp  --  eth1   *       0.0.0.0/0            0.0.0.0/0           tcp dpt:22 state NEW,ESTABLISHED 
    0     0 ACCEPT     all  --  *      *       10.0.0.0/8           0.0.0.0/0           
    0     0 ACCEPT     all  --  *      *       172.16.0.0/12        0.0.0.0/0           
 2517  231K ACCEPT     all  --  *      *       192.168.0.0/16       0.0.0.0/0           
   35 12374 DROP       all  --  !tun+  *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 32187 packets, 4374K bytes)
 pkts bytes target     prot opt in     out     source               destination         
 3681 2443K ACCEPT     tcp  --  *      eth1    0.0.0.0/0            0.0.0.0/0           tcp spt:22 state ESTABLISHED 
70697   10M ACCEPT     all  --  *      *       0.0.0.0/0            XXX.XXX.XXX.XXX      
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            10.0.0.0/8          
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            172.16.0.0/12       
   27  5787 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.0.0/16      
 2265  150K DROP       all  --  *      !tun+   0.0.0.0/0            0.0.0.0/0

是的,如果我执行 ifconfig,我只有 eth1 而不是 eth0,所以事实并非如此。

这也是 netstat -rn 的输出

Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         XX.XXX.242.128  128.0.0.0       UG        0 0          0 tun0
0.0.0.0         192.168.1.1     0.0.0.0         UG        0 0          0 eth1
XX.XXX.193.107  192.168.1.1     255.255.255.255 UGH       0 0          0 eth1
XX.XXX.242.0    0.0.0.0         255.255.255.0   U         0 0          0 tun0
128.0.0.0       XX.XXX.242.128  128.0.0.0       UG        0 0          0 tun0
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth1

答案1

正如 penguin359 正确所说,问题在于返回数据包将通过 VPN 路由,而不是通过本地路由器(传入连接来自本地路由器)。路由器上的 SNAT 是一种解决方案,但如果这不可行,您可以在 PC 上使用高级路由。

除了现有的 iptables 规则之外,您还需要添加这些高级路由规则:

ip rule add from 192.168.1.X table 128
ip route add table 128 to 192.168.1.0/24 dev eth1
ip route add table 128 default via 192.168.1.1

将 192.168.1.X 替换为您 PC 的 LAN IP 地址。 192.168.1.1 是 LAN 的路由器,192.168.1.0/24 是 LAN 的子网。

第一个命令创建一条规则,使源地址为 192.168.1.X 的任何数据包都使用特殊路由表其中编号为 128。接下来的两个命令创建路由表 128,其中默认网关是您的路由器(而不是主路由表中的 VPN 服务器)。

源地址为 192.168.1.X 的唯一数据包将是响应来自路由器的传入连接的数据包(即端口转发的 SSH 连接)和发往 LAN 的数据包。这些正是您不希望使用 VPN 的数据包。所有其他传出数据包将具有不同的源地址,并将使用通过 VPN 路由它们的主路由表。

答案2

澄清一下,当 VPN 运行时,来自外部源的 SSH 被破坏,但在运行 VPN 之前,来自所有源的 SSH 都正常工作。问题归结于路由表。如上所示,默认路由 ( 0.0.0.0) 将前往tun0。我不明白 的有趣网络掩码有什么用128.0.0.0,但这会导致任何以 1-126 开头的外部地址使用tun0。对于 SSH,传入数据包来自何处并不重要,传出数据包只会从路由表中匹配的位置发出。我自己也做过这样的奇特配置。我用于解决此类问题的标准解决方案是使用传入 SNAT 规则,将传入数据包的源地址更改为路由器的内部 IPv4 地址。这将导致它看起来像是与 PC 的内部连接,并且它会很乐意将其路由回路由器,因为它驻留在上面路由表中的本地目的地上。然后,路由器将反转 SNAT 并将其发送回野外,以供所有邪恶的黑客嗅探和刺激。按照规定,SNAT 必须存在iptables于路由器上,而不是网络内的 PC 上。如果您只是使用普通 Linksys WRT 路由器之类的东西,您可能必须在其上安装 OpenWRT 或类似设备才能对防火墙/NAT 规则进行这种控制。

相关内容