文章目录
防火墙分为三层与四层防火墙
- 三层指的是网络层,四层是传输层
- 三层对IP进行限制,四层是对端口进行限制
一、Linux防火墙
防火墙除了软件及硬件的分类,也可对数据封包的取得方式来分类,可分为代理服务器(Proxy)及封包过滤机制(IP Filter)。
- 代理服务
- 是一种网络服务,通常就架设在路由上面,可完整的掌控局域网的对外连接。
- IP Filter
- 这种方式可以直接分析最底层的封包表头数据来进行过滤,所以包括 MAC地址, IP, TCP, UDP,ICMP 等封包的信息都可以进行过滤分析的功能,用途非常广泛。
1.1 iptables
其实Iptables服务不是真正的防火墙,只是用来定义防火墙规则功能的"防火墙管理工具",将定义好的规则交由内核中的netfilter即网络过滤器来读取,从而真正实现防火墙功能。
netfilter才是防火墙真正的安全框架(framework),位于内核空间,设置了“关卡”在Input、Output上(链)网卡的驱动是在内核空间当中,Netfilter也是在内核空间当中,所以Iptables+netfilter 可以在内核空间 当中设置“关卡”, 当用户去访问应用服务时,数据包是通过网卡流经内核空间之后到达用户空间
-
netfilter——内核空间
-
iptables ———— 用户空间的客户端代理
-
iptables抵挡封包的方式:
- 拒绝让 Internet 的封包进入 Linux 主机的某些 port
- 拒绝让某些来源 IP 的封包进入
- 拒绝让带有某些特殊标志( flag )的封包进入
- 分析硬件地址(MAC)来提供服务
1.1.1 五链四表
五链
iptables命令中设置数据过滤或处理数据包的策略叫做规则,将多个规则合成一个链,叫规则链。 规则链则依据处理数据包的位置不同分类:
-
PREROUTING:在进行路由判断之前所要进行的规则(DNAT/REDIRECT)
-
INPUT:处理入站的数据包
-
OUTPUT:处理出站的数据包
-
FORWARD:处理转发的数据包
-
POSTROUTING:在进行路由判断之后所要进行的规则(SNAT/MASQUERADE)
iptables是Linux上的软件防火墙,是用户空间的工具,iptables设置的规则会在netfilter框架中生效,netfilter一共由五链四表
数据包到达时需要经过的链的路径如下
-
到本地某个进程的报文:PREROUTING‐‐> INPUT‐‐>OUTPUT ‐‐>POSTROUTING
-
由本机转发的报文:PREROUTING ‐‐> FORWARD ‐‐> POSTROUTING
-
由本机的某个进程发出报文(通常为响应报文): OUTPUT ‐‐> POSTROUT
四表
iptables中的规则表是用于容纳规则链,规则表默认是允许状态,那么规则链就是设置被禁止的规则,而反之,如果规则表是禁止状态,那么规则链就是设置被允许的规则。
每个表上通常会匹配约定俗成的意义的数据包
- raw表
- 确定是否对该数据包进行状态追踪
- 关闭nat上启用的连接追踪机制
- mangle表
- 为数据包设置标识(较少使用)
- 拆解报文、修改报文、重新封装报文
- nat表
- 修改数据包中的源、目的IP地址或端口
- 网络地址转换
- filter表
- 确定是否放行该数据包(过滤)
- 负责过滤功能,防火墙
表链关系
-
PREROUTING:raw/mangle/nat
-
INPUT:mangle/filter
-
OUTPUT:raw/mangle/nat/filter
-
POSTROUTING:mangle/nat
-
FORWARD:mangle/filter
规则表的先后顺序:raw→mangle→nat→filter
链的规则和默认规则的设置一般有白名单和黑名单的两种方式
- 如果默认规则设置为DROP的话就是白名单模式,我们需要将想要放行的数据包添加到规则中
- 如果默认规则设置为ACCEPT的话就是黑名单模式,我们需要将想要拒绝的数据包添加到规则中
1.1.2 iptables规则说明
常用格式:
- iptables [-t 表名] 选项 [链名] [条件] [-j 控制类型]
- iptables –[A|I 链] [-i|o 网络接口] [-p 协议] [-s 来源ip/网域] [-d 目标ip/网域] – j[ACCEPT|DROP]
参数
-P:设置默认策略:iptables -P INPUT (DROP|ACCEPT)
-S:查看这些rules是如何建立的
-F:清空规则链
-L:查看规则链
-A:在规则链的末尾加入新规则
-l num:在规则链的头部加入新规则
-D num:删除某一条规则
-s:匹配来源地址IP/MASK,加叹号"!"表示除这个IP外。
-d:匹配目标地址
-i 网卡名称:匹配从这块网卡流入的数据
-o 网卡名:匹配从这块网卡流出的数据
-p:匹配协议,如tcp,udp,icmp
--dport num:匹配目标端口号
--sport num:匹配来源端口号
-
规则:根据指定的匹配条件来尝试匹配每个经流“关卡”的报文,一旦匹配成功,则由规则后面指定的处理动作进行处理
-
匹配条件
- 基本匹配条件:sip、dip(三层)
- 扩展匹配条件:sport、dport(四层)
- 扩展条件也是条件的一部分,只不过使用的时候需要用-m参数声明对应的模块
-
处理动作
- accept:接受
- drop:丢弃
- reject:拒绝
- snat:源地址转换,解决内网用户同一个公网地址上上网的问题
- masquerade:是snat的一种特殊形式,使用动态的、临时会变的ip上
- dnat:目标地址转换
- redirect:在本机作端口映射
- log:记录日志,/var/log/messages文件记录日志信息,然后将数据包传递给下一条规则
-
安装
iptables-services
,在centos7和centos8上,默认没有自带iptables服务,导致无法开机自动导入
yum install iptable-service -y
systemctl stop firewalld.service
systemctl disable firewalld.service
- 查看规则
[root@localhost~]# iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
#默认的链都是放行策略
iptables [-t tables] [-L] [-nv]
参数:
-t:指定表名,默认是filter表
-L:指定链名,默认是所有链
-n:不进行IP名与主机名的反查,显示信息的速度会快很多
-v:显示详细信息,包括封包数相关网络接口等
-x:展开数字
--line-numbers:显示规则序号
[root@localhost~]# iptables -L -t filter
[root@localhost~]# iptables -nL -t nat
[root@localhost~]# iptables -nL -t mangle
[root@localhost~]# iptables -nL -t raw
查看每个表的规则:
policy:当前链的默认策略,当所有规则都没有匹配成功时执行的策略
packets:当前链默认策略匹配到的包的数量
bytes:当前链默认策略匹配到的包的大小
pkts:对应规则匹配到的包数量
bytes:对应规则匹配到的包大小
target:对应规则执行的动作
prot:对应的协议,是否针对某些协议应用此规则
opt:规则对应的选项
in:数据包由哪个接口流入
out:数据包由哪个接口流出
source:源ip地址
distination:目的ip地址
[root@localhost ~]# iptables -vnL INPUT -t filter
[root@localhost ~]# iptables -nL -t nat
[root@localhost ~]# iptables -nL -t mangle
[root@localhost ~]# iptables -nL -t raw
1.1.3 iptables用法说明
-
-t table指定表
- raw
- mangle
- nat
- filter 默认
-
subcommand子命令
- -N:new,自定义一条新的规则链
- -E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除
- -X:delete,删除自定义的空的规则链
- -P:policy,设置默认策略;对filter表中的链而言,其默认策略有:ACCEPT:接收,DROP:丢弃
-
案例
[root@localhost ~]# yum install -y httpd
[root@localhost ~]# echo "hello world" > /var/www/html/index.html
[root@localhost ~]# systemctl enable --now httpd
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source
#默认规则是可以访问,所以可以访问自己的网页
[root@localhost ~]# iptables -P INPUT DROP
#修改默认规则为DROP,包被丢弃就访问不了了,那么ssh也访问不了了
[root@localhost ~]# iptables —A INPUT -s 192.168.175.1 -j ACCEPT
#添加规则放行本机的全部访问
[root@localhost ~]# iptables -A INPUT -p tcp -s 192.168.175.0/24 --dport 22 -j ACCEPT
#添加放行主机连接22端口的数据包
[root@localhost ~]# iptables -D INPUT 1
#把第一条规则删掉,现在只有22端口可以访问,80端口就访问不来了
[root@localhost ~]# iptables -A INPUT -p TCP -s 192.168.175.0/24 --dport 80 -j ACCEPT
#放行80端口
[root@localhost ~]# iptables -nL --line-numbers
[root@localhost ~]# iptables -nL --line-numbers
Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT tcp -- 192.168.175.0/24 0.0.0.0/0 tcp dpt:22
2 ACCEPT tcp -- 192.168.175.0/24 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
1.1.4 自定义链
- 可以将同一种作用的规则整合到同一个链中进行管理
- 比如与网页有关的,可以自定义一个web_chain
使用自定义链
创建自定义链 iptables -t filter -N http_chain
引用自定义链 iptables -I INPUT -p tcp --dport 80 -j http_chain
创建规则(和五链使用方法一样)
iptables -t filter -A http_chain -s 192.168.80.1 -j REJECT
iptables -t filter -A http_chain -s 10.1.0.0/16 -j REJECT
删除自定义链
删除引用
[root@localhost ~]# iptables -t filter -D INPUT -p tcp --dport 80 -j http_chain
删除链上所有规则 [root@localhost ~]# iptables -F http_chain
删除链 [root@localhost ~]# iptables -X http_chain
[root@localhost ~]# iptables -D INPUT 2
#把自己放行80的规则删了
[root@localhost ~]# iptables -N web_chain
#新建一个web_chain链
[root@localhost ~]# iptables -N web_chain -t filter
#可以把链指定到表里,默认就是放到filter表里
[root@localhost ~]# iptables -A web_chain -s 192.168.175.0/24 -p tcp -m multiport --dports 80,443 -j ACCEPT
#加了-m multiport可以一次指定多个端口可以是dports了
#但是现在还是访问不了,因为只是有了这个链,但是链没有用上
[root@localhost ~]# iptables -A INPUT -j web_chain
#添加自定义的链加入到了INPUT链里
[root@localhost ~]# iptables -X web_chain
iptables: Too many links.
#删除链,但是被使用中就不能删除
[root@localhost ~]# iptables -nL --line-numbers
[root@localhost ~]# iptables -D INPUT 2
[root@localhost ~]# iptables -X web_chain
iptables: Directory not empty.
[root@localhost ~]# iptables -F web_chain
[root@localhost ~]# iptables -X web_chain
- 链的管理
- -A:append,追加
- -I:insert,插入,要指名插入至的规则编号,默认为第一条
- -D:delete,删除
- 指明规则序号
- 指明规则本身
- -R:replace,替换指定链上的指定规则编号
- -F:flush,清空指定的规则链
- -Z:zero,置零
- iptables的每条规则都有两个计数器
- 匹配到的报文的个数
- 匹配到的所有报文的大小之和
- iptables的每条规则都有两个计数器
- chain
- PREROUTING
- INPUT
- FORWARD
- OUTPUT
- POSTROUTING
- 匹配条件
- 基本:通用的
- -s:指定源IP地址
- -d:指定目的IP地址
- -p:指定协议类型
- -i:指定网卡流入
- -o:指定网卡流出
- 扩展:需加载模块
- 基本:通用的
- tcp/udp
- –dport:指定目的端口
- –sport:指定源端口
Iptables 开放tcp、udp端口
例:开放samba端口(udp137,138;tcp139,445)
[root@localhost ~]# iptables -A INPUT -i ens33 -p udp --dport 137:138 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -i ens33 -p udp --dport 139 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -i ens33 -p udp --dport 445 -j ACCEPT
- iprange:匹配报文的源/目的地址所在范围
- –src-range
- –dst-range
iptables -A INPUT -d 172.16.1.100 -p tcp --dport 80 -m iprange --src-range 172.16.1.5-172.16.1.10 -j DROP
- string:指定匹配报文中的字符串,可以过滤网页内容
- –algo:指定匹配算法,可以是bm/kmp
- bm:Boyer-Moore
- kmp:Knuth-Pratt-Morris
- –string:指定需要匹配的字符串
- –from offset:开始偏移
- –to offset:结束偏移
- –algo:指定匹配算法,可以是bm/kmp
iptables -A OUTPUT -p tcp --sport 80 -m sting --algo bm --from 62 --string "google" -j REJECT
#先把自己的网页正常可以放行访问
[root@localhost ~]# iptables -A INPUT -p TCP -s 192.168.175.0/24 --dport 80 -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -p tcp --sport 80 -m string --algo bm --from 0 --string "world" -j REJECT
访问不来了
但是如果把world去掉就好了
[root@localhost ~]# echo "hello linux" > /var/www/html/index.html
- iptables匹配ICMP端口和ICMP类型
iptables –A INPUT –p icmp --icmp-type 类型 –j ACCEPT
参数:--icmp-type :后面必须要接 ICMP 的封包类型,也可以使用代号,
例如 8 代表 echo request 的意思。(可自查询ICMP-type对应表)
[root@localhost ~]# iptables -P INPUT ACCEPT
放行所有数据包
[root@localhost ~]# iptables -A INPUT -p icmp --icmp-type 8 -j REJECT
ping不了
- 指定TCP匹配扩展
使用 --tcp-flags 选项可以根据tcp包的标志位进行过滤。
[root@localhost ~]# iptables -A INPUT -p tcp --tcp-flags SYN,FIN,ACK SYN
[root@localhost ~]# iptables -A FROWARD -p tcp --tcp-flags ALL SYN,ACK
上实例中第一个表示SYN、ACK、FIN的标志都检查,但是只有SYN匹配。第二个表示ALL(SYN,ACK,FIN,RST,URG,PSH)的标志都检查,但是只有设置了SYN和ACK的匹配。
[root@localhost ~]# iptables -A FORWARD -p tcp --syn
选项--syn相当于"--tcp-flags SYN,RST,ACK SYN"的简写。
SYN Flood(DDos)
攻击原理
攻击者首先伪造地址对服务器发起SYN请求,服务器会回应一个ACK+SYN(可以+请确认)。而真实的IP会认为,我没有发送请求,不作回应。服务器没有收到回应,会重试3-5次并且等待一个SYN Time(一般30秒-2分钟)后,丢弃这个连接。
如果攻击者大量发送这种伪造源地址的SYN请求,服务器端将会消耗非常多的资源来处理这种半连接,保存遍历会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。TCP是可靠协议,这时就会重传报文,默认重试次数为5次,重试的间隔时间从1s开始每次都番倍,分别为1s+ 2s + 4s + 8s +16s = 31s,第5次发出后还要等32s才知道第5次也超时了,所以一共是31 + 32= 63s。
- state模块:用于针对tcp连接进行限制,较耗资源
iptables -A INPUT -m 模块名 --state 状态
参数:
-m iptables的模块
state:状态检查
mac:网卡硬件地址
--state 连接追踪中的状态:
NEW:新建立一个会话
ESTABLISHED:已建立的连接
RELATED:有关联关系的连接
INVALID:无法识别的连接
[root@localhost ~]# iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
# 放行ssh的首次连接状态
[root@localhost ~]# iptables -A INPUT -m mac --mac-source 00:0C:29:56:A6:A2 -j ACCEPT
# 对局域网内mac地址为00:0C:29:56:A6:A2主机开放其联机
1.1.5 保存与恢复
-
用脚本保存各iptables命令;让此脚本开机后自动运行
-
/etc/rc.d/rc.local
文件中添加脚本路径/PATH/TO/SOME_SCRIPT_FILE
-
用规则文件保存各规则,开机时自动载入此规则文件中的规则
-
定义Unit File,Centos 7,8可以安装iptables-services实现iptables.service
yum install iptables-services -y
iptables-save > /etc/sysconfig/iptables
iptables-restore < /etc/sysconfig/iptables
systtemctl enable iptables.service
1.1.6 转发本地端口
[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 6666 -j REDIRECT --to-port 22
6666也可以访问ssh
[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80
8080也可以转到80
1.2 firewalld
firewalld也是防火墙的一种用户工具,最终生效的依然是netfilter框架。
firewalld会将规则分为不同的区域,比如public、home、trusted等,默认是public。
firewall-cmd --get-default-zone 可以查看默认区域
firewall-cmd --set-default-zone 可以设置默认区域
firewall-cmd --add-port= --permanent 永久放行端口,需要指定是tcp还是udp
firewall-cmd --add-services= --permanent永久放行服务
firewall-cmd --add-rich-rule= --permanent添加富规则
firewall-cmd --reload 刷新防火墙,因为firewalld是动态防火墙,设置的规则都不会立即生效,需要重载才会生效
- 查看firewalld服务当前所使用的区域
[root@localhost ~]# firewall-cmd --get-default-zone
public
[root@localhost ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
- 查询ens33网卡在firewalld服务中的区域
[root@localhost ~]# firewall-cmd --get-zone-of-interface=ens33
public
默认public就不放行http,自己的网页访问不了
- 把firewalld服务中ens33网卡的默认区域修改为trusted,并在系统重启后生效。分别查看当前与永久模式下的区域名称
[root@localhost ~]# firewall-cmd --permanent --zone=trusted --changeinterface=ens33
The interface is under control of NetworkManager, setting zone to 'trusted'.
success
[root@localhost ~]# firewall-cmd --permanent --get-zone-of-interface=ens33
trusted
[root@localhost ~]# firewall-cmd --get-zone-of-interface=ens33
trusted
如果没有生效可以用reload重新加载配置
[root@localhost ~]# firewall-cmd --reload
success
现在trusted模式就可以放行访问
- 把firewalld服务的当前默认区域设置为public
[root@localhost ~]# firewall-cmd --set-default-zone=public
Warning: ZONE_ALREADY_SET: public
success
[root@localhost ~]# firewall-cmd --get-default-zone
public
[root@localhost ~]# firewall-cmd --permanent --get-zone-of-interface=ens33
public
- 启动/关闭firewalld防火墙服务的应急状况模式,阻断一切网络连接(当远程控制服务器时请慎用)
[root@localhost ~]# firewall-cmd --panic-on
[root@localhost ~]# firewall-cmd --panic-off
- 查询public区域是否允许请求SSH和HTTPS协议的流量
[root@localhost ~]# firewall-cmd --zone=public --query-service=ssh
yes
[root@localhost ~]# firewall-cmd --zone=public --query-service=https
no
- 把firewalld服务中请求HTTPS协议的流量设置为永久允许,并立即生效
[root@localhost ~]# firewall-cmd --zone=public --add-service=https
success
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-service=https
success
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]# firewall-cmd --zone=public --query-service=https
yes
- 把firewalld服务中请求HTTP协议的流量设置为永久拒绝,并立即生效
[root@localhost ~]# firewall-cmd --zone=public --remove-service=https --
permanent
success
[root@localhost ~]# firewall-cmd --reload
success
- 把在firewalld服务中访问8080和8081端口的流量策略设置为允许,但仅限当前生效
[root@localhost ~]# firewall-cmd --zone=public --add-port=8080-8081/tcp
success
[root@localhost ~]# firewall-cmd --zone=public --list-ports
8080-8081/tcp
二、SELinux安全子系统
SELinux(Security-Enhanced Linux)是美国国家安全局在linux开源社区的帮助下开发的一个强制访问控制(MAC,Mandatory Access Control)的安全子系统。RHEL7系统使用SELinux技术的目的是为了让各个服务进程都受到约束,使其仅获取到本应该获取的资源。
SELinux服务有三种配置模式,具体如下:
- enforcing:强制启用安全策略模式,将拦截服务的不合法请求
- permission:遇到服务越权访问时,只发出警告而不强制拦截
- disabled:对于越权的行为不警告也不拦截。
然在禁用SELinux服务后确实能够减少报错几率,但这在生产环境中相当不推荐。
vim /etc/selinux/config #配置文件
SELinux服务的主配置文件中,定义的是SELinux的默认运行状态,可以将其理解为系统重启后的状态,因此它不会在更改后立即生效。可以使用getenforce命令获得当前SELinux服务的运行模式
getenforce
可以用setenforce [0|1]命令修改SELinux当前的运行模式(0为禁用,1为启用)。注意,这种修改只是临时的,在系统重启后就会消失。