Linux防火墙 —— Iptables & Firewalld

防火墙-iptables

一:防火墙iptables

1.分类

逻辑分类:主机防火墙(个人)和网络防火墙(集体)
主机防火墙:针对单个主机进行防护
网络防火墙:它往往处于网络入口或者边缘,针对于网络入口进行防护,服务于防火墙背后的局域网

物理分类:硬件防火墙和软件防火墙
硬件防火墙:在硬件级别实现部分防火墙功能,另一部分基于软件实现,性能高,成本高
软件防火墙:应用软件处理逻辑运行于通用硬件平台之上,性能低,成本低

2.简介
iptables其实并不是真正的防火墙,我们可以把他理解为一个客户端的代理,用户是通过iptables这个代理,将用户的安全设定执行到对应的“安全框架”中,这个“安全框架”才是真正的防火墙。这个框架叫做“netfilter”。
netfilter 内核态 位于内核空间
iptables 用户态 位于用户空间

3.组成

四表:

raw 追踪数据包
mangle 对数据包打标记
nat 地址转换
filter 数据包过滤

raw:
	Chain PREROUTING (policy ACCEPT)
	Chain OUTPUT (policy ACCEPT)
mangle:
	Chain PREROUTING (policy ACCEPT)
	Chain INPUT (policy ACCEPT)
	Chain FORWARD (policy ACCEPT)
	Chain OUTPUT (policy ACCEPT)
	Chain POSTROUTING (policy ACCEPT)
nat:
	Chain PREROUTING (policy ACCEPT)
	Chain INPUT (policy ACCEPT)
	Chain OUTPUT (policy ACCEPT)	
	Chain POSTROUTING (policy ACCEPT)
filter:
	Chain INPUT (policy ACCEPT)
	Chain FORWARD (policy ACCEPT匹配过的数据包不会在去匹配)
	Chain OUTPUT (policy ACCEPT)

五链:

PREROUTING 在路由之前
INPUT 数据包进入时
FORWARD 数据包经过时
OUTPUT 数据包出去时
POSTROUTING 在路由之后

4.数据包流向

Linux防火墙 —— Iptables & Firewalld_iptables

二:防火墙iptable使用

1.删除规则

iptables -F   [-t 表名] 默认时删除filter表  删除的是表里的所有

2.查看规则

iptables -L
iptables -L -n
iptables -L --line   (man手册上没有这个参数)

3.添加规则
语法:

iptables -t 表 动作  链  匹配条件 -j 目标动作

动作:
添加规则:-A

iptables -t filter -A INPUT -p icmp -j REJECT
iptables -t filter -A INPUT -p tcp --dport 22 -s 192.168.122.113 -j REJECT

插入规则:-I
如果不指定插入到第几条,默认插入到第一条
插到那默认就是第几条

iptables -t filter -I INPUT 2 -p tcp --dport 22 -s 192.168.122.114 -j REJECT 插入到第二条规则上面
iptables -t filter -I INPUT -p tcp --dport 22 -s 192.168.122.114 -j REJECT 默认插入到第一行

替换(修改)规则:-R

iptables -t filter -R INPUT 2 -p tcp --dport 22 -s 192.168.122.115 -j REJECT 把114-->115

删除规则:-D

iptables -t filter -D INPUT -p tcp --dport 22 -s 192.168.122.115 -j REJECT
iptables -L --line (要删除的序号)
iptables -t filter -D INPUT(链) 2

修改默认策略:-P 只能用DROP和ACCEPT

iptables -t filter -P INPUT DROP
iptables -t filter -P INPUT ACCEPT

添加自定义链:-N 默认不生效 是用来存储规则的

iptables -N blackrach 自己创建的链
iptables -t filter -A blackrach -p tcp --dport 22 -s 192.168.122.116 -j REJECT 往自定义链上添加
iptables -A INPUT -j blackrach 关联自定义链,使用自定义链

修改自定义链名称:-E

iptables -E blackrach blackcloud

删掉自定义规则:不能被关联,必须是空链

iptables -X +链名 删除自定义链
计数清零:-Z
清空字节数
清空数据包个数
-v 显示详细的计数信息
iptables -Z 清空计数

4.匹配条件

基本匹配:
协议 -p tcp udp icmp
查端口:vim /etc/services 记录的是tcp/udp协议簇
vim /etc/protocols 记录的是icmp
-p tcp udp icmp

端口:使用端口前加协议(-p)
–sport源端口

iptables -A INPUT -p tcp --sport 22 -s 10.18.44.10 -j REJECT
--dport目标端口
iptables -A INPUT -p tcp --dport 22 -s 10.18.44.10 -j REJECT

IP
-s 源IP source ip地址 网段 逗号可以分开多个地址
-d 目标IP destination
扩展匹配:
-m 后面+扩展匹配
-m multiport 多端口

iptables -A INPUT -m multiport --sports(--source-ports) 80,20,22,1000:2000 -j DROP
-m iprange 多ip地址
iptables -A INPUT -m iprange --src-range 10.18.44.211-10.18.44.250 -j DROP
-m mac
iptables -A INPUT -m mac --mac-source 52:54:00:86:a1:86 -j REJECT

获取MAC的方式

[root@xingdian opt]# arp -a 10.0.102.101
[root@xingdian opt]# arping -I eth0 10.0.102.101

目标动作:
ACCEPT 允许数据包通过(默认策略)
DROP 直接丢弃数据包,不给任何回应
REJECT 拒绝数据包,必要时会给数据发送端一个响应
SNAT 源地址转换,可以解决內网用户用一个公网IP上网问题 POSTROUTING
DNAT 目标地址转换 PREROUTING
REDIRECT 做端口映射(扩展)

三:网络地址转换NAT

SNAT:把内网地址转换成公网地址
client ----------------iptables----内网ip–公网(baidu公网)

一个数据包在经过路由之后(或者说在通过防火墙的过滤之后)才被知道他的源IP是谁,在路由之前只能看到目标IP,如果我看不到你的源IP,那怎么匹配想过滤的数据包并进行源地址转换?我防火墙根本就不能确定你是否是符合匹配条件的IP,所以只能使用POSTROUTING

iptables -t nat -A POSTROUTING -s 192.168.122.0/24 -d 192.168.122.0/24 -j SNAT --to-source 192.168.2.1

DNAT:要把别人的公网ip换成我们内部的IP
web-server iptables client

如果不在路由之前就把目标地址转换完成,很显然当数据包到达入口IP之后,目的已经达到了,因为他本来的目标IP就是防火墙的对外公网IP,那么数据包还会往里面走吗?显然不可能了,所以只能使用PREROUTING

            1.1                  1.2  2.1                2.2
            A ---------------------B---------------------C
                                  转发
iptables -t nat -A PREROUTING -d 192.168.1.2 -j DNAT --to-destination 192.168.2.2
iptables -t nat -A POSTROUTING -d 192.168.2.2 -j SNAT --to 192.168.2.1



防火墙-firewalld

一:简介

CentOS7中默认将原来的防火墙iptables升级为了firewalld,firewalld跟iptables比起来至少有两大好处:

1、firewalld可以动态修改单条规则;
2、firewalld在使用上要比iptables人性化很多,即使不明白“四张表五条链”而且对TCP/IP协议也不理解也可以实现大部分功能。

注:实际上iptables还有第五张表—security表,但是这张表需要和selinux结合使用

二:firewalld目录结构

firewalld的配置文件以xml格式为主(主配置文件firewalld.conf例外),有两个存储位置
1、/etc/firewalld/
2、/usr/lib/firewalld/
使用规则:当需要一个文件时firewalld会首先到第一个目录中去查找,如果可以找到,那么就直接使用,否则会继续到第二个目录中查找。注:两个目录下的同名配置文件第一个目录内的生效

第二个目录中存放的是firewalld给提供的通用配置文件,如果我们想修改配置, 那么可以copy一份到第一个目录中,然后再进行修改,当然也可以直接修改第二个目录下的文件

三:使用

查看服务状态:

# systemctl status firewalld
# systemctl status -l firewalld
-l 完整信息 如果屏幕显示空间不够,默认情况下会缩略显示

启动关闭服务:

# systemctl start firewalld
# systemctl stop firewalld
# systemctl reload firewalld 重新加载配置

zone:
firewalld默认提供了九个zone配置文件:block.xml、dmz.xml、drop.xml、external.xml、 home.xml、internal.xml、public.xml、trusted.xml、work.xml,他们都保存在“/usr/lib /firewalld/zones/”目录下

九个zone其实就是九种方案,而且起决定作用的其实是每个xml文件所包含的内容,而不是文件名,所以不需要对每种zone(每个文件名)的含义花费过多的精力,比如trusted这个zone会信任所有的数据包,也就是说所有数据包都会放行,但是public这个zone只会放行其中所配置的服务,其他的一律不予放行,其实我们如果将这两个文件中的内容互换一下他们的规则就换过来了,也就是public这个zone会放行所有的数据包

注意:生效的只有默认zone里面的规则

trusted.xml中zone的target,就是因为他设置为了ACCEPT,所以才会放行所有的数据包,而 public.xml中的zone没有target属性,这样就会默认拒绝通过,所以public这个zone只有其中配置过的服务才可以通过

九区:

drop(丢弃)
任何接收的网络数据包都被丢弃,没有任何回复。仅能有发送出去的网络连接。

block(限制)
任何接收的网络连接都被 IPv4 的 icmp-host-prohibited 信息和 IPv6 的 icmp6-adm-prohibited 信息所拒绝。

public(公共)
在公共区域内使用,不能相信网络内的其他计算机不会对您的计算机造成危害,只能接收经过选取的连接。

external(外部)
特别是为路由器启用了伪装功能的外部网。您不能信任来自网络的其他计算,不能相信它们不会对您的计算机造成危害,只能接收经过选择的连接。

dmz(非军事区)
用于您的非军事区内的电脑,此区域内可公开访问,可以有限地进入您的内部网络,仅仅接收经过选择的连接。

work(工作)
用于工作区。您可以基本相信网络内的其他电脑不会危害您的电脑。仅仅接收经过选择的连接。

home(家庭)
用于家庭网络。您可以基本信任网络内的其他计算机不会危害您的计算机。仅仅接收经过选择的连接。

internal(内部)
用于内部网络。您可以基本上信任网络内的其他计算机不会威胁您的计算机。仅仅接受经过选择的连接。

trusted(信任)
可接受所有的网络连接。

配置方法:

三种:firewall-config(图形方式)、firewall-cmd(命令行方式)和直接编辑xml文件

命令行方式:
显示防火墙状态:

[root@qf-xingdian ~]# firewall-cmd --state
running

列出当前有几个zone:

[root@qf-xingdian ~]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work

取得当前活动的zones:

[root@qf-xingdian ~]# firewall-cmd --get-active-zones
public
interfaces: ens33

设置当前区域的接口:

[root@qf-xingdian ~]# firewall-cmd --get-zone-of-interface=enp03s  

临时修改网络接口(enp0s3)为内部区域(internal):

[root@qf-xingdian ~]# firewall-cmd --zone=internal --change-interface=enp03s

取得默认的zone:

[root@qf-xingdian ~]# firewall-cmd --get-default-zone

public
设置默认zone:

[root@qf-xingdian ~]# firewall-cmd --set-default-zone=public

拒绝所有包:

[root@qf-xingdian ~]# firewall-cmd --panic-on

取得当前支持的service(跟当前服务器是否已经安装某服务无关):

[root@qf-xingdian ~]# firewall-cmd --get-services
RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client ceph ceph-mon dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync freeipa-ldap freeipa-ldaps freeipa-replication ftp high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mosh mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster radius rpc-bind rsyncd samba samba-client sane smtp smtps snmp snmptrap squid ssh synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server

检查下一次重载后将激活的服务:

[root@qf-xingdian ~]# firewall-cmd --get-service --permanent
RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client ceph ceph-mon dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync freeipa-ldap freeipa-ldaps freeipa-replication ftp high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mosh mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster radius rpc-bind rsyncd samba samba-client sane smtp smtps snmp snmptrap squid ssh synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server

列出zone public 端口:

[root@qf-xingdian ~]# firewall-cmd --zone=public --list-ports 

列出zone public当前设置:

[root@qf-xingdian ~]# firewall-cmd --zone=public --list-all
public (default, active)
interfaces: eno16777736
sources:
services: dhcpv6-client ssh
ports:
masquerade: no 伪装功能
forward-ports:
icmp-blocks:
rich rules:
增加zone public开放http service:
[root@qf-xingdian ~]# firewall-cmd --zone=public --add-service=http
success
[root@qf-xingdian ~]# firewall-cmd --permanent --zone=internal --add-service=http
success
--permanent 永久生效

重新加载配置:

[root@qf-xingdian ~]# firewall-cmd --reload
success

增加zone internal开放443/tcp协议端口:

[root@qf-xingdian ~]# firewall-cmd --zone=internal --add-port=443/tcp
success

删除zone public 中ssh服务:

[root@qf-xingdian ~]# firewall-cmd --zone=public --remove-service=ssh

列出zone internal的所有service:

[root@qf-xingdian ~]# firewall-cmd --zone=internal --list-services
dhcpv6-client ipp-client mdns samba-client ssh

设置黑/白名单: (hosts.allow hosts.deny)
增加172.28.129.0/24网段到zone trusted(信任)

[root@qf-xingdian ~]# firewall-cmd --permanent --zone=trusted --add-source=172.28.129.0/24
success

列出zone truste的白名单:

[root@qf-xingdian ~]# firewall-cmd --permanent --zone=trusted --list-sources
172.28.129.0/24

活动的zone:

[root@qf-xingdian ~]# firewall-cmd --get-active-zones
public
interfaces: eno16777736

添加zone truste后重新加载,然后查看–get-active-zones:

[root@qf-xingdian ~]# firewall-cmd --reload
success
[root@qf-xingdian ~]# firewall-cmd --get-active-zones
public
interfaces: ens32 veth4103622
trusted
sources: 172.28.129.0/24

列出zone drop所有规则:

[root@qf-xingdian ~]# firewall-cmd --zone=drop --list-all
drop
interfaces:
sources:
services:
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:

添加172.28.13.0/24到zone drop:

[root@qf-xingdian ~]# firewall-cmd --permanent --zone=drop --add-source=172.28.13.0/24
success
添加后需要重新加载:
[root@localhost zones]# firewall-cmd --reload
success
[root@localhost zones]# firewall-cmd --zone=drop --list-all
drop
interfaces:
sources: 172.28.13.0/24
services:
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
[root@qf-xingdian ~]# firewall-cmd --reload
success

从zone drop中删除172.28.13.0/24:

[root@qf-xingdian ~]# firewall-cmd --permanent --zone=drop --remove-source=172.28.13.0/24
success

查看所有的zones规则:

[root@qf-xingdian ~]# firewall-cmd --list-all-zones

需要开放端口或开放某IP访问权限,需要先查看我们当前默认的zone是哪个,然后在对应的zone里面添加port和source,这样对外才会有作用。

比如当前的默认zone是public,需要开放80端口对外访问,则执行如下命令:
[root@qf-xingdian ~]# firewall-cmd --zone=public --permanent --add-port=80/tcp
success
[root@qf-xingdian ~]# firewall-cmd --reload
success

可以直接修改对应的配置文件:
以public zone为例,对应的配置文件是/etc/firewalld/zones/public.xml,像我们刚刚添加80端口后,体现在public.xml 中的内容为:

# cat public.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="dhcpv6-client"/>
<service name="ssh"/>--reload 或重
<port protocol="tcp" port="80"/>
</zone>

注意在修改配置文件后 --reload 或重启 firewall 服务。
端口转发:
端口转发可以将指定地址访问指定的端口时,将流量转发至指定地址的指定端口。转发的目的如果不指定 ip 的话就默认为本机,如果指定了 ip 却没指定端口,则默认使用来源端口。 如果配置好端口转发之后不能用,可以检查下面两个问题:

  1. 比如将 80 端口转发至 8080 端口,首先检查本地的 80 端口和目标的 8080 端口是否开放监听了
  2. 其次检查是否允许伪装 IP,没允许的话要开启伪装 IP
1.firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080
# 将80端口的流量转发至8080
2. firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.0.1
# 将80端口的流量转发至192.168.0.1
3. firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.0.1:toport=8080
# 将80端口的流量转发至192.168.0.1的8080端口