当前位置: 首页 > 工具软件 > UFW > 使用案例 >

Linux学习整理-网络防火墙ufw

廖诚
2023-12-01

Linux的防火墙的术语

先整理一下他们之间的关系

  • netfilter

​netfilter 项目是一个社区驱动的协作 FOSS 项目,为Linux 2.4.x 和更高版本的内核系列提供包过滤软件。netfilter 项目通常与iptables及其后继者nftables相关联。

netfilter 项目支持数据包过滤、网络地址 [和端口] 转换 (NA[P]T)、数据包日志记录、用户空间数据包排队和其他数据包处理。​

这是个linux内核的东西。

  • iptables

iptables 是一个配置 Linux 内核 防火墙 的命令行工具,是 Netfilter 项目的一部分。术语 iptables 也经常代指该内核级防火墙。iptables 可以直接配置,也可以通过许多 控制台 和 图形化 前端配置。iptables 用于 ipv4,ip6tables 用于 IPv6。iptables和ip6tables 拥有相同的语法,但是有些特别的选项,对 IPv4 和 IPv6 有些不同的。

这个东西工作在用户空间。

还有ip6tables,arptables ,ebtables。

4表5链

  • filter表——过滤数据包
  • Nat表——用于网络地址转换(IP、端口)
  • Mangle表——修改数据包的服务类型、TTL、并且可以配置路由实现QOS
  • Raw表——决定数据包是否被状态跟踪机制处理
  • INPUT链——进来的数据包应用此规则链中的策略
  • OUTPUT链——外出的数据包应用此规则链中的策略
  • FORWARD链——转发数据包时应用此规则链中的策略
  • PREROUTING链——对数据包作路由选择前应用此链中的规则(所有的数据包进来的时侯都先由这个链处理)
  • POSTROUTING链——对数据包作路由选择后应用此链中的规则(所有的数据包出来的时侯都先由这个链处理)
  • nfttables

nftables取代了流行的{ip,ip6,arp,eb}tables。该软件提供了一个新的内核数据包分类框架,该框架基于特定于网络的虚拟机 (VM) 和新的nft用户空间命令行工具。nftables重用了现有的 Netfilter 子系统,例如现有的钩子基础设施、连接跟踪系统、NAT、用户空间队列和日志子系统。

  • firewalld

Firewalld 提供动态管理的防火墙,支持定义网络连接或接口的信任级别的网络/防火墙区域。它支持 IPv4、IPv6 防火墙设置、以太网桥和 IP 集。运行时和永久配置选项是分开的。它还为服务或应用程序提供直接添加防火墙规则的接口。

firewalld是centos自带的防火墙软件,当然Ubuntu也可以安装。

  • ufw

ufw是Ubuntu自带的防火墙软件,也是管理netfilter的一个软件。使用方式非常简单。

centos也可以安装。

归根结底,不管是ufw还是firewalld,还是iptables最后都是操作内核的netfilter。

2 ufw的用法

2.1 ufw防火墙开启关闭状态确认

ufw [--dry-run] enable|disable|reload
# ufw防火墙关闭
root@node2:~# systemctl stop ufw
# ufw防火墙状态
root@node2:~# systemctl status ufw
● ufw.service - Uncomplicated firewall
     Loaded: loaded (/lib/systemd/system/ufw.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Sat 2022-01-08 10:49:50 UTC; 17s ago

# ufw防火墙打开
root@node2:~# systemctl start ufw
# ufw防火墙状态
root@node2:~# systemctl status ufw
● ufw.service - Uncomplicated firewall
     Loaded: loaded (/lib/systemd/system/ufw.service; enabled; vendor preset: enabled)
     Active: active (exited) since Sat 2022-01-08 10:51:09 UTC; 3s ago

# ufw防火墙无效
root@node2:~# ufw disable 
Firewall stopped and disabled on system startup

# ufw防火墙状态-无效
root@node2:~# ufw status
Status: inactive

# ufw防火墙生效
root@node2:~# ufw enable 
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

# ufw防火墙状态-有效
root@node2:~# ufw status 
Status: active       

这里要注意一下,开启ufw防火墙可能会中断正在连接中的ssh。

 2.2 ufw防火墙的默认模式

ufw [--dry-run] default allow|deny|reject [incoming|outgoing|routed]

allow 是默认允许所有访问,也就是我们所说的黑名单。有要拒绝的访问,就要加到规则中。

deny 是默认拒绝所有访问,也就是我们所说的白名单。有要允许的访问,就要加到规则中。

reject跟deny一样也是拒绝所有访问。但是跟deny不一样的是 会提醒访问者 访问被拒绝,而deny只会提示访问超时。

 2.3 ufw规则添加

ufw  [--dry-run] [delete] [insert NUM] [prepend] allow|deny|reject|limit [in|out] [log|log-all] [ PORT[/PROTOCOL] | APPNAME ] [comment COMMENT]

ufw [--dry-run] [rule] [delete] [insert NUM] [prepend] allow|deny|reject|limit [in|out [on INTERFACE]] [log|log-all] [proto  PROTOCOL] [from ADDRESS [port PORT | app APPNAME ]] [to ADDRESS [port PORT | app APPNAME ]] [comment COMMENT]

 下面开始用实验来说明ufw的使用方法

2.3.1 首先开启ufw的默认模式为deny

在此之前最好先把端口22 设置为allow,要不然在没有规则的情况下,把模式设置为deny,会导致你的远程连接被断开。

ufw allow 22

root@node2:~# ufw default deny
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)

2.3.2 查看防火墙的访问规则

root@node2:~# ufw status 
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere                  
22 (v6)                    ALLOW       Anywhere (v6)             

2.3.3 添加新的规则

当前机器的端口开放情况,可以看到本机的nginx服务是开启状态,然后在本机用curl命令也可以访问服务。

200root@node2:lsof -i4:80
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   1083     root    6u  IPv4  37452      0t0  TCP *:http (LISTEN)
nginx   1084 www-data    6u  IPv4  37452      0t0  TCP *:http (LISTEN)
nginx   1085 www-data    6u  IPv4  37452      0t0  TCP *:http (LISTEN)

root@node2:~# curl -s localhost -w '%{http_code}' -o /dev/null
200

但是在node1机器上测试nginx,发现经过5秒然后连接超时。

root@node1:~# curl 192.168.0.203 --connect-timeout 5
curl: (28) Connection timed out after 5002 milliseconds

原因就是因为默认deny状态下,80端口未被开放,所以从外面来的访问被拒绝。

如果用reject,会直接告诉访问者,端口拒绝访问,而不是timeout

root@node2:~# ufw reject 80/tcp
Rule added
Rule added (v6)
root@node2:~# ufw status 
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere                  
80/tcp                     REJECT      Anywhere                  
22 (v6)                    ALLOW       Anywhere (v6)             
80/tcp (v6)                REJECT      Anywhere (v6)  

然后在node1机器上,再次测试,发现直接被拒绝。这就是rejectdeny的区别。

root@node1:~# curl 192.168.0.203 --connect-timeout 5
curl: (7) Failed to connect to 192.168.0.203 port 80: Connection refused

用allow来开启80端口的访问

root@node2:~# ufw allow 80/tcp
Rule updated
Rule updated (v6)

然后在node1机器上,再次测试,发现可以访问80

root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200

以上就是最基本的端口开闭。

有的时候可能需要更加复杂的规则来约束访问。

比如说只允许某个ip的机器来访问某个端口。

root@node2:~# ufw allow from 192.168.0.202 to any port 80 proto tcp
Rule added
# 这里已经把之前的规则删除了,只留下端口22,然后添加80端口的访问规则
# 可以看到80端口的规则from 变成 固定的IP地址
root@node2:~# ufw status 
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere                  
80/tcp                     ALLOW       192.168.0.202             
22 (v6)                    ALLOW       Anywhere (v6) 

然后在node1机器上测试,访问成功。

root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200

在centos机器上测试,访问失败。

[root@centos ~]# curl 192.168.0.203 --connect-timeout 2
curl: (28) Connection timed out after 2045 milliseconds

只开放UDP的端口,然后用tcp来访问该端口也会失败。

root@node2:~# ufw allow 8090/udp
Rule added
Rule added (v6)
root@node2:~# ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere                  
80/tcp                     ALLOW       192.168.0.202             
8090/udp                   ALLOW       Anywhere                  
22 (v6)                    ALLOW       Anywhere (v6)             
8090/udp (v6)              ALLOW       Anywhere (v6)             

root@node2:~# nc -l 8090
# 用nc命令去扫描8090端口
root@node1:~# nc -v -w 2 192.168.0.203 -z 8090
nc: connect to 192.168.0.203 port 8090 (tcp) failed: Connection refused

协议+IP(from to)+端口(from to)可以识别成一个唯一的链接。然后根据这个规则,可以随意的设计防火墙的访问规则。

2.3.4 ufw的限流规则

ufw除了单纯的拒绝,允许以外,还有一个限流的规则,防止同一个IP的暴力访问。使用方式如下:

root@node2:~# ufw limit 80
Rule added
Rule added (v6)

 然后在centos上访问80端口,可以看到第6次访问就失败了。前面的5次都访问成功。

[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
000[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null

ufw  supports  connection  rate limiting, which is useful for protecting against brute-force login attacks. When a limit rule is used, ufw will normally allow the connection but will deny connections if an IP address attempts to initiate 6 or more connections within 30 seconds

也就是说 30秒内大于等于6次访问就会被拒绝。

2.3.5 删除规则

推荐使用序号删除,从后往前删除,要是从前面删除,序号重新排序。

root@node2:~# ufw status numbered 
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22                         ALLOW IN    Anywhere                  
[ 2] 80/tcp                     ALLOW IN    192.168.0.202             
[ 3] 8090/udp                   REJECT IN   Anywhere                  
[ 4] 8090/tcp                   ALLOW IN    Anywhere                  
[ 5] 80                         LIMIT IN    Anywhere                  
[ 6] 22 (v6)                    ALLOW IN    Anywhere (v6)             
[ 7] 8090/udp (v6)              REJECT IN   Anywhere (v6)             
[ 8] 8090/tcp (v6)              ALLOW IN    Anywhere (v6)             
[ 9] 80 (v6)                    LIMIT IN    Anywhere (v6)             

# 根据序号删除
root@node2:~# ufw delete 8
Deleting:
 allow 8090/tcp
Proceed with operation (y|n)? y
Rule deleted (v6)
root@node2:~# ufw status numbered 
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22                         ALLOW IN    Anywhere                  
[ 2] 80/tcp                     ALLOW IN    192.168.0.202             
[ 3] 8090/udp                   REJECT IN   Anywhere                  
[ 4] 8090/tcp                   ALLOW IN    Anywhere                  
[ 5] 80                         LIMIT IN    Anywhere                  
[ 6] 22 (v6)                    ALLOW IN    Anywhere (v6)             
[ 7] 8090/udp (v6)              REJECT IN   Anywhere (v6)             
[ 8] 80 (v6)                    LIMIT IN    Anywhere (v6)             

root@node2:~# 

2.3.6 ufw的规则生效顺序

ufw的规则是,序号最小的先生效。

root@node2:~# ufw status numbered 
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22                         ALLOW IN    Anywhere                  
[ 2] 80/tcp                     ALLOW IN    192.168.0.202             
[ 3] 80                         LIMIT IN    Anywhere                  
[ 4] 22 (v6)                    ALLOW IN    Anywhere (v6)             
[ 5] 80 (v6)                    LIMIT IN    Anywhere (v6)  

来个试验。

访问80端口

序号2       从192.168.0.202访问没有任何限制。

序号3       从别的机器访问是有ratelimit的。

可以看到centos30秒内第6次访问被决绝。 序号3生效

[root@centos ~curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200[root@centos ~]# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
000[root@centos ~]# 

从node1访问,30秒内10次全部成功。对于192.168.0.202来说序号2 先生效。

root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# 

现在调整80端口的规则顺序,limit 80 在 allow 80 的前面了。

root@node2:~# ufw delete 5
Deleting:
 limit 80
Proceed with operation (y|n)? y
Rule deleted (v6)
root@node2:~# ufw delete 3
Deleting:
 limit 80
Proceed with operation (y|n)? y
Rule deleted
root@node2:~# ufw insert 1 limit 80
Rule inserted
Rule inserted (v6)
root@node2:~# ufw status numbered 
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 80                         LIMIT IN    Anywhere                  
[ 2] 22                         ALLOW IN    Anywhere                  
[ 3] 80/tcp                     ALLOW IN    192.168.0.202             
[ 4] 80 (v6)                    LIMIT IN    Anywhere (v6)             
[ 5] 22 (v6)                    ALLOW IN    Anywhere (v6)   

再次在node1测试,第6次访问被决绝!对于192.168.0.202 来说 序号1 先生效!

root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
200root@node1:~# curl -s 192.168.0.203  -w '%{http_code}' -o /dev/null
000root@node1:~# 

以上就是ufw的基本用法,ufw还有路由功能,还没研究,有空补上。

 类似资料: