Ubuntu 18.04 防火墙设置ufw详解

Ubuntu18.04 自带防火墙程序ufw,只是安装后并没有默认打开,用了一下发现比较容易使用,本文整理记录了我的ufw使用实践,并重点翻译了ufw官方帮助文档里一些常用配置。

这里先mark几个有用链接:
UFW防火墙简单设置: https://wiki.ubuntu.org.cn/UFW
高级操作:
https://help.ubuntu.com/community/UFW#Advanced_Example
官方帮助文档:
http://manpages.ubuntu.com/manpages/bionic/man8/ufw.8.html

基本操作

注:所有ufw操作命令都需要root权限,普通用户需要加sudo执行。下文不再单独说明。

启用、禁止防火墙

下面的命令我加了中文标注以方便理解,如果有英文,则是直接复制自官方帮助文档。

# 开启防火墙并随系统启动。reloads firewall and enables firewall on boot.
ufw enable 

这个语句看着简单,但是要小心使用。Ubuntu安装完毕,默认没有启动ufw。所以如果直接运行上述语句,那么它启动后就会使用默认规则,禁止一切流量,包括SSH的22端口,如果本来就是在SSH上远程操作,那么悲剧了,无法再进行任何远程操作。因此对于远程操作,ufw允许在没有enable ufw之前就可以先添加一条规则来开放ssh的22端口 ufw allow port 22, 然后再执行ufw enable命令。

# 关闭所有外部对本机的访问(本机访问外部仍然正常)
ufw enable default deny 

# 关闭防火墙 unloads firewall and disables firewall on boot
ufw disable

# 关闭并恢复到默认安装设置。 Disables  and  resets  firewall to installation defaults.
ufw reset

查看防火墙状态

ufw status #最简单命令
ufw status verbose # 这个会额外显示logging的设置,默认是打开,等级是low。
ufw status numbered # 这个会按照数字显示每一个rule,方便后来使用delete ruleNum来删除某条规则。
这个数字顺序很重要,后续会介绍。

防火墙规则设置

Ufw允许设置多条规则,这些规则是顺序执行的,如果判定当前请求符合某条规则,则不会继续执行该规则后面的所有规则。

完整的规则命令如下,[ ]内的是可选参数,可以省略。规则命令大致分为两类,简介类型和标准类型。从字面上就可以看出,简洁类型就是那些短小精悍型规则 🙂

ufw [--dry-run] [rule] [delete] [insert NUM] 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]
--dry-run 用来测试语法指令是否正确,并不将该规则写入。don't modify anything, just show the changes

打开或关闭某个端口

ufw allow 80 #允许外部访问80端口, 默认协议是TCP和UDP, 二者都被允许访问
ufw allow 80/tcp #允许外部使用TCP协议访问80端口
ufw deny 80 #禁止外部访问80端口, 默认协议是TCP和UDP, 二者都被禁止访问

打开或关闭某个服务

ufw允许使用某些服务名来代替端口,比如ftp,ssh, http, https等等,可以使用sudo less /etc/services 列出当前注册的服务,比如下面是本机关于http和SSH的定义。这些在添加ufw规则时最好确认一下它内容再说。

ufw allow http # 等效于80/tcp, 允许外部使用TCP协议访问80端口
ufw deny ssh #禁止外部访问2端口
ufw allow from 192.168.1.0/24 to any app <name> #允许192.168.1.X地址访问某个app,注意 any 和 app 是两个分别的关键词, 不能删掉。

打开或关闭某个应用(App)

ufw还允许使用它实现定制好的App rules来直接添加规则,比如Samba文件共享服务。首先可以使用ufw app list 命令列出ufw支持的App。下面列出并过滤除了Samba

然后再执行 ufw app info Samba 即可以查看它的详细定义。可以看到它使用了4个端口:

然后就可以使用如下命令设置该应用访问:

ufw allow Samba # 允许访问Samba服务
ufw deny Samba

IP 地址过滤

IP地址可以是单个地址,也可以是一个地址段

ufw allow from 192.168.1.0/24  # 允许192.168.1.1 到192.168.1.254,

/24是子网掩码,表示IP地址的前24bit和输入参数相同,IP V4例使用4个字节共32bit地址,所以上面的192.168.1.0/24就涵盖整个192.168.1.0~192.168.1.255共256个地址,除去系统禁止使用的0和255,还有254个地址可以使用。类似的, /32就表示单一IP,/30则表示和输入参数前30bit相同的4个IP地址。

ufw deny proto tcp from 10.0.0.0/8 to 192.168.0.1 port 22 #拒绝所有的TCP流量从10.0.0.0/8 到192.168.0.1地址的22端口
ufw allow proto tcp from 192.168.1.0/24 to any port 22 # 允许192.168.1.x的IP地址访问SSH 端口

上面的目标地址192.168.0.1可以换成any。结合此规则就可以限制某些端口或者服务只能某些ip地址或内部局域网内访问。

防火墙规则操作

规则执行顺序

前面提到防火墙的规则是顺序执行的,如果判定当前请求符合某条规则,则不会继续执行该规则后面的所有规则。所以具体的一些规则要放在前面,通用的规则放在后面。比如这个例子:

ufw deny from 192.168.0.1 to any port 22 # 拒绝来自192.168.0.1对22端口的访问
ufw deny from 192.168.0.7 to any port 22 # 拒绝来自192.168.0.7对22端口的访问
ufw allow from 192.168.0.0/24 to any port 22 proto tcp # 允许来自192.168.0.X对22端口的访问

上面3行就实现了拒绝192.168.0.1和192.168.0.7, 而对其他192.168.0.X里的252个有效IP地址都放行。如果把第3行放在最上面,则那两句deny不起作用。

删除规则

删除规则有两种方法: 直接引用原文删除法和索引删除法。

直接引用原文删除 就是找出原有规则, 在ufw RULE 之间加上关键词delete,就可以删除该规则

ufw allow ssh # allow ssh service
ufw delete allow ssh # remove "allow ssh server" => disable ssh

索引删除法就是先找出该规则的索引,利用 ufw status numbered 列出来,然后执行 ufw delete NUM 就可以了。如下面的例子里,就可以通过 ufw delete 2来删除80端口对应的规则。

插入规则

有时候根据需要,因为顺序执行的缘故,某些规则要指定放在某个规则前面,此时就需要在指定位置插入规则。插入规则需要事先知道当前规则列表中的序号,决定插入位置的序号后,使用 ufw insert NUM allow|deny ... 来实现插入。

防火墙事件记录Logging

打开/关闭 Logging

ufw logging on # enable logging. Default logging level is low
ufw logging off #disable logging.

Logging 等级

上面 logging on后 默认是low 等级。ufw支持多个等级: 'low', 'medium', 'high' and 'full'。简单说low记录事件做少,其他等级记录逐级增加。官方文档如下描述:

Log levels  above  medium  generate  a  lot of logging output, and may quickly fill up your disk. Log level medium may generate a lot of logging output on a busy system.

所以使用默认的low level就够了。log文件保存在/var/log/ufw.log 文件内,可以用tail -n COUNT file的形式显示最后几行

Logging 消息分析

结合下面例子:
Nov  11 18:24:57 HOSTNAME: [ Uptime] [UFW BLOCK] IN= OUT=wlan0  MAC=a6:8d:e2:51:62:4c:f0:4b:3a:4f:80:30:08:00 
SRC=77.72.85.26 DST=157.230.26.180
LEN=60 TOS=0x00 PREC=0x00 TTL=64  ID=47904 DF PROTO=TCP SPT=52279 DPT=9001 WINDOW=14600 RES=0x00 SYN  URGP=0

基本我们就是关注这几项, SPT: 源端口, DPT:目标端口, SRC: 源IP地址 and 目标IP地址。我把这个网页上的内容直接拿过来了放在下面: https://ubuntuforums.org/showthread.php?t=2085110&p=12361050#post12361050

date It's good practice to watch the dates and times. If things are out of order or blocks of time are missing then an attacker probably messed with your logs.

Hostname The server’s hostname

Uptime The time in seconds since boot.

[UFW BLOCK] Logging event。

IN= and OUT=wlan0 indicate whether it was incoming or outgoing. So this packet was outbound on my wlan0 connection.
Another example:
IN=eth0 OUT= The IN is the network interface name that the packet arrived on. The OUT is blank because the packet is not been re-transmitted, which might be the case if this was a router application.

MAC=a6:8d:e2:51:62:4c:f0:4b:3a:4f:80:30:08:00 These are the Machine Address Codes for the local area destination (a6:8d:e2:51:62:4c (eth0)) and source (f0:4b:3a:4f:80:30) network interface cards. In your case the source is probably the MAC of your ISP gateway NIC. 6 bytes each. The extra 2 bytes (08:00) at the end are the frame type, in this case it means "ethernet frame carried an IPv4 datagram".

SRC=77.72.85.26 DST=157.230.26.180 This indicates the source IP, who sent the packet initially and destination IP where the package should go.

LEN=60 This indicates the length of the packet.

TOS and PREC These are details about the packets that aren't really relevant for reading logs. They're set to 0 which means they're not relevant in this particular packet either. More here if you care.

TTL 64 = This indicates the "Time to live" for the packet. Basically each packet will only bounce through the given number of routers before it dies and disappears. If it hasn't found its destination before the TTL expires, then the packet will evaporate. This field keeps lost packets from clogging the internet forever.

ID=47904 Not sure what this one is, but it's not really important for reading logs. It might be ufw's internal ID system, it might be the operating system's ID.

PROTO=TCP This indicates the protocol of the packet. In this case it was TCP. The other one you'll see is UDP. More explanation here.

SPT=52279
 This indicates the source port.

DPT=9001 This indicates the destination port. The source & destination port will be the most important fields to understand (along with source & destination IPs) when dissecting firewall logs.

WINDOW=14600 This indicates the size of packet the sender is willing to receive.

RES=0x00 This bit is reserved for future use & is always set to 0. Basically it's irrelevant for log reading purposes.

SYN URGP=0 SYN indicates that this connection requires the three-way handshake typical of TCP connections. URGP indicates whether the urgent pointer field is relevant. 0 means it's not. Doesn't really matter for firewall log reading. The important one here is "SYN" meaning it it attempting to make a NEW connection. 

This log entry means the attempt has been blocked.