作者选择了 COVID-19 救援基金作为 Write for Donations计划的一部分,接受捐款。
介绍
防火墙可能是防御网络攻击最重要的防线之一.从头开始配置防火墙的能力是一个赋权技能,使管理员能够控制他们的网络。
Packet Filter (PF)是一个著名的防火墙应用程序,由安全驱动的OpenBSD项目在上游维护. 它被更准确地表述为包过滤工具,因此这个名称,以其简单的语法,方便用户,以及广泛的特征而出名. PF 是默认状态的防火墙,将连接信息存储在可以用于分析目的的_状态表. PF是FreeBSD基础系统的一部分,并得到强大的开发者社区的支持. 尽管FreeBSD和OpenBSD版本的PF与内核架构相关,但一般而言它们的语法相似. 根据其复杂性,共同规则可以被修改,以便以相对较少的努力进行两种分配.
在本教程中,您将从头开始在 FreeBSD 12.1 服务器上构建防火墙,使用 PF. 您将设计一个可以用作未来项目的模板的基本规则集。
注意:从 2022 年 7 月 1 日开始,DigitalOcean 不再支持通过控制面板或 API 创建新的 FreeBSD Droplets. 但是,您仍然可以使用自定义图像创建 FreeBSD Droplets. 了解如何按照 我们的产品文档导入自定义图像到 DigitalOcean。
前提条件
在您开始本教程之前,您将需要以下内容:
- 1G FreeBSD 12.1 服务器(或 [ZFS] (https://www.freebsd.org/doc/handbook/zfs.html) 或 [UFS] (https://www.freebsd.org/doc/handbook/filesystems.html ). 您可以使用 $[ How to get started with FreeBSD 教程] (https://andsky.com/tech/tutorials/how-to-get-started-with-freebsd) 来设置您的服务器, 以达到您的首选配置 。
- FreeBSD没有默认启用的防火墙——定制是FreeBSD特质的标志. 因此,当您首次启动您的服务器时,您需要临时保护,同时配置 PF 。 咨询您的云提供商,确定在开始前立即保护的最快路径. 无论您选择哪种方法,您的临时防火墙必须只允许进入 SSH 流量,并且可以允许所有类型的出行流量. .
步骤1 - 构建您的初步规则
您将通过编写一组初步的规则来开始本教程,提供基本的保护和从互联网访问关键服务。
有两种方法来构建防火墙: default deny 和 default permit. 默认拒绝方法会阻止所有流量,只允许规则中指定的内容。
PF 规则集被写入一个名为 /etc/pf.conf
的配置文件中,这也是其默认位置。只要在 /etc/rc.conf
配置文件中指定,可以将此文件存储在其他地方。
与您的非根用户登录您的服务器:
1[environment local]
2ssh freebsd@your_server_ip
然后创建您的 /etc/pf.conf
文件:
1sudo vi /etc/pf.conf
如果您想在教程中任何时候看到完整的基本规则,您可以参阅 步骤 4或 [步骤 8](https://andsky.com/tech/tutorials/how-to-configure-pf-on-freebsd-12-1 step-8%E2%80%94-reverting-back-to-your-base-rulesetules-(可选))。
根据三个核心行动: " 块 " 、 " 通过 " 和 " 匹配 " 过滤组合。 与其他选择相结合,它们就形成了规则。 当包件符合规则中规定的标准时,即采取行动。 如你所想,通行 ' 和
封锁 ' 规则将通行'和
封锁 ' 交通。 " 匹配 " 规则在找到匹配标准时对一个数据包进行动作,但不会通过或阻挡。 例如,您可以在匹配的包上执行_network地址翻译_(NAT)而不通过或屏蔽它,它会坐在那里,直到您告诉它做另一个规则的某事,比如路由它到另一个机器或网关.
接下来,将第一个规则添加到您的 /etc/pf.conf
文件中:
1[label /etc/pf.conf]
2block all
这个规则阻止了各个方向的所有形式的流量. 由于它不指定方向,它默认为进
和离开
。 这个规则对于需要从世界中隔离的本地工作站是合法的,但它在很大程度上是不切实际的,并且不会在远程服务器上工作,因为它不允许SSH流量。
查看您的 /etc/pf.conf
文件,以允许 SSH 流量使用以下突出的行:
1[label /etc/pf.conf]
2block all
3pass in proto tcp to port 22
<$>[注] 注: 或者您可以使用协议的名称:
1[label /etc/pf.conf]
2block all
3pass in proto tcp to port ssh
为了保持一致性,我们将使用端口号码,除非有合理的理由不这样做. 在/etc/services
文件中有详细的协议列表及其各自的端口号码,建议您查看。
PF从顶部到底部顺序处理规则,因此当前的规则集最初会阻止所有流量,但如果下一行的标准匹配,则会通过它,这在这种情况下是SSH流量。
现在你可以 SSH 到你的服务器,但你仍然阻止所有形式的流量,这是一个问题,因为你不能从互联网上访问关键的服务来安装包,更新你的时间设置,等等。
要解决此问题,请将以下突出规则附加到您的 /etc/pf.conf
文件的末尾:
1[label /etc/pf.conf]
2block all
3pass in proto tcp to port { 22 }
4pass out proto { tcp udp } to port { 22 53 80 123 443 }
您的规则表现在允许出 [SSH] (https://andsky.com/tech/tutorials/understanding-the-ssh-encryption-and-connection-process), [DNS] (https://andsky.com/tech/tutorials/an-introduction-to-dns-terminology-components-and-concepts), [HTTP] (https://andsky.com/tech/tutorials/http-1-1-vs-http-2-what-s-the-difference), [NTP] (https://andsky.com/tech/tutorials/recommended-steps-for-new-freebsd-12-0-servers# how-to-configure-ntp-to-keep-accurate-time), 和 HTTPS 交通, 以及阻断所有内向交通, (SSH除外). 您将端口编号和协议置于卷轴括号中,这在 PF 语法中构成一个列表,允许您在需要时添加更多的端口编号. 您还添加了关于 " 53 " 和 " 123 " 的UDP协议的通关规则,因为DNS和NTP经常在TCP和UDP协议之间切换. 你几乎完成了初步规则,只需要增加一些规则就可以实现基本的功能.
完成初步规则集以突出规则:
1[label Preliminary Ruleset /etc/pf.conf]
2set skip on lo0
3block all
4pass in proto tcp to port { 22 }
5pass out proto { tcp udp } to port { 22 53 80 123 443 }
6pass out inet proto icmp icmp-type { echoreq }
保存和退出文件。
您创建了一个)](https://www.freebsd.org/cgi/man.cgi?query=ping§ion=8&manpath=freebsd-release-ports)工具来解决问题。 inet
选项代表了 IPv4 地址家族。
ICMP 是一种多用途的消息传输协议,由网络设备用于各种类型的通信。 例如, ping 工具使用一种称为 echo request 的消息类型,您已将其添加到您的icmp_type
列表中。 作为预防措施,您只允许您需要的消息类型来防止不受欢迎的设备与您的服务器联系。
您现在有一个工作规则集,为大多数机器提供基本功能. 在下一节中,让我们通过启用PF并测试您的初步规则集来确认一切正常工作。
步骤2 - 测试您的初步规则
在此步骤中,您将测试您的初步规则集,并从云防火墙过渡到您的 PF 防火墙,允许 PF 完全接管。您将使用 pfctl
实用程序激活您的规则集,这是 PF 的内置命令行工具,以及与 PF 接口的主要方法。
PF 规则集仅仅是文本文件,这意味着在加载新规则集时没有复杂的程序。你可以加载新规则集,而旧规则集已经消失。
FreeBSD使用被称作 ["rc" system (https://www.freebsd.org/cgi/man.cgi?query=rc&sektion=8&manpath=freebsd-release-ports) 的外壳脚本网络来管理服务在启动时的启动方式;我们在各种"rc"配置文件中指定了这些服务. 对于PF等全球服务,请使用 " /etc/rc.conf " 文件。 由于 " rc " 文件对FreeBSD系统的福祉至关重要,不应直接编辑。 相反,FreeBSD提供了一个名为"sysrc"的命令行工具,旨在帮助您安全地编辑这些文件.
让我们使用sysrc
命令行实用程序启用 PF:
1sudo sysrc pf_enable="YES"
2sudo sysrc pflog_enable="YES"
通过打印您的 /etc/rc.conf
文件的内容来验证这些更改:
1sudo cat /etc/rc.conf
您将看到以下结果:
1[secondary_label Output]
2pf_enable="YES"
3pflog_enable="YES"
您还启用了pflog
服务,这反过来也启用了pflogd
日志模板用于在PF中登录。
您在您的 /etc/rc.conf
文件中指定两个全球服务,但直到您重新启动服务器或手动启动服务器之前,它们将不会初始化。
通过重新启动服务器启动 PF:
1sudo reboot
连接将被放弃. 给它几分钟更新。
现在 SSH 回到服务器:
1[environment local]
2ssh freebsd@your_server_ip
虽然您已初始化您的 PF 服务,但您实际上还没有加载您的 /etc/pf.conf
规则集,这意味着您的防火墙尚未激活。
用「pfctl」加载规则集:
1sudo pfctl -f /etc/pf.conf
如果没有错误或消息,这意味着您的规则集没有错误,防火墙是活跃的。
现在PF正在运行,您可以将服务器从云防火墙中分离出来。 请咨询您的云提供商,以确保您在临时保护中使用的任何东西都被禁用。
为了更好地测量,重新启动您的服务器:
1sudo reboot
几分钟后,SSH 返回您的服务器:
1[environment local]
2ssh freebsd@your_server_ip
PF现在是您正在运作的防火墙,您可以通过使用 pfctl 实用程序访问一些数据来确保它运行。
让我们来看看一些统计数据和数值,用‘pfctl -si’:
1sudo pfctl -si
您通过了-si
旗帜,这代表了 show info. 这是您可以使用 pfctl 的许多滤波器参数组合之一,用于分析有关您的防火墙活动的数据。
您将看到以下表格数据(值将因机器而异):
1[secondary_label Output]
2Status: Enabled for 0 days 00:01:53 Debug: Urgent
3
4State Table Total Rate
5 current entries 5
6 searches 144 1.3/s
7 inserts 11 0.1/s
8 removals 6 0.1/s
9Counters
10 match 23 0.2/s
11 bad-offset 0 0.0/s
12 fragment 0 0.0/s
13 short 0 0.0/s
14 normalize 0 0.0/s
15 memory 0 0.0/s
16 bad-timestamp 0 0.0/s
17 congestion 0 0.0/s
18 ip-option 0 0.0/s
19 proto-cksum 0 0.0/s
20 state-insert 0 0.0/s
21 state-limit 0 0.0/s
22 src-limit 0 0.0/s
23 synproxy 0 0.0/s
24 map-failed 0 0.0/s
由于你刚刚激活了规则集,你还不会看到很多信息,但是这个输出显示PF已经记录了23个匹配的规则,这意味着你的规则集的标准匹配了23次。
您的规则也允许流量从互联网上访问一些关键服务,包括 ping 实用程序。
让我们检查互联网连接和 DNS 服务与 ping 对 google.com
:
1ping -c 3 google.com
由于您运行了计数旗 -c 3
,您将看到三个成功的连接响应:
1[secondary_label Output]
2PING google.com (172.217.0.46): 56 data bytes
364 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms
464 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms
564 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms
6
7--- google.com ping statistics ---
83 packets transmitted, 3 packets received, 0.0% packet loss
9round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms
确保您可以使用以下命令访问 pkgs 存储库:
1sudo pkg upgrade
如果有任何要升级的软件包,请继续升级。
如果这两个服务都工作,这意味着你的防火墙正在工作,你现在可以继续。虽然你的初步规则集提供了保护和功能,但它仍然是一个基本规则集,并可能使用一些改进。
步骤3 - 完成您的基本规则
在此步骤中,您将从初步的规则集中建立起,以完成您的基本规则集,您将重新组织一些规则并使用更先进的概念。
添加宏和表
在初步规则设置中,您将所有参数密码为每个规则,即组成列表的端口号。这可能在未来变得无法管理,取决于您的网络的性质。 为组织目的,PF 包括 macros、 lists 和 tables。
打开文件,将一些参数转换为宏:
1sudo vi /etc/pf.conf
现在将以下内容添加到规则集的顶部:
1[label /etc/pf.conf]
2vtnet0 = "vtnet0"
3icmp_types = "{ echoreq }"
4. . .
用新的变量修改以前的 SSH 和 ICMP 规则:
1[label /etc/pf.conf]
2. . .
3pass in on $vtnet0 proto tcp to port { 22 }
4. . .
5pass inet proto icmp icmp-type $icmp_types
6. . .
您以前的 SSH 和 ICMP 规则现在使用宏。 变量名称由 PF 的美元符号语法表示。 您将您的 vtnet0
界面分配给具有相同名称的变量,就像一个形式一样,这使您有机会在未来更名。
接下来,您将实施一个 table,类似于 macro,但旨在存储 IP 地址组。 让我们创建一个非可路由 IP 地址的表,这些地址通常在 denial of service attacks (DOS) 中发挥作用。 您可以使用 RFC6890,该表定义了专用 IP 地址注册表。 您的服务器不应该通过公开面向接口发送或接收这些地址的数据包。
通过直接在icmp_types
宏中添加以下内容来创建此表:
1[label /etc/pf.conf]
2. . .
3table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 \
4 172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 \
5 192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \
6 240.0.0.0/4 255.255.255.255/32 }
7. . .
现在,在设置跳过 lo0
规则下的<rfc6890>
表中添加您的规则:
1[label /etc/pf.conf]
2. . .
3set skip on lo0
4block in quick on egress from <rfc6890>
5block return out quick on egress to <rfc6890>
6. . .
在这里,你介绍了返回 ' 方案,它补充了你的
排除 ' 规则。 这将丢弃数据包, 同时向试图建立这些连接的主机发送_ RST 消息, 这对于分析主机活动有用 。 然后,您添加)_ 。 这通常是一种寻找默认路线的更清洁的方法,特别是在复杂的网络中. `快克 ' 关键词在不考虑其他规则的情况下立即执行规则。 例如,如果一个有不合逻辑的 IP 地址的包试图连接到服务器,那么您想要立即丢弃连接,并且没有理由通过规则的其余部分运行该包.
保护您的 SSH 端口
由于您的SSH 端口对公众开放,它会受到开发利用. 攻击者的更明显的警告迹象之一是大量登入尝试. 例如,如果同一个IP地址试图在一秒内登录到您的服务器上10次,你可以假设它不是用人手完成的,而是用试图破解您登录密码的计算机软件完成的. 这些类型的系统利用经常被称作_brute force_攻击,如果服务器的密码很弱,通常成功.
<$>[警告] 警告: 我们强烈建议在所有服务器上使用公钥身份验证。请参阅DigitalOcean关于[基于密钥的身份验证]的教程(https://andsky.com/tech/tutorials/how-to-configure-ssh-key-based-authentication-on-a-freebsd-server)。
PF 具有用于处理暴力和其他类似攻击的内置功能. 使用 PF 您可以限制单个主机允许的同时连接尝试数量. 如果主机超过这些限制,连接将被放弃,并将被禁止从服务器上。
更改以前的 SSH 规则以限制单个主机同时连接的数量,如下所示:
1[label /etc/pf.conf]
2. . .
3pass in on $vtnet0 proto tcp to port { 22 } \
4 keep state (max-src-conn 15, max-src-conn-rate 3/1, \
5 overload <bruteforce> flush global)
6. . .
您添加 保持状态
选项, 允许您定义超载表的状态标准 。 您通过 max- src- conn
参数来指定单个主机每秒允许的同步连接数量, 和 max- src- conn- rate
参数来指定单个主机每秒允许的新连接数量 。 请具体说明最大-弧相干'的
15'个连接,而最大-弧相干'的
3'个连接。 如果一个主机超过这些限制,则"超载"机制将源IP添加到QQbruteforce 表格中,禁止它们进入服务器. 最后, " flush Global " 选项立即取消了连接.
您已在 SSH 规则中定义过载表,但未在规则集中声明该表。
在icmp_types
宏下方添加<bruteforce>
表:
1[label /etc/pf.conf]
2. . .
3icmp_types = "{ echoreq }"
4table <bruteforce> persist
5. . .
持久
关键字允许在规则集中存在一个空的表,如果没有它,PF会抱怨表中没有IP地址。
这些措施确保您的 SSH 端口受到强大的安全机制的保护。PF 允许您配置快速解决方案来保护您免受灾难性的剥削。
清洁你的交通
注意:以下部分描述了 TCP/IP 协议套件的基本基础。 如果您打算构建 Web 应用程序或网络,您最好掌握这些概念。 请参阅 DigitalOcean 的 介绍网络术语,接口和协议 教程。
由于TCP/IP协议套件的复杂性,以及恶意行为者的持续性,包往往会出现差异和模糊性,如重叠的IP片段,错误的IP地址等。
当数据通过互联网旅行时,它通常在源头上被分成较小的片段,以适应目标主机的传输参数,在那里它被重新组装成完整的包裹。不幸的是,入侵者可以以多种方式劫持这个过程,超出本教程的范围。
添加直接在您的区块所有
规则之前的扫描
关键字:
1[label /etc/pf.conf]
2. . .
3set skip on lo0
4scrub in all fragment reassemble max-mss 1440
5block all
6. . .
这条规则适用于所有进入的流量。 包括防止碎片进入系统的 " 碎片再组装 " 选项。 相反,它们被缓存在内存中,直到它们重新组装成完整的包,这意味着你的过滤规则只需要与统一的包相抗衡. 您还包括`max-ms 1440' 选项,它代表重新组合的 TCP 包的最大段尺寸_最大段大小_,也称为_活负荷_。 您指定了一个 1440 字节的值, 它在大小和性能之间保持平衡, 给信头留下很多空间 .
碎片化的另一个重要方面是被称为 maximum transmission unit (MTU) 的术语。 TCP/IP 协议允许设备进行包尺寸的谈判,以便进行连接。 目标主机使用 ICMP 消息来告知其 MTU 的源 IP,这个过程被称为 MTU 路径发现。 特定的 ICMP 消息类型是 destination unreachable。 您将通过将unreach
消息类型添加到您的icmp_types
列表来启用 MTU 路径发现。
您将使用您的服务器的默认 MTU 1500 字节,可以用ifconfig
命令确定:
1ifconfig
您将看到包含当前 MTU 的以下输出:
1[secondary_label Output]
2vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
3. . .
更新icmp_types
列表以包含 destination unreachable 消息类型:
1[label /etc/pf.conf]
2vtnet0 = "vtnet0"
3icmp_types = "{ echoreq unreach}"
4. . .
现在你有政策来处理碎片化,进入你的系统的包将是统一和一致的,这是可取的,因为有这么多的设备通过互联网交换数据。
你现在要努力防止另一个安全隐患 被称为_IP spoofing_. 攻击者经常改变其源IP,使其看起来像是居住在一个组织内一个可信赖的节点上. PF 包括处理被窃取源IP的_antispoofing_指令. 当应用到特定的接口时,反渗出会阻断该接口网络上的所有流量(除非它来自该接口). 例如,如果对居住在 " 5.5.5.1/24 " 的接口进行防盗,则来自 " 5.5. 5.0/24 " 网络的所有流量均不能与系统通信,除非其来源于该接口.
添加以下突出内容,以便在您的vtnet0
界面中应用反弹性:
1[label /etc/pf.conf]
2. . .
3set skip on lo0
4scrub in
5antispoof quick for $vtnet0
6block all
7. . .
保存和退出文件。
这个反间谍规则说,来自)的所有流量只能通过vtnet0
接口,否则它将立即被快速
关键字丢弃。
要证明你的反弹规则,你会打印你的规则集在屏幕上其语法形式. 规则在PF通常是写在缩短的形式,但他们也可以写在语法形式。
使用pfctl
打印/etc/pf.conf
的内容,使用以下命令:
1sudo pfctl -nvf /etc/pf.conf
这个pfctl
命令采用了-nvf
旗帜,这些旗帜打印了规则集并测试它,而无需实际上加载任何东西,也被称为 dry run。
您将看到类似于下列输出的东西在消毒部分中:
1[secondary_label Output]
2. . .
3block drop in quick on ! vtnet0 inet from your_server_ip/20 to any
4block drop in quick on ! vtnet0 inet from network_address/16 to any
5block drop in quick inet from your_server_ip to any
6block drop in quick inet from network_address to any
7block drop in quick on vtnet0 inet6 from your_IPv6_address to any
8. . .
你的反对规则发现它是)服务器是network_address/16
网络的一部分,并且有一个额外的IPv6地址。
您的反洗规则是您基本规则的最后一个添加,在下一步,您将启动这些更改并进行一些测试。
第4步:测试你的基本规则
在此步骤中,您将审查和测试您的基本规则集,以确保一切正常工作。最好避免同时实施太多规则而不测试它们。
以下是您完整的基本规则:
1[label Base Ruleset /etc/pf.conf]
2vtnet0 = "vtnet0"
3icmp_types = "{ echoreq unreach }"
4table <bruteforce> persist
5table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 \
6 172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 \
7 192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \
8 240.0.0.0/4 255.255.255.255/32 }
9
10set skip on lo0
11scrub in all fragment reassemble max-mss 1440
12antispoof quick for $vtnet0
13block in quick on $vtnet0 from <rfc6890>
14block return out quick on egress to <rfc6890>
15block all
16pass in on $vtnet0 proto tcp to port { 22 } \
17 keep state (max-src-conn 15, max-src-conn-rate 3/1, \
18 overload <bruteforce> flush global)
19pass out proto { tcp udp } to port { 22 53 80 123 443 }
20pass inet proto icmp icmp-type $icmp_types
请确保您的 /etc/pf.conf
文件与此处的完整基本规则集相同,然后继续保存并退出文件。
您的完整的基本规则为您提供:
- 可以定义关键服务和设备的宏集.
- 处理包件破碎和不合逻辑的IP地址的网络卫生政策。
- 一个 default 拒绝 过滤结构, 它会阻断一切, 只允许您指定的内容 。
- 进入 SSH 访问,但限制主机可以进行同步连接的次数.
- 联合国 外出交通政策 让你从互联网上获得一些关键服务
- ICMP政策,提供对接器和MTU路径的发现。 .
运行以下pfctl
命令以进行干跑:
1sudo pfctl -nf /etc/pf.conf
你通过-nf
的旗帜,告诉pfctl
在不加载的情况下运行规则集,如果有什么不对劲,会引发错误。
现在,没有遇到的错误,加载规则集:
1sudo pfctl -f /etc/pf.conf
如果没有错误,这意味着您的基本规则集是活跃的,并正常运作,正如教程中之前的那样,您将对您的规则集进行一些测试。
第一次测试互联网连接和DNS服务:
1ping -c 3 google.com
您将看到以下结果:
1[secondary_label Output]
2PING google.com (172.217.0.46): 56 data bytes
364 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms
464 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms
564 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms
6
7--- google.com ping statistics ---
83 packets transmitted, 3 packets received, 0.0% packet loss
9round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms
然后,检查你是否进入了pkgs
存储库:
1sudo pkg upgrade
再一次,如果需要,升级包。
最后,重新启动您的服务器:
1sudo reboot
给您的服务器几分钟重新启动,您已经完成并实施了您的基本规则,这在您的进展方面是一个重要的步骤,您现在已经准备好探索PF的一些高级功能。
步骤5 - 管理你的过度负荷表
随着时间的推移,bruteforce
过载表将充满恶意IP地址,需要定期清除,攻击者不太可能继续使用相同的IP地址,因此将它们存储在过载表中很长一段时间是不直观的。
您将使用pfctl
手动清除已存储在过载表中48小时或更长时间的IP地址,使用以下命令:
1sudo pfctl -t bruteforce -T expire 172800
你会看到类似的输出:
1[secondary_label Output]
20/0 addresses expired.
您通过了t bruteforce
旗帜,这代表 table bruteforce,以及-T
旗帜,允许您运行一小部分内置命令。在这种情况下,您运行了 expire
命令来清除所有t bruteforce
的条目,其时间值以秒为代表。
这个规则适用于快速修复,但一个更强大的解决方案是用 FreeBSD 的任务计划器 cron 来自动化这个过程。
在 /usr/local/bin
目录中创建一个 shell 脚本文件:
1sudo vi /usr/local/bin/clear_overload.sh
将以下内容添加到 shell 脚本中:
1[label /usr/local/bin/clear_overload.sh]
2#!/bin/sh
3
4pfctl -t bruteforce -T expire 172800
使用以下命令使文件可执行:
1sudo chmod 755 /usr/local/bin/clear_overload.sh
接下来您将创建一个 _ cron job_. 这些工作会根据您指定的时间重复运行 。 它们通常用于备份,或者任何需要每天同时运行的过程. 您用 crontab 文件创建 cron 工作 。 请参看man pages以了解更多关于cron(8)和crontab(5)的信息.
使用以下命令创建 root user crontab 文件:
1sudo crontab -e
现在将以下内容添加到 crontab 文件中:
1[label crontab]
2# minute hour mday month wday command
3
4 * 0 * * * /usr/local/bin/clear_overload.sh
保存和退出文件。
<$>[注] 注: 请将每个值与其相应的表输入对齐,以便可读性,如果在添加内容时情况不正确对齐。
这个 cron job 每天在深夜运行clear_overload.sh
脚本,从 _overload 表中删除 48 小时的 IP 地址。
步骤6 - 引入你的规则集的
在此步骤中,您将引入 anchors,用于将规则添加到主规则集中,无论是手动还是从外部文本文件中添加。
创建一个名为 /etc/blocked-hosts-anchor
的文件:
1sudo vi /etc/blocked-hosts-anchor
将以下内容添加到文件中:
1[label /etc/blocked-hosts-anchor]
2table <blocked-hosts> { 192.168.47.1 192.168.47.2 192.168.47.3 }
3
4block return out quick on egress from <blocked-hosts>
保存和退出文件。
这些规则声明和定义<blocked-hosts>
表,然后防止<blocked-hosts>
表中的每个IP地址访问来自外部世界的服务。
您仍然需要在您的 /etc/pf.conf
文件中声明:
1sudo vi /etc/pf.conf
现在,在区块所有
规则后添加以下栏规则:
1[label /etc/pf.conf]
2. . .
3block all
4anchor blocked_hosts
5load anchor blocked_hosts from "/etc/blocked-hosts-anchor"
6. . .
保存和退出文件。
这些规则声明被阻止_主机
并从/etc/blocked-hosts-anchor
文件中将规则加载到您的主要规则集中。
现在,通过使用pfctl
重新加载您的规则集来启动这些更改:
1sudo pfctl -f /etc/pf.conf
如果没有错误,则意味着您的规则集中没有错误,并且您的更改是活跃的。
使用「pfctl」來確認您的子正在運行:
1sudo pfctl -s Anchors
Anchors
的旗帜是Anchors Show
的意思,你会看到以下输出:
1[secondary_label Output]
2blocked_hosts
该pfctl
实用程序还可以通过-a
和-s
旗帜来解析您的的特定规则:
1sudo pfctl -a blocked_hosts -s rules
您将看到以下结果:
1[secondary_label Output]
2block return out quick on egress from <blocked-hosts> to any
的另一个特征是,它们允许您在不需要重新加载规则集的情况下添加规则,这可以用于测试,快速修复,紧急情况等。例如,如果内部主机表现异常,并且您想阻止它进行外部连接,您可以设置一个,允许您从命令行快速干预。
让我们打开 /etc/pf.conf
并添加另一个:
1sudo vi /etc/pf.conf
您将命名子rogue_hosts
,并将其放置在block all
规则中:
1[label /etc/pf.conf]
2. . .
3block all
4anchor rogue_hosts
5. . .
保存和退出文件。
要启动这些更改,请使用pfctl
重新加载规则集:
1sudo pfctl -f /etc/pf.conf
再次,使用pfctl
来验证正在运行:
1sudo pfctl -s Anchors
这将产生以下产出:
1[secondary_label Output]
2blocked_hosts
3rogue_hosts
现在子正在运行,您可以随时添加规则,通过添加以下规则来测试:
1sudo sh -c 'echo "block return out quick on egress from 192.168.47.4" | pfctl -a rogue_hosts -f -'
这会调用echo
命令及其字符串内容,然后将其输入到pfctl
实用程序中,以``符号,在那里将其处理成一个轴承规则。你会用sh -c
命令打开另一个壳会话。这是因为你在两个过程之间建立了一个管道,但需要sudo
特权在整个命令序列中继续存在。有多个方法来解决这一问题;在这里你会使用sudo sh -c
开启一个额外的壳过程。
现在,再次使用pfctl
来验证这些规则是有效的:
1sudo pfctl -a rogue_hosts -s rules
这将产生以下产出:
1[secondary_label Output]
2block return out quick on egress inet from 192.168.47.4 to any
的使用完全是局面性的,往往是主观的。像任何其他功能一样,使用有优点和缺点。 一些应用程序,如 blacklistd与的界面是设计的。 接下来,您将专注于与PF登录,这是网络安全的一个关键方面。 你的防火墙是没有用的,如果你看不到它正在做什么。
第7步:记录您的防火墙活动
在这一步骤中,你将与PF伐木公司合作,后者由一个名为 " pflog " 的假接口管理。 通过在/etc/rc.conf'文件中添加
pflog_uplied=YES'文件,在启动时启用了日志。 这使得pflogd守护进程能够将一个名为"pflog0"的界面,并以二进制格式将日志写入名为"/var/log/pflog"的文件. 日志可以从界面中实时解析出,也可以用 [tcpdump(8) (https://man.openbsd.org/tcpdump.8]] 工具读取"/var/log/pflog"文件.
首先从 /var/log/pflog
文件中访问一些日志:
1sudo tcpdump -ner /var/log/pflog
您通过底部
旗帜来格式化输出以便可读性,并指定要从中读取的文件,在您的情况下是/var/log/pflog
。
您将看到以下结果:
1[secondary_label Output]
2reading from file /var/log/pflog, link-type PFLOG (OpenBSD pflog file)
在这些早期阶段,在 /var/log/pflog
文件中可能没有任何数据. 在短时间内,日志文件将开始生长。
您还可以使用以下命令从pflog0
界面实时查看日志:
1sudo tcpdump -nei pflog0
您通过-nei
旗帜,这些旗帜也将输出格式化为可读性,但这次指定一个界面,在您的情况下是pflog0
。
您将看到以下结果:
1[secondary_label Output]
2tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
3listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes
您现在将看到实时连接,如果可能的话,请从远程计算机中 ping 服务器,您将看到连接正在发生。
要退出此状态并返回命令行,请按CTRL + Z
。
有大量的信息在互联网上关于 tcpdump(8),包括官方的 网站。
使用 pftop 访问日志文件
该pftop
实用程序是用于实时快速查看防火墙活动的工具,其名称受着众所周知的UnixTop
实用程序的影响。
要使用它,您需要安装pftop
包:
1sudo pkg install pftop
现在运行pftop
二进制:
1sudo pftop
这将产生以下输出(您的IP将有所不同):
1[secondary_label Output]
2PR DIR SRC DEST STATE AGE EXP PKTS BYTES
3tcp In 251.155.237.90:27537 157.225.173.58:22 ESTABLISHED:ESTABLISHED 00:12:35 23:59:55 1890 265K
4tcp In 222.186.42.15:25884 157.225.173.58:22 TIME_WAIT:TIME_WAIT 00:01:25 00:00:06 22 3801
5udp Out 157.245.171.59:4699 67.203.62.5:53 MULTIPLE:SINGLE 00:00:14 00:00:16 2 227
创建额外的日志接口
像任何其他接口一样,可以创建多个日志接口,并用一个 /etc/hostname
文件命名。
创建一个名为「pflog1」的额外日志界面:
1sudo vi /etc/hostname.pflog1
将以下内容添加到 /etc/hostname.pflog1
文件中:
1[label /etc/hostname.pflog1]
2up
现在在您的 /etc/rc.conf
文件中启动设备启动时:
1sudo sysrc pflog1_enable="YES"
您现在可以监控和记录您的防火墙活动,这样您就可以看到谁正在连接到您的服务器以及正在建立的连接类型。
在本教程中,您将一些先进的概念纳入您的 PF 规则集. 只需要在您需要时实施先进的功能。
步骤8 - 返回您的基本规则
在这个最后的部分中,您将返回您的基本规则,这是一个快速的步骤,将您带回一个最小化的功能状态。
使用以下命令打开基本规则集:
1sudo vi /etc/pf.conf
删除文件中的当前规则集,并用以下基本规则集替换它:
1[label /etc/pf.conf]
2vtnet0 = "vtnet0"
3icmp_types = "{ echoreq unreach }"
4table <bruteforce> persist
5table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 \
6 172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 \
7 192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \
8 240.0.0.0/4 255.255.255.255/32 }
9
10set skip on lo0
11scrub in all fragment reassemble max-mss 1440
12antispoof quick for $vtnet0
13block in quick on $vtnet0 from <rfc6890>
14block return out quick on egress to <rfc6890>
15block all
16pass in on $vtnet0 proto tcp to port { 22 } \
17 keep state (max-src-conn 15, max-src-conn-rate 3/1, \
18 overload <bruteforce> flush global)
19pass out proto { tcp udp } to port { 22 53 80 123 443 }
20pass inet proto icmp icmp-type $icmp_types
保存和退出文件。
重新加载规则:
1sudo pfctl -f /etc/pf.conf
如果命令中没有错误,则您的规则集没有错误,您的防火墙正在正常运作。
您还需要禁用您创建的pflog1
界面,因为您可能不知道是否需要它,您可以使用sysrc
实用程序禁用pflog1
:
1sudo sysrc pflog1_enable="NO"
现在从 /etc
目录中删除 /etc/hostname.pflog1
文件:
1sudo rm /etc/hostname.pflog1
在退出之前,重新启动服务器,以确保所有更改都是活跃和持久的:
1sudo reboot
在登录到您的服务器之前等待几分钟。
可选情况下,如果您想与 Web 服务器实现 PF,则以下为此场景的规则集。
1[label Simple Web Server Ruleset]
2vtnet0 = "vtnet0"
3icmp_types = "{ echoreq unreach }"
4table <bruteforce> persist
5table <webcrawlers> persist
6table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 \
7 172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24 \
8 192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 \
9 240.0.0.0/4 255.255.255.255/32 }
10
11set skip on lo0
12scrub in all fragment reassemble max-mss 1440
13antispoof quick for $vtnet0
14block in quick on $vtnet0 from <rfc6890>
15block return out quick on egress to <rfc6890>
16block all
17pass in on $vtnet0 proto tcp to port { 22 } \
18 keep state (max-src-conn 15, max-src-conn-rate 3/1, \
19 overload <bruteforce> flush global)
20pass in on $vtnet0 proto tcp to port { 80 443 } \
21 keep state (max-src-conn 45, max-src-conn-rate 9/1, \
22 overload <webcrawlers> flush global)
23pass out proto { tcp udp } to port { 22 53 80 123 443 }
24pass inet proto icmp icmp-type $icmp_types
这就形成了一个名为 " o-webcrawlers- " 的超载表,它比起你的SSH端口,基于 " max-src-conn 45 " 和 " max-src-conn-rate " 的值,具有更加宽松的超载政策。 这是因为并非所有超载都是来自坏角色。 它们也可以来自非有害的网瓶,因此避免在 " 80 " 和 " 443 " 港口采取过多的安全措施。 如果您决定执行 Webserver 规则, 您需要将 {webcrawlers} 表格添加到 `/etc/pf.conf' 中, 并定期从表格中清除 IP 。 为此请参看步骤5.
结论
在本教程中,您已在 FreeBSD 12.1 上配置了 PF。 您现在有一个基本的规则集,可以作为您的所有 FreeBSD 项目的起点。 有关 PF 的更多信息,请参阅 pf.conf(5)人的页面。
访问我们的 FreeBSD 主题页面 查看更多教程和问答。