找回密码
 立即注册
首页 业界区 业界 ufw配置自动管理端口转发和DNAT+MASQUERADE

ufw配置自动管理端口转发和DNAT+MASQUERADE

阮蓄 2025-6-2 23:14:44

  • 端口A转发到本地的端口B
  • 端口A转发到另一台机器的端口B(需借助DNAT)
一般情况下, 我们配置ufw来实现端口转发时会在修改 /etc/ufw/before.rules 文件, 增加*nat部分.
但当ufw reload或重启ufw时, ufw并不会自动帮我们清除原本的*nat规则, 导致每次刷新ufw都会产生一份新的*nat, 重启一次增加一份.
除非手动执行iptables -F -t nat来清除旧规则, 但这又会导致另一个问题, docker创建的规则也会被这个命令清理.
再除非你创建一个新Chain......
上面的操作不管怎么套娃, 都避免不了手动执行某个命令, 因此我期望寻找一种让ufw自动管理的方案, 于是就有了这篇文章.
思路构建


  • 首先我不想让ufw默认允许转发, 也就是说我不想修改/etc/default/ufw文件
  • 其次, 我不想修改/etc/ufw/sysctl.conf文件, 因为我在/etc/sysctl.conf中开启了net.ipv4.ip_forward
我们知道MASQUERADE规则需要配置在POSTROUTING中, REDIRECT和DNAT规则需要配置在POSTROUTING中.
所以我们需要自定义两个新的Chain, 分别附加到 PREROUTING 和 POSTROUTING 两个部分.
我们仍然将规则编写在/etc/ufw/before.rules中, 并附加在自己的这两个Chain中
每次ufw创建规则前, 自动删除我们自定义的这两个Chain的所有规则, 之后ufw会再次将/etc/ufw/before.rules中自定义的规则添加
before.init 自动删除

首先我们要修改的是 /etc/ufw/before.init 这个文件, 虽然ufw并没有自动帮我们删除的功能, 但是它贴心的准备了这个文件, 用于在ufw初始化之前执行一些指令.
我们需要为这个文件添加执行权限, 这样ufw才会执行这个文件
  1. chmod a+x /etc/ufw/before.init
复制代码
在这个文件中, 我们主要修改的就是case中start和stop这两个部分.

  • 创建了 ufw-nat-pre 附加到 PREROUTING
  • 创建了 ufw-nat-post 附加到 POSTROUTING
我的完整case如下, 如果想重新起名直接替换即可
  1. case "$1" in
  2. start)
  3.     # typically required
  4.     if iptables -t nat -L -n >/dev/null 2>&1;then
  5.         printf "*nat\n"\
  6. ":PREROUTING ACCEPT [0:0]\n"\
  7. ":POSTROUTING ACCEPT [0:0]\n"\
  8. "COMMIT\n" | iptables-restore -n
  9.     fi
  10.     # flush the chains (if they exist)
  11.     if iptables -t nat -L ufw-nat-pre -n >/dev/null 2>&1; then
  12.         iptables -t nat -D PREROUTING -j ufw-nat-pre 2>/dev/null || true
  13.         iptables -t nat -F ufw-nat-pre 2>/dev/null || true
  14.         iptables -t nat -X ufw-nat-pre 2>/dev/null || true
  15.     else
  16.         # setup nat chains
  17.         printf "*nat\n"\
  18. ":ufw-nat-pre - [0:0]\n"\
  19. "-A PREROUTING -j ufw-nat-pre\n"\
  20. "COMMIT\n" | iptables-restore -n
  21.     fi
  22.     if iptables -t nat -L ufw-nat-post -n >/dev/null 2>&1; then
  23.         iptables -t nat -D POSTROUTING -j ufw-nat-post 2>/dev/null || true
  24.         iptables -t nat -F ufw-nat-post 2>/dev/null || true
  25.         iptables -t nat -X ufw-nat-post 2>/dev/null || true
  26.     else
  27.         # setup nat chains
  28.         printf "*nat\n"\
  29. ":ufw-nat-post - [0:0]\n"\
  30. "-A POSTROUTING -j ufw-nat-post\n"\
  31. "COMMIT\n" | iptables-restore -n
  32.     fi
  33.     ;;
  34. stop)
  35.     # typically required
  36.     if iptables -t nat -L ufw-nat-pre -n >/dev/null 2>&1; then
  37.         iptables -t nat -D PREROUTING -j ufw-nat-pre 2>/dev/null || true
  38.         iptables -t nat -F ufw-nat-pre 2>/dev/null || true
  39.         iptables -t nat -X ufw-nat-pre 2>/dev/null || true
  40.     fi
  41.     if iptables -t nat -L ufw-nat-post -n >/dev/null 2>&1; then
  42.         iptables -t nat -D POSTROUTING -j ufw-nat-post 2>/dev/null || true
  43.         iptables -t nat -F ufw-nat-post 2>/dev/null || true
  44.         iptables -t nat -X ufw-nat-post 2>/dev/null || true
  45.     fi
  46.     ;;
  47. status)
  48.     # optional
  49.     ;;
  50. flush-all)
  51.     # optional
  52.     ;;
  53. *)
  54.     echo "'$1' not supported"
  55.     echo "Usage: before.init {start|stop|flush-all|status}"
  56.     ;;
  57. esac
复制代码
before.rules 自定义规则

首先我们要修改的是 /etc/ufw/before.rules 这个文件, 直接在文件的末尾添加即可
如何添加iptables规则需要自行搜索或询问AI, 我这里仅提供示例便于读者知道自定义规则怎么添加, 以及添加在什么地方
注意端口转发到另一个IP的端口需要在两个部分都配置
  1. *nat
  2. :ufw-nat-pre - [0:0]
  3. # 本机的 20000 端口的 tcp 和 udp 转发到本机的 22 端口
  4. -A ufw-nat-pre -p tcp --dport 20000 -j REDIRECT --to-port 22
  5. -A ufw-nat-pre -p udp --dport 20000 -j REDIRECT --to-port 22
  6. # 本机的 20001 端口的 tcp 和 udp 转发到 1.1.1.1 的 22 端口 (注意: 还需要配置 ufw-nat-post
  7. -A ufw-nat-pre -p tcp --dport 20001 -j DNAT --to-destination 1.1.1.1:22
  8. -A ufw-nat-pre -p udp --dport 20001 -j DNAT --to-destination 1.1.1.1:22
  9. # end
  10. COMMIT
  11. *nat
  12. :ufw-nat-post - [0:0]
  13. # 本机的 20001 端口的 tcp 和 udp 转发到 1.1.1.1 的 22 端口 (注意: 还需要配置 ufw-nat-pre
  14. -A ufw-nat-post -d 1.1.1.1 -p tcp --dport 22 -j MASQUERADE
  15. -A ufw-nat-post -d 1.1.1.1 -p udp --dport 22 -j MASQUERADE
  16. # end
  17. COMMIT
复制代码
配置允许来自那个IP的转发数据
如果你需要允许来自所有IP的请求都进行转发, 可以修改默认的转发策略. 假如仅允许来自8.8.8.8的转发数据可以进行如下配置.
找到 *filter 部分, 在 COMMIT 前添加下面的信息
  1. # allow forward
  2. -A ufw-before-input -s 8.8.8.8 -j ACCEPT
  3. -A ufw-before-output -d 8.8.8.8 -j ACCEPT
复制代码
完成

注意: 如果先前就创建了规则且没有删除, 或者不小心把docker的规则删掉了, 可以重启下系统来刷新
这样我们就可以愉快的在 before.rules 添加规则, 然后使用 ufw reload 重载规则了
同时发布在个人博客中 https://blog.akvicor.com/posts/ufw/forward/

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册