UFW
是 "简单防火墙" 的缩写,是更复杂的 iptables
实用程序的前端。它旨在使管理防火墙变得像设置端口打开和关闭以及调节允许通过的流量一样简单。
ufw
可以在 Debian
和 Ubuntu
系统中使用,是默认的防火墙配置工具,默认 ufw
是禁用状态,支持 IPv4
和 IPv6
。
国内的服务器,一般都会有安全组,如果有安全组,则无须使用
ufw
国外的服务器,一般端口全都是放行的,所以有必要使用ufw
如果是CentOS
系统,可以使用firewalld
,强烈建议弃用CentOS
系统,官方早已经不维护了,会有很多漏洞无法修复。
推荐系统:Debian
>Ubuntu
>>>>>CentOS
提示:以下所有命令默认在 root
环境下运行,如果是非 root
环境,则命令需要加前缀:sudo
ufw 使用 {#ufw-%E4%BD%BF%E7%94%A8}
更新软件包:
apt update
`apu upgrade
`
安装 {#%E5%AE%89%E8%A3%85}
# 安装
apt-get install ufw
帮助命令
ufw --help
推荐配置 {#%E6%8E%A8%E8%8D%90%E9%85%8D%E7%BD%AE}
如果要开启防火墙的话,建议先拒绝所有入站流量,然后逐一打开需要的端口。
# 默认阻止入站(不会立即切断你的 SSH 连接,因为防火墙尚未启用)
ufw default deny incoming
默认允许出站
ufw default allow outgoing
拒绝所有访问(如果配置了入站/出战,这个可以不配置)
ufw default deny
根据需求开启端口
ufw allow 22
⚠注意
确保在修改SSH
端口后,不要关闭当前SSH
窗口,尝试使用新的端口进行SSH
登录,以确保没有防火墙或其他网络配置问题,以免被自己锁定出服务器。
启用禁用 {#%E5%90%AF%E7%94%A8%E7%A6%81%E7%94%A8}
# 启用
ufw enable
查看状态
ufw status verbose
禁用
ufw disable
防火墙规则存放位置
/etc/ufw 中的规则文件(后缀名:.rules)
允许拒绝 {#%E5%85%81%E8%AE%B8%E6%8B%92%E7%BB%9D}
allow
例子:
# 接受 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
例子:
# 拒绝 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
删除 {#%E5%88%A0%E9%99%A4}
# 要删除规则,只需在原始规则前加上删除,删除 80 端口的 tcp 配置
ufw delete deny 80/tcp
显示规则的顺序和ID号
ufw status numbered
删除编号规则(删除规则,规则将向上移动以填充列表)
ufw delete 1
日志 {#%E6%97%A5%E5%BF%97}
# 启用日志
ufw logging on
禁用日志
ufw logging off
Docker不遵守ufw规则 {#docker%E4%B8%8D%E9%81%B5%E5%AE%88ufw%E8%A7%84%E5%88%99}
如果你在服务端使用 Docker
映射了某个宿主机端口,然后公网访问这个端口的话,你会发现仍然可以访问,即使 ufw
禁用了这个端口,却不起效果。
因为默认状态下的 Docker
并不遵守 ufw
的防火墙规则,如下图:
解决ufw和docker的问题 {#%E8%A7%A3%E5%86%B3ufw%E5%92%8Cdocker%E7%9A%84%E9%97%AE%E9%A2%98}
解决方案:https://github.com/chaifeng/ufw-docker
目前新的解决方案只需要修改一个 UFW
配置文件即可,Docker
的所有配置和选项都保持默认。
修改 UFW
的配置文件 /etc/ufw/after.rules
,在最后添加上如下规则:
# 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
文件配置:
# 下载脚本
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
。那就可以用以下命令来允许外部网络访问这个服务:
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
,就用类似下面的命令:
ufw route allow proto tcp from any to 172.17.0.2 port 80
如果一个容器的服务是 UDP
协议,假如是 DNS 服务,可以用下面的命令来允许外部网络访问所有发布出来的 DNS 服务:
ufw route allow proto udp from any to any port 53
同样的,如果只针对一个特定的容器,比如 IP 地址为 172.17.0.2
:
ufw route allow proto udp from any to 172.17.0.2 port 53
ufw-docker
也是支持 Docker Swarm
的,详细教程及配置参考文章:https://github.com/chaifeng/ufw-docker