以下实验的实操都是在redhat7.0上
iptables相关概念
iptables其实不是真正的防火墙
,我们可以把它理解成一个客户端代理,用户通过 iptables这个代理,将用户的安全设定执行到对应的安全框架中,这个安全框架”才是直正的防火墙,这个框架的名字叫 netfilter
。
netfilter才是防火墙真正的安全框架( framework),netfilter位于内核空间。
iptables其实是个命令行工具,位于用户空间,我们用这个工具操作真正的框架。
netfilter/ iptables(下文中简称为 iptables)组成 Linux平台下的包过滤防火墙,与大多数的 Linux软件一样,这个包过滤防火墙是兔费的,它可以代替昂贵的商业防火墙解决方案,完成封包过滤、封包重定向和网络地址转换(NAT)等功能。
TABLES(表)
-t 表
这个选项指定命令要操作的匹配包的表。如果内核被配置为自动加载模块,这时若模块没有加载,系统将尝试为该表加载适合的模块
filter表
,这是默认表,包含了内建的链INPUT(处理进入的包)、FORWORD(处理通过的包)、OUTPUT(处理本地的包)
nat表
,这个表被查询时表示遇到了产生新的连接的包
由三个内建的连接构成:
PREROUTING(修改路由之前进入的包)
OUTPUT(修改路由之前本地的包)
POSTROUTING(修改准备出去的包)
mangle表
由两个内建的连接构成:PREROUTING(修改路由之前进入的包)、OUTPUT(修改路由之前本地的包)
COMMANDS(命令)
-A 添加规则
-I:插入规则
-R:替代规则
-D :删除规则
-N:添加一条或更多规则
-L:显示所选链的所有规则
-E:根据用户给出的名字对指定链进行重命名
-X:删除指定用户的自定义链
-P:设置链的目标规则 不能使用REJECT
-S:查看(列出)规则
-N:添加链接
-F:刷新,清空所选链
-i lo:只能本机本地用户可以登陆,其他机子的用户不能登陆;
-Z:将所有链或所有链的计数器为清零
-j:动作,目标跳转
DROP:丢弃
ACCEPT:接受
REJECT:拒绝
-p:指定要匹配的数据包协议类型
-s:指定源地址
-d:指定目标地址
-i:进入网络接口(名称)
-o:输出接口(名称)
-n:ip地址和端口号以数字方式显示,默认情况下,程序是显示主机名,网络或服务
–state:一个逗号分割的匹配连接状态列表
value:NEW、RELATED(已经使用过的或已存在的连接;)、ESTABLISHED(正在使用的,双向传送的连接)、INVALID(未知链接)、NEW(包为新的连接、否则是非双向传送的)
ping的协议是tcp/ip协议族的ICMP协议。
iptables命令选项输入顺序:
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> – sport 源端口 <-d 目标IP/目标子网> – dport 目标端口 -j 动作
实验操作:
安装iptables:
yum install iptables-services -y
关闭firewalld,打开iptables
systemctl stop firewalld.service 关闭firewalld
systemctl disable firewalld.service 开机不自启
systemctl mask firewalld.service 锁死
systemctl start iptables.service 打开iptables
systemctl enable iptables.service 开机自启iptables
修改火墙策略(在filter
表实现)
[root@localhost Desktop]# iptables -Z INPUT #将所有链或所有链的计数器为清零
[root@localhost Desktop]# iptables -N LINUX #添加新的链
[root@localhost Desktop]# iptables -E LINUX linux #修改链的名称
[root@localhost Desktop]# iptables -X WESTOS #删除链
[root@localhost Desktop]# iptables -P INPUT DROP
##设置链的目标规则,但是只能是使用DROP和ACCEPT,不能使用REJECT;
添加防火墙策略
iptables -t filter -A INPUT -s 172.25.254.110 -p tcp --dport 22 -j REJECT
#添加在filter表中的INPUT,源地址为172.25.254.110,协议:tcp,端口:22,动作:REJECT,拒绝110主机远程连接访问
iptables -A INPUT ! -s 172.25.254.110 -p tcp --dport 22 -j ACCEPT
#"!"
除了172.25.254.110这台主机外,其他的主机都被允许
[root@localhost Desktop]# iptables -t filter -I INPUT -s 172.25.254.70 -p tcp -- dport 22 -j REJECT
#插入规则,拒绝70主机远程访问
[root@loalhost Desktop]# iptables -t filter -R INPUT 1 -s 172.25.254.70 -p tcp --dport 22 -j DROP
#修改规则,丢弃70主机远程访问的包,让客户端一直处于一个等待的状态
测试:
拒绝:[root@foundation70 ~]# ssh root@172.25.254.110
# 拒绝连接
ssh: connect to host 172.25.254.125 port 22: Connection refused
丢弃:[root@foundation70 ~]# ssh root@172.25.254.110
丢弃70主机远程访问的包,让客户端一直处于一个等待的状态
[root@base1 Desktop]# iptables -A INPUT -j REJECT
# 任何人访问我的时候都被拒绝
[root@base1 Desktop]# iptables -t filter -A INPUT -s 172.25.254.110 -p tcp --dport 22 -j ACCEPT
# 只允许110这台主机连接
[root@base1 Desktop]# iptables -nL
在110这台主机上测试,拒绝访问,是因为第一条规则是拒绝了所有访问,那么后面的规则不会被访问到,所以不生效
[root@foundation78 ~]# ssh root@172.25.254.110
sh: connect to host 172.25.254.125 port 22: Connection refused
[root@localhost Desktop]# iptables -S INPUT
#查看防火墙策略列表
iptables -D INPUT 2 #删除第二条规则
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#正在连接的服务,已存在连接的服务。
iptables -A INPUT -m state --state new -i lo -j ACCEPT
回环接口,允许本地主机的用户可以登陆,其他用户就不可以
iptables -A INPUT -m state --state new -p tcp --dport 22 -j ACCEPT
#允许22端口
iptables -A INPUT -m state --state new -p tcp --dport 80 -j ACCEPT
#允许80端口
iptables -A INPUT -j REJECT
#拒绝其他所有服务连接
iptales -nL
#查看所有规则
测试:# 在70这台主机上测试,连接成功
[kiosk@foundation70 ~]$ ssh root@172.25.254.110
root@172.25.254.110’s password:
Last login: Mon Aug 19 10:34:02 2019
例题:添加squid+sshd+dns服务,在上面的规则上添加一个端口为3128和53即可
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #正在连接的服务,已存在连接的服务。
iptables -A INPUT -m state --state new -i lo -j ACCEPT 回环接口,允许本地主机的用户可以登陆,其他用户就不可以
iptables -A INPUT -m state --state new -p tcp --dport 3128 -j ACCEPT 允许3128端口
iptables -A INPUT -m state --state new -p tcp --dport 22 -j ACCEPT 允许22端口
iptables -A INPUT -m state --state new -p tcp --dport 53 -j ACCEPT 允许53端口
iptables -A INPUT -j REJECT #拒绝其他所有服务连接
service iptables save
#保存策略;
iptables-save
#已经配置的规则,可以用重定向到一个文件中,该命令输出的是iptables规则的当前配置,是从配置角度输出的;
ptables-save > /etc/sysconfig/iptables
#保存策略在该文件中;
[root@localhost Desktop]# iptables -F
#清空规则
systemctl restart iptables.service
#清空后再重启动服务会显示出来保存的规则
实现端口转发和地址伪装(在nat表中实现)
准备三台虚拟机,一台是服务器,一台是客户端,一台是被连接的客户端
服务端设置:
地址伪装
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.25.254.110
# 从eth0出去的数据做SNAT转换为172.25.254.110
iptables -t nat -nL
查看nat表
sysctl -a | grep ip_froward # 查看内核IP路由功能功能是否打开,1打开,0关闭
若未打开进入配置文件vim /etc/sysctl.conf中进行修改:net.ipv4.ipforward=1
客户端(192.168.0.210)设置
设置网关:
GATEWAY=192.168.0.110
测试:单向主机ping是否能ping通,连接成功
不在同一个网段的访问:
[root@client Desktop]# ssh root@172.25.254.70# 此处输入的密码是转换后主机(172.25.254.70)的密码
root@172.25.254.784’s password:
Last login: Sun Dec 9 12:52:27 2018 from 172.25.254.125
[root@foundation78 ~]# w -i 但是在70主机上面查看是172.25.254.110访问的它,实际上是192.168.0.210访问的
端口转发
客户端
iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-dest 192.168.0.210
# 所有从eth0进来的数据都转发到192.168.0.210这台主机上
iptables -t nat -nL
测试:在客户端70主机测试,70主机远程访问一直认为是172.25.254.110服务器,实际上访问的是192.168.0.210
[root@foundation70 ~]# ssh root@172.25.254.110
root@172.25.254.125’s password: # 此处输入的密码192.25.254.210主机上的密码,
[root@base3 ~]# ifconfig # 查看,转发成功
转发过去的主机192.168.0.210上可以看见访问主机的来源是172.25.254.70
如果远程连接出现这种情况的话,需要删除该文件/root/.ssh/known_hosts
排错方法:
客户端A:192.168.0.210
客户端B(被连接的):172.25.254.70
服务端C:eth0:172.25.254.110
eth1:192.168.0.110
单向ping不通
检查客户端:
- 查看网关是否添加:route -n
- 查看ip
- 客户端ping网关
检查服务端:
- 查看ip是否是双网卡主机
- 查看防火墙策略:iptables -t nat -nL
- ping B
- 路由转换是否打开
- 重启网络
- 查看策略:iptables -nL,若存在策略,清空策略:iptables -F
SElinux修改服务端口
安装
yum install httpd
systemctl start httpd
netstat -antlupe | grep httpd
vim /etc/httpd/conf/httpd.conf
端口改为8080
systemctl restart httpd.service
重启服务
netstat -antlupe | grep httpd
修改成功
当SElinux打开的状态时,重启服务失败
打开selinux
端口修改错误
因为SELinux 防火墙 httpd 服务里没有 8888 端口
setenforce 0 #当设置 SELinux 为警告级别时,端口修改成功
systemctl restart httpd.service
netstat -antlupe | grep httpd
setenforce 1 #设置成强制级别时,修改端口又出现错误
systemctl restart httpd.service 端口修改还是失败
semanage port -l |grep http 查看httpd的端口在 SELinux 中的端口号没有 8888 端口
semanage port -a -t(指向类型) http_port_t -p tcp 8888添加端口
semanage port -l |grep http查看添加成功
重启服务,修改成功;
semanage port -D -t(指向类型) http_port_t -p tcp 8888删除端口