也就apache服务运行在80端口,ssh服务运行在22端口,有必要开启iptables防火墙么?
netstat -lnpActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program nametcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -tcp6 0 0 :::22 :::* LISTEN -Active UNIX domain sockets (only servers)Proto RefCnt Flags Type State I-Node PID/Program name Pathunix 2 [ ACC ] STREAM LISTENING 5749599 - /var/run/mysqld/mysqld.sock
我不开防火墙,服务器上开放的也就是这两个端口,我开了防火墙,这两个端口还是要放行,那开启防火墙的意义到底是什么?
1个packet,Destination IP == 你Linux服务器的,TCP destination port =445,到达你的主机,最终的命运是什么?
无论配置iptables与否,最终都是Drop,对吗?
既然都是drop,那配置iptables有何意义吗?
1个packet从网卡被DMA 到RX ring buffer,触发硬中断,CPU查询中断向量表,找到对应的中断处理程序处理。关闭网卡中断,标记软中断,软中断处理程序call网卡驱动程序的poll从RX ring buffer拉取packet。
先创建一个skb来管理这个packet。Packet先经过漫长的底层网络栈,再进入TCP/IP栈,到达TCP时,依据packet源目IP、源目端口号(4元组),计算出hash id。
如果和hash表match,接收,将packet放入对应的socket的receive queue,唤醒服务器进程,进行接收。
如果不match,并不是drop就完事了,tcp还需要发送一个reset报文给源IP地址主机。
这是一个长长的流水线,直到流水线的末尾(tail)才将不是目的端口为80,22丢弃。
如果在最靠近流水线起点(head)的地方丢弃目的端丢弃口≠80,22的packet,将会大大节省很多CPU周期。
Linux的netfilter subsystem,在
Ingress
pre-routing
input
forward
output
post-routing
egress
这7个checkpoint处都预置了hook,每个hook可以挂一个filter函数或多个filter list。
每个hook初始化为NULL,意味着如果不定义filter,直接跳过。
如果hook挂一个函数指针,就call 它一下,如果丢了,就返回,网卡驱动程序就poll下一个packet。如果没有丢,在流水线上继续处理。
如果hook挂filter list,就顺序call 它们一下,任意一个丢,就返回,网卡驱动程序就poll下一个packet。如果都不丢,在流水线上继续处理。
7个hook分布于packet的receive、forward、output不同位置。
一个要本地接收packet,需要先经过ingress hook,再pre-routing hook,最后input hook。
可以用iptables定义自己的filter放置在以上三处的任何一处。当然越早越节省CPU周期,因为早早就把不想接收的packet给过滤出去了。
ingress hook,pre-routing hook,input hook这三个hook在流水线上,都比socket lookup要早。
配置iptables,可以让流水线的hook早早将packet丢弃,也无需发送reset报文。
不配置iptables,hook全是null,在流水线的末尾将packet丢弃,需要发送reset报文。
从这个意义上来说,配置iptables可以大大节省CPU周期。
此外,iptables有一个默认的policy drop。意味着凡是没有明确permit的packet,将全部drop,这样就避免不小心配置了非80,22端口之外的端口,但是被外界可以访问的安全威胁。
如果单纯配置iptables,iptables仅仅是一个stateless防火墙,什么意思?
如果攻击者伪造一个目的IP=你服务器的IP,目的端口=80的packet,你的iptables一定会放行,即使它的序列号、ACK、syn、fin是非法的,也可以蒙混过关。
为了具有stateful能力,配置iptables时,需要配合-m conntrack,-m state,自动开启conntrack。这样conntrack就可以将非法的TCP报文过滤出去。
可是,iptables、conntrack全部开启了,也只能在IP、TCP层面进行过滤,包括TCP的状态、序列号,如果application的data有安全威胁(病毒),iptables、conntrack是无能无力的。
只要在上文的7个checkpoint挂接一个可以做packet深度检测(包括application)的filter即可。当然对于input方向,ingress优先于pre-routing,pre-routing优先于input。
这样的话,当packet到达socket receive queue的时候,就真的安全了。
有人会问,既然挂hook越早越好,为什么不能在DMA之后,创建skb用来管理packet之前能否挂一个hook?
好问题,有的,这项技术在Linux上叫XDP(eXpress Data Path)。
网卡驱动程序先call一下XDP,如果XDP挂接的prog==NULL,直接跳过,进行上文的流水线操作。
如果XDP挂接的prog!=NULL,直接call prog,凡是不match filter的,一律就地drop。不浪费感情( 创建skb),也不浪费精力(不会拖延到ingress丢)。
如果matched filter,直接返回,继续流水线的常规操作。
XDP过滤技术显然比iptables、nftable、conntrack更早丢弃本该丢弃的packet,大大节省CPU周期,也是对抗DDOS攻击有效的防守方法。当然,如果硬件网卡上可以预置filter,那是最理想的,对CPU的影响几乎忽略不计,这样的网卡非常昂贵也非常稀少。