防火墙分为三层与四层防火墙
防火墙除了软件及硬件的分类,也可对数据封包的取得方式来分类,可分为代理服务器(Proxy)及封包过滤机制(IP Filter)。
其实Iptables服务不是真正的防火墙,只是用来定义防火墙规则功能的"防火墙管理工具",将定义好的规则交由内核中的netfilter即网络过滤器来读取,从而真正实现防火墙功能。
netfilter才是防火墙真正的安全框架(framework),位于内核空间,设置了“关卡”在Input、Output上(链)网卡的驱动是在内核空间当中,Netfilter也是在内核空间当中,所以Iptables+netfilter 可以在内核空间 当中设置“关卡”, 当用户去访问应用服务时,数据包是通过网卡流经内核空间之后到达用户空间
netfilter——内核空间
iptables ———— 用户空间的客户端代理
iptables抵挡封包的方式:
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中的规则表是用于容纳规则链,规则表默认是允许状态,那么规则链就是设置被禁止的规则,而反之,如果规则表是禁止状态,那么规则链就是设置被允许的规则。
每个表上通常会匹配约定俗成的意义的数据包
表链关系
PREROUTING:raw/mangle/nat
INPUT:mangle/filter
OUTPUT:raw/mangle/nat/filter
POSTROUTING:mangle/nat
FORWARD:mangle/filter
规则表的先后顺序:raw→mangle→nat→filter
链的规则和默认规则的设置一般有白名单和黑名单的两种方式
常用格式:
参数
-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:匹配来源端口号
规则:根据指定的匹配条件来尝试匹配每个经流“关卡”的报文,一旦匹配成功,则由规则后面指定的处理动作进行处理
匹配条件
处理动作
安装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
-t table指定表
subcommand子命令
案例
[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
使用自定义链
创建自定义链 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
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
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
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 –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-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。
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主机开放其联机
用脚本保存各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
[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
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是动态防火墙,设置的规则都不会立即生效,需要重载才会生效
[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:
[root@localhost ~]# firewall-cmd --get-zone-of-interface=ens33
public
默认public就不放行http,自己的网页访问不了
[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模式就可以放行访问
[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
[root@localhost ~]# firewall-cmd --panic-on
[root@localhost ~]# firewall-cmd --panic-off
[root@localhost ~]# firewall-cmd --zone=public --query-service=ssh
yes
[root@localhost ~]# firewall-cmd --zone=public --query-service=https
no
[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
[root@localhost ~]# firewall-cmd --zone=public --remove-service=https --
permanent
success
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]# firewall-cmd --zone=public --add-port=8080-8081/tcp
success
[root@localhost ~]# firewall-cmd --zone=public --list-ports
8080-8081/tcp
SELinux(Security-Enhanced Linux)是美国国家安全局在linux开源社区的帮助下开发的一个强制访问控制(MAC,Mandatory Access Control)的安全子系统。RHEL7系统使用SELinux技术的目的是为了让各个服务进程都受到约束,使其仅获取到本应该获取的资源。
SELinux服务有三种配置模式,具体如下:
然在禁用SELinux服务后确实能够减少报错几率,但这在生产环境中相当不推荐。
vim /etc/selinux/config #配置文件
SELinux服务的主配置文件中,定义的是SELinux的默认运行状态,可以将其理解为系统重启后的状态,因此它不会在更改后立即生效。可以使用getenforce命令获得当前SELinux服务的运行模式
getenforce
可以用setenforce [0|1]命令修改SELinux当前的运行模式(0为禁用,1为启用)。注意,这种修改只是临时的,在系统重启后就会消失。