Linux ufw(防火墙)使用指南,解决ufw和docker冲突问题,保护你的服务器/VPS

文章已同步至【博客】,欢迎访问【主页】😃

文章地址:blog.fanjunyang.zone/archives/li...

UFW 是 "简单防火墙" 的缩写,是更复杂的 iptables 实用程序的前端。它旨在使管理防火墙变得像设置端口打开和关闭以及调节允许通过的流量一样简单。

ufw 可以在 Debian 和 Ubuntu 系统中使用,是默认的防火墙配置工具,默认 ufw 是禁用状态,支持 IPv4 和 IPv6。

国内的服务器,一般都会有安全组,如果有安全组,则无须使用 ufw 国外的服务器,一般端口全都是放行的,所以有必要使用 ufw
如果是 CentOS 系统,可以使用 firewalld,强烈建议弃用 CentOS 系统,官方早已经不维护了,会有很多漏洞无法修复。 推荐系统:Debian > Ubuntu >>>>> CentOS

提示:以下所有命令默认在 root 环境下运行,如果是非 root 环境,则命令需要加前缀:sudo

ufw 使用

更新软件包:

sql 复制代码
apt update

apu upgrade

安装

bash 复制代码
# 安装
apt-get install ufw

# 帮助命令
ufw --help

推荐配置

如果要开启防火墙的话,建议先拒绝所有入站流量,然后逐一打开需要的端口。

csharp 复制代码
# 默认阻止入站(不会立即切断你的 SSH 连接,因为防火墙尚未启用)
ufw default deny incoming

# 默认允许出站
ufw default allow outgoing

# 拒绝所有访问(如果配置了入站/出战,这个可以不配置)
ufw default deny

# 根据需求开启端口
ufw allow 22

⚠注意 确保在修改 SSH 端口后,不要关闭当前 SSH 窗口,尝试使用新的端口进行 SSH 登录,以确保没有防火墙或其他网络配置问题,以免被自己锁定出服务器。

启用禁用

bash 复制代码
# 启用
ufw enable

# 查看状态
ufw status verbose

# 禁用
ufw disable

# 防火墙规则存放位置
# /etc/ufw 中的规则文件(后缀名:.rules)

允许拒绝

allow 例子:

python 复制代码
# 接受 97 端口的 tcp/udp 流量
ufw allow 97

# 接受 97 端口的 tcp/udp 流量,并添加备注
ufw allow 97 comment 'open 97 port'

# 接受 97 端口的 tcp 流量
ufw allow 97/tcp

# 接受 97 端口的 udp 流量
ufw allow 97/udp

# 通过服务名来处理, 会从 /etc/services 中查找端口
ufw allow ssh

# 允许特定IP访问
ufw allow from 1.2.3.4

# 允许特定子网访问
ufw allow from 1.2.3.4/97

# 允许特定IP使用任何协议访问22端口
ufw allow from 1.2.3.4 to any port 22

# 允许特定IP使用任何TCP协议访问22端口
ufw allow from 1.2.3.4 to any port 22 proto tcp

deny 例子:

python 复制代码
# 拒绝 97 端口的 tcp/udp 流量
ufw deny 97

# 拒绝 97 端口的 tcp 流量
ufw deny 97/tcp

# 拒绝 97 端口的 udp 流量
ufw deny 97/udp

# 通过服务名来处理, 会从 /etc/services 中查找端口
ufw deny ssh

# 拒绝特定IP访问
ufw deny from 1.2.3.4

# 同allow
ufw deny from 1.2.3.4 to any port 22
ufw deny from 1.2.3.4 to any port 22
ufw allow from 1.2.3.4/97 to any port 22 proto tcp

删除

perl 复制代码
# 要删除规则,只需在原始规则前加上删除,删除 80 端口的 tcp 配置
ufw delete deny 80/tcp

# 显示规则的顺序和ID号
ufw status numbered

# 删除编号规则(删除规则,规则将向上移动以填充列表)
ufw delete 1

日志

csharp 复制代码
# 启用日志
ufw logging on

# 禁用日志
ufw logging off

Docker不遵守ufw规则

如果你在服务端使用 Docker 映射了某个宿主机端口,然后公网访问这个端口的话,你会发现仍然可以访问,即使 ufw 禁用了这个端口,却不起效果。

因为默认状态下的 Docker 并不遵守 ufw 的防火墙规则,如下图:

解决ufw和docker的问题

解决方案:github.com/chaifeng/uf...

目前新的解决方案只需要修改一个 UFW 配置文件即可,Docker 的所有配置和选项都保持默认。

修改 UFW 的配置文件 /etc/ufw/after.rules,在最后添加上如下规则:

sql 复制代码
# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-docker-logging-deny - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j ufw-user-forward

-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16

-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN

-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12

-A DOCKER-USER -j RETURN

-A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] "
-A ufw-docker-logging-deny -j DROP

COMMIT
# END UFW AND DOCKER

或者使用 ufw-docker 工具下载脚本,修改 after.rules 文件配置:

bash 复制代码
# 下载脚本
wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker

# 赋予权限
chmod +x /usr/local/bin/ufw-docker

# 修改配置文件
ufw-docker install

ufw-docker install 命令做了以下事情:

  • 备份文件 /etc/ufw/after.rules
  • 把 UFW 和 Docker 的相关规则添加到文件 after.rules 的末尾

然后重启 UFW,systemctl restart ufw。现在外部就已经无法访问 Docker 发布出来的任何端口了,但是容器内部以及私有网络地址上可以正常互相访问,而且容器也可以正常访问外部的网络。可能由于某些未知原因,重启 UFW 之后规则也无法生效,请重启服务器。

如果希望允许外部网络访问 Docker 容器提供的服务,比如有一个容器的服务端口是 80。那就可以用以下命令来允许外部网络访问这个服务:

python 复制代码
ufw route allow proto tcp from any to any port 80

这个命令会允许外部网络访问所有用 Docker 发布出来的并且内部服务端口为 80 的所有服务。

请注意,这个端口 80 是容器的端口,而非使用 -p 0.0.0.0:8080:80 选项发布在服务器上的 8080 端口。

如果有多个容器的服务端口为 80,但只希望外部网络访问某个特定的容器。比如该容器的私有地址为 172.17.0.2,就用类似下面的命令:

css 复制代码
ufw route allow proto tcp from any to 172.17.0.2 port 80

如果一个容器的服务是 UDP 协议,假如是 DNS 服务,可以用下面的命令来允许外部网络访问所有发布出来的 DNS 服务:

python 复制代码
ufw route allow proto udp from any to any port 53

同样的,如果只针对一个特定的容器,比如 IP 地址为 172.17.0.2:

css 复制代码
ufw route allow proto udp from any to 172.17.0.2 port 53

ufw-docker 也是支持 Docker Swarm的,详细教程及配置参考文章:github.com/chaifeng/uf...

相关推荐
刘马想放假2 分钟前
CANviz 使用指南|Linux 安装、DBC 解码、实时曲线与 J1939 实战
linux·python·websocket
IT_陈寒17 分钟前
Vue的watch把我坑惨了,原来要这样用才靠谱
前端·人工智能·后端
黃芢輝1 小时前
开源实战:基于 Spring Boot 3 + Vue 3 + Redis 的高校选修课管理系统(志愿填报 + 统一抽签)
后端
小雨的AI中台笔记1 小时前
502 还是 503?「无可用渠道」其实只有三个原因
后端
LCG元1 小时前
我让AI重写了这个老系统
后端
吴汐1 小时前
【CRMEB 社区版】二开第一问:这个需求该进 driver,还是进 modules?
后端
新*1 小时前
Elasticsearch 7.17 的 SQL 到底能查到什么?一次踩坑记录
后端·sql·elasticsearch·查询
kloc1 小时前
聊天室项目入口网关子服务的实现
linux·c++
GeW1 小时前
深圳APEC峰会倒计时:数据库与Linux运维的"隐形考场"
linux
卷无止境1 小时前
SALib敏感性分析的python库学习笔记
后端·python