原来的:
我刚刚为我的路由器从旧的 Linux 安装 (Debian squeeze) 切换到新的 Linux 安装 (Linux Mint 17.3)(我使用一台安装了 Linux 的完整台式电脑作为我的路由器)。 Linux PC 直接连接到我的 DSL 调制解调器并协商 PPPoE 连接,然后为我的所有其他设备路由互联网连接。
据我所知,我的设置与之前的 Debian 安装相同。我有一个简单的rc.local
脚本来设置 iptables,它在新机器上是相同的,并且正在运行(我通过/etc/rc.local
从根控制台运行来确保这一点)。我还在新盒子上设置了 DNS。
大多数功能都是一样的,但我遇到了一个问题:我的 Windows 机器上的 VPN 无法再进行连接。查看 Wireshark,我注意到初始 PPTP 数据包似乎已成功发送和接收,但随后有一个从我的 Windows 机器发送的“Set-Link-Info”数据包,然后 Windows 机器开始设置“PPP LCP 配置请求” ”数据包。此时,它没有收到任何响应。 Wireshark 对我旧的 Debian 设置的捕获显示,此时它得到了响应,最终产生了“PPP LCP 配置确认”。
我真的不知道还要检查什么。我不明白为什么 PPTP 连接在我的新设置中卡在这里。关于如何排除故障有什么想法吗?
注意:这是/etc/rc.local
我设置整个 iptables 配置的(两次安装都是相同的):
#!/bin/sh -e
echo "*** Running rc.local ***"
# First up, make sure 'net.ipv4.ip_forward=1' exists, uncommented, in /etc/sysctl.conf (just do this manually)
echo "MAKE SURE net.ipv4.ip_forward=1 EXISTS, UNCOMMENTED, IN /etc/sysctl.conf OR NAT WILL NOT WORK!!!"
echo ""
# Firewall variables
#WAN_IFACE="eth0" # At the time of writing, this is the NIC built into the mobo
WAN_IFACE="ppp0" # Virtual PPP interface when using PPPoE
LAN_IFACE="eth1" # At the time of writing, this is the extension NIC card
LAN_IP="192.168.1.1/24" # Class-C internal network
# Setup iptables... flush existing rules
iptables -F
iptables -t nat -F
set +e
# Set +e here to continue on error; iptables may give an error if this chain doesn't currently exist and we try to delete it
iptables -X LOGGING
set -e
# Set default policies for chains
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
# Allow all local loopback access
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A OUTPUT -o lo -p all -j ACCEPT
# Allow incoming traffic for established connections
iptables -A INPUT -i $WAN_IFACE -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i $WAN_IFACE -p udp -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i $LAN_IFACE -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i $LAN_IFACE -p udp -m state --state RELATED,ESTABLISHED -j ACCEPT
# Allow incoming ICMP traffic
iptables -A INPUT -p icmp -j ACCEPT
###
# Uncomment lines in this section to allow unsolicited incoming traffic on ports
## Open common service ports
## SSH
#iptables -A INPUT -i $WAN_IFACE -p tcp --destination-port 22 -j ACCEPT
## HTTP (8080 + 8081)
#iptables -A INPUT -i $WAN_IFACE -p tcp --destination-port 8080 -j ACCEPT
#iptables -A INPUT -i $WAN_IFACE -p tcp --destination-port 8081 -j ACCEPT
iptables -A INPUT -i eth1 -p tcp --destination-port 8080 -j ACCEPT
iptables -A INPUT -i eth1 -p tcp --destination-port 8081 -j ACCEPT
# DNS
iptables -A INPUT -i eth1 -p tcp --destination-port 53 -j ACCEPT
iptables -A INPUT -i eth1 -p udp --destination-port 53 -j ACCEPT
# Local Samba connections
iptables -A INPUT -p tcp --syn -s $LAN_IP --destination-port 139 -j ACCEPT
iptables -A INPUT -p tcp --syn -s $LAN_IP --destination-port 445 -j ACCEPT
###
# NAT setup - allow the NAT masquerading
iptables -t nat -A POSTROUTING -o $WAN_IFACE -j MASQUERADE
# Allow forwarding of packets between the Internet and local network interface(s)
iptables -A FORWARD -i $WAN_IFACE -o $LAN_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $LAN_IFACE -o $WAN_IFACE -j ACCEPT
# Logging setup
iptables -N LOGGING
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix="IPTables-Dropped: " --log-level 4
iptables -A LOGGING -j DROP
# Logging; uncomment the below to log dropped input packets to syslog (verbose; only use for debugging!)
echo "Uncomment the necessary lines in rc.local to enable iptables logging..."
#iptables -A INPUT -j LOGGING
echo "*** Finished running rc.local ***"
exit 0
更新:
我对此进行了更多调查,对我的 Linux 路由器所输出内容的 Wireshark 分析揭示了一个非常显着的差异。这是两个屏幕截图,第一个来自我的旧 Debian 盒子,其路由工作正常,第二个来自我的新 Mint 盒子,但路由不起作用:
我用红色和蓝色条纹替换了 IP 地址,以指示我的 Linux 路由器的公共 IP 地址,以及我们正在与之通信的远程地址,以便通过 PPTP 协议建立 VPN 连接。另外,我的 Windows 计算机在本地网络上的 IP 地址以绿色标出。
需要注意的是 PPTP 协议完成并且我们切换到 PPP LCP 数据包后会发生什么。在 Debian 机器上,它会继续将这些数据包的源地址转换为我的公共 IP 地址,然后再将它们发送到公共互联网。但在我的 Linux Mint 盒子上,发送的数据包的源地址仍然保留为尝试建立连接的 Windows 计算机的本地网络地址。它使用本地 C 类源地址将数据包发送到互联网 - 当然它们不会被路由!
问题是,是什么导致我的 Linux Mint 机器上的 NAT 崩溃,而 Debian 机器上却没有发生这种情况? iptables是一样的,都是/etc/network/interfaces
一样的。我不知道......但也许这个发现会帮助这里的人帮助我解决这个问题。 :-)
答案1
为了使 NAT 正常工作,您需要加载特定于协议的帮助程序模块。默认情况下,您只会加载 TCP 和 UDP 的。
这就是为什么您会看到 PPTP 流量(实际上是 GRE 上的 PPP)在没有 NAT 的情况下逃逸。nf_nat_proto_gre
至少从 Linux 4.4 开始,该模块是。
类似的情况也适用于连接跟踪(没有它,GRE 数据包将不会被视为已建立或相关连接的一部分)。那是nf_conntrack_proto_gre
。
事实证明,PPTP 也需要特殊处理(我猜它在 PPP 协商中嵌入了 IP 地址,但我没有检查过)。该特殊处理由 提供,nf_nat_pptp
并且 PPTP 连接的跟踪由 提供nf_conntrack_pptp
。
Amodprobe ip_nat_pptp
应该可以让您的 VPN 正常工作。模块之间的依赖关系最终将加载所有四个模块。要使其在启动时继续工作,请添加nf_nat_pptp
到/etc/modules
.
(不,我不知道这是在哪里记录的,抱歉!)
答案2
德罗伯特的回答是正确的。但对于较新的内核版本,还有另一个问题 - 出于安全原因,net.netfilter.nf_conntrack_helper 的默认值更改为 0。
参见相关:
- https://bugzilla.redhat.com/show_bug.cgi?id=1369489
- https://forum.configserver.com/viewtopic.php?t=10475
简单的修复方法就是再次将其设为 1。添加在/etc/sysctl.conf底部
net.netfilter.nf_conntrack_helper = 1
然后重新启动或运行sysctl -p