• firewall详解与操作


    firewall是什么:

      先声明一点,不知道iptables的,可以先去了解下。

      firewalld的底层是通过iptables来实现的,,firewalld 和 iptables 都不是防火墙,它们只是防火墙的管理程序,真正的防火墙是内核的netfilter。CentOs 6 中使用iptables来管理防火墙,到了CentOs 7 默认使用firewalld来管理防火墙, firewalld 的底层还是调用 iptables 的,firewalld在iptables的基础上加了许多很好用的功能。总的来说,firewalld 是系统服务,有守护进程。iptables 也只是一个工具,不是服务。firewall的包过滤机制也是通过iptables来实现的,

      firewalld 的设计者认识到大多数的 iptables 使用案例仅涉及到几个单播源 IP,仅让每个符合白名单的服务通过,而其它的会被拒绝。这种模式的好处是,firewalld 可以通过定义的源 IP 和/或网络接口将入站流量分类到不同区域zone。每个区域基于指定的准则按自己配置去通过或拒绝包。

    firewall对比iptables有什么变化:

    firewall基于iptables 进行语法简化。firewalld 通过使用服务名而不是它的端口和协议去指定服务,使它更易于使用,例如,是使用 samba 而不是使用 UDP 端口 137 和 138 和 TCP 端口 139 和 445。它进一步简化语法,消除了 iptables 中对语句顺序的依赖。可以认为firewall就是iptables的管理工具,并且firewall中加入了防火墙的“zone”的概念 ,zone可以理解为 firewalld 的单位、规则集:

    默认的规则集有:

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

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

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

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

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

    • work(工作),用于工作区。你可以基本相信网络内的其他计算机不会危害到你。仅仅接收经过选择的连接。

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

    • internal(内部),用于内部网络。你可以基本相信网络内的其他计算机不会危害到你。仅仅接收经过选择的连接。

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

    firewall的默认zone是public,默认只开放ssh服务和ipv6-client服务

    firewall规则集使用详解:

    首先,我们来看看一个规则集中都包含了什么:

    [root@localhost opt]# firewall-cmd --zone=public --list-all
    public
    target: default
    icmp-block-inversion: no
    interfaces: 
    sources: 
    services: ssh dhcpv6-client
    ports: 
    protocols: 
    masquerade: no
    forward-ports: 
    source-ports: 
    icmp-blocks: 
    rich rules:

    public  表示 public 区域
    target: default

    默认可以取四个值:default、ACCEPT、%%REJECT%%、DROP

    • ACCEPT:通过这个包。
    • %%REJECT%%:拒绝这个包,并返回一个拒绝的回复。
    • DROP:丢弃这个包,不回复任何信息。
    • default:不做任何事情。

    icmp-block-inversion: no
    interfaces:   划归本规则集管理的硬件设备,如网卡等
    sources:   信任区域的源ip
    services: ssh dhcpv6-client  开放的服务
    ports:   开放的端口
    protocols: 
    masquerade:   no表示这个区域是否允许 IP 伪装。如果允许,它将允许 IP 转发,它可以让你的计算机作为一个路由器。
    forward-ports:   列出转发的端口。
    source-ports:   信任区域的源ip及端口
    icmp-blocks:   阻塞的 icmp 流量的黑名单。
    rich rules:  在一个区域中优先处理的高级配置。

    firewall的使用:

    活动区域中扮演两个不同的角色。关联接口行为的区域作为接口区域,并且,关联源行为的区域作为源区域(一个区域能够扮演两个角色)。firewalld 按下列顺序处理一个包:

    1. 相应的源区域。可以存在零个或一个这样的区域。如果这个包满足一个富规则rich rule、服务是白名单中的、或者目标没有定义,那么源区域处理这个包,并且在这里结束。否则,向上传递这个包。
    2. 相应的接口区域。肯定有一个这样的区域。如果接口处理这个包,那么到这里结束。否则,向上传递这个包。
    3. firewalld 默认动作。接受 icmp 包并拒绝其它的一切。

    这里的关键信息是,源区域优先于接口区域。因此,对于多区域的 firewalld 配置的一般设计模式是,创建一个优先源区域来允许指定的 IP 对系统服务的提升访问,并在一个限制性接口区域限制其它访问。

    一个简单的多区域示例

    为演示优先权,让我们在 public 区域中将 http 替换成 ssh,并且为我们喜欢的 IP 地址,如 1.1.1.1,设置一个默认的 internal 区域。以下的命令完成这个任务:

    # firewall-cmd --permanent --zone=public--remove-service=ssh
    # firewall-cmd --permanent --zone=public--add-service=http
    # firewall-cmd --permanent --zone=internal --add-source=1.1.1.1
    # firewall-cmd --reload

    这些命令的结果是生成如下的配置:

    # firewall-cmd --zone=public--list-all
    
    public(default, active)
    
    interfaces: eno1 eno2
    
    sources:
    
    services: dhcpv6-client http
    
    ports:
    
    masquerade:no
    
    forward-ports:
    
    icmp-blocks:
    
    rich rules:
    
    # firewall-cmd --permanent --zone=public--get-target
    
    default
    
    # firewall-cmd --zone=internal --list-all
    
    internal (active)
    
    interfaces:
    
    sources:1.1.1.1
    
    services: dhcpv6-client mdns samba-client ssh
    
    ports:
    
    masquerade:no
    
    forward-ports:
    
    icmp-blocks:
    
    rich rules:
    
    # firewall-cmd --permanent --zone=internal --get-target
    
    default

     

    在上面的配置中,如果有人尝试从 1.1.1.1 去 ssh,这个请求将会成功,因为这个源区域(internal)被首先应用,并且它允许 ssh 访问。

    如果有人尝试从其它的地址,如 2.2.2.2,去访问 ssh,它不是这个源区域的,因为和这个源区域不匹配。因此,这个请求被直接转到接口区域(public),它没有显式处理 ssh,因为,public 的目标是 default,这个请求被传递到默认动作,它将被拒绝。

    如果 1.1.1.1 尝试进行 http 访问会怎样?源区域(internal)不允许它,但是,目标是 default,因此,请求将传递到接口区域(public),它被允许访问。

    现在,让我们假设有人从 3.3.3.3 拖你的网站。要限制从那个 IP 的访问,简单地增加它到预定义的 drop 区域,正如其名,它将丢弃所有的连接:

    # firewall-cmd --permanent --zone=drop --add-source=3.3.3.3
    
    # firewall-cmd --reload

     

    下一次 3.3.3.3 尝试去访问你的网站,firewalld 将转发请求到源区域(drop)。因为目标是 DROP,请求将被拒绝,并且它不会被转发到接口区域(public)。

    一个实用的多区域示例

    假设你为你的组织的一台服务器配置防火墙。你希望允许全世界使用 http 和 https 的访问,你的组织(1.1.0.0/16)和工作组(1.1.1.0/8)使用 ssh 访问,并且你的工作组可以访问 samba 服务。使用 firewalld 中的区域,你可以用一个很直观的方式去实现这个配置。

    public 这个命名,它的逻辑似乎是把全世界访问指定为公共区域,而 internal 区域用于为本地使用。从在 public 区域内设置使用 http 和 https 替换 dhcpv6-client 和 ssh 服务来开始:

    # firewall-cmd --permanent --zone=public--remove-service=dhcpv6-client
    # firewall-cmd --permanent --zone=public--remove-service=ssh
    # firewall-cmd --permanent --zone=public--add-service=http
    # firewall-cmd --permanent --zone=public--add-service=https

    然后,取消 internal 区域的 mdnssamba-client 和 dhcpv6-client 服务(仅保留 ssh),并增加你的组织为源:

    # firewall-cmd --permanent --zone=internal --remove-service=mdns
    # firewall-cmd --permanent --zone=internal --remove-service=samba-client
    # firewall-cmd --permanent --zone=internal --remove-service=dhcpv6-client
    # firewall-cmd --permanent --zone=internal --add-source=1.1.0.0/16

    为容纳你提升的 samba 的权限,增加一个富规则:

    # firewall-cmd --permanent --zone=internal --add-rich-rule='rule family=ipv4 source address="1.1.1.0/8" service name="samba" accept'

    最后,重新加载,把这些变化拉取到会话中:

    # firewall-cmd --reload

     

    仅剩下少数的细节了。从一个 internal 区域以外的 IP 去尝试通过 ssh 到你的服务器,结果是回复一个拒绝的消息。它是 firewalld 默认的。更为安全的作法是去显示不活跃的 IP 行为并丢弃该连接。改变 public 区域的目标为 DROP,而不是 default 来实现它:

    # firewall-cmd --permanent --zone=public--set-target=DROP
    # firewall-cmd --reload

    但是,等等,你不再可以 ping 了,甚至是从内部区域!并且 icmp (ping 使用的协议)并不在 firewalld 可以列入白名单的服务列表中。那是因为,icmp 是第 3 层的 IP 协议,它没有端口的概念,不像那些捆绑了端口的服务。在设置公共区域为 DROP 之前,ping 能够通过防火墙是因为你的 default 目标通过它到达防火墙的默认动作(default),即允许它通过。但现在它已经被删除了。

    为恢复内部网络的 ping,使用一个富规则:

    # firewall-cmd --permanent --zone=internal --add-rich-rule='rule protocol value="icmp" accept'
    # firewall-cmd --reload

    结果如下,这里是两个活动区域的配置:

    # firewall-cmd --zone=public--list-all
    public(default, active)
    interfaces: eno1 eno2
    sources:
    services: http https
    ports:
    masquerade:no
    forward-ports:
    icmp-blocks:
    rich rules:
    # firewall-cmd --permanent --zone=public--get-target
    DROP
    # firewall-cmd --zone=internal --list-all
    internal (active)
    interfaces:
    sources:1.1.0.0/16
    services:ssh
    ports:
    masquerade:no
    forward-ports:
    icmp-blocks:
    rich rules:
    rule family=ipv4 source address="1.1.1.0/8" service name="samba" accept
    rule protocol value="icmp" accept
    # firewall-cmd --permanent --zone=internal --get-target
    default

    这个设置演示了一个三层嵌套的防火墙。最外层,public,是一个接口区域,包含全世界的访问。紧接着的一层,internal,是一个源区域,包含你的组织,它是 public 的一个子集。最后,一个富规则增加到最内层,包含了你的工作组,它是 internal 的一个子集。

    这里的关键信息是,当在一个场景中可以突破到嵌套层,最外层将使用接口区域,接下来的将使用一个源区域,并且在源区域中额外使用富规则。

    firewall常用的配置命令:

    修改firewall防护等级
    firewall-cmd --set-default-zone=block

    查看当前zone的详细规则
    firewall-cmd --list-all

    放开22tcp端口
    firewall-cmd --zone=public --add-port=22/tcp --permanent 限制ip的同时限制端口

    firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.74.129" port protocol="tcp" port="28088" accept"
    systemctl restart firewalld

    
    添加单个ip为信任
    firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.128' accept"
    添加IP段为信任
    firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.0/24' accept"
    删除信任的ip段
    firewall-cmd --permanent --remove-rich-rule="rule family='ipv4' source address='192.168.1.128' accept"
    
    还有更多的富规则配置方法可以使用man firewalld.richlanguage来查看
    
    在添加信任的时候,我们除了可以在当前的规则集中添加信任,还可以将需要信任的ip或ip段添加到更受信任的规则集中来实现
    
    如:firewall-cmd --permanent --zone=trusted --add-source=192.168.74.1
    效果与在当前zone中添加信任的效果是一样的,不过,最好在当前zone中添加富规则,这样的话,相对易管理

     这里仅列出几个常用的,更多的写法可以参考man,使用man firewalld.richlanguage来查看

    在日常维护中,我们可能用的比较多的就是使用防火墙来对ip进行封禁等操作:

    永久封禁单个ip的所有请求
    firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='222.222.222.222' reject"
    
    当然,我们平时或许不需要这样来做,因为这样做的话,还需要重启下firewall,firewall还提供timeout参数
    即时生效,一定时间内对服务/ip等等的需求来进行开放或者封禁,比如我们可以写个自动化脚本,当发现有异常的连接时就可以添加一条rule将其相应的地址drop掉
    而且还可以使用--timeout给设置个时间段,过时之后自动删除!所以--timeout和--permanent是不可以一起使用的。
    如:firewall-cmd --add-service=ssh --timeout=10s

    在实际的应用中发现:

    1.安装并运行docker的主机,在打开firewall服务后,创建新容器会报如下错误,且旧容器的服务无法访问:

    [root@localhost ~]# docker run -d -p 8080:80 --name="nginx-8080" docker.io/nginx
    e0243020be093c04c3c6de16692839156655f489631077693f2cb3cdab7ebb4c
    /usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint nginx-8080 (cebe58ea6558cf6a5eb2b39d7eae5520ef365538e1cc5f39f50ee83aacc8862b):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8080 -j DNAT --to-destination 172.17.0.3:80 ! -i docker0: iptables: No chain/target/match by that name.
     (exit status 1)).
    [root@localhost ~]# 

    解决办法是重启docker,重启后问题不再出现,且之后对每次对firewall服务的操作都会影响docker提供的服务,所以每次修改firewall之后都要重启docker

    原因:

    docker 使用iptables 来实现网络隔离。docker 默认使用 bridge 网桥模式来实现容器的网络。dockerd 会在 iptables 建立 docker 链来设置所有的规则。firewalld 启动或重启时,会将iptables的规则清空。导致docker启动新容器出错。旧容器服务无法访问,这时就需要重启docker。

    2.测试发现,在限制192.168.74.129只能访问28088端口的同时,docker启动的其他端口的服务也可以被访问。而系统本地的服务正常被限制。

    原因: docker会将一些映射规则自动的加载到iptables的DOCKER chain中。docker配置后的转发规则允许ip对这个docker下所有的服务端口进行访问。

     

  • 相关阅读:
    hdu 1074
    hdu 4091
    hdu 4422
    hdu 3940
    hdu 2831
    hdu 1172
    hdu 3732
    hdu 1250
    hud 2073
    IOS socket基于tcp/udp的通信
  • 原文地址:https://www.cnblogs.com/xiaoyuxixi/p/13213474.html
Copyright © 2020-2023  润新知