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

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

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

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

ufw 可以在 DebianUbuntu 系统中使用,是默认的防火墙配置工具,默认 ufw 是禁用状态,支持 IPv4IPv6

国内的服务器,一般都会有安全组,如果有安全组,则无须使用 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
  • UFWDocker 的相关规则添加到文件 after.rules 的末尾

然后重启 UFWsystemctl 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...

相关推荐
2401_8581205313 分钟前
古典舞在线交流平台:SpringBoot设计与实现详解
java·spring boot·后端
IChen.15 分钟前
解决centos 删除文件后但空间没有释放
linux·运维·centos
紫队安全研究23 分钟前
《Web3 安全:攻击与防御全景指南》
安全·web3
赐你岁月如歌25 分钟前
如何使用ssm实现基于web的网站的设计与实现+vue
java·后端·ssm
何陈陈1 小时前
【Linux】线程池
linux·服务器·开发语言·c++
S hh1 小时前
【Linux 】文件描述符fd、重定向、缓冲区(超详解)
linux·运维·服务器
DuoRuaiMiFa1 小时前
Linux系统性能调优实战指南
linux
憧憬一下1 小时前
线程池的实现和讲解:解决多线程并发服务器创建销毁线程消耗过大的问题
linux·线程池·c/c++·嵌入式linux
朝九晚五ฺ2 小时前
【Linux探索学习】第三弹——Linux的基础指令(下)——开启新篇章的大门
linux·运维·学习