赞
踩
firewalld是红帽系统版本7以后才出现的,版本7以前我们使用的是iptables来实现对于系统网络端口访问的控制的管理
firewalld是centos7的一大特性,最大的好处有两个:支持动态更新,不用重启服务;第二个就是加入了防火墙的“zone”概念
(不过,笔者使用的是rhel7版本,也是红帽的系统)
动态防火墙后台程序—firewalld,提供了一个动态管理的防火墙,用以支持网络“zones”,区分配对一个网络及其相关链接和界面一定程度的信任。
基于用户对网络中设备和交通所给与的信任程度,防火墙可以用来将网络分割成不同的区域—firewalld域
网络区名称 | 默认配置 |
---|---|
trusted(信任) | 可接受所有的网络连接 |
home(家庭) | 用于家庭网络,仅接受ssh,mdns,ipp-client,samba-client,或dhcpv6-client服务连接 |
internal(内部) | 用于内部网络,仅接受ssh,mdns,ipp-client,ipp-client,samba-client,dhcpv6-client服务连接 |
work(工作) | 用于工作区,仅接受ssh或dhcpb6-client服务连接 |
public(公共) | 在公共区域内使用,仅接受ssh或dhcpv6-client服务连接,为firewalld的默认区域 |
external(外部) | 出去的ipv4网络连接通过此区域伪装和转发,仅接受ssh服务连接 |
dmz(非军事区) | 仅接受ssh服务连接 |
block(限制) | 拒绝所有网络连接 |
drop(丢弃) | 任何接受的网络数据包都被丢弃,没有任何回复 |
上面表格中的block和drop的区别在于,虽然二者都同样是默认拒绝所有访问链接,但是block对于客户端有回显,而drop则没有回显。
那么,二者谁更有利一些呢?
并不是看起来‘一丢了事’的drop更好,而是block。
虽然看似直接丢包不回显,省去了服务端对于客户端访问请求的处理与应答。但是,实际上,对于客户而言,没有回显就导致客户无法明确地知道问题出在了哪里,就极有可能误认为是链接过程有问题,从而多次尝试访问,反而增大了服务端的访问量,增大了消耗与压力。
两台虚拟机desktop,server,一台真实物理主机
desktop:
两块虚拟网卡,配置ip地址:172.25.254.106 192.168.0.106
server:
一块虚拟网卡,配置ip地址:192.168.0.206
真实物理主机:
配置ip地址:172.25.254.6
firewall-config
(ROL是我们人为设定的一个域,不是默认就有的)
(当前使用的默认域会被黑体加粗显示)
firewall对于域的管理与查看:
firewall-cmd --state查看火墙当前状态(是否运行)
firewall-cmd --get-active-zones查看当前正在生效的域
firewall-cmd --get-default查看默认(使用,生效)的域
firewall-cmd --get-zones 查看全部的域
firewall-cmd --zone=public --list-all 查看public域的各项参数设定(配置)
firewall-cmd --get-services查看火墙可以设置添加的服务(有的服务可能无法直接添加到火墙中,只能打开其所使用的端口)
firewall-cmd --list-all-zones 查看所有的域及其内的参数
firewall-cmd --set-default-zone=dmz设置默认的域为dmz
基于ip的火墙访问控制:
firewall-cmd --add-source=172.25.254.250 --zone=trusted
将ip源(ip地址为)172.25.254.250的ip记录添加到trusted域
(从而使得所有从该ip来的访问都以trusted域中的参数来控制访问,也就是说不会受firewalld限制)
firewall-cmd --remove-source=172.25.254.250 --zone=trusted
将ip源(ip地址为)172.25.254.250的ip记录移除出trusted域
基于网卡(接口)的火墙访问控制:
firewall-cmd --remove-interface=eth1 --zone=public
将eth1网卡的接口从移public域中移出
(desktop的两块网卡,默认是在默认域public中的)
firewall-cmd --add-interface=eth1 --zone=trusted
将eth1网卡的接口移到trusted域中
(使得来访问eth1网卡上的ip的访问不会受到限制)
firewall-cmd --change-interface=eth1 --zone=public
将eth1网卡的接口从原来的域中移到public域中
firewall对于系统服务和端口的管理:
火墙工作时访问的策略 cd /etc/firewalld/zones 火墙工作时访问的数据 cd /usr/lib/firewalld/ /usr/lib/firewalld/services目录下的xml文件是可以在firewalld服务中开启的服务 /etc/firewalld/zones下的文件是生效的域中的参数配置(策略) 更改数据文件后,需要firewall-cmd --reload重启火墙才能生效 firewall-cmd --reload后,原配置public.xml文件会变为public.xml.old备份文件。新的配置再写入public.xml文件,并被读取 firewall-cmd --list-services 查看当前域(默认域)中开启的服务 firewall-cmd --list-ports 查看当前域中开启的端口 firewall-cmd --add-port=8080/tcp 在当前域中开启端口8080,以tcp协议的方式 firewall-cmd --remove-port=8080/tcp 在当前域中删除(关闭)端口8080 firewall-cmd --remove-service=ssh 在当前域中删除(关闭)服务ssh firewall-cmd --reload 刷新火墙当前的状态,但是已经连接的服务并不会受到干涉(关闭ssh,连接不会断掉) firewall-cmd --complete-reload 先断掉所有服务,再刷新火墙,然后按照新的火墙允许的列表重新连接 firewall-cmd --add-service 临时添加服务 (不需要重启火墙即可生效,直接firewall-cmd --list-services即可查看到) (reload后就恢复配置文件中的原来的配置了,反而在firewall-cmd --list-all中无法查看到) firewall-cmd --permanent --add-service永久添加服务 firewall-cmd --reload 需要重启火墙才能生效
下图为例:
事实上,并不是系统中的所有服务都会显示在firewall-cmd --get-services命令中,系统中可能存在部分服务无法直接添加到防火墙的服务中,比如之前所使用到的iscsi服务。这从图一中可以看出
图二至图四中,复制一相同格式,相同权限的xml文件
将其中的< short >< description >和port更改为iscsi的相应参数
重启防火墙firewalld服务后,服务读取了iscsi.xml文件,可以看到该服务
图五中,可以看到添加iscsi服务前的配置在public.xml.old文件中
图六中,可以看到将public.xml文件中的iscsi删除,reload重新加载后,更改生效
图七中,为firewalld管理系统端口的执行结果
想要只在firewall处拒绝172.25.254.250ip的主机访问httpd服务,这种精细的操作,使用firewalld无法实现。这时就需要我们对于更底层的部分进行操作管理。
Direct Rules概述:
通过firewall-cmd工具,可以使用 --direct选项在runtime运行时间里增加和删除链。如果不熟悉iptables,使用直接接口非常危险,因为可能无意间导致防火墙被入侵。直接端口模式适用于服务或者程序,以便于在运行时间内增加特定的防火墙规则。直接端口模式添加的规则优先应用
正因如此,通过使用–direct选项,我们可以更直接地去访问内核中的netfilter,这就需要我们要对于iptables以及内核中的table表和chain链的一些基本的概念
这里补充一下firewalld服务和iptables的一些粗略的大致的运行机理:
(个人理解,仅供参考)
iptables,是红帽系统中版本7以前所使用的。
firewalld,则是版本7以后才出现的
前者操作接近于windows,操作简单,精度低(即无法实现精准控制)
后者操作近似于对原始的数据,操作复杂,精度高
二者都是通过对于内核中的netfilter操作实现控制端口的目的。
但是,应该只有内核kernel本身才能对于netfilter做到直接操作。iptables和firewalld都是间接地操作netfilter(这张表?)
iptables更接近内核,相对于firewalld来说能更直接地去控制管理
当我们有某个端口的访问时,系统就会根据netfilter这张表来进行处理与控制
接下来简单地介绍以下我们要接触到的,内核中netfilter的3张表,5条链。
(内核中不止这些)
具体可以参考一下别人的博客:https://www.jianshu.com/p/70f7efe3a227
filter:
这张表有3条链:input,forward,output
都是关于本机中内核的访问与输出,forward(转发)如:经过内核进行的路由转换(路由转换是否输出,只是经过内核)
(经过内核的都属于filter表)
input访问请求
output内核对于请求的反馈
(访问本机内核的,经过内核的)
nat:
这张表有4条链:input,prerouting,postrouting,output
(该表上的input,output未经过内核,而filter中的则要经过内核)
路由之前,源地址转换(拆封,DNAT)——prerouting
路由之后,源地址转换(封装,SNAT)——postrouting
mangle:
这张表有5条链:input,prerouting,forward,postrouting,output
- -direct选项使用示例如下:
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1 -s 172.25.254.250 -p tcp --dport 80 -j REJECT (|ACEPT | DROP)
添加火墙策略 ipv4 表filter中的INPUT链第1条,其是顺序访问链上的记录的,越是前面的,优先级越高(因为是访问内核的请求) -s 访问来源的ipv4地址 -p使用协议tcp --dport访问目的地端口80 -j动作拒绝
firewall-cmd --reload 重新加载,使更改生效
firewall-cmd --direct --get-all-rules 查看上面添加的火墙策略
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1 -s 172.25.254.250 -p tcp --dport 80 -j REJECT
拒绝ip地址为172.25.254.250的主机访问本机端口80
想要恢复访问,不是将REJECT更改为ACCEPT执行;而是将--add-rule更改为--remove-rule执行:
firewall-cmd --permanent --direct --remove-rule ipv4 filter INPUT 1 -s 172.25.254.250 -p tcp --dport 80 -j REJECT
下图为例:
图一为添加火墙策略后,172.25.254.6无法通过ssh访问22端口,而192.168.0.206可以访问
图二为删除火墙策略后,172.25.254.6恢复访问22端口
图三中可以看到,添加–permanent参数虽然可以成功地添加策略,却无法删除策略,删除时必须去掉该选项参数
(1)目的地地址转换:(输出端转发)
即是网关中路由器的功能
即按照前面博客中的设置主机路由功能,使其作为路由器,即可以被其他主机作为网关,被动地将其他主机的数据包转发给目的地主机
1.在desktop上:
firewall-cmd --list-all 查看当前默认域的火墙设置 sysctl -a | grep ip_forward 查看主机的数据包转发功能是否开启 (出现=1为开启,=0则未开启) firewall-cmd --permanent --add-masequrade 开启主机的火墙上的地址伪装的功能 (开启后,可以通过firewall-cmd --list-all命令查看到) (该命令开启后应该就自动开启了主机的数据包转发的功能,至少在博主的主机上是这样的,可能是因为masequrade地址伪装功能,可能是在数据包转发功能的基础之上才能实现的) 如果主机的ip_forward功能仍未开启的话,也可以单独开启本功能: vim /etc/sysctl.conf 编辑加入: net.ipv4.ip_forward = 1 然后重启网络服务 systemctl restart network
2.在客户端server:
按照前文博客中的方式方法,设定网关为desktop的192.168.0.106
直接ssh主机172.25.254.6,通过desktop充当路由器
这时在172.25.254.6主机上使用w -i命令查看到的应该是172.25.254.106在登陆
上面的即是如何开启firewalld火墙服务的端口转发ip_forward功能和地址伪装功能masequrade,从而实现路由器的作用
(2)源地址转换:(输入端转发)
上面的路由功能虽然是实现了路由功能
但是,其并不是主动地将数据包转发出去,而是作为路由器被动地将别人访问不在同一个网段主机的消息传递过去
而下面的则是当别人访问本机时,主动地将访问本机的访问请求消息,转发给指定的其他的主机
1.在desktop上:
在前面开启了数据转发和地址伪装功能的前提下:
firewall-cmd --add-forward-port=port=22:proto=tcp:toport=22:toaddr=172.25.254.6
访问该主机的22端口(-forward-port=port=22)的访问请求
都会被转发给172.25.254.6的22端口(toport=22:toaddr=172.25.254.200)
firewall-cmd | --add-forward-port= | port=22 | :proto=tcp | :toport=22 | :toaddr=172.25.254.6
上面的命令可以拆分成这几段来理解
2.在客户端server:
ssh root@192.168.0.106
试图远程登陆192.168.0.106,会被其地址转发到172.25.254.6主机上
这时远程登陆输入的密码是实际登陆的172.25.254.6主机的密码(因为实际登陆的是那一台主机)
(3)限定主机进行地址转换
上面的(1)中的路由功能,完全可以被更加精准地限制在某个ip的访问,只有来自此ip地址的主机的数据包才能被转发
在服务端desktop上:
将之前开启的端口转发和地址伪装功能关闭:
firewall-cmd --add-rich-rule 'rule family=ipv4 source address=192.168.0.206 masquerade'
设置火墙,使得当数据包来源是192.168.0.206地址的主机时,可以开启masquerade功能
使用iptables的方式来管理主机系统的网络端口
切换到iptables管理方式: 先关闭firewalld服务 systemctl stop firewalld systemctl disabled firewalld systemctl mask firewalld 服务禁止到什么程度,视情况自己选择使用 如果不关闭firewalld服务,可能会有错误 至少博主虽然可以使用iptables -nL,但是却会显示很多的chain链,这是不正常的 systemctl start iptables man 8 iptables 查看iptables使用参数 -t(tables)指定 表,对哪一个表进行操作;不指定该参数,默认对filter表操作 -A 添加(默认添加在最后,作为最后一条记录) -C 检查(查看)(该参数不常用) -D 删除 -I 插入(指定插在链的第几条记录,不指定的话,默认第一条记录) -R 替换 -L 列出(以表格的形式列出表中的链条中的记录) -S 直接显示链条中的记录 -F 刷新(刷为空,将所有链中的记录全部删除) -Z 将数据包的状态都由related,established刷新为new状态 -N 新建链 -X 删除链 -P 指定参数policy,只有ACCEPT和DROP -E 重命名链 -h 帮助
示例如下:
iptables -t(tables) -nL -nL参数查看火墙策略 iptables -L 查看火墙策略 iptables -F 清空iptables(默认表filter)策略 iptables -t filter -A INPUT -s 172.25.254.250 -p tcp --dport 22 -j REJECT 命令 -t指定表filter -A在链INPUT中添加 -s指定对访问ip为172.25.254.250的主机执行该记录权限操作 -p使用tcp协议 --dport访问目的地端口为22 -j执行动作REJECT拒绝 iptables -D INPUT 2 删除默认filter表中的INPUT链的第2条记录 iptables -t filter -I INPUT 1 -s 172.25.254.250 -p tcp --dport 22 -j REJECT 将该记录插入filter表中的INPUT链中的第一条记录 iptables -t filter -R INPUT 1 -s 172.25.254.250 -p tcp --dport 22 -j DROP 将上面插入的第一条记录替换为DROP的该记录 iptables -N redhat 增加一条redhat链 iptables -E redhat WESTOS 将上面的redhat链更名为WESTOS iptables -X WESTOS 将WESTOS链删除 iptables -P INPUT DROP 将INPUT链的策略policy更改为DROP
保存iptables:
(1)service iptables save
保存到文件/etc/sysconfig/iptables中
(2)iptables-save > /etc/sysconfig/iptables
iptables -F
将策略刷新为空后
systemctl restart iptables
重启iptables服务即可恢复原来的设置
由于可能存在着对某个ip的记录是在表中的最后一个,那么每次访问都要去最后一条才能找到,匹配到,这很浪费时间
因此我们给其标记状态,以避免多次的重复认证。
最初的状态是NEW,通过认证后就是ESTABLISHED状态,认证后断开连接再连接就是RELATED状态
而只有NEW状态需要在表中查找策略来认证身份是否具有权限,另外两种状态则不需要再次认证。
想要只允许访问squid+sshd+dns 3个服务访问(端口3128,22,53)
设定策略如下:
iptables -F 先将以前的策略清空
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
首先第一条记录就是说,只要状态为ESTABLISHED,RELATED的访问就都可以允许访问
iptables -A INPUT -m state --state NEW -i lo -j ACCEPT
第二条记录,只要来自回环接口lo(load backup)的访问就都可以允许访问
iptables -A INPUT -m state --state NEW -p tcp --dport 3128 -j ACCEPT
第三条记录,状态为NEW的来访问tcp端口3128的请求都允许访问,访问后状态标记为ESTABLISHED,RELATED
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -j REJECT
第六条记录,不符合以上记录的条件的访问都不允许访问
iptables -nL
以上的顺序最好不要改变,因为这些策略记录是按照从前往后的顺序去读取的,改变记录的顺序就可能导致效率降低,甚至是功能错误。
(1)想让server ping 真机(192.168.0.206 —> 172.25.254.6)
(内网——>外网)
1.在desktop上:
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.25.254.106
(desktop的eth0的ip,与server不在同一个网段)
在nat表的POSTROUTING链上添加记录,在输出端口(-o)eth0进行SNAT转换,将数据包发送地址伪装为eth0网卡的ip的172.25.254.106
2.在客户端server:
设定网关为desktop的192.168.0.100
直接ping主机172.25.254.200,通过desktop充当路由器
总体上来说,要满足3个条件:
desktop要开启了路由功能ip_forward=1
desktop火墙策略设定正确:
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.25.254.100
server网关设定为desktop
(网关,策略,内核的数据转发功能)
(2)想让真机ssh desktop,desktop将其转发到server
(172.25.254.200 —> 192.168.0.200)
(外网——>内网)
1.在desktop上:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22 -j DNAT --to-dest 192.168.0.206
(server的ip,与真机不在同一个网段)
在nat表的PREROUTING链上添加记录,在输入端口(-i)eth0的22端口进行DNAT转换,将访问数据转发至ip为192.168.0.206的主机上
2.在真机172.25.254.6上:
不必设定网关
直接ssh desktop 172.25.254.106,被desktop自动转到server192.168.0.206
当我们开启了SElinux功能后,SElinux会限制我们对于系统服务所使用的端口的开启。
即我们只能使用在SElinux中允许使用的服务端口。
semanage port -l | grep http
查看SElinux下允许http服务使用的端口
semanage port -a -t http_port_t -p tcp 8888
在SElinux控制http服务的http_port_t功能中添加8888端口,使用tcp协议
下图为例:
图一中,开启SElinux,启动httpd服务后,查看httpd服务所使用的端口是80
编辑修改httpd服务的配置文件,将其默认监听端口由80更改为8080.
重启服务,并查看端口,可见更改成功。
而当我再次更改其端口为8888时,重启服务失败(由于SElinux限制)。
setenforce 0切换到警告模式下,再次重启服务就成功了。
图二中,可以看到,默认的SElinux允许httpd服务开启的端口有80,8080,但是没有8888端口,而这就是图一中,为什么在强制模式下无法重启httpd服务的原因
而当我们添加了8888端口后,httpd服务即可成功重启
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。