从理论上和实践上来讲,防火墙(或数据包过滤器)都是一个大而复杂的话题。 与其他实现相比,各种操作系统中的数据包筛选器都有其优缺点。 在本文中,我将专门研究RouterOS中的防火墙,并着眼于其祖先iptables。
前言
本文适用于谁?
如果您知道如何使用iptables,然后继续设置防火墙,那么本文对您来说没有什么新意(好吧,除了NAT表中使用具有其他名称的链)。 如果这是您第一次在RouterOS中看到防火墙,并且想要获取现成的脚本进行配置,那么您将在这里找不到它。 该材料面向那些希望基本了解防火墙工作原理以及ip数据包在其处理的不同阶段发生的情况的人员。 经验以及使用数据包过滤器解决日常和异常问题将带来更深入的了解。
理论部分
什么是三层防火墙?

假设您有一台具有Internet访问权限的路由器,并且具有两个桥接接口:bridge-lan(ether2-ether5)和bridge-dmz(ether6-ether10)。
在网桥接口中,设备独立地从其子网中查找邻居并交换数据包,路由器充当交换机,并且不会在网络级别监视此类流量(当然,您可以强制其执行此操作,但是我们将在第二次讨论第2层防火墙)。
如有必要,请联系连接到另一个网桥接口或位于全局网络上的设备,这些设备将数据包传输到路由器,路由器确定路由并在网络(第3层)级别对其进行处理。
数据包流程图
完整的流量路径在数据包流程图中进行了描述,有几种正式的版本(v5, v6 ),它们需要在日常工作中了解和使用,但是要了解数据包过滤器的操作,它们会过载,因此我将以轻量级版本进行说明。

输入/输出接口是任何(物理或虚拟)第3层路由器接口。 从本地网络到Internet的数据包到达输入接口,然后离开输出接口。 从Internet到本地网络的数据包也到达输入接口,并离开输出接口。 数据包流始终在单向输入->输出中读取。
术语功能
在研究iptables的数据包流时,您可以通过“表中的链”或“表中的表”找到描述。 该图显示了链表,将规则添加到防火墙时,一切都会相反。
但是实际上,数据包在[链+表]块之间移动,例如,如果您在[prerouting + mangle]块中接受,则传输数据包仍将在[forward + mangle]中进行处理。 在带有pbr和队列的复杂配置中记住这一点很重要。
iptables文档具有更精确的定义,但简单地说:
链负责处理数据包的位置和规则序列。
表格确定可以对程序包执行的操作。
基本软件包后续选项

过境

- 来自网络的数据包到达路由器接口之一
- 在PREROUTING链中,管理员可以影响数据包路由:确定输出接口(基于策略的路由)或重定向到另一个地址(dst-nat)。
- 根据数据包的路由表,确定传出接口。
- FORWARD链是传递流量的主要过滤位置。
- 进入网络之前的最后一项是POSTROUTING链,您可以在其中更改发件人地址(src-nat)。
- 小包上线了。
传入

- 来自网络的数据包到达路由器接口之一
- 点击PREROUTING链。
- 根据路由表,将数据包发送到本地进程进行处理。
- INPUT链由管理员过滤传入的流量。
- 该包由本地流程处理。
外向

- 路由器进程之一生成了一个ip数据包(新的或响应的-没关系)。
- 根据路由表,为数据包定义了输出接口。
- 管理员可以过滤传出流量或更改OUTPUT链中的路由。
- 对于程序包,将在输出接口上做出最终决定。
- 数据包与通过的流量一样都属于POSTROUTING。
- 小包上线了。
连接跟踪器
首先,您需要了解什么是有状态和无状态数据包过滤器。

一个例子。 计算机192.168.100.10打开与服务器192.0.2.10的tcp连接。 在客户端,服务器端80使用动态端口 49149。在接收内容之前,客户端和服务器必须交换数据包以建立tcp会话。
在无状态情况下,您需要打开从本地网络到Internet以及从Internet到本地网络的流量(至少对于动态端口范围而言)。 整体上是一个洞。
在有状态路由器中,它分析数据包,并在从192.168.100.10:49149接收到192.0.2.10:80的tcp syn后,将其视为新连接的开始。 192.168.100.10:49149和192.0.2.10:80之间的所有其他数据包(任何方向)都将被视为已建立连接的一部分,直到tcp会话关闭或计时器到期。
对于无法清楚地区分连接的开始和结束的UDP / ICMP和其他类型的流量,第一个数据包是第一个数据包,其余数据包被视为已建立连接的一部分并更新计时器,路由器在计时器到期后会忘记此类连接。
连接跟踪器将包分为几种类型:

new-打开连接的数据包,例如tcp的syn或udp流中的第一个数据包。
建立 -与已知连接有关的数据包。
related-与多协议中的附加连接(sip,pptp,ftp等) 相关的数据包。
无效 -来自未知连接的数据包。
未跟踪 -数据包未跟踪的连接跟踪器。
连接跟踪器配置
已启用=是-已启用。
已启用=否-已禁用。
enabed = auto-禁用,直到使用conntrack功能的规则出现在防火墙中。 默认情况下使用。

其余参数是不同的计时器,通常不需要调整。
管理员可以查看和删除连接,例如,到NAT的连接如下所示:

使用conntrack会影响性能和资源消耗(尤其是使用大量连接时),但是由于大多数配置,它都无法使用 您将拥有一个没有NAT的无状态防火墙。
TTL
生存时间-IP数据包头中的字段,用于确定数据包在销毁之前可以通过的路由器数量,可以防止路由循环期间无休止的数据包转发。

转发时,如果TTL = 0,则路由器会将TTL值减小1。 在这种情况下,TTL = 1的数据包将到达路由器的本地进程。
一些运营商使用TTL技巧来阻止使用路由器。 所有这些限制都非常值得在mangle表中增加ttl值。
NAT
网络地址转换-用于更改ip数据包头中的地址的技术。 像linux一样,NAT是数据包过滤器的一部分。 NAT基于连接跟踪器工作。
最初,NAT被设计为解决IPv4地址耗尽问题的快速解决方案;对于本地网络,建议使用范围为10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16并将其转换为一个(或几个)可路由地址。 实际上,还有更多的服务子网可以在专用网络上使用,并且路由器原则上与NAT相同,但是建议遵循这些标准。
仅NAT处理:tcp,udp,icmp以及[IP]-> [防火墙]-> [服务端口]中的一些多协议。 仅处理连接中的第一个(连接状态=新)数据包,其余数据包将自动处理,而无需NAT表的参与。 这可以通过规则中计数器的更改来跟踪。
数据包头分别包含源和目标地址,并且NAT分为源和目标NAT。
源NAT-发送者地址欺骗,存在于世界上绝大多数家用和公司路由器中。

它允许许多在本地网络上具有“灰色”地址的设备使用一个(或几个)实际地址与Internet通信。

回到数据包流,在确定是否路由数据包之后,我们看到SRC-NAT在后路由中。
响应数据包通过一个隐式 DST-NAT,其中收件人地址更改为本地地址。
目标NAT-收件人地址的替换。

如有必要,它用于将数据包转发到另一个地址,通常用于将端口从外部网络“转发”到本地。

根据数据包流,DST-NAT操作在做出有关“预路由”中的路由的决定之前发生;存在隐式 SRC-NAT用于响应流量。
NAT是一种功能非常强大的流量管理工具,但应在最后使用(当其他工具无济于事时)。
链条(链条)基本和用户
链由规则组成,并强制执行数据包处理逻辑。
有几个基本链映射到数据包流:
预路由(dstnat) -决定路由之前的数据包处理
输入 -处理发往路由器本地进程的数据包
输出 -处理路由器本地进程生成的数据包
转发 -处理通过流量
后路由(srcnat) -处理流量准备好传输到接口
一切都像iptables中一样,但是nat中的链被重命名。 与之相关的内容(很可能是热点或nat的硬件卸载)对我来说是未知的,但它丝毫没有改变。
程序包按顺序通过链中的规则,如果适用于所有条件,则将操作应用于程序包。 如果操作正在终止并且没有丢弃数据包,则将其传递到下一个数据包流块。
所有基链都有默认操作(如果程序包不符合任何规则) -accept 。
自定义链对于减少每个数据包通过的规则数量以及建立用于处理流量的复杂规则是必要的。 所有用户链都有默认的动作- 返回 。

在表中,您可以将规则从几个不同的基本(和用户)链转发到用户链,但是数据包将返回到它来自的链。

条款及细则
链由规则组成;每个规则由条件和动作组成。 有很多条件,但并非所有人都会在实际配置中使用。 大多数条件都可以加上“ not”(在符号“!”之前)的前缀。 为了符合规则,包装必须适合所有这些条件。

一些条件条件 | 内容描述 |
---|
src地址 | 源地址 |
dst地址 | 收件人地址 |
src地址列表 | 列出了源地址。 |
dst-address-list | 收件人地址已列出 |
协议 | 传输层协议 |
服务端口 | 源端口 |
dst端口 | 收件人端口 |
港口 | 源端口或目标端口 |
接口内 | 程序包所在的接口 |
出接口 | 数据包将从其发送到网络的接口 |
接口内列表 | 列出了软件包所来自的接口 |
出接口列表 | 列出了将数据包发送到网络的接口 |
第7层协议 | 分析连接中前10个数据包的内容 |
内容 | 批量搜索给定的字符串 |
tls主机 | 在tls标头中搜索主机 |
安全策略 | 检查报文是否与ipsec策略匹配 |
包大小 | 数据包大小(以字节为单位) |
src-mac-address | mac软件包源地址 |
连接标记 | 连接标签 |
包标记 | 包装标签 |
路由标记 | 分组路径点 |
连接状态 | 连接包状态 |
tcp标志 | 标志tcp包 |
icmp选项 | ICMP软件包选项 |
随机的 | 以其他概率触发规则(当其他条件一致时) |
时间 | 您可以指定规则的工作时间,很遗憾,没有日期转换 |
ttl | 包中的Ttl字段值 |
dscp | 数据包中的DSCP(ToS)字段值 |
-//- | -//- |
之前 | 控制台选项(无条件),允许您在指定的规则之前添加规则 |
残障人士 | 控制台选项(非条件),允许您禁用规则 |
注意事项
作为源(目标)地址,可以指定:单个IP,通过连字符或子网的地址范围。
需要使用地址列表来组合相同名称下的多个未连接的ip。 与netfilter中的ipset不同,MikroTik列表中的条目可以在指定的时间段后删除。 您可以在[IP]-> [防火墙]-> [地址列表]中查看列表并进行更改。
作为端口号(端口,src端口,dst端口),您可以指定单个端口,用逗号分隔的多个端口或通过连字符的端口范围。
在MSC的最后一个MUM上,有一个很好的演示,介绍了各种条件对数据包处理速度的影响(您将学习如何使用原始表来减少路由器的负载),他们对以下内容感兴趣: 记录和演示 。
表动作
程序包上的可用操作集取决于处理程序包的表。

过滤器 -流量过滤表,您可以在其中丢弃数据包的两个位置之一。
NAT-用于修改IP数据包头中的IP地址和端口(tpc,udp)的表。
Mangle-用于修改ip数据包的其他字段并设置各种标签的表。

内部数据包标签有三种类型:连接,数据包,路由。 标签仅存在于路由器中,并且不会进入网络。 一个数据包可以具有每种类型的一个标签,同时依次传递多个mark- *规则,则这些标签将被覆盖。
只能在预路由和输出链中设置路由标签,其余都可以在任何链中设置。
优良作法是先标记连接,然后标记数据包(数据包)或路由(路由)。 检查标签的速度比数据包字段的速度快。 实际上,在复杂的队列中并非总是这样,或者pbr附加的连接标记没有用。
RAW-允许数据包绕过连接跟踪器的表。 它用于抵消DoS并减少cpu的负载(例如,绕过多播流量)。 让您丢弃数据包。
终止操作完成了链中数据包的处理,并将其传递到数据包流中的下一个块,或者将其丢弃。
动作桌子 | 动作片 | 内容描述 | 终止吗 |
---|
全部 | 接受 | 停止处理数据包并将其传输到下一个Pakcet流块 | 是的 |
全部 | 日志 | 日志包信息:在现代版本中,您可以将日志添加到任何其他操作中。 | 没有啦 |
全部 | 通道 | 计算数据包数量。 用于调试 | 没有啦 |
全部 | 将src添加到地址列表,并将dst添加到地址列表 | 将数据包中的源(目标)地址添加到给定列表中 | 没有啦 |
全部 | 跳 | 转到用户链 | 是的 |
全部 | 归还 | 返回父链。 在基础链中,它的作用就像接受 | 是的 |
过滤器和原始 | 下降 | 在数据包流上停止数据包流并丢弃 | 是的 |
过滤和预路由 | 快速通道 | 标记数据包以实现快速数据包流 | 是的 |
筛选条件 | 拒绝 | 与丢弃类似,但是向数据包发送方发送有关丢弃数据包的通知(tcp或icmp) | 是的 |
筛选条件 | 陷阱 | 模拟开放端口的存在。 用于防止DoS,误导和(有时)调试 | 是的 |
NAT | 纳豆 | 将发件人地址替换为指定的地址 | 是的 |
NAT | 假面舞会 | src-nat的一种特殊情况是将发件人地址替换为接口中的地址之一,用于动态(dhcp,vpn)接口。 如果接口上有多个IP,则不建议使用 | 是的 |
NAT | 一样的 | src-nat的特例。 将发件人地址替换为指定范围内的地址 | 是的 |
NAT | dst-nat | 将收件人地址替换为指定的地址 | 是的 |
NAT | 重新导向 | dst-nat的一种特例,将接收者地址替换为数据包所到达的路由器接口的地址 | 是的 |
NAT | 网图 | 不能替代dst-nat。 用于网络到网络的转换,请参见示例 | 是的 |
angle | 标记连接 | 连接标签 | 没有啦 |
angle | 标记包 | 队列中应用的数据包标签 | 没有啦 |
angle | 标记路由 | 在策略基础路由中应用的路由标签 | 没有啦 |
angle | 更改ttl | 编辑ttl | 没有啦 |
angle | 更改DCSP(TOS) | 更改DCSP十进制 | 没有啦 |
angle | 更改短信 | 将mss更改为tcp syn | 没有啦 |
angle | 清除df | 清除请勿脆弱标志 | 没有啦 |
angle | 去除ipv4选项 | 清除高级ipv4选项 | 没有啦 |
angle | 设定优先级 | 为CoS设置优先级 | 没有啦 |
angle | 路线 | 设置数据包的网关。 简单版本的PBR | 没有啦 |
angle | 嗅探 | 将数据包封装在udp中并发送到指定的ip | 没有啦 |
angle | 嗅电脑 | tzsp的类似物,但封装类型不同。 在Wiki中,如果用例具有calea | 没有啦 |
angle | 通道 | 默认情况下,mangle中的大多数规则不会阻止数据包通过,您可以通过设置passtrough = no来更改此行为。 | 没有啦 |
生的 | 无痕 | 不要在连接跟踪器中跟踪包 | 是的 |
如果有谁愿意,我可以写更多有关FastTrack和FastPath的文章,但是您不应该期望这些技术带来奇迹。
关于DPI的几句话
有几种可能性可以使包比传输层头更深一些:
内容 -在包中搜索给定的字符串。
layer7-protocol-缓冲来自连接的前10个数据包(或2KiB),并在缓冲的数据中搜索regexp。 大量的layer7规则会严重影响性能。
tls-host是HTTPS连接的TLS / SNI标头中的主机名地址。
例子
不要盲目地复制示例,最好带上设备并尝试自己编写配置(或重写示例,但要深入研究每个规则的作用)。 如果您不知道如何添加规则:在默认和最小本地配置中,无法从wan接口访问路由器,请通过地址列表过滤添加该路由器。
默认防火墙RouterOS
一个相当安全的配置,但是在非常混乱的地方:
/ip firewall filter # (established, related) (untracked) add action=accept chain=input connection-state=established,related,untracked # (invalid) add action=drop chain=input connection-state=invalid # icmp add action=accept chain=input protocol=icmp # add action=drop chain=input in-interface-list=!LAN # ipsec add action=accept chain=forward ipsec-policy=in,ipsec add action=accept chain=forward ipsec-policy=out,ipsec # add action=fasttrack-connection chain=forward connection-state=established,related # add action=accept chain=forward connection-state=established,related,untracked # add action=drop chain=forward connection-state=invalid # wan , dstnat (, src-nat dst-nat) add action=drop chain=forward connection-nat-state=!dstnat connection-state=new in-interface-list=WAN /ip firewall nat #Source NAT ipsec, WAN add action=masquerade chain=srcnat ipsec-policy=out,none out-interface-list=WAN
我从未使用过默认配置,但在使用默认防火墙之前要差得多。
最小的家庭防火墙
最容易想到的事情。 是的,不允许有未跟踪的流量(但是在防火墙的基础研究阶段您仍然不需要它)并且隧道ipsec会有问题(同样,如果您可以配置ipsec,您自己就知道需要做什么)。
/ip firewall filter # (established, related) add chain=input connection-state=established,related action=accept # icmp add chain=input connection-state=new protocol=icmp action=accept # add chain=input connection-state=new in-interface-list=LAN action=accept # add chain=input action=drop # add chain=forward connection-state=established,related action=accept # add chain=forward connection-state=new in-interface-list=LAN action=accept # add chain=forward action=drop /ip firewall nat #Source NAT WAN add chain=srcnat out-interface-list=WAN action=masquerade
DMZ示例
在“家用”路由器上,缩写词DMZ喜欢在本地子网中呼叫一台计算机,外部网络的所有端口都将转发到该计算机上。
实际上,事实并非如此,DMZ选项之一是将必须从Internet提供访问权限的资源分开,这样就可以进行成功的攻击(具有cms且经常发现漏洞的Web服务器是攻击者的理想目标)。 万一遭到黑客攻击,攻击者将无法影响本地网络中的参与者。

# /ip firewall nat add chain=dstnat dst-port=80,443 action=dst-nat to-address=192.168.200.2 /ip firewall filter # icmp add chain=input connection-state=established,related action=accept add chain=input protocol=icmp connection-state=new action=accept # add chain=input in-interface=ether2-lan action=accept # add chain=input action=drop # add chain=forward connection-state=established,related action=accept # add chain=forward in-interface=ether2-lan connection-state=new action=accept # web add chain=forward out-interface=ether3-dmz dst-address=192.168.200.2 dst-port=80,443 connection-state=new action=accept # add chain=forward action=drop
发夹NAT

/ip firewall nat add chain=dstnat dst-port=80 action=dst-nat to-address=192.168.100.2
典型的情况是,当您将端口转发到本地网络上的服务器时,一切都从外部进行,但是在本地网络内部,无法从外部地址访问服务器。
让我们看看会发生什么:
- 计算机192.168.100.10向192.0.2.100发送请求
- 它在路由器上执行DST-NAT,并将数据包转发到192.168.100.2
- 服务器看到来自192.168.100.10的数据包已到达地址192.168.100.2并正在从本地地址响应
- 计算机从192.168.100.2接收到意外的数据包并将其丢弃。
解决方案是添加一条附加规则,将源地址更改为路由器的地址,以便服务器将数据包返回到路由器,路由器将把数据包发送到初始化计算机。
/ip firewall nat # add chain=dstnat dst-port=80 action=dst-nat to-address=192.168.100.2 # , add chain=srcnat src-address=192.168.100.0/24 dst-address=192.168.100.2 action=masquerade
实际上,这种方案并不经常使用,但是作为调试防火墙的示例,我真的很喜欢它。
正确使用netmap

Netmap是一种用于将地址从一个子网转换为另一子网的地址的技术。
IP地址(在掩码条目中)由两部分组成:网络(子网掩码中指定的位数)和主机(剩余位数)。 Netmap更改了地址的网络部分,但没有接触主机部分。

VPN通道连接了两个路由器。 路由器为子网提供相同的地址。 必须在子网之间进行访问。
如果没有其他解决办法,您将无法做。
来自左侧子网的用户将通过192.168.102.0/24子网向右敲动
右侧子网中的用户将通过192.168.101.0/24子网向左敲
在MikroTik上进行配置1。
# /ip route add distance=1 dst-address=192.168.102.0/24 gateway /ip firewall nat # add action=netmap chain=srcnat dst-address=192.168.102.0/24 out-interface=ipip src-address=192.168.100.0/24 to-address=192.168.101.0/24 # add action=netmap chain=dstnat dst-address=192.168.101.0/24 in-interface=ipip src-address=192.168.102.0/24 to-address=192.168.100.0/24
MikroTik2的配置几乎相同:
/ip route add distance=1 dst-address=192.168.101.0/24 gateway=10.10.10.1 /ip firewall nat add action=netmap chain=srcnat dst-address=192.168.101.0/24 out-interface=ipip src-address=192.168.100.0/24 to-address=192.168.102.0/24 add action=netmap chain=dstnat dst-address=192.168.102.0/24 in-interface=ipip src-address=192.168.101.0/24 to-address=192.168.100.0/24
例如,如果您与具有相交子网的远程点有许多连接,并且无法更改远程设备上的设置,则使用netmap会有更复杂的配置,但这已经是高级路由。
如果您不了解任何内容(关于netmap),则不需要它,只是在转发端口时不使用此操作。