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...