15、iptables详解
--
http://www.netfilter.org/
http://www.iptables.org/
--参考路径
http://www.netfilter.org/documentation/index.html#documentation-howto
1,包过滤防火墙
在网络层对数据包进行选择,主要是对数据包的所使用的协议,端口,源地址和目标地址等参数来进行过滤
2,代理网关 squid(代理网关,反向代理web加速) varnish nginx haproxy --后面这几个软件也可以去做反向代理(但不做代理网关)
把内网和外网是完全隔离的,内网和外网不能进行直接的TCP通讯,必须通过代理网关的处理
.exe .jpg
3,状态检测
TCP有三次握手的阶段,常用的WEB,文件下载,发送和接收邮件等等都是TCP
状态检测防火墙除了包过滤防火墙所考查的参数之外,还要关心数据包连接的状态
可以做安全控制的:
tcpwrapper
pam 可植入性安全模块
selinux security enhanced linux (在rwx权限之外,进程访问文件或目录加的额外权限)
完整性检测 tripwire
入测检测 snort
SSL/TLS 网络传输加密通讯
ip tunnel + ipsec 网络传输加密通讯
netfilter / iptables --iptables 的全名 2.4版本后都集成有这个组件
--查看一下iptables的模块
ls /lib/modules/2.6.18-164.el5/kernel/net/netfilter/
ls /lib/modules/2.6.18-164.el5/kernel/net/ipv4/netfilter/
* stateless packet filtering (IPv4 and IPv6)
* stateful packet filtering (IPv4 and IPv6)
* all kinds of network address and port translation, e.g. NAT/NAPT (IPv4 only)
* flexible and extensible infrastructure
* multiple layers of API's for 3rd party extensions
* large number of plugins/modules kept in 'patch-o-matic' repository
iptables 基本概念
四张表: 表里有链 (chain )
filter: 用来进行包过滤: INPUT OUTPUT FORWARD
nat: 用来网络地址转换: network address translation ,允许一个内网地址块,通过NAT转换成公网IP,实现对公网的访问,解决IP地址不足
PREROUTING POSTROUTING OUTPUT
mangle :用来对数据包标志
PREROUTING INPUT OUTPUT FORWARD POSTROUTING
raw:对原始数据包的处理
PREROUTING OUTPUT
Incoming / \ Outgoing
-->[Routing ]--->|FORWARD|------->
[Decision] \_____/ ^
| |
v ____
___ / \
/ \ |OUTPUT|
|INPUT| \____/
\___/ ^
| |
----> Local Process ----
iptables
-A 增加一条规则,默认就是在后面增加
-D 删除
-L 列出规则
-n 以数值显示
-I 在最前面插入规则
-v 显示统计数据,与-L一起用,看到的信息更多
-F 清空规则
-z 清空计数器
-x 清空自定义链
-t 后接表名
-P policy,默认策略
-p 后接协议名
--dport 目标端口
--sport 源端口
-d 目标地址
-s 源地址
-i 接网卡接口, 进入的网卡接口
-o 接网卡接口, 出去的网卡接口
-j 后接动作
动作的分类:
ACCEPT 接收数据包
DROP 丢弃数据包
REJECT 拒绝数据包,和DROP的区别就是REJECT会返回错误信息,DROP不会
MASQUEREAD IP地址伪装,使用NAT转换成外网IP,可以PPP拔号(外网IP不固定情况)
SNAT 源地址转换,它与MASQUEREAD的区别是SNAT是接一个固定IP
DNAT 目标地址转换
LOG 记录日志
例1,列规则
iptables -L --默认看的就是filter表
iptables -L -t filter
iptables -L -t nat
iptables -L -t mangle
iptables -L -t raw
例2,对ping的控制
# iptables -A INPUT -p icmp -j REJECT --可以不加-t filter,默认就是对此表进行操作
# iptables -t filter -A INPUT -p icmp -j REJECT
--有返回信息
# iptables -t filter -A OUTPUT -p icmp -j REJECT
--无返回信息
# iptables -t filter -A INPUT -p icmp -j DROP
--无返回信息
# iptables -t filter -A OUTPUT -p icmp -j DROP
--无返回信息
只允许35ping本地,其它都拒绝
# iptables -t filter -A INPUT -p icmp -j REJECT
# iptables -t filter -A INPUT -s 10.1.1.35 -p icmp -j ACCEPT
--错误写法
# iptables -t filter -A INPUT -s 10.1.1.35 -p icmp -j ACCEPT
# iptables -t filter -A INPUT -p icmp -j REJECT
--正确写法
--如果要把一条规则加到前面,使用-I参数
# iptables -t filter -A INPUT -p icmp -j REJECT
# iptables -t filter -I INPUT -s 10.1.1.35 -p icmp -j ACCEPT
--正确写法
# iptables -t filter -I INPUT 2 -s 10.1.1.36 -p icmp -j ACCEPT
--把这一条加为第2条(指定数字为第几条)
------------------------------------------------
规则就是一个访问控制列表(ACL),读取的顺序是从上往下一条一条匹配,匹配一条就不继续往下匹配,最后匹配默认策略,所以正确写法应该是把刚才允许10.1.1.35的写到最前面
-----------------------------------------------
删除的方法:
方法一:
# iptables -t filter -D INPUT -s 10.1.1.35 -p icmp -j ACCEPT
--加的时候怎么写,删除时就要怎么写 A 参数换成 D就可以
方法二;
# iptables -L -n --line
# iptables -D INPUT 2
--在规则比较多或者不好写规则的情况下,可以先用--line或者--line-number列出行号,再用行号删除
方法三:
# iptables -F
--直接清空filter表的所有规则
例3,规则的保存与还原
# /etc/init.d/iptables save --这样是默认保存到/etc/sysconfig/iptables
# iptables-save > /etc/sysconfig/iptables--将当前规则保存到这个文件,文件可以自定义
# iptables -F
# iptables -X
# iptables -Z --使用这三条来清空filter表,如果别的表也要清空的话,就加-t 表名都清一次
# iptables-restore < /etc/sysconfig/iptables --把保存的规则还原回去
--/etc/sysconfig/iptables文件为默认保存文件,重启iptables服务会默认把此文件里的规则还原。当然也可以手工保存到另一个文件,就需要iptables-restore手工还原了。
例4,默认策略的修改
# iptables -P INPUT DROP --INPUT键默认策略改为DROP,改回来把DROP换成ACCEPT就行了
# iptables -P OUTPUT DROP --OUTPUT键默认策略改为DROP
例5,实现允许ssh过来,ssh出去,别的都拒绝 (要求,INPUT和OUTPUT双链默认策略都为DROP)
client server
源 目标
随机 ---------> 22
随机 <-------- 22
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
下面两条定义允许ssh进来
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
下面两条定义允许ssh出去
# iptables -A INPUT -p tcp --sport 22 -j ACCEPT
# iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
例6,在例五的基础上允许ping自己的IP,本地回环127.0.0.1和10.1.1.35
下面两条定义能ping自己和127本地回环
# iptables -A INPUT -i lo -p icmp -j ACCEPT
# iptables -A OUTPUT -o lo -p icmp -j ACCEPT
--这里用lo设备是127网段的所有回环地址都可以。如果指定ip127.0.0.1的话,只能控制这一个IP。在控制的范围上还是有区别的
下面两条定义此服务器和35这台机器可以互ping
# iptables -A INPUT -p icmp -s 10.1.1.35 -j ACCEPT
# iptables -A OUTPUT -p icmp -d 10.1.1.35 -j ACCEPT
--把默认策略先改为允许,然后把基本都安装起来,再把默认策略改回为drop
# yum install httpd* sendmail* m4 postfix bind* vsftpd* dhcp* samba* mysql* -y
例7,
在上面的基础上再加上只允许10.1.1.0这个网段访问你的httpd服务,和你只能访问10.1.1.0网段的httpd服务
例8
在上面的基础上再加上允许别人访问本台服务器的DNS
只需要做udp的53端口就可以了,不用写tcp 53(因为tcp 53主要是用于主从DNS服务器同步的)
-------------------------------
一些特殊的写法
连接端口
iptables -A INPUT -p tcp --dport 1:1000 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 22,80,110 -j ACCEPT
硬件地址
iptables -A INPUT -m mac --mac-source 00:23:CD:95:DA:0B -p all --dport 80 -j ACCEPT
例9 sendmail 或 postfix
例10 dhcp
iptables 对dhcp端口控制无效
67 68
例11
samba
137 138 139 445
例12 FTP
用iptables实现ftp的主动模式能够访问
下面两句实现的是命令端口的连接
# iptables -A INPUT -p tcp --dport 21 -j ACCEPT
# iptables -A OUTPUT -p tcp --sport 21 -j ACCEPT
--不加这两句,客户端访问时都不能登录,加了后可以登录,但用ls列出ftp的共享信息的话就发现不行,这是因为20的数据端口还没有做规则
# iptables -A INPUT -p tcp --dport 20 -j ACCEPT
# iptables -A OUTPUT -p tcp --sport 20 -j ACCEPT
--主动模式是20端口去主动连接,所以上面两条,实现了主动模式的连接,注意:如果使用linux的ftp命令来做实验的话,注意登录后使用passive命令关掉被动模式再试验
被动模式
客户端连接服务器的随机端口
vim /etc/vsftpd/vsftpd.conf
在最后加上
pasv_enable=YES
pasv_min_port=3000
pasv_max_port=3100 --最小端口范围和最大端口范围可以自定义
/etc/init.d/vsftpd restart --重启服务
下面两句就是针对上面的被动配置来设置的允许规则
# iptables -A INPUT -p tcp --dport 3000:3100 -j ACCEPT
# iptables -A OUTPUT -p tcp --sport 3000:3100 -j ACCEPT
--练习:上面的ftp是服务端写的规则,客户端应该怎么写去主动或被动访问别人的ftp服务器?
例13
nfs
--因为nfs用到rpc调用,端口不固定,所以需要把端口给固定起来.nis服务也会用到rpc调用,也需要做端口绑定(鸟哥书上面nis那章节有)
vim /etc/sysconfig/nfs --在此文件里加上下面四句
LOCKD_TCPPORT=3000
LOCKD_UDPPORT=3000
MOUNTD_PORT=3001
STATD_PORT=3002
/etc/init.d/portmap restart --这里先把默认策略改成ACCEPT,再启动就可以启动起来,然后再把默认策略改回成DROP,再继续做下面的实验
/etc/init.d/nfs restart
--如果是rhel6的话,则绑定完端口后,先重启rpcbind,再重启nfs
netstat -ntl |grep 300 去查看,看到rpc.的守护进程的端口为自己绑定的端口
iptables -A INPUT -p tcp --dport 3000:3002 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 3000:3002 -j ACCEPT
iptables -A INPUT -p udp --dport 3000:3002 -j ACCEPT
iptables -A OUTPUT -p udp --sport 3000:3002 -j ACCEPT
还要加上2049(nfs)和111(portmap)的端口的规则
iptables -A INPUT -p tcp --dport 2049 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 2049 -j ACCEPT
iptables -A INPUT -p udp --dport 2049 -j ACCEPT
iptables -A OUTPUT -p udp --sport 2049 -j ACCEPT
iptables -A INPUT -p tcp --dport 111 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 111 -j ACCEPT
iptables -A INPUT -p udp --dport 111 -j ACCEPT
iptables -A OUTPUT -p udp --sport 111 -j ACCEPT
--现在就可以用另一台机showmount -e 查看并进行挂载了
--练习:把上面的3000,3001,3002,2049,111合起来只写4条iptables来做
[root@localhost ~]# iptables -A INPUT -p tcp -m multiport --dport 111,2049,3000,3001,3002 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -p udp -m multiport --dport 111,2049,3000,3001,3002 -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -p tcp -m multiport --sport 111,2049,3000,3001,3002 -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -p udp -m multiport --sport 111,2049,3000,3001,3002 -j ACCEPT
练习:上面四条做的是为NFS服务器的身份允许别人访问
如果你做为NFS客户端去访问别人的NFS服务器,又应该如何写?
例14
yum
例15
mysql
3306
例16
oracle 监听
1521
=======================================================
准备两台虚拟机和真实机一起三台机做实验
内网 iptables网关 外网
81.1.1.129 ----> 81.1.1.1 vmnet1
网关指向
打开路由
172.16.2.35 eth0 <----- 172.16.2.28
网关指向
把gateway加上路由功能
echo "1" > /proc/sys/net/ipv4/ip_forward --临时生效
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
sysctl -p --改完后使用此命令,使之修改永久生效
路由功能加了后,网关都指向了gateway这台物理机,那么 两个网段的这两台机就能互相ping通
问题:这里我们模拟内外网的访问,网关互指,中间网关打开ip_forward,但实际的网络访问环境中,外网客户会把网关指向你公司的网关吗?
--禁止内网129这台和外网28互ping
# iptables -A FORWARD -p icmp -s 81.1.1.129 -j REJECT
--禁止内外网互ping
# iptables -A FORWARD -i vmnet1 -p icmp -j REJECT
或
# iptables -A FORWARD -o eth0 -p icmp -j REJECT
--禁止内网128这台上外网的172.16.2.28IP的这一个网站
# iptables -A FORWARD -s 81.1.1.129 -d 172.16.2.28 -p tcp --dport 80 -j REJECT
--这样的做法,如果要做网络管理(控制内部员工上网的行为,用iptables来做就比较繁锁,可以选用squid这种代理网关)
例2,
SNAT 源地址转换
内网多个IP转换成外网IP去连接公网
现在内网129可以ping通外网28
还有28的/var/log/httpd/access_log 记录129访问过来的信息,IP为129内网IP
在外网28上把指向172.16.2.35的网关给del掉
那么内网129不能访问外网28了
在中间的网关机写上下面的一句
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.16.2.35
内网129就可以访问外网28了
并且外网28的/var/log/httpd/access_log 记录的访问记录是172.16.2.35的访问
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
-- MASQUERADE 是伪装的意思,默认就是自动转换成eth0的外网IP,可以用于外网IP不固定的情况(比如PPP拔号时)
--练习:
现在我的172.16.2.35是通过尚观路由器172.16.2.1可以实际上外网的
请问,我一个hostonly网段的虚拟机81.1.1.129如何才能通过NAT上外网
hostonly虚拟机 真实机 尚观路由器 尚观外网IP
vmnet1 eth0
81.1.1.129 81.1.1.1 172.16.2.35 172.16.2.1 163.125.91.14
网关指向 81.1.1.1 | |
------------ |
----------------------|
DNS指向172.16.2.1
假设129访问百度
访问www.baidu.com
dns查询的IP包
SIP:81.1.1.129 172.16.2.35 163.125.91.14
DIP:172.16.2.1 172.16.2.1 网通DNS服务器
80端口的访问
SIP:81.1.1.129
DIP:61.135.169.125
答案:
1,把81.1.1.129的网关指向81.1.1.1
2,把81.1.1.129的DNS指向172.16.2.1(尚观router)或者8.8.8.8(外部DNS),也就是和35一样的指向能上外网的DNS(129和35可以指的不一样)
3,在172.16.2.35上加两条iptables规则
# iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 80 -j SNAT --to-source 172.16.2.35
# iptables -t nat -A POSTROUTING -o eth0 -p udp --dport 53 -j SNAT --to-source 172.16.2.35
如果把DNS指向81.1.1.1(并且212.1这台没有开启DNS服务,因为会做缓存),那么就要在上面两条的基础上再加上一条就可以上网了
# iptables -t nat -A PREROUTING -p udp --dport 53 -i vmnet1 -j DNAT --to-destination 172.16.2.1
例3,
DNAT 目的地址转换
也就是外网是客户端,要访问我们内网的服务器,客户端只是访问外网IP,内网里不同的服务器不同的IP,可以使用DNAT把不同的请求转换到不同的内网服务器
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to-destination 81.1.1.129
|
外网IP |
网关
内网IP |
|
|
FTP 服务器 邮件 web DNS