进出 WAN 的端口转发?

haw*_*awk 5 networking firewall port-forwarding ubuntu-server

是否可以将数据包从互联网端口转发到互联网上的另一个地址?

我发现的所有端口转发教程都重点关注 NAT 端口转发,但我只想将连接重定向到另一个公共地址,并且我似乎无法为此目的调整防火墙设置。有可能吗?

我正在使用iptables/ufw并且尝试了以下操作(在 /etc/ufw/before.rules 中):

:PREROUTING ACCEPT [0:0]
-A PREROUTING -i eth0 -d $VPS_PUBLIC_IP -p tcp --dport 80 -j DNAT --to-destination $PUBLIC_WEB_SERVER_IP:80
Run Code Online (Sandbox Code Playgroud)

(我也尝试*nat在此之前添加该行,但随后我也收到错误Bad argument '*nat'。)

但是当我启动 ufw 时,出现“RULE_APPEND failed (Invalid argument):rule in chain PREROUTING”错误。

我的最终目标是能够在浏览器中访问(例如)https://1.2.3.4 ,并在没有 VPN 的情况下查看(公共托管)网站https://9.8.7.6 。

更新:我正在尝试从我的 PC 连接到 VPS 并转发到公共网络服务器。我的 VPS 除了转发连接之外应该不做任何事情。

haw*_*awk 7

如果您希望用户能够通过连接到 VPS 来访问网站,如下图所示,其中每个网络接口都位于 WAN(互联网)上:

\n
        e.g. 1.2.3.4\n         \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n         \xe2\x94\x82  VPS  \xe2\x94\x82\n         \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n             \xe2\x96\xb2        WAN (Internet)\n     \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n     \xe2\x96\xbc               \xe2\x96\xbc\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90      \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82  User  \xe2\x94\x82      \xe2\x94\x82 Website \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98      \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n                      e.g. 9.8.7.6 \xe2\x86\x90 example.com\n
Run Code Online (Sandbox Code Playgroud)\n

那么以下两个解决方案中的任何一个都可以做到这一点。

\n

概述

\n

首先,基于 Rusty Russel 的NAT HOWTOPacket Filtering HOWTO快速概述 netfilter 设计。您可以跳过本节或稍后阅读,这样可能会更有意义,因为我上次写了此概述。

\n
              (D-NAT)           (S-NAT)\nIncoming \xe2\x95\xad\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xae           \xe2\x95\xad\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xae Outgoing\n      \xe2\x94\x80\xe2\x94\x80\xe2\x96\xb6\xe2\x94\x82PREROUTING\xe2\x94\x82           \xe2\x94\x82POSTROUTING\xe2\x94\x82\xe2\x94\x80\xe2\x94\x80\xe2\x96\xb6\n         \xe2\x95\xb0\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xaf           \xe2\x95\xb0\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xaf\n                \xe2\x94\x82                  \xe2\x96\xb2\n                \xe2\x96\xbc     \xe2\x95\xad\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xae    \xe2\x94\x82\n           Routing \xe2\x94\x80\xe2\x94\x80\xe2\x96\xb6\xe2\x94\x82FORWARD\xe2\x94\x82\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n           Decision   \xe2\x95\xb0\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xaf    \xe2\x94\x82\n                \xe2\x94\x82                  \xe2\x94\x82\n                \xe2\x96\xbc                  \xe2\x94\x82\n             \xe2\x95\xad\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xae    Local    \xe2\x95\xad\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xae\n             \xe2\x94\x82INPUT\xe2\x94\x82\xe2\x94\x80\xe2\x96\xb6 Process \xe2\x94\x80\xe2\x96\xb6\xe2\x94\x82OUTPUT\xe2\x94\x82\n             \xe2\x95\xb0\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xaf             \xe2\x95\xb0\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x95\xaf\n
Run Code Online (Sandbox Code Playgroud)\n

您可以在这五个“钩子”中添加规则:

\n
\n\n\n\n\n\n\n\n\n\n\n
预路由输入向前输出后布线
\n
\n

每个挂钩都提供规则可以利用的某些功能/扩展,例如\nD-NAT 和 S-NAT。(编辑:\n不同的功能集实际上因表而异,例如\n“过滤器”(包括INPUT、FORWARD、OUTPUT)和\n“nat”(包括PREROUTING、INPUT、OUTPUT、\nPOSTROUTING)。我不知道现在对表格有了很好的理解。)

\n

每个传入数据包都会经过 PREROUTING,每个传出数据包都会经过 POSTROUTING。在 PREROUTING 之后(在“路由决策”处),寻址到本地计算机的数据包将通过 INPUT,而其他数据包将通过 FORWARD。进程创建的新数据包首先通过 OUTPUT,然后通过 POSTROUTING,与已通过 FORWARD 的数据包一起。(注意:默认情况下可能会禁用转发。)

\n

每个规则都是有序规则链的一部分,并且规则从上到下进行评估(可以通过运行iptables -L -t filterand查看规则链iptables -L -t nat)。每条规则都可以尝试匹配数据包的某些特征,如果匹配,则可以选择修改数据包,并决定接受它(让它继续前进)、丢弃它或跳转到另一个链。如果没有规则匹配,则默认策略\n决定是接受还是丢弃数据包。

\n
\n

将数据包转发到原始网络似乎\n是一件罕见或不寻常的事情,但这是可能的\n(请参阅“目标 NAT 到同一网络\n”并且与 MASQUERADE 选项相关联。(似乎\n通常您希望阻止直接访问机器,因此您可以将其放入专用网络中,就像反向代理的情况一样)。

\n

要点是您需要:(1) 启用转发,\n(2) 更改传入数据包的目标地址,\n以及 (3) 更改数据包上的源地址,以便\n目标不会直接回复用户(\n将被正常配置的防火墙阻止)。\n传向另一个方向(网站到 VPS)的数据包\n会自动转发回用户。

\n

如果可能的话,您可能希望严格匹配下面的规则\n数据包,以获得最大的安全性。(如果像我一样,\n你这样做主要是为了学习练习,这可能并不重要,但在玩防火墙时记住这一点是有好处的。)

\n

临时解决方案

\n

运行以下命令(改编自 Rusty Russel 的\n2002 NAT HOWTO第4.1 \n 和10节)以添加两个新的 NAT 规则,一个在 PREROUTING 阶段,另一个在 POSTROUTING 阶段。如果您没有将相关 IP 地址定义为变量,请替换它们。

\n
iptables -t nat -A PREROUTING -d $VPS_PUBLIC_IP -p tcp --dport 443 -j DNAT --to $PUBLIC_WEB_SERVER_IP\niptables -t nat -A POSTROUTING -d $PUBLIC_WEB_SERVER_IP -p tcp --dport 443 -j MASQUERADE\n
Run Code Online (Sandbox Code Playgroud)\n

为此,必须启用转发:

\n
echo 1 > /proc/sys/net/ipv4/ip_forward\n
Run Code Online (Sandbox Code Playgroud)\n

(请参阅数据包如何穿过过滤器

\n

iptables此处使用的参数细分(man iptables详细信息请参见):

\n
    \n
  • -t nat说使用NAT数据包匹配表:

    \n
    \n

    当遇到创建新连接的数据包时,\n将查阅此表。\n它由四个内置函数组成:PREROUTING\n(用于在数据包进入时立即更改数据包)、\nINPUT(用于更改发往本地的数据包\n) nsockets)、OUTPUT(用于在路由之前更改本地生成的数据包)和 POSTROUTING(用于在数据包即将发出时对其进行更改)。

    \n
    \n
  • \n
  • -A PREROUTING将规则附加到 PREROUTING 链。

    \n
  • \n
  • -A POSTROUTING将规则附加到 POSTROUTING 链。

    \n
  • \n
  • -d $VPS_PUBLIC_IP当数据包的目的地是 VPS 时应用该规则,即用户已在1.2.3.4浏览器中键入\n。

    \n
  • \n
  • -d $PUBLIC_WEB_SERVER_IP当数据包的目的地是 Web 服务器的公共 IP 时,\n应用该规则。在用户的数据包到达 VPS 并通过 PREROUTING 链(更改了目标地址)和 FORWARD 链(未更改任何内容)之后,情况确实如此。

    \n
  • \n
  • -p tcp匹配世界著名的TCP协议的数据包。

    \n
  • \n
  • --dport 443匹配前往端口 443 (HTTPS) 的数据包。

    \n
  • \n
  • -j DNAT代表“跳转到 DNAT(目标 NAT)”。\n我无法解释它,但man iptables说:

    \n
    \n

    这指定了规则的目标;即,如果数据包与其匹配,该怎么办。目标可以是用户定义的链(除了此规则所在的链)、立即决定数据包命运的特殊内置目标之一,或者扩展(请参阅下面的扩展)。

    \n
    \n

    和来自man iptables-extensions

    \n
    \n

    DNAT虚拟状态,如果原始目的地与回复源不同,则匹配。

    \n
    \n
  • \n
  • --to $PUBLIC_WEB_SERVER_IP将数据包的目标IP(由于NAT)更改为 Web 服务器的 IP。

    \n
  • \n
  • -j MASQUERADE将源 IP 更改为 VPS 的 IP,\相当于-j SNAT --to $VPS_PUBLIC_IP. 这使得 Web 服务器响应 VPS,然后 VPS 解开数据包并将其转发给用户。如果没有这个,\n服务器将直接响应用户,\n用户的防火墙很可能会拒绝它,因为它是防火墙无法识别的\n新连接。\n有关详细信息,请参阅\n Netfilter\的连接跟踪系统\n并说明如何破坏数据包

    \n
  • \n
\n

如果 VPS IP 未在证书中作为 SAN(主题\n备用名称)列出,您将收到 SSL 证书警告。

\n

永久解决方案

\n

要使其永久用于ufw(简单防火墙),请将以下内容添加到 /etc/ufw/before.rules(替换 VPS 和 Web 服务器的实际 IP 地址)。

\n

注意:默认情况下,ufw 将 FORWARD 策略设置为“deny”\n(在 中也显示为“DROP” iptables -L -t filter)。这就是-A FORWARD ... -j ACCEPT需要该规则的原因。\n如果您的默认策略是“接受”(如 中所示ufw default allow routed),则不需要该规则。

\n
*nat\n-A PREROUTING -d $VPS_PUBLIC_IP -p tcp --dport 443 -j DNAT --to $PUBLIC_WEB_SERVER_IP\n-A POSTROUTING -d $PUBLIC_WEB_SERVER_IP -p tcp --dport 443 -j MASQUERADE\nCOMMIT\n\n*filter\n-A FORWARD -d $PUBLIC_WEB_SERVER_IP -p tcp --dport 443  -j ACCEPT\nCOMMIT\n
Run Code Online (Sandbox Code Playgroud)\n

请务必将其放在文件末尾现有COMMIT行之后。另外,请完整阅读此答案,确保您不会将自己锁定在 SSH 之外。

\n

然后打开 /etc/ufw/sysctl.conf 并取消注释“取消注释以允许该主机在接口之间路由数据包”的行,因此结果应该是:

\n
net/ipv4/ip_forward=1\nnet/ipv6/conf/default/forwarding=1\nnet/ipv6/conf/all/forwarding=1\n
Run Code Online (Sandbox Code Playgroud)\n

然后启用ufw:

\n
ufw enable\n
Run Code Online (Sandbox Code Playgroud)\n

如果您通过 SSH 连接,它会要求确认\n以防启用 ufw 会阻止端口 22 并将您锁定。\n这种情况不应该发生,因此只需键入“y”并按 Enter 键即可。\n如果您\n担心的话,请先通过 VPS\n控制面板进行备份/快照。

\n

测试一下是否有效。如果你运行iptables -L -t filter你应该看到这样的一行:

\n
ACCEPT     tcp  --  0.0.0.0/0            example.com        tcp dpt:443\n
Run Code Online (Sandbox Code Playgroud)\n

靠近顶部的标题“Chain FORWARD\n(policy DROP)”部分下。如果您运行iptables -L -t nat\n您应该在部分标题\n“Chain PREROUTING(策略接受)”和“Chain POSTROUTING\n(策略接受)”下看到您的规则。

\n

有关详细信息,请参阅UFWman ufwman ufw-framework

\n

做出改变

\n

如果您需要进行更改,您可能应该iptables -F -t nat首先运行\n以清除 PREROUTING\n和 POSTROUTING\n链中的规则,否则您可能会得到重复的\n规则。如果您需要刷新 FORWARD 链中的规则,请不要运行iptables -F -t filter,因为您的 SSH 会话将会中断(如果 INPUT 链的默认策略是拒绝/删除)并且我还没有找到解决方案防止这种情况发生的方法(即使您更改默认策略,当您将其更改回拒绝时,它也会中断)。如果reboot您不介意的话,或者\n删除特定规则:首先用\n列出它们iptables -L --line-numbers -t filter,然后\n用\n删除iptables -D FORWARD 7(例如删除\n第七条规则)。

\n

然后重新启动ufw:systemctl restart ufw

\n


use*_*686 6

这是可能的,尽管您还需要对相同数据包使用 SNAT 或 MASQUERADE 规则,因此最终目标主机会将连接视为来自您而不是来自原始客户端。(这与从 LAN 到 LAN \xe2\x80\x93 的端口转发完全相同,需要“发夹 NAT”来防止回复数据包绕过网关,这样网关就没有机会取消 NAT。)

\n

请注意,“dport”选项写为--dport,而不是-dport。(后者意味着-d作为port目标 IP 地址。)

\n