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

相关推荐
醇氧14 分钟前
ab (Apache Bench)的使用
linux·学习·centos·apache
newxtc28 分钟前
【魔珐有言-注册/登录安全分析报告-无验证方式导致安全隐患】
人工智能·安全·网易易盾·ai写作·极验
喜欢打篮球的普通人28 分钟前
rust高级特征
开发语言·后端·rust
速盾cdn28 分钟前
速盾:如何有效防止服务器遭受攻击?
网络·安全·web安全
moneyxjj1 小时前
Linux各种解压命令汇总
linux·运维·服务器
白白♛~1 小时前
网络管理之---3种网络模式配置
linux·服务器·网络
代码小鑫1 小时前
A032-基于Spring Boot的健康医院门诊在线挂号系统
java·开发语言·spring boot·后端·spring·毕业设计
GOTXX1 小时前
NAT、代理服务与内网穿透技术全解析
linux·网络·人工智能·计算机网络·智能路由器
豌豆花下猫2 小时前
REST API 已经 25 岁了:它是如何形成的,将来可能会怎样?
后端·python·ai
始终奔跑在路上2 小时前
安全见闻2
安全·网络安全