首页 > 代码库 > Linux学习笔记——iptables浅析

Linux学习笔记——iptables浅析

最近总结一些知识点越发吃力了,看来还是知识储备不足,用的不熟啊,还是硬着头皮来吧,争取多写点,毕竟好记性不如烂笔头不是么。

防火墙,就是用于实现Linux下访问控制的功能,它分为硬件的或者软件的防火墙两种。对于TCP/IP的模型来讲,第三层是网络层,三层的防火墙会在这层对源地址和目标地址进行检测。但是对于七层的防火墙,不管你源端口或者目标端口,源地址或者目标地址是什么,都将对你所有的东西进行检查。所以,对于设计原理来讲,七层防火墙更加安全,但是这却带来了效率更低。市面上通常的防火墙方案,都是两者结合的。由于我们都需要从防火墙所控制的这个口来访问,所以防火墙的工作效率就成了用户能够访问数据多少的一个最重要的控制,配置的不好甚至有可能成为流量的瓶颈。

大体了解了iptables具体是干什么的,接下来就来谈谈他的内部构造,太平盛世也是需要“条条框框”的制约才会更加繁荣!

iptables按功能划分为四张表分别为:netfilter、nat、mangle、raw,按作用范围来划分又分为五个链分别为:PREROUTING、INPUT、OUTPUT、FORWARD、POSTROUTING,见下图。

技术分享

iptables结构图

四表具体参数:

filter: 过滤,防火墙;

nat: network address translation, 网络地址转换;

mangle:拆解报文,做出修改,封装报文;

raw:关闭nat表上启用的连接追踪机制;

五链(又叫钩子函数hook functions)具体参数:

PREROUTING:请求报文数据流入前路由;

INPUT:报文进入主机后向用户空间流入;

FORWARD:数据在内核空间进行转发;

OUTPUT:用户空间将请求报文处理后返回给内核空间;

POSTROUTING:内核空间将响应报文数据路由转发

书接上回,那位朋友问了,既然定义了表定义了链,那这些是肿么协同工作的呢,诶!问到点上了这些条条框框说白了四张表就是大框框,而那五个链则是这些框里一条一条的规则,也就是常说的策略!那他们怎么对应的呢?别急,看下边:

netfilter:INPUT,FORWARD,OUTPUT
nat:PREROUTING,OUTPUT,POSTROUTING
mangle:PREROUTING,INPUT,OUTPUT,FORWARD,POSTROUTING
raw:PREROUTING,OUTPUT

这个是CentOS6上的,CentOS7之后会有一些变动,但功能没变只是有的框里边装的规则变多了而已,淡定。

规则这个东西是人定的,那执行总得有个优先顺序,iptables的条件筛选的执行顺序就是raw --> mangle --> nat --> filter。

下边来看下怎么来操作这个东东呢,走着

iptables命令:
  iptables [-t table] {-A|-D} chain rule-specification
  iptables [-t table] -I chain [rulenum] rule-specification
  iptables [-t table] -R chain rulenum rule-specification
  iptables [-t table] -D chain rulenum
  iptables [-t table] -S [chain [rulenum]]
  iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
  iptables [-t table] -N chain
  iptables [-t table] -X [chain]
  iptables [-t table] -P chain target
  iptables [-t table] -E old-chain-name new-chain-name

吓人吗,嗯挺吓人的,咱抽丝剥茧来看看葫芦里卖的什么药。

-t table这个是指定要在哪个表里设置或调整规则,

table:可以指定为filter,nat,mangle,raw,如果不加表名则默认为filter表。

常用命令:
A:append,向表中的指定链末尾添加一条规则;
D:Delete,删除表中指定链的指定规则;
I:Insert,向指定表中指定链的指定位置插入一条规则;
R:Replace,替换掉指定的规则;
S:列出指定链的所有规则,如果不指定链则列出所有链规则;
F:Flush,清空指定链上的规则,不指定则将表上的所有规则清空;
N:new, 创建新的自定义规则链;
X:drop, 删除用户自定义的空的规则链;
Z:zero,清零,置零规则计数器;
P:Policy,为指定链设置默认策略;对filter表中的链而言,默认策略通常有ACCEPT, DROP, REJECT; 
E: rEname,重命令自定义链;引用计数不为0的自定义链,无法改名,也无法删除;
L:list,列出指定链上的所有规则;
  -n: numberic,以数字格式显示地址和端口号;
  -v: verbose,显示详细信息;
  -vv, -vvv
  --line-numbers:显示规则编号;
  -x: exactly, 显示计数器计数结果的精确值;

条件匹配:

基本匹配:
[!] -s, --src, --source IP|Netaddr:检查报文中源IP地址是否符合此处指定的地址范围;
[!] -d, --dst, --destination IP|Netaddr:检查报文中源IP地址是否符合此处指定的地址范围;
-p, --protocol {tcp|udp|icmp}:检查报文中的协议,即ip首部中的protocols所标识的协议;
-i, --in-interface IFACE:数据报文的流入接口;仅能用于PREROUTING, INPUT及FORWARD链上;
-o, --out-interface IFACE:数据报文的流出接口;仅能用于FORWARD, OUTPUT及POSTROUTING链上;

扩展匹配:

-m macth_name --spec_options

隐式扩展:

对-p protocol指明的协议进行的扩展,可省略-m选项;
-p tcp
--dport PORT[-PORT]:目标端口,可以是单个端口或连续多个端口;
--sport PORT[-PORT]
--tcp-flags LIST1 LIST2:检查LIST1所指明的所有标志位,且这其中,LIST2所表示出的所有标记位必须为1,而余下的必须为0;没有LIST1中指明的,不作检查;
SYN, ACK, FIN, RST, PSH, URG
--tcp-flags SYN,ACK,FIN,RST SYN
--syn: 
-p udp
--dport
--sport
-p icmp
--icmp-type
#可用数字表示其类型:
  0:echo-reply
  8: echo-request

显式扩展: 

必须使用-m选项指定使用的扩展;

目标:

-j TARGET:jump至指定的TARGET
 ACCEPT: 接受
DROP: 丢弃
REJECT: 拒绝
RETURN: 返回调用链
REDIRECT:端口重定向
LOG: 记录日志
MARK:做防火墙标记
DNAT:目标地址转换
SNAT:源地址转换
MASQUERADE:地址伪装
自定义链:由自定义链上的规则进行匹配检查

在实际的生产环境中,可能会用到一种场景,内网中的一部分主机无法直接接入外网,但是可以通过某一台主机是可以上网,还有一种场景是公司的web服务器时架设在内网之中,那外网主机要想访问自己的web服务器该怎么实现呢?下边来解决下这两种问题

问题一:内网主机访问外网

   

~] iptables -t nat -A POSTROUTING -s 192.168.30.0/24 ! -d 192.168.30.0/24 -p tcp -j SNAT --to-source 10.35.21.2
#解释下,该条iptables策略需要设置在可以连接外网的主机上,该主机也可以跟内网主机通信,那此时这台主机就扮演了网络防火墙的角色,因为内网地址是无法在互联网上被路由器转发,所以就需要通过nat表的POSTROUTING链加入源地址转换策略,来将内网主机的IP地址转换为可接入外网的主机的IP地址,向外发送请求报文,从而达到访问外网的目的。
~]# iptables -t nat -A PREROUTING -d 10.35.21.2 -p tcp --dport 80 -j DNAT --to-destination 192.168.30.21:80 
#解析下,外网主机访问192.168.30.21这个主机的web服务时无法直接访问的,因为内网地址在互联网中无法被路由转发,所以就将10.35.21.2这台主机对外宣称自己为公司的web服务器,但实际上10.35.21.2是没有部署web服务器的,此时就是将所有访问10.35.21.2的所有外网主机的请求报文转发给内网的192.168.30.21这台web服务器中,经由其处理完成之后将响应报文回送给10.35这台主机,再响应给其他的外网主机。

===*** 我是分割线 ***===*** 我是分割线 ***===*** 我是分割线 ***===*** 


系统的INPUT 和OUTPUT默认策略为DROP,请完成以下关于iptables的题目

~]# iptables -P INPUT DROP
~]# iptables -P OUTPUT DROP

限定条件:本地服务器IP地址为172.16.0.10/16;

1、限制本地主机的web服务器在周一不允许访问;新请求的速率不能超过100个每秒;web服务器包含了admin字符串的页面不允许访问;web服务器仅允许相应报文离开本机;

~]# iptables -A INPUT -d 172.16.0.10 -p tcp --dport 80 -m time ! --weekdays monday -m limit --limit 100/second -m string --algo bm ! --string ‘admin‘ -m state --state NEW -j ACCEPT
~]# iptables -A OUTPUT -s 172.16.0.10 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT


2、在工作时间,即周一到周五的8:30-18:00,开放本机的ftp服务给172.16.0.0网络中的主机访问;数据下载请求的次数每分钟不得超过5个;

~]# iptables -s 172.16.0.0/16 -d 172.16.0.10 -p tcp --dport 21 -m time --timestart 8:30 --timestop 18:00 ! --weekdays sat,sun -m limit --limit 5/minute -m --state RELATED -j ACCEPT
~]# iptables -A OUTPUT -s 172.16.0.10 -d 172.16.0.0/16 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT


3、开放本机的ssh服务给172.16.x.1-172.16.x.100中的主机,x为你的座位号,新请求建立的速率一分钟不得超过2个;仅允许相应报文通过其服务端口离开本机;

~]# iptables -A INPUT -d 172.16.0.10 -p tcp --dport 22 -m iprange --src-range 172.16.30.1 to 172.16.30.100  -m limit --limit 2/minute -m state --state NEW -j ACCEPT
~]# iptables -A OUTPUT -s 172.16.0.10 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT


4、拒绝TCP标志位全部为1及全部为0的报文访问本机;

~]# iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
~]# iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP


5、允许本机ping别的主机;但不开放别的主机ping本机;

~]# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
~]# iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT

6、判断下属规则的意义;

#iptables -N clean_in 
#自定义名为clean_in的链
#iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP 
#向clean_in链中添加一条规则,禁止广播
#iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP
#向clean_in链中添加一条规则,禁止广播
#iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP
#禁止tcpflag标志位全为0的报文
#iptables -A clean_in -d 172.16.100.7 -j RETURN
#检测完无匹配就跳回主链;继续下一条检测
#iptables -A INPUT -d 172.16.100.7 -j clean_in
#来自网络上的主机请求本地主机的请求报文都转至clean_in链进行过滤
#iptables -A INPUT -i lo -j ACCEPT
#放行本地回环接口请求数据报文
#iptables -A OUTPUT -o lo -j ACCEPT
#放行本地回环接口响应数据报文
#iptables -A INPUT -i eth0 -m multiport -p tcp --dports 53,113,135,137,139,445 -j DROP
#禁止eth0接口上协议为tcp的所有目标地址接口为53,113,135,137,139,445的请求报文
#iptables -A INPUT -i eth0 -p udp --dport 1026 -j DROP
#禁止eth0接口udp的1026端口
#iptables -A INPUT -i eth0 -m multiport -p tcp --dports 1433,4899 -j DROP
#禁止eth0接口tcp的所有目标地址端口为1433,4899的请求报文
#iptables -A INPUT -p icmp -m limit --limit 10/second -j ACCEPT
#只允许icmp协议报文每秒10个速率放行


7、通过tcp_wrapper控制vsftpd仅允许172.16.0.0/255.255.0.0网络中主机访问,但172.16.100.3除外;对所被拒绝的访问尝试都记录在/var/log/tcp_wrapper.log日志文件中;

~]# vim /etc/hosts.allow
vsftpd:172.16.0.0/255.255.0.0 EXCEPT 172.16.100.3
~]# vim /etc/hosts.deny
vsftpd:ALL :spawn /bin/echo `date` attempt login from %c to %s ,%d >> /var/log/tcp_wrapper.log


8、删除/boot/grub/grub.conf文件中所有行的行首的空白字符;

#方法一、
~]# sed -i ‘s@^[[:space:]]\+@@g‘ /boot/grub/grub.conf
#方法二、
~]# vim /boot/grub/grub.conf
:1,$s@^[[:space:]]\+@@g #命令行模式下进行替换操作


9、删除/etc/fstab文件中所有以#开头,后跟至少一个空白字符的行的行首的#和空白字符;

~]# sed -i ‘s@^#[[:space:]]\+@@g‘ /etc/fstab


10、把/etc/fstab文件的奇数行另存为/tmp/fstab.3;

方法一、
~]# sed ‘n;d‘ /etc/fstab >/tmp/fstab.3
方法二、
~]# sed ‘1~2w /tmp/fstab.3‘ /etc/fstab


11、echo一个文件路径给sed命令,取出其基名;进一步取出其路径名;

#取出基名:
~]# echo "/etc/sysconfig/network-scripts/ifcfg-eth0/" |sed ‘s@^/.*/\([^/]\+\)/\?@\1@g‘
#取出路径名:
~]# echo "/etc/sysconfig/network-scripts/ifcfg-eth0/" |sed ‘s@[^/]\+/\?$@@‘

12、统计当前系统上所有tcp连接的各种状态的个数;

~]# netstat -nat |awk ‘/^t.*/{state[$NF]++}END{for(i in state){print i,state[i]}}‘


13、统计指定的web访问日志中各ip的资源访问次数;

~]# cat /etc/httpd/logs/access_log-20170224 |awk  ‘/^[0-9]/{IP[$1]++}END{for(i in IP){printf "client IP %s,total source %s\n",i,IP[i]}}‘


14、授权centos用户可以运行fdisk命令完成磁盘管理,以及使用mkfs或mke2fs实现文件系统管理;

~]# visudo
User_Alias ADMINS = centos
Cmnd_Alias DISKMANAGE = /usr/sbin/fdisk,/usr/sbin/mkfs,/usr/sbin/mke2fs
ADMINS ALL = (root) DISKMANAGE


15、授权gentoo用户可以运行逻辑卷管理的相关命令;

~]# visudo
User_Alias LVMMANAGER = gentoo
Cmnd_Alias LVMCOMND = /usr/sbin/pv*,/usr/sbin/vg*,/usr/sbin/lv*
LVMCOMND ALL = (root) LVMCOMND


16、基于pam_time.so模块,限制用户通过sshd服务远程登录只能在工作时间进行;

vim /etc/pam.d/sshd
account required pam_time.so
*;*;*;MoTuWeThFr0900-1800  #上面表示工作时间的9点到下午6点


17、基于pam_listfile.so模块,定义仅某些用户,或某些组内的用户可登录系统;

 ~]# vim /etc/limitusers
root 
centos
gentoo
 ~]# chmod 600 /etc/limitusers
 ~]# chown root /etc/limitusers
 ~]# vim /etc/pam.d/sshd
auth required pam_listfile.so item=user sense=allow file=/etc/limitusers onerr=succeed



本文出自 “积小流,成江海” 博客,请务必保留此出处http://goodjoe.blog.51cto.com/9173556/1909422

Linux学习笔记——iptables浅析