防火墙是指设置在不同网络之间,比如可信任的内部网和不可信的公共网,或者不同网络安全域之间的软硬件系统组合。它可通过检测、限制、更改跨越防火墙的数据流,尽可能地对外部屏蔽网络内部的信息、结构和运行状况,以此来保护企业内部网络的安全。防火墙是企业网络安全的屏障,它可以强化网络安全策略,对网络访问和内部资源使用进行监控审计,防止敏感信息的泄露。通常防火墙是由专门的硬件和软件来实现的,它的作用就像是门卫一样,管理进出的人员,防止可疑人员出入。
安全策略大致分为两种,一种是经过内核可filter表,一种是不经过内核的nat表,还有一种mangle表,包含前两种表的所有功能。
经过内核 - -> filter表 - -> 分为input,output,forward(转发)
不经过内核 - -> nat表(地址转换) - - > 分为input,output,postrouting(SNAT), prerouting(DNAT)
mangle表其中包含前两种表的所有功能,但不常用,只有当前两种表被规则填满的时候,才会使用它。
所以说防火墙是安装在内核上的插件,而firewalld和iptables都是在防火墙上配置安全策略的软件。而真正使用规则的是内核的netfilter.
firewalld的默认区域是public,firewalld默认提供了九个zone配置文件,它们都是xml(可扩展性标志性语言)格式的,用来作数据封装,都保存在“/usr/lib/firewalld/zones/”目录下,所以使用firewalld来配置策略,有三种方法,一种使用图形化的管理,一种使用firewall-cmd方法,还可以直接修改zone文件。
firewalld和iptables的比较:
在RHEL7系统中,默认使用firewalld来管理子系统,但底层调用的命令仍然是iptables。
firewalld跟iptables比较起来至少有两大好处:
1. firewalld可以动态修改单条规则
2. firewalld在使用上比iptables便利很多,即使不清楚TCP/IP协议也可以实现大部分的功能。
但是firewalld每个服务都需要配置才能通过,因为默认全部都是拒绝,而iptables默认全部是允许,需要拒绝的才会去限制。
在rhel7之后的系统中,默认使用的是firewalld防火墙,firewalld可以使用图形化界面管理,具体参数如下:
图形界面的命令为firewall-config
首先得开启firewalld服务,使用命令才能看到配置内容
上图中的一些含义
参数 | 含义 |
---|---|
permanent | 永久生效(服务重启后) |
runtine | 立即生效(服务重启后失效) |
block | 全部被阻止(但有回应) |
dmz | 军事级别 |
external | 附加 |
ROL | 主机ip |
trusted | 完全开放 |
firewall-cmd要使定义的协议永久生效,需要加一句 - -permanent, - -zone不写的话就使用默认值
[root@localhost ~]# firewall-cmd --state ##查看firewalld的状态
running
[root@localhost ~]# firewall-cmd --get-active-zones ##查看当前活动的区域
ROL
sources: 172.25.0.252/32
trusted
interfaces: eth0 eth1
[root@localhost ~]# firewall-cmd --get-zones ##查看所有可用区域
ROL block dmz drop external home internal public trusted work
[root@localhost ~]# firewall-cmd --zone=public --list-all ##查看指定域的所有设置
public
interfaces:
sources:
services: dhcpv6-client http https ssh
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:
[root@localhost ~]# firewall-cmd --get-services ##列出所有的预设服务
amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns ftp high-availability http https imaps ipp ipp-client ipsec kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp open pmcd pmproxy pmwebapi pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind samba samba-client smtp ssh telnet tftp tftp-client transmission-client vnc-server wbem-https
[root@localhost ~]# firewall-cmd --set-default-zone=trusted ##修改默认区域
success
[root@localhost ~]# firewall-cmd --get-default-zone ##查询默认区域
trusted
[root@localhost ~]# firewall-cmd --zone=public --add-source=172.25.0.0/24 ##设置网络地址到指定的区域
success
[root@localhost ~]# firewall-cmd --zone=internal --add-interface=eth0 ##添加网络接口
[root@localhost ~]# firewall-cmd --zone=internal --remove-interface=eth0 ##删除网络接口
[root@localhost ~]# firewall-cmd --zone=internal --change-interface=eth0 ##改变网络接口
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-service=smtp ##添加服务
[root@localhost ~]# firewall-cmd --permanent --zone=public --remove-service=smtp ##删除服务
[root@localhost ~]# firewall-cmd --permanent --zone=public --list-ports ##列出端口
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-port=8080/tcp ##添加端口
[root@localhost ~]# firewall-cmd --permanent --zone=public --remove-port=8080/tcp ##删除端口
**firewall-cmd --reload ##重新加载防火墙,这并不会中断已经建立的连接,如果打算中断,可以使用 --complete-reload选项)**
[root@localhost ~]# firewall-cmd --direct --get-all-rules ##获取当前的规则
[root@localhost ~]# firewall-cmd --direct --add-rule ipv4 filter INPUT 1 -s 172.25.254.70 -p tcp --dport 22 -j REJECT ##添加规则为拒绝从172.25.254.70主机发送过来的tcp协议的端口为22的请求,22端口为ssh服务,可以进行测试
success
[root@localhost ~]# firewall-cmd --direct --get-all-rules
ipv4 filter INPUT 1 -s 172.25.254.70 -p tcp --dport 22 -j REJECT
测试:
[root@localhost Desktop]# ssh [email protected]
ssh: connect to host 172.25.254.171 port 22: Connection refused
一般的服务都可以直接通过类似于上面的命令来进行规则的编写,但有一个服务是一个特殊,就是ftp服务
ftp服务有两个端口,控制端口21和数据传输端口20,而且工作模式分为主动模式和被动模式,被动模式代表数据传输端口不是20,而是一个大于1024的随机端口号,每次连接都会修改,所以被动模式更加安全,那么这里firewalld使用的就是被动模式,并不能单纯的使用上面的命令来说明用哪一个端口来允许这个连接行为,只能说除了可以连接的其他主机都不可以,具体配置方法如下:
通过查看/usr/lib/firewalld/services/ftp.xml文件,可以看到里面包含了一个模块module name="nf_conntrack_ftp" 这个模块是用来跟踪ftp服务的。
[root@localhost ~]# firewall-cmd --direct --add-rule ipv4 filter INPUT 1 ! -s 172.25.254.70 -p tcp --dport 21 -j REJECT
[root@localhost ~]# firewall-cmd --add-forward-port=port=22:proto=tcp:toport=22:toaddr=172.25.254.70
success ##将发到本机的22端口的请求发送到172.25.254.70的22端口主机上
[root@localhost ~]# firewall-cmd --list-all
public (default, active)
interfaces: eth0 eth1
sources: 172.25.0.0/24
services: dhcpv6-client http https ssh
ports:
masquerade: no
forward-ports: port=22:proto=tcp:toport=22:toaddr=172.25.254.70
icmp-blocks:
rich rules:
[root@localhost ~]# firewall-cmd --add-masquerade ##必须打开masquerade,这条配置才能生效
success
[root@localhost ~]# sysctl -a | grep ip_forward ##此时ip_forward打开
net.ipv4.ip_forward = 1
测试:
用其他主机ssh本机时,默认会进入到70主机里面,并且输入密码时,输入的也应该是70的密码
yum install iptables-services -y
选项 | 含义 |
---|---|
-F | 清除链中所有的规则 |
-P | 为链设置一条默认策略 |
-A | 为链增加一条规则说明 |
-D | 从链中删除一条规则 |
-L | 查看当前表中的链和规则 |
-n | 不做解析 |
-N | 增加链 |
-E | 修改链名称 |
-X | 删除链 |
-R | 修改策略 |
-I | 插入策略 |
-j | 动作 |
-s | 数据来源 |
-p | 网络协议 |
–dport | 端口 |
iptables -F命令在管理员决定从头开始的时候非常有用。由于防火墙的设置通常不会写的太长,因此每次将服务器应用到一个新环境的时候重写防火墙设置,可以避免因为疏忽而造成的前后设置上的冲突。
添加规则时注意若是不写明在哪一条添加,默认会添加到最后一行
用于防火墙设置的相关选项
选项 | 含义 |
---|---|
-p proto | 匹配网络协议:tcp、udp、icmp |
|
匹配ICMP协议,和-p icmp配合使用 |
-s source-ip | 匹配来源主机(或网络)的ip地址 |
|
匹配来源主机的端口,和-s source-ip配合使用 |
-d dest-ip | 匹配目标主机的ip地址 |
|
匹配目标主机的端口 |
添加:
[root@localhost ~]# iptables -nL -t filter ##查看当前filter表的规则,-t后面添加表的类型,默认会显示filter表
Chain INPUT (policy ACCEPT) ##表示filter中的INPUT表,并且默认设置为ACCEPT
target prot opt source destination
Chain FORWARD (policy ACCEPT) ##表示forware表
target prot opt source destination
Chain OUTPUT (policy ACCEPT) ##表示output表
target prot opt source destination
[root@localhost ~]# iptables -A INPUT -i lo -j ACCEPT ##在INPUT表中添加如果是通过本地回环接口进来的数据包全部通过
[root@localhost ~]# iptables -A INPUT -p tcp --dport 80 -j ACCEPT ##添加如果是通过tcp协议的80端口进来的数据包执行动作为通过
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
插入:
[root@localhost ~]# iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT ##表明将这条规则插入到第一行
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@localhost ~]# iptables -D INPUT 3 ##表示修改当前存在的第三条规则,3也可以变成想要删除的规则内容
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
命令格式为:iptables -m state --state [!] state [,state,state,state]
其中,state表示一个逗号分割的拉列表,用来指定连接状态,共有4中
1. NEW:该包想要开始一个新的连接(重新连接或连接重定向)
2. RELATED:该包是属于某个已经建立的连接所建立的新连接。如FTP的数据传输连接和控制连接
3. ESTABLISHED:该包属于某个已经建立的连接
4. INVALID:该包不属于任何连接,通常这些包都被丢弃
SNAT表示内网主机A想要访问外网用户B,所以得先通过拥有双网卡主机的C进行SNAT,转换成同外网主机同网段的IP地址,以便访问B。
这里各主机的配置如下:
A:172.25.70.1 #内网主机
B:172.25.254.70 #外网主机
C:eth0: 172.25.254.171 #外网网段ip
eth1: 172.25.70.171 #内网网段ip
重点内容从原理图便可以看出,A本来是想直接连接B主机的,但是因为不再一个网段,并不能直接进行连接,所以A主机的网关是和它同网段的双网卡主机的eth1,A通过网关将数据包发送给eth1之后,eth1发送给eth0,进行源地址转换,伪装成外网网段的ip,去连接B主机。
所以,这个设置时进行SNAT配置,而且SNAT时在网关之后,用POSTROUTING
双网卡主机设置:
[root@localhost ~]# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.25.254.171
[root@localhost ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@localhost ~]# sysctl -p
[root@localhost ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:172.25.254.171
用内网主机进行ssh登陆外网主机
外网主机显示结果:
[root@localhost Desktop]# w
15:37:57 up 4:50, 4 users, load average: 0.18, 0.36, 0.31
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
kiosk :0 :0 10:48 ?xdm? 18:57 0.19s gdm-session-wor
kiosk pts/0 :0 10:53 5.00s 4.89s 9.63s /usr/libexec/gn
kiosk pts/2 :0 11:01 1:17 0.08s 0.03s ssh root@172.25
root pts/4 172.25.254.171 15:37 3.00s 0.04s 0.04s -bash
外网主机B以为需要连接的是双网卡主机的外网,但实际需要连接的是内网主机A,所以双网卡主机网卡eth0收到后,先送给eth1进行DNAT,然后通过网关送到内网主机A上
原理图如下:
在双网卡主机上对iptables进行设置:
[root@localhost ~]# iptables -t nat -A PREROUTING -i eth0 -d 172.25.254.171 -j DNAT --to-dest 172.25.70.1 ##从eth0进入的数据如果想要连接172.25.254.171进行DNAT装换直接连接到172.25.70.1
[root@localhost ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT all -- 0.0.0.0/0 172.25.254.171 to:172.25.70.1
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:172.25.254.171
通过外网主机进行测试:
[root@localhost Desktop]# ssh [email protected]
root@172.25.254.171's password:
Last login: Wed Dec 6 15:32:52 2017
[root@localhost ~]# ifconfig
eth0: flags=4163 mtu 1500
inet 172.25.70.1 netmask 255.255.255.0 broadcast 172.25.70.255
inet6 fe80::5054:ff:fe00:250a prefixlen 64 scopeid 0x20
ether 52:54:00:00:25:0a txqueuelen 1000 (Ethernet)
RX packets 709 bytes 58899 (57.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 382 bytes 40519 (39.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 0 (Local Loopback)
RX packets 19 bytes 1776 (1.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 19 bytes 1776 (1.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0