本节大纲:

1.iptables简介

2.防火墙介绍

3.iptables的优点



1.iptables简介

iptables是Linux下的配置防火墙的工具,用于配置Linux内核集成的IP信息包过滤系统,使增删改查信息包过滤表中的规则更加简单。

 

iptables是与最新的3.5版本Linux内核集成的IP信息包过滤系统。如果Linux系统连接到因特网或LAN、服务器或连接LAN和因特网的代理服务器,则该系统有利于在Linux系统上更好地控制IP信息包过滤和防火墙配置。


  防火墙在做信息包过滤决定时,有一套遵循和组成的规则,这些规则存储在专用的信息包过滤表中,而这些表集成在Linux内核中。在信息包过滤表中,规则被分组放在我们所谓的链(chain)中。而netfilter/iptables IP信息包过滤系统是一款功能强大的工具,可用于添加、编辑和移除规则。


  虽然netfilter/iptables IP信息包过滤系统被称为单个实体,但它实际上由两个组件netfilter和iptables组成。

  netfilter组件也称为内核空间(kernelspace),是内核的一部分,由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。

  iptables组件是一种工具,也称为用户空间(userspace),它使插入、修改和除去信息包过滤表中的规则变得容易。除非您正在使用Red Hat Linux 7.1或更高版本,否则需要下载该工具并安装使用它。


2.防火墙介绍

Firewall,防火墙,也称防护墙,,是一种隔离工具。其工作于主机或网络的边缘,对于进出本主机或网络的报文根据事先定义好的检测规则作匹配检测,对于能够被规则匹配到的报文做出相应处理。

  防火墙有主机防火墙和网络防火墙,主机防火墙主要用来监测和处理流经本主机的数据包;网络防火墙则是用来监测和处理流经本防火墙的数据包。


  与Linux内核各版本集成的防火墙历史版本:

    2.0.x内核:ipfwadm

    2.2.x内核:ipchains

    2.4.x内核:iptables


3.iptables的优点

netfilter/iptables的最大优点是它可以配置有状态的防火墙,这是ipfwadm和ipchains等以前的工具都无法提供的一种重要功能。


有状态的防火墙能够指定并记住为发送或接收信息包所建立的连接的状态。防火墙可以从信息包的连接跟踪状态获得该信息。在决定新的信息包过滤时,防火墙使用的这些状态信息可以增加其效率和速度。这里有四种有效状态,名称分别为ESTABLISHED、INVALID、NEW和RELATED。

ESTABLISHED:指出该信息包属于已建立的连接,该连接一直用于发送和接收信息包并且完全有效。

INVALID:指出该信息包与任何已知的流或连接都不相关联,它可能包含错误的数据或头。

NEW:意味着该信息包已经或将启动新的连接,或者它与尚未用于发送和接收信息包的连接相关联。

RELATED:表示该信息包正在启动新连接,以及它与已建立的连接相关联。


netfilter/iptables的另一个重要优点是,它使用户可以完全控制防火墙配置和信息包过滤。用户可以定制自己的规则来满足特定需求,从而只允许想要的网络流量进入系统。


另外,netfilter/iptables是免费的,这对于那些想要节省费用的人来说十分理想,它可以代替昂贵的防火墙解决方案。


4.防火墙的类型


包过滤防火墙:

包过滤是IP层实现,包过滤根据在网络层对数据包的源IP、目的IP、协议类型(TCP/UDP/ICMP)、源端口、目的端口等包头信息及数据包传输方向灯信息来判断是否允许数据包通过。


应用层防火墙:

也称为应用层代理防火墙,基于应用层协议的信息流检测,可以拦截某应用程序的所有封包,提取包内容进行分析。有效防止SQL注入或者XSS(跨站脚本攻击)之类的恶意代码。实现七层的包过滤


状态检测防火墙:

TCP有三次握手的阶段,常用的WEB,文件下载,发送和接收邮件等等都是TCP。结合包过滤和应用层防火墙优点,基于连接状态检测机制,将属于同一连接的所有包作为一个整体的数据流看待,构成连接状态表(通信信息,应用程序信息等),通过规则表与状态表共同配合,对表中的各个连接状态判断。


5.iptables数据包过滤匹配流程

默认防火墙规则


iptables(17)_import

拒绝与禁止一个数据包

iptables(17)_软件包_02

IP防火墙的数据包传输

在IP防火墙中,有三个内建的过滤规则链被使用。所有到达接口的数据包都按照输入规则链被过滤。如果数据包被接受,它会被送到路由模块。路由功能决定数据包是被送到本地还是转发到另一个出站接口。

iptables(17)_import_03

如果被转发,数据包会由转发规则链进行第二次过滤。如果数据包被接受,它会被送到输出规则链。

本地产生的出站数据包和将被转发的数据包都要经过输出规则链。如果数据包被接受,它会被送出接口。

回环路径包括两个规则链,如图示。每一个回环数据包在出回环接口之前需要通过输出规则链,在那里它会被送到回环的输入接口,然后输入规则链被应用。

iptables(17)_软件包_04


iptables添加规则的考量点

 添加规则的考量点:

 a) 要实现哪种功能:判断添加在哪张表上

 b) 报文流经的路径:判断添加在哪个链上


iptables处理的优先级次序

 链:链上规则的次序,即为检查的次序,因此隐含一定的法则

 a) 同类规则(访问同一应用),匹配范围小的放上面

 b)不同类规则(访问不同应用),匹配到报文频率较大的放上面

 c) 将那些可由一条规则描述的多个规则合并为一个

 d) 设置默认策略


功能的优先级次序:raw --> mangle --> nat --> filter


iptables(17)_import_05

iptables(17)_认证_06


6.iptables规则

6.1.iptables规则的组成

  iptables规则的组成部分:报文的匹配条件,匹配到之后的处理动作

    匹配条件:根据协议报文特征指定

      基本匹配条件:源IP,目标IP,源端口,目标端口

      扩展匹配条件:连接追踪,状态追踪

    处理动作:

      内建处理机制

      自定义处理机制

    注意:报文不会经过自定义链,只能在内置链上通过规则进行引用后生效


6.2 iptables规则管理工具

  iptables是一种规则管理工具,可实现iptables规则的添加、修改、删除和显示等功能。

  规则和链有计数器:

    pkts:表示由规则或链所匹配到的报文的个数

    bytes:表示由规则或链所匹配到的所有报文大小之和


  iptables命令:

  说明:

    iptables是用来设置、维护和检查Linux内核的IP包过滤规则的。

    可以定义不同的表,每个表都包含几个内部的链,也能包含用户定义的链。每个链都是一个规则列表,对对应的包进行匹配;每条规则指定应当如何处理与之相匹配的包。这被称作“target”,也可以跳向同一个表内的用户定义的链。


    targets:

    防火墙的规则指定所检查包的特征和目标。如果包不匹配,将送往该链中下一条规则检查;如果匹配,则下一条规则由目标值确定。该目标值可以是用户定义的链名,或是某个专用值,如ACCEPT,DROP,QUEUE或者RETURN。


语法:

 

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

iptables分为四表五链,表是链的容器,链是规则的容器,规则指定动作。

四表:

解释表中的链

filter

用于包过滤 

INPUT、OUTPUT和FORWARD

nat

网络地址转发

PREROUTING、POSTROUTING和OUTPUT

mangle

对特定数据包修改

PREROUTING、POSTROUTING、INPUT、OUTPUT和FORWARD

raw

不做数据包链接跟踪,对原始数据包的处理

PREROUTING和OUTPUT

说明:nat说白了就是允许一个内网地址块,通过NAT转换成公网IP,实现对公网的访问,解决IP地址不足


五链:

INPUT

本机数据包入口

OUTPUT

本机数据包出口

FORWARD

经过本机转发的数据包

PREROUTING

防火墙之前,修改目的地址(DNAT)

POSTROUTING

防火墙之后,修改源地址(SNAT)

数据包的处理方式不同,流经的链也不同:

数据流入时要经过的链:PREROUTING --> INPUT

数据流出时要经过的链:OUTPUT --> POSTROUTING

数据转发时要经过的链:PREROUTING --> FORWARD --> POSTROUTING


命令格式:iptables [-t table] 命令 [chain] 匹配条件 动作



规则管理选项:

命令

描述

-A,append

追加一条规则

-I,insert

插入一条规则,默认链头,就是最前面出入一条规则后跟编号,指定第几条

-D,delete

删除一条规则

-F,flush

清空规则

-L,list

列出规则

-P,policy

设置链缺省规则

-m,module

模块,比如state、multiport

-n以数值显示
-v显示统计数据,与-L一起用,看到的信息更多
-z清空计数器
-x清空自定义链

匹配条件

描述

-i

入口网卡接口

-o

出口网卡接口

-s,source

源地址

-d,destination

目标地址

-p,policy

默认策略

-P, protocol后接协议名,协议类型

--sport

源端口

--dport

目的端口

-t后接表名
-j后接动作

动作

描述

ACCEPT

允许数据包通过

DROP

丢弃数据包不做处理

REJECT

拒绝数据包,并返回报错信息,这就是和DROP的区别

SNAT

一般用于nat表的POSTROUTING链,进行源地址转换

DNAT

一般用于nat表的PREROUTING链,进行目的地址转换

MASQUERADE

动态源地址转换,动态IP时使用

LOG记录日志

模块

描述

state

包状态,有四个:NEW、RELATED、ESTABLISHED和INVALID

mac

源MAC地址

limit

包速率限制

multiport

多端口,以逗号分隔

iprange

端口范围,以逗号分隔



 

常用options:
-t table:
  filter,nat,mangle,raw

链管理选项:
-F:flush,清空规则链,若省略链则表示清空指定表上的所有的链
-N:new,创建新的自定义规则链
-X:drop,删除用户自定义的空的规则链
-Z:zero,清零,置零规则计数器,让计数器重新开始计数
-P:Policy,为指定链设置默认策略,对filter表中的链而言,默认策略通常有ACCEPT,DROP,REJECT
-E:rEname,重命名自定义链,引用计数不为0的自定义链无法改名也无法删除

规则管理选项:
-A:append,将新规则追加于指定链的尾部
-I:insert,将新规则插入至指定链的指定位置,不指定位置则默认插入为第一条
-D:delete,删除指定链上的指定规则
#  有两种指定方式:
#  a) 指定匹配条件
#  b) 指定规则编号
-R:replace,替换指定链上的指定规则

查看选项:
-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 match_name --spec_options
    例如:-m tcp --dport 22
    隐式扩展:对-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必须为1,其余的必须为0
  --syn:表示匹配三次握手中的第一次握手
  
-p udp
  --dport
  --sport
  
-p icmp
  --icmp-type:可用数字表示其类型
    0:echo-reply,响应
    8:echo-request,请求
如:
  iptables -A OUTPUT -s 192.168.1.1 -p icmp --icmp-type 8 -j ACCEPT
  iptables -A INPUT -d 192.168.1.1 -p icmp --icmp-type 0 -j ACCEPT

显式扩展:必须使用-m选项指定使用的扩展
multiport扩展:以离散方式定义多端口匹配,最多指定15个端口
[!] --source-ports,--sports port[,port |,port:port]...:指定多个源端口
[!] --destination-ports,--dports port[,port |,port:port]...:指定多个目标端口
[!] --ports port[,port |,port:port]...:指定特定端口
如:
iptables -I INPUT -s 192.168.1.0/24 -d 192.168.1.250 -p tcp -m multiport --dports 22,80 -j ACCEPT

iprange扩展:指明连续的(但一般是不能扩展为整个网络)ip地址范围时使用
[!] --src-range from[-to]:指明连续的源IP地址范围
[!] --dst-range from[-to]:指明连续的目标IP地址范围
如:
iptables -I INPUT -d 192.168.1.250 -p tcp -m multiport --dports 22:23,80 -m iprange --src-range 192.168.1.1-192.168.1.249 -j ACCEPT

string扩展:检查报文中出现的字符串
--algo {bm|kmp}:指定字符串比对算法
[!] --string pattern
[!] --hex-string pattern
如:
iptables -I OUTPUT -m string --algo bm --string 'movie' -j REJECT表示无论是谁访问的,只要响应报文中包含movie字符串的全部拒绝掉

time扩展:基于时间做检查,根据报文到达的时间与指定的时间范围进行匹配
--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:指定起始日期
--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:指定结束日期
--timestart hh:mm[:ss]:指定起始时间
--timestop hh:mm[:ss]:指定结束时间
[!] --monthdays day[,day...]:指定一个月内具体哪几天
[!] --weekdays day[,day...]:指定一周内具体周几
如:
-m time --weekdays Sa,Su
-m time --datestart 2007-12-24 --datestop 2007-12-27
-m time --datestart 2007-01-01T17:00 --datestop 2007-01-01T23:59:59
-m time --timestart 12:30 --timestop 13:30
-m time --weekdays Fr --monthdays 22,23,24,25,26,27,28

connlimit扩展:连接限制,根据每客户端IP(也可以是地址块(仅centos7支持))做并发连接数数量匹配
[!] --connlimit-above n:连接的数量大于n
[!] --connlimit-upto n:连接的数量小于等于n,centos7上新版的iptables才有此选项
--connlimit-mask prefix_length
如:
iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT
iptables -A INPUT -p tcp --syn --dport 23 -m connlimit ! --connlimit-above 2 -j ACCEPT
iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 16 --connlimit-mask 24 -j REJECT

limit扩展:基于收发报文的速率做检查
--limit rate[/second|/minute|/hour|/day]:指定速率
--limit-burst number:指定峰值

state扩展:状态扩展,根据连接追踪机制检查连接的状态
调整连接追踪功能所能够容纳的最大连接数量:并发量很大的情况下建议把值调大点
/proc/sys/net/nf_conntrack_max

iptables的链接跟踪表最大容量为/proc/sys/net/nf_conntrack_max文件设定的值,链接碰到各种状态的超时后就会从表中删除
所以解决方法一般有两个:
a) 加大ip_conntrack_max值
vim /etc/sysctl.conf
net.ipv4.ip_conntrack_max = 393216
net.ipv4.netfilter.ip_conntrack_max = 393216

b) 降低ip_conntrack timeout时间
vim /etc/sysctl.conf
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait =  60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120
iptables -t nat -L -n

已经追踪到并记录下的连接:
/proc/net/nf_conntrack

不同协议或连接类型追踪的时长:
/proc/sys/net/netfilter/*
可追踪的连接状态:
NEW:新发出的请求,连接追踪模板中不存在此连接相关的信息条目,因此,将其识别为第一次发来的请求
ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前期间内所进行的通信的状态
RELATED:相关的连接,如ftp协议的命令连接与数据连接之间的关系
追踪RELATED状态的专用模块:/lib/modules/KERNEL-VERSION/kernel/net/netfilter/nf_conntrack*.ko
INVALIED:无法识别的连接

--state STATE1,STATE2,...:指明要检查的状态
例:开放被动模式的ftp服务需要以下几步:
a) 装载FTP追踪时的专用模块(nfconntrack_ftp.ko)
modprobe nfcontrack_ftp

b) 放行请求报文
命令连接:NEW,ESTABLISHED
iptables -A INPUT -d LocalIP -p tcp --dport 21 -m state --state NEW,ESTABLISHED  -j ACCEPT
数据连接:RELATED,ESTABLISHED
iptables -I INPUT -d LocalIP -m state --state RELATED,ESTABLISHED -j ACCEPT
c) 放行响应报文
iptables -I OUTPUT -s LocalIP  -m state --state ESTABLISHED -j ACCEPT

目标选项:
-j TARGET:跳转至指定的TARGET
常用的TARGET:
ACCEPT:接受
DROP:丢弃
REJECT:拒绝
RETURN:返回调用链
REDIRECT:端口重定向
LOG:记录日志
MARK:做防火墙标记
DNAT:目标地址转换
iptables -t nat -A PREROUTING -d ExternalIP -p tcp|udp --dport PORT -j DNAT --to-destination InterServerIP[:PORT]
SNAT:源地址转换
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNET -j SNAT --to-source ExternalIP
MASQUERADE:地址伪装
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNET -j MASQUERADE
自定义链:由自定义链上的规则进行匹配检查
保存及重载规则:
保存规则至指定文件:
iptables-save > /PATH/TO/SOMEFILE
从指定文件重载规则:
iptables-restore < /PATH/FROM/SOMEFILE

CentOS6:
service iptables save    #相当于iptables-save > /etc/sysconfig/iptables
service iptables restore    #相当于iptables-restore < /etc/sysconfig/iptables

CentOS7:引入了新的iptables前端管理服务工具:firewalld
firewall-cmd
firewalld-config

7.示例


 

#!/bin/bash
#防火墙过滤脚本(主机型防火墙)
iptables -t filter -P INPUT ACCEPT    // 首先给2个链 的默认策略改成允许 防止远程操作断开
iptables -t filter -P OUTPUT ACCEPT
iptables -F INPUT    //然后清除所有内容
iptables -F OUTPUT
#清除所有内容,上面的可以合成一个命令iptables -F,默认是filter表
iptables -t nat -F    //清空nat表
iptables -I INPUT -p tcp -m multiport --dport 22,25,80,21,110,143 -j ACCEPT  //填写规则
iptables -I INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 8 -j DROP
iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
iptables -t filter -P INPUT DROP    //再把默认策略改成拒绝
iptables -I OUTPUT -p udp --sport 53 -j ACCEPT
iptables -I OUTPUT -p tcp -m multiport --sport 22,25,80,21,110,143 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 3 -j ACCEPT
iptables -t filter -P OUTPUT DROP
#从MAC地址匹配
#根据MAC地址封锁主机
#iptables -A INPUT -m mac --mac-source 00:0c:29:c0:55:3f -j DROP

测试各种服务

首先测试www服务

iptables(17)_认证_06

 我们开放80端口在尝试,执行上面的脚本

[root@hao ~]# sh fang.sh   //运行脚本

iptables(17)_认证_06

Web服务前面搭建好了

例如:禁止从其他主机ping主机,但是允许本机ping其他主机

[root@hao ~]# ping 192.168.129.1

PING 192.168.129.1 (192.168.129.1) 56(84) bytes of data.

64 bytes from 192.168.129.1: icmp_seq=1 ttl=128 time=0.150 ms

64 bytes from 192.168.129.1: icmp_seq=2 ttl=128 time=0.190 ms

64 bytes from 192.168.129.1: icmp_seq=3 ttl=128 time=0.127 ms

64 bytes from 192.168.129.1: icmp_seq=4 ttl=128 time=0.150 ms

64 bytes from 192.168.129.1: icmp_seq=5 ttl=128 time=0.136 ms

64 bytes from 192.168.129.1: icmp_seq=6 ttl=128 time=0.289 ms

64 bytes from 192.168.129.1: icmp_seq=7 ttl=128 time=0.131 ms

64 bytes from 192.168.129.1: icmp_seq=8 ttl=128 time=0.175 ms

但是客户端ping主机就是不通

这时查看下脚本原件

iptables(17)_import_05

 默认就是 filter表

iptables(17)_认证_06

 在来测试 dns服务器

iptables(17)_认证_06

 iptables(17)_import_05

 加入规则表后 就可以了

iptables(17)_import_05

 iptables(17)_import_05

可以正常访问了!主机型防火墙 安全级别最高 因为 INPUT和OUTPUT  默认策略是拒绝所有!这样可以防止防弹木马攻击! 

DNAT(Destination Network Address Translation,目的地址转换) 通常被叫做目的映谢。而SNAT(Source Network Address Translation,源地址转换)通常被叫做源映谢。

SNAT

iptables(17)_认证_06

 内网访问 外网

iptables(17)_import_05

客户端ip地址

网关指向server的eth0 网卡

 iptables(17)_import_05

server的2块网卡ip地址

iptables(17)_import_05

 server0的网卡ip地址

iptables(17)_import_05

 ping测试

iptables(17)_import_05

 不通

iptables(17)_import_05

 做防火墙规则

然后做SNAT策略

Nat表里POSTROUTING链 的网卡eth1 (出) 的源目标地址 192.168.80.0/24 转成 目标ip地址 192.168.90.33

下面一条命令 打开网关路由的转发 一定要打开

iptables(17)_import_05

 一定要清空

Filter表

iptables(17)_import_05

 nat 表

iptables(17)_import_05

 在来测试

DNAT测试

iptables(17)_import_05

 让pc 能访问内网的ssh 22端口

结果如下

iptables(17)_import_05

 iptables(17)_import_05

 防火墙策略

Nat表里 PREROUTING链 的网卡eth0 的源目标地址 192.168.80.33 tcp 协议 的端口22 转成 目标ip地址 192.168.90.44 的22端口

[root@jack ~]# iptables -t nat -A PREROUTING -i eth0 -d 192.168.80.33 -p tcp --dport 22 -j DNAT --to 192.168.90.44:22

iptables(17)_import_05

 iptables(17)_import_05

 一定要给内网服务器 加上默认路由

打开网关路由的转发 一定要打开

iptables(17)_import_05

 


 

其他规则示例:
iptables-restore < 规则文件 # 导入防火墙规则
/etc/init.d/iptables save # 保存防火墙设置
/etc/init.d/iptables restart # 重启防火墙服务
iptables -L -n # 查看规则
iptables -t nat -nL # 查看转发
iptables -L INPUT # 列出某规则链中的所有规则
iptables -X allowed # 删除某个规则链 ,不加规则链,清除所有非内建的
iptables -Z INPUT # 将封包计数器归零
iptables -N allowed # 定义新的规则链
iptables -P INPUT DROP # 定义过滤政策

开启与删除端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允许TCP的22端口访问
# 如果OUTPUT 设置成DROP的,要写上下面一条
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
# 注:不写导致无法SSH.其他的端口一样,OUTPUT设置成DROP的话,也要添加一条链
# 如果开启了web服务器,OUTPUT设置成DROP的话,同样也要添加一条链
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
# 做WEB服务器,开启80端口 ,其他同理
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 做邮件服务器,开启25,110端口
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
# 允许icmp包通过,允许ping
iptables -A OUTPUT -p icmp -j ACCEPT (OUTPUT设置成DROP的话)
iptables -A INPUT -p icmp -j ACCEPT (INPUT设置成DROP的话)
# 允许loopback!(不然会导致DNS无法正常关闭等问题)
IPTABLES -A INPUT -i lo -p all -j ACCEPT (如果是INPUT DROP)
IPTABLES -A OUTPUT -o lo -p all -j ACCEPT(如果是OUTPUT DROP)
iptables -I INPUT -p udp --dport 53 -j ACCEPT # 允许UDP的53端口访问,插入在第一条
iptables -A INPUT -p tcp --dport 22:25 -j ACCEPT # 允许端口范围访问
iptables -D INPUT -p tcp --dport 22:25 -j ACCEPT # 删除这条规则

# 允许多个TCP端口访问
iptables -A INPUT -p tcp -m multiport --dports 22,80,8080 -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT # 允许192.168.1.0段IP访问
iptables -A INPUT -s 192.168.1.10 -j DROP # 对1.10数据包丢弃
iptables -A INPUT -i eth0 -p icmp -j DROP # eth0网卡ICMP数据包丢弃,也就是禁ping

# 允许来自lo接口,如果没有这条规则,将不能通过127.0.0.1访问本地服务
iptables -A INPUT -i lo -j ACCEPT

# 限制并发连接数,超过30个拒绝
iptables -I INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 30 -j REJECT

# 限制每个IP每秒并发连接数最大3个
iptables -I INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT

# iptables服务器作为网关时,内网访问公网
iptables –t nat -A POSTROUTING -s [内网IP或网段] -j SNAT --to [公网IP]

# 访问iptables公网IP端口,转发到内网服务器端口
iptables –t nat -A PREROUTING -d [对外IP] -p tcp --dport [对外端口] -j DNAT --to [内网IP:内网端口]

# 本地80端口转发到本地8080端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

添加网段转发
# 例如通过vpn上网
echo 1 > /proc/sys/net/ipv4/ip_forward # 在内核里打开ip转发功能
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE # 添加网段转发
iptables -t nat -A POSTROUTING -s 10.0.0.0/255.0.0.0 -o eth0 -j SNAT --to 192.168.10.158 # 原IP网段经过哪个网卡IP出去
iptables -t nat -nL # 查看转发

# 允许已建立及该链接相关联的数据包通过
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# ASDL拨号上网
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o pppo -j MASQUERADE
iptables -P INPUT DROP # 设置INPUT链缺省操作丢弃所有数据包,只要不符合规则的数据包都丢弃。注意要在最后设置

#端口映射
# 内网通过有外网IP的机器映射端口
# 内网主机添加路由
route add -net 10.10.20.0 netmask 255.255.255.0 gw 10.10.20.111 # 内网需要添加默认网关,并且网关开启转发
# 网关主机
echo 1 > /proc/sys/net/ipv4/ip_forward # 在内核里打开ip转发功能
iptables -t nat -A PREROUTING -d 外网IP -p tcp --dport 9999 -j DNAT --to 10.10.20.55:22 # 进入
iptables -t nat -A POSTROUTING -s 10.10.20.0/24 -j SNAT --to 外网IP # 转发回去
iptables -t nat -nL # 查看转发
封单个IP的命令:iptables -I INPUT -s 124.115.0.199 -j DROP
封IP段的命令:iptables -I INPUT -s 124.115.0.0/16 -j DROP
封整个段的命令:iptables -I INPUT -s 194.42.0.0/8 -j DROP
封几个段的命令:iptables -I INPUT -s 61.37.80.0/24 -j DROP
只封80端口:iptables -I INPUT -p tcp –dport 80 -s 124.115.0.0/24 -j DROP
解封:iptables -F
清空:iptables -D INPUT 数字

列出 INPUT链 所有的规则:iptables -L INPUT --line-numbers
删除某条规则,其中5代表序号(序号可用上面的命令查看):iptables -D INPUT 5
开放指定的端口:iptables -A INPUT -p tcp --dport 80 -j ACCEPT
禁止指定的端口:iptables -A INPUT -p tcp --dport 80 -j DROP
拒绝所有的端口:iptables -A INPUT -j DROP

centos6的iptables基本配置
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -s 222.186.135.61 -p tcp -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,URG RST -j DROP
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

# 允许某段IP访问任何端口
iptables -A INPUT -s 192.168.0.3/24 -p tcp -j ACCEPT
# 设定预设规则 (拒绝所有的数据包,再允许需要的,如只做WEB服务器.还是推荐三个链都是DROP)
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 注意: 直接设置这三条会掉线

*filter
:INPUT ACCEPT [637:58967]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [5091:1301533]
# 允许的IP或IP段访问 建议多个
-A INPUT -s 127.0.0.1 -p tcp -j ACCEPT
-A INPUT -s 192.168.0.0/255.255.0.0 -p tcp -j ACCEPT
# 开放对外开放端口
-A INPUT -p tcp --dport 80 -j ACCEPT
# 指定某端口针对IP开放
-A INPUT -s 192.168.10.37 -p tcp --dport 22 -j ACCEPT
# 拒绝所有协议(INPUT允许)
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,URG RST -j DROP
# 允许已建立的或相关连的通行
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 拒绝ping
-A INPUT -p tcp -m tcp -j REJECT --reject-with icmp-port-unreachable
COMMIT
# Completed on Fri Feb 9 12:10:37 2007

ptables -A INPUT -s 192.168.1.1 # 比对封包的来源IP # ! 192.168.0.0/24 ! 反向对比
iptables -A INPUT -d 192.168.1.1 # 比对封包的目的地IP
iptables -A INPUT -i eth0 # 比对封包是从哪片网卡进入
iptables -A FORWARD -o eth0 # 比对封包要从哪片网卡送出 eth+表示所有的网卡
iptables -A INPUT -p tcp # -p ! tcp 排除tcp以外的udp、icmp。-p all所有类型
iptables -D INPUT 8 # 从某个规则链中删除一条规则
iptables -D INPUT --dport 80 -j DROP # 从某个规则链中删除一条规则
iptables -R INPUT 8 -s 192.168.0.1 -j DROP # 取代现行规则
iptables -I INPUT 8 --dport 80 -j ACCEPT # 插入一条规则
iptables -A INPUT -i eth0 -j DROP # 其它情况不允许
iptables -A INPUT -p tcp -s IP -j DROP # 禁止指定IP访问
iptables -A INPUT -p tcp -s IP --dport port -j DROP # 禁止指定IP访问端口
iptables -A INPUT -s IP -p tcp --dport port -j ACCEPT # 允许在IP访问指定端口
iptables -A INPUT -p tcp --dport 22 -j DROP # 禁止使用某端口
iptables -A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j DROP # 禁止icmp端口
iptables -A INPUT -i eth0 -p icmp -j DROP # 禁止icmp端口
iptables -t filter -A INPUT -i eth0 -p tcp --syn -j DROP # 阻止所有没有经过你系统授权的TCP连接
iptables -A INPUT -f -m limit --limit 100/s --limit-burst 100 -j ACCEPT # IP包流量限制
iptables -A INPUT -i eth0 -s 192.168.62.1/32 -p icmp -m icmp --icmp-type 8 -j ACCEPT # 除192.168.62.1外,禁止其它人ping我的主机
iptables -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -m recent --update --seconds 5 --hitcount 20 --rttl --name WEB --rsource -j DROP # 可防御cc攻击(未测试)

例1,列规则

   


 

iptables -L --默认看的就是filter表
iptables -L -t filter
iptables -L -t nat
iptables -L -t mangle
iptables -L -t raw

例2,控制ping


 

ICMP协议传输过程是双向的,可以对其INPUT或OUTPUT都可以控制
172.16.0.0/16网段ping本机,会被拒绝(客户端会收到拒绝信息)
# iptables -t filter -A INPUT -p icmp -s 172.16.0.0/16 -j REJECT
# iptables -t filter -D INPUT -p icmp -s 172.16.0.0/16 -j REJECT --删除上一条规则
# iptables -t filter -A INPUT -p icmp -s 172.16.0.0/16 -j DROP
# iptables -t filter -D INPUT -p icmp -s 172.16.0.0/16 -j DROP
# iptables -t filter -A OUTPUT -p icmp -d 172.16.0.0/16 -j REJECT
# iptables -t filter -D OUTPUT -p icmp -d 172.16.0.0/16 -j REJECT
# iptables -t filter -A OUTPUT -p icmp -d 172.16.0.0/16 -j DROP
# iptables -t filter -D OUTPUT -p icmp -d 172.16.0.0/16 -j DROP
--上面四种方法都可以控制拒绝172.16.0.0/16网段ping本机
# iptables -t filter -A INPUT -p icmp -j REJECT --如果不写-s或-d,默认代表所有人
扩展
我想实现所有人都ping不通我,但是172.16.X.X(X你自定义)这个IP能ping通我
--提示:iptables的匹配规则:读取的顺序是从上往下一条一条匹配,匹配一条就不继续往下匹配,都没有匹配,则最后匹配默认策略
# iptables -t filter -A INPUT -p icmp -j REJECT
# iptables -t filter -A INPUT -p icmp -s 172.16.X.X -j ACCEPT
--此写法错误的
# iptables -t filter -A INPUT -p icmp -j REJECT
# iptables -t filter -I INPUT -p icmp -s 172.16.X.X -j ACCEPT
--正确写法,把第二条加到第一条前面
# iptables -t filter -I INPUT 2 -p icmp -s 172.16.X.X -j ACCEPT
--链后面接数字2,表示插入到原来第二条的上面,成为新的第2条
删除的方法:
方法一:
# iptables -t filter -D INPUT -s 10.1.1.9 -p icmp -j ACCEPT
--加的时候怎么写,删除时就要怎么写 A 参数换成 D就可以
方法二;
# iptables -L -n --line
# iptables -D INPUT 2
--在规则比较多或者不好写规则的情况下,可以先用--line或者--line-number列出行号,再用行号删除
方法三:
# iptables -F
--直接清空filter表的所有规则
iptables -X
iptables -Z --清除计数器,自定义链

例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手工还原了。
扩展,如何完全关闭rhel6的iptables服务
因为rhel6在安全性有很多加强,就算是你把iptables服务关闭,并chkconfig iptables off,重启还是有可能会有规则
所以可以用下面的方法
# iptables -F
# iptables -F -t nat
# iptables -F -t mangle
# /etc/init.d/iptables save --保存为空规则
# chkconfig iptables on
或者用下面的方法
# echo > /etc/sysconfig/iptables
# /etc/init.d/iptables restart
# chkconfig iptables on

例4,每个链的默认策略的修改


 

# iptables -P INPUT DROP --INPUT键默认策略改为DROP,改回来把DROP换成ACCEPT就行了
# iptables -P OUTPUT DROP --OUTPUT键默认策略改为DROP

例5,实现允许ssh过来(代表本机为服务器身份),ssh出去(代表本机为客户端身份),别的任何访问都拒绝  (要求,INPUT和OUTPUT双链默认策略都为DROP)

         


 

OUTPUT INPUT
客户端 随机端口 ---》 服务器 22
客户端 随机端口 《--- 服务器 22
INPUT OUTPUT
实现允许10.1.1.0/24网段来ssh本机(服务器),其它任何访问都拒绝(在双链拒绝的情况下)
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
# iptables -A INPUT -p tcp --dport 22 -s 10.1.1.0/24 -j ACCEPT
# iptables -A OUTPUT -p tcp --sport 22 -d 10.1.1.0/24 -j ACCEPT
实现允许从本机(客户端)ssh到10.1.1.0/24网段的服务器,其它任何访问都拒绝(在双链拒绝的情况下)
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
# iptables -A OUTPUT -p tcp --dport 22 -d 10.1.1.0/24 -j ACCEPT
# iptables -A INPUT -p tcp --sport 22 -s 10.1.1.0/24 -j ACCEPT

例6,在例五的基础上允许ping自己的IP,本地回环127.0.0.1和10.1.1.8


 

下面两条定义能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.8 -j ACCEPT
# iptables -A OUTPUT -p icmp -d 10.1.1.8 -j ACCEPT

例7,

在上面的基础上再加上只允许10.1.1.0/24这个网段访问你的httpd服务,和你只能访问10.1.1.0/24网段的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 25,110 -j ACCEPT
硬件地址
iptables -A INPUT -m mac --mac-source 00:23:CD:95:DA:0B -p all --dport 80 -j ACCEPT

例9 邮件服务器


 

25 smtp 110 pop3 143 imap
客户端 邮件服务器
随机 -------》 25,110,143
随机 《------ 25,110,143
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
# iptables -A INPUT -p tcp -m multiport --dport 25,110,143 -s 10.1.1.0/24 -j ACCEPT
# iptables -A OUTPUT -p tcp -m multiport --sport 25,110,143 -d 10.1.1.0/24 -j ACCEPT

例10    dhcp

   iptables 对dhcp端口控制无效

应用层

表示层

会话层

传输层

网络层

数据链路层

物理层


例11

samba

139   445


例12

nfs


 

--因为nfs用到rpc调用,端口不固定,所以需要把端口给固定起来.nis服务也会用到rpc调用,也需要做端口绑定
vim /etc/sysconfig/nfs --在此文件里加上下面四句
LOCKD_TCPPORT=3000
LOCKD_UDPPORT=3000
MOUNTD_PORT=3001
STATD_PORT=3002
/etc/init.d/nfs restart
/etc/init.d/rpcbind restart --这里先把默认策略改成ACCEPT,再启动就可以启动起来,然后再把默认策略改回成DROP,再继续做下面的实验
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(rpcbind)的端口的规则
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合起来来做


 

[root@localhost ~]# iptables -A INPUT -p all -m multiport --dport 111,2049,3000,3001,3002 -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -p all -m multiport --sport 111,2049,3000,3001,3002 -j ACCEPT

练习:上面四条做的是为NFS服务器的身份允许别人访问

如果你做为NFS客户端去访问别人的NFS服务器,又应该如何写?


例13: yum

视你做的yum类型而定

file

ftp

http


例14

mysql

3306


例15

oracle 监听

1521


例16

rsync

873

还加一个22


练习:

ftp实现双链拒绝的情况下,客户端通过主动和被动都能访问进来

服务器端准备:


 

# yum install vsftpd -y
# vim /etc/vsftpd/vsftpd.conf
pasv_min_port=3000
pasv_max_port=3005
# /etc/init.d/vsftpd restart
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP

客户端测试方法:

1,命令连接测试,能成功连接上就表示命令端口连接没问题

# ftp 10.1.1.9

2,数据传输测试,用上面的命令登录成功后,在客户端使用passive指令转换你的主动和被动模式,

(服务器端不用转换,因为服务器端默认就是主动和被动都支持的)

然后使用ls指令能看到里面的pub子目录就表示数据传输OK了(因为默认是登录到服务器的/var/ftp/目录,里面有一个pub子目录)

ftp有主动和被动的连接两种

1,为什么有主动和被动两种连接方式呢?

因为这是一种比较古老的设计方式,它是假设客户端用户有防火墙并且还不会配置防火墙的情况下,才设计出两种模式。

防火墙默认只会拒绝进来的包,而不会拒绝出去或出去回来的包。

2,一般用主动好还是被动好?

用被动比较常见,(原因参考问题一)

3,主动和被动在使用时的区别?

没有防火墙,那么使用起来没什么区别,只是底层传输包的方式不一样

有防火墙,那么防火墙的规则写法也不一样

主动:


 

server client
20 21 n m
<-------------
-------------->
---------------------------------------->
<---------------------------------------
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 21 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 20 -j ACCEPT
iptables -A INPUT -p tcp --dport 20 -j ACCEPT
被动:
server client
随机端口 21 n m
3000-3005 <---------------
---------------->
<--------------------------------------------
--------------------------------------------->
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 3000:3005 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 3000:3005 -j ACCEPT
iptables——路由
什么是路由,什么是路由表?
路由就是跨网络访问(路径选择)
路由表是记录路由信息的表(可以单路由表,也可以多路由表)
我们现在讨论的是单路由表,你在linux下用route -n查看
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 vmnet8
1.1.1.0 0.0.0.0 255.255.255.0 U 0 0 0 vmnet1
172.16.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 172.16.1.1 0.0.0.0 UG 0 0 0 eth0


问题1:按上面的路由表来看,如果我ping一个公网IP(如ping 14.215.177.38),应该怎么走?

答案:

我在本机访问一个IP,先找路由表里是否有你访问的网段,有的话则从这个路由条目后面指定的网卡出去;如果路由表里没有你访问的网段,则会找默认路由(也就是网关);如果网关也没有的话,则会报错网络不可达。

问题2:按上面的路由表来看,如果我ping一个公网IP(如ping 1.1.1.1),会怎么走?

答案:

按上面问题的答案来讲,我ping 1.1.1.1应该不会走网关,而是走本地路由从vmnet1网卡出去(因为路由表里有1.1.1.0/24的路由)。但是1.1.1.1实际应该是一个真正的公网IP.这样其实会影响你访问公网的1.1.1.0/24.所以一般来说,不要在内网网卡上配置公网IP,我这里配置1.1.1.1只是为了方便而已(另一个目的就是为了说明这个问题)

问题3:如何加网关和删除网关,加网关有什么要求?

route add default gw  x.x.x.x    --临时加网关,马上生效

route del default gw  x.x.x.x     --临时删网关,马上生效

永久加网关的方法

在网卡配置文件里/etc/sysconfig/network-scripts/ifcfg-eth0

加一句GATEWAY=x.x.x.x

加网关只能加你已经有的路由网段里的一个IP才行(此IP不一定存在)

问题4:一个linux上能有几个有效网关?

准确来说:一个路由表上可以加多个网关,但只有一个生效。但一台linux是可以做多路由表的,一个路由表一个有效网关,多路由表就是多个网关了。

问题5:我一台linux上如果有双物理网卡,请问可不可以两个网卡配置同网段的不同IP呢?

假设我的eth0 10.1.1.11/24

      eth1 10.1.1.11/24

如果两个网卡同网段,则会有下面两条路由

10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 eth0

10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 eth1

它会实现从两张网卡进来的包,却从一张网卡出去,问题就产生了。

也有解决方法(比如多路由表)

静态路由

如下图的实验:

用真实机虚拟的hostonly网络vmnet1模拟IP为1.1.1.1,三台虚拟机都是双网卡(全连接hostonly的vmnet1网络),IP分配如下(掩码假设全为24位),做实验的话使用iptables -F把所有的防火墙规则清空

宿主机          VM1         VM2        VM3

        eth1     -->     eth0        eth1

               2.2.2.2  《--     2.2.2.3    4.4.4.4

       ip_forward    ip_forward

vmnet1         eth0          eth1            eth0

1.1.1.1    --》   1.1.1.2         3.3.3.3 《--     3.3.3.4

从1.1.1.1 ping 1.1.1.2

在宿主机上ping 1.1.1.2,能通

从1.1.1.1 ping 2.2.2.2

ping 2.2.2.2 不能通

解决方法:

1,在宿主机上加路由

route add -net 2.2.2.0 netmask 255.255.255.0 dev vmnet1

或者

route add -net 2.2.2.0/24 dev vmnet1

2,加网关

route del -net 2.2.2.0 netmask 255.255.255.0 dev vmnet1  --先删除上面的路由

route add default gw 1.1.1.2

在宿主机加了一个网关指向1.1.1.2的基础上,我再继续在宿主机上ping 2.2.2.3 不能ping

解决方法:

在vm2上加网关指向2.2.2.2

route add default gw 2.2.2.2

还要在VM1上打开ip_forward,打开方法有两种

1,# echo 1 > /proc/sys/net/ipv4/ip_forward    --马上生效,但重启后就不生效了

2,# vim /etc/sysctl.conf  

net.ipv4.ip_forward = 1        --改为1

# sysctl -p            --保存后,使用此命令让它永久生效

继续ping 3.3.3.3    不通

解决:再在VM1上route add default gw 2.2.2.3

继续ping 3.3.3.4    不通

解决:在VM2上打开ip_forward

还要在VM3上route add default gw 3.3.3.3

继续ping 4.4.4.4  不通

解决:如果在VM2上加一个网关指向3.3.3.4,其实是有问题的,因为VM2上这样就有两个网关了。如果你不使用多路由表的做法,这两个网关只能有一个网关有效。

所以加网关的方式不可行,只能在VM2加路由

route add -net 4.4.4.0 netmask 255.255.255.0 dev eth1

上面终于从1.1.1.1ping到4.4.4.4

如果我把上面的所有网关和ip_forward去掉,然后手动加上路由(也就是说四台机都有四个网段的路由),你会发现也一样从1.1.1.1能ping通4.4.4.4

那么如果还有5网段,6网段,7网段,甚至更多(类似因特网),手动把全世界所有的路由加上也是不可能的事。实际的做法就是使用路由协议(rip,ospf,bgp等)来做,这就是动态路由了。

linux下可以安装类似zebra这样的软路由软件,可以把linux模拟成一台cisco路由器来进行配置。

注意:上面所有网卡都在同网络,你可以换一种方式再去尝试:1网段用vmnet1来模拟,2网段用vmnet2来模拟,3网段用vmnet3来模拟,4网段用vmnet4来模拟

=======================================================================

补充一点虚拟机的网段知识:

问题1:vmware虚拟机的bridge,host-only,NAT这三种网络有什么区别?

bridge:与宿主机的物理网卡在同一个交换机

host-only:私有网络.与宿主机的物理网卡不在同一个交换机,而是虚拟出独立的一个交换机。两个虚拟机的网卡连在同一个host-only(如vmnet1),那么这两个网卡就相当在同一个虚拟交换机。

NAT:私有网络。可以把它看作是做了NAT的host-only.

       10.1.1.9        10.1.1.11

       eth0         桥接    eth0  

       宿主机            宿主机

       vmnet1            vmnet1

       1.1.1.1            2.2.2.1

1.1.1.128                        2.2.2.128

问题2:vmware虚拟机可以有几个bridge网络,几个host-only网络,几个NAT网络?

有几个bridge网络是与宿主机有几张物理网卡有关。

host-only和NAT网络可以虚拟无数个。

使用vmware-netcfg去图形配置

问题3:如果我的电脑是windows,安装了windows版本的vmware虚拟机,虚拟机里安装的是linux系统。请问怎么让linux虚拟机在有路由器和无路由器需要拔号上网这两种情况下能实现上外网?

               网络

                |              

               modem  (俗称"猫")

                |

               路由器( dhcp + snat)

                |

           |-----------|

              交换机1         交换机2

               |  

       |--------------|

         电脑1         电脑2

=====================================================================

准备两台虚拟机和真实机一起三台机做实验

--下面图中10.1.1.0/24网段为外网,1.1.1.0/24网段为内网(虽然实际环境里10.1.1.0/24网段是内网保留网段,1.1.1.0/24网段是公网网段,但我这里只是内网模拟实验为了方便而已,你自己也可以定义自己的网段都行)

 内网(VM1)        iptables网关(宿主机)            外网(VM2)

1.1.1.128  ---》       1.1.1.1  vmnet1  

eth0        

             ip_forward              

                10.1.1.9 eth0  《----      10.1.1.11

--注意:模拟上面的环境时,宿主机可以模拟中间的双网卡网关,但不能模拟内网或外网其中一台(原因是宿主机本来就是与虚拟的所有网段是直通的,你如果把它做为内网,则它会直接连接外网而不会走中间的网关)

--所以两种模拟方法:1,宿主机模拟网关,两台虚拟机分别模拟内外网;2,不要宿主机,三台虚拟机来模拟,中间的双网卡网关使用一台双网关的虚拟机模拟,另两台用单两卡来模拟

把gateway加上路由功能

# echo "1" > /proc/sys/net/ipv4/ip_forward   --临时生效

# vim /etc/sysctl.conf

net.ipv4.ip_forward = 1

# sysctl -p    --改完后使用此命令,使之修改永久生效

路由功能加了后,网关都指向了gateway这台物理机,那么  两个网段的这两台机就能互相ping通

例一:禁止内网1.1.1.128和外网10.1.1.11互ping

iptables -A FORWARD -p icmp -s 1.1.1.128 -j DROP

或者

iptables -A FORWARD -p icmp -s 10.1.1.11 -j DROP

例二:禁止内网1.1.1.128上外网的10.1.1.11这个网站

iptables -A FORWARD -p tcp --dport 80 -s 1.1.1.128 -d 10.1.1.11 -j DROP

--这样的做法,如果要做网络管理(控制内部员工上网的行为,用iptables来做就比较繁锁,可以选用squid这种代理网关)

======================================================================

问题:这里我们模拟内外网的访问,网关互指,中间网关打开ip_forward,但实际的网络访问环境中,外网客户会把网关指向你公司的网关吗?

 内网              iptables网关               外网

1.1.1.128     ---->  1.1.1.1  vmnet1  

          网关指向  

             打开ip_forward          

                10.1.1.9 eth0               10.1.1.11

把上图先去掉外网上的网关(因为实际情况下,别人公司的外网服务器不可能把网关指向你),去掉这个网关后,内外网就不能通了,要靠做NAT才能通

张三        李四            王五

发信人:张三    发信人:李四        发信人:王五  

收信人:王五 --->    收信人:王五  -----------> 收信人:李四

                         |

       发信人:王五           |

    <-----    收信人:张三  <---------------|  

SIP:1.1.1.128     DIP:10.1.1.11

到达中间iptables网关,需要做SNAT

SIP:10.1.1.9    DIP:10.1.1.11

到达外网服务器,然后返回

SIP:10.1.1.11    DIP:10.1.1.9

回到中间iptables网关,会自动做DNAT

SIP:10.1.1.11    DIP:1.1.1.128

解决方法:在中间网关机器上写规则

实现内网可以上外网的web

iptables -t nat -A POSTROUTING -p tcp --dport 80 -o eth0 -j SNAT --to-source 10.1.1.9

实现内网可以ping外网

iptables -t nat -A POSTROUTING -p icmp -o eth0 -j SNAT --to-source 10.1.1.9

下面这条不写协议,也就表示所有内网上外网的都会做SNAT成10.1.1.9这个IP地址

iptables -t nat -A POSTROUTING  -o eth0 -j SNAT --to-source 10.1.1.9

iptables -t nat -A POSTROUTING  -o eth0 -j MASQUERADE    --这条命令和上条命令实现的效果是一样的,但区别在于MASQUERADE可以动态SNAT成你的公网IP(用于公网IP不固定的情况,比如家用的ADSL拔号上网)

做了SNAT后,并且可以10.1.1.11的/var/log/httpd/access_log里验证得到:在你做NAT之前,靠双网关互指访问网站,它的访问日志里全是你内网的IP。而做了NAT之后,日志里是你公网的IP。

===========================================================

题目1:

现在我的172.16.2.9(网段为172.16.0.0/16)是通过公司路由器172.16.1.1可以实际上外网的

请问,我一个hostonly网段的虚拟机1.1.1.128(这里1.1.1.0/24网络模拟的是内网)如何才能通过NAT上外网

虚拟机上DNS和网关要不要指,怎么指?

hostonly虚拟机          宿主机                  公司路由器   公司外网IP

          vmnet1      eth0              

1.1.1.128 ---》  1.1.1.1   172.16.2.9 --> 172.16.1.1  121.15.27.169

DNS指向8.8.8.8

在虚拟机上把网关指向1.1.1.1,把DNS指向8.8.8.8;那么包的过程如下

DNS包

SIP:1.1.1.128    DIP:8.8.8.8

到达真实机

SIP:1.1.1.128    DIP:8.8.8.8

到达路由器SNAT

SIP:121.15.27.169    DIP:8.8.8.8

到达DNS服务器返回

SIP:8.8.8.8    SIP:121.15.27.169

返回路由器自动DNAT

SIP:8.8.8.8    DIP:1.1.1.128

--通过分析得到DNS数据包从路由器无法回到虚拟机(他这里是回到1.1.1.128,如果这是一个公网IP,则回到公网去了;就算是你是一个内网IP,他也无法回到你的内网)

解决方法:

在中间的真实机上做    SNAT  --to-source 172.16.2.8

并且打开ip_forward

做完之后,数据包过程如下

DNS包

SIP:1.1.1.128    DIP:8.8.8.8

到达真实机

SIP:172.16.2.9    DIP:8.8.8.8

到达路由器SNAT

SIP:121.15.27.169    DIP:8.8.8.8

到达DNS服务器返回

SIP:8.8.8.8    SIP:121.15.27.169

返回路由器自动DNAT

SIP:8.8.8.8    DIP:172.16.2.9

返回到真实机自动DNAT

SIP:8.8.8.8    DIP:1.1.1.128

总结:

满足四个条件,这个hostonly虚拟机就可以上外网

1,虚拟机网关指向宿主机的同网段IP(我这个例子里是指向1.1.1.1)

2,DNS指向公网DNS服务器(我这里是指向8.8.8.8);这里DNS也可以指向1.1.1.1,但是要在宿主机上多做一条DNAT,把udp的53端口目标地址DNAT成8.8.8.8

3,宿主机打开ip_forward(因为写NAT规则都需要这个要求)

4,宿主机上写一条SNAT把虚拟机上网的所有数据包SNAT成宿主机上外网的IP(我这里为172.16.2.9)

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.16.2.9

或者

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

===================================================================

DNAT  目的地址转换

   也就是外网是客户端,要访问我们内网的服务器,客户端只是访问外网IP,内网里不同的服务器不同的IP,可以使用DNAT把不同的请求转换到不同的内网服务器

           客户端  elinks www.abc.com

            |  

       外网IP     |

           网关 (打开ip_forward)

       内网IP     |

                |

            |

         邮件           web          DNS

   1.1.1.127    1.1.1.128    1.1.1.129

iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dport 25,110 -j DNAT --to-destination 1.1.1.127

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 1.1.1.128

iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to-destination 1.1.1.129

============================================================

NPT 网络端口转换

           客户端    10.1.1.10

            |

                  |

           web    10.1.1.9

默认情况web是监听80端口,如果我把web改成监听8080.那么客户端在elinks 10.1.1.9时就访问不到,除非elinks 10.1.1.9:8080

在web服务器上写上一条端口转换的iptables规则,把访问80的转成8080.然后客户端再去elinks 10.1.1.9不用写端口也可以访问成功

# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

=======================================================================

题目2:

要求:写出这个电信用户访问到双线web服务器时并返回的IP变化过程(只写源IP,目标IP,和做SNAT还是DNAT等)

你觉得架构会不会有问题?

192.168.1.100                       192.168.2.100

       电信用户        网通用户

         |           |  

192.168.1.1      |          |            192.168.2.1

       电信用户家里路由器  网通用户家里路由器    

51.1.2.3      |         |        61.1.2.3

         |www.abc.com     |                

         |            |

71.1.2.3          |          |        81.1.2.3

        公司电信路由器   公司网通路由器

10.1.1.1      |              |        172.16.2.1

         |         |

         |         |

10.1.1.100     eth0 双线web服务器 eth1        172.16.2.100

这里应该有智能DNS(DNS服务器会通过SIP是电信还是网通,来智能的解析同一个网站的DIP;在此例中,电信用户会被解析访问71.1.2.3,网通用户会被解析访问81.1.2.3)

SIP:192.168.1.100    DIP:71.1.2.3

--

基于状态的iptables

如果按照tcp/ip来划分连接状态,有11种之多(课后可以自己去读一下相关知识)

但iptables里只有4种状态;ESTABLISHED、NEW、RELATED及INVALID

这两个分类是两个不相干的定义。例如在TCP/IP标准描述下UDP及ICMP数据包是没有连接状态的,但在state模块的描述下,任何数据包都有连接状态。

   1、ESTABLISHED

   (1)与TCP数据包的关系:首先在防火墙主机上执行SSH Client,并且对网络上的SSH服务器提出服务请求,而这时送出的第一个数据包就是服务请求的数据包,如果这个数据包能够成功的穿越防火墙,那么接下来SSH Server与SSH Client之间的所有SSH数据包的状态都会是ESTABLISHED。

   (2)与UDP数据包的关系:假设我们在防火墙主机上用firefox应用程序来浏览网页(通过域名方式),而浏览网页的动作需要DNS服务器的帮助才能完成,因此firefox会送出一个UDP数据包给DNS Server,以请求名称解析服务,如果这个数据包能够成功的穿越防火墙,那么接下来DNS Server与firefox之间的所有数据包的状态都会是ESTABLISHED。

   (3)与ICMP数据包的关系:假设我们在防火墙主机ping指令来检测网络上的其他主机时,ping指令所送出的第一个ICMP数据包如果能够成功的穿越防火墙,那么接下来刚才ping的那个主机与防火墙主机之间的所有ICMP数据包的状态都会是ESTABLISHED。

   由以上的解释可知,只要第一个数据包能够成功的穿越防火墙,那么之后的所有数据包(包含反向的所有数据包)状态都会是ESTABLISHED。

   2、NEW

   首先我们知道,NEW与协议无关,其所指的是每一条连接中的第一个数据包,假如我们使用SSH client连接SSH server时,这条连接中的第一个数据包的状态就是NEW。

   3、RELATED

   RELATED状态的数据包是指被动产生的数据包。而且这个连接是不属于现在任何连接的。RELATED状态的数据包与协议无关,只要回应回来的数据包是因为本机送出一个数据包导致另一个连接的产生,而这一条新连接上的所有数据包都是属于RELATED状态的数据包。

   4、INVALID

   INVALID状态是指状态不明的数据包,也就是不属于以上三种状态的封包。凡是属于INVALID状态的数据包都视为恶意的数据包,因此所有INVALID状态的数据包都应丢弃掉,匹配INVALID状态的数据包的方法如下:

   iptables -A INPUT -p all -m state INVALID -j DROP

   我们应将INVALID状态的数据包放在第一条。

           随机        |     80

           --------- |---》      

       client            |       server      

           《------------- | -----

           随机        |     80  

client访问server过去

第一个数据包(new状态),如果拒绝,那么后续包都会被拒绝(因为后面来的都会是第一个,都为new状态)

第一个数据包如果允许过去,那么后续包的状态为established

server返回给client

返回的所有包都为established

例1:

有下面两台机

10.1.1.9        10.1.1.10

10.1.1.9是可以ssh访问10.1.1.10,也可以elinks访问10.1.1.10

1,在10.1.1.10上

iptables -P INPUT DROP

iptables -P OUTPUT DROP

这里就把双链都关掉,10.1.1.9任何访问都过不来了

2,

按以前的做法

在10.1.1.10上允许别人ssh进来

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

在10.1.1.10上允许别人elinks进来

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT

或者把上面四条合下面两条

iptables -A INPUT -p tcp -m multiport  --dport 22,80 -j ACCEPT

iptables -A OUTPUT -p tcp -m multiport  --sport 22,80 -j ACCEPT

把上面的两条再换成

iptables -A INPUT -p tcp -m multiport  --dport 22,80 -j ACCEPT

iptables -A OUTPUT -p tcp -m state --state established -j ACCEPT

(后面一句可以翻译成tcp协议的连接只要你进得来,你就回得去)

(无论他是用哪个随机端口访问进来的;因为只要能进来,那么后续的包都属于ESTABLISHED状态了)

例2:

--有些服务器,可能希望你ping不通他,但是他可以ping通你

一种:

修改proc的内核参数,禁ping

二种:使用状态iptables

有下面两台机

10.1.1.9        10.1.1.10

实现10.1.1.10这个IP能ping通所有人.但所有人不能ping通10.1.1.10

                   |

           ---------》|

       client            |  server      

         10.1.1.9            |  10.1.1.10

               <-------|  <--------            

                new    established

           INPUT    拒绝    允许

           OUTPUT   允许    允许

1,在10.1.1.10上

iptables -P INPUT DROP

iptables -P OUTPUT DROP

这里就把双链都关掉,10.1.1.9任何访问都过不来了

2,在10.1.1.10上

iptables -A INPUT -p icmp -m state --state ESTABLISHED -j ACCEPT

iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED -j ACCEPT

--重点是INPUT那条不能允许NEW状态的;

--注意第二步的第二条(也就是output这条),如果只写了NEW状态,那么10.1.1.10ping所有人,都只能通第一个包;加上ESTABLISHED状态,所有包都能通

例3:

1,在双链默认策略为drop的情况下,只有10.1.1.x(IP你自己自定义)可以ssh访问我

2, 在上面的基础上加上需求:实现我想访问别人的服务(任何服务),都可以成功;

3,继续加需求:但别人想访问我的服务,只允许可以访问我的80端口

4,继续加需求:允许我ping任何人,但只允许10.1.1.x(IP你自己自定义)这一个IP能ping通我

iptables -P INPUT DROP

iptables -P OUTPUT DROP

iptables -A INPUT -p tcp --dport 22 -s  10.1.1.x -j ACCEPT

iptables -A OUTPUT -m state new,established,related -j ACCEPT

iptables -A INPUT -m state established,related -j ACCEPT

iptables -A INPUT -p tcp --dport 80  -j ACCEPT

iptables -A INPUT -p icmp -s 10.1.1.x -j ACCEPT

========================================================================

tcpdump          

   tcpdump - dump traffic on a network

   参数的分类:

   协议 tcp udp arp icmp

   数据内容 端口,Ip  :

       src port 80    --源

       dst port 22    --目标

   tcpdump tcp dst port 80 -n

   tcpdump -i eth1 tcp dst port 80 -n   --小写i参数指定哪个网卡

   tcpdump tcp dst port 80 -n -w tcpdump.txt  --把dump出来的信息保存到tcpdump.txt文件

   tcpdump -r tcpdump.txt --然后需要使用tcpdump -r去读取

   关系参数 :  !   and   or

   tcpdump tcp dst port 80 -n and src 10.2.2.4

   tcpdump tcp dst port 80 -n and ! src 10.2.2.4

   tcpdump tcp dst port 80 -n and  host  10.2.2.4

   -vv <---把数据包的详细内容都记录下来

   -w <---把数据保存到某个文件

======================================================================

   练习:

捕捉所有访问本机ftp服务器的连接,并且数据包是来自10.2.2.4

tcpdump tcp dst port 21 and src 10.2.2.4 -n

捕捉所有来自10.2.2.1的arp协议的数据包,并且捕捉的显示要求输出以太网数据帧的信息 -e  

tcpdump arp and src 10.2.2.1 -n -e

捕捉所有本机web服务回应10.2.2.4的数据包

tcpdump tcp src port 80 and dst 10.2.2.4

图形的抓包工具:wireshark

yum install wireshark*

============================================================

linux 高级路由  策略路由

lartc(linux advanced routing and traffic control)

http://www.lartc.org

# rpm -qa |grep iproute        --iproute2工具包软件

iproute-2.6.32-31.el6.x86_64

ip命令就属于iproute2软件包

ip addr

ip neigh

ip rule

ip route

ip tunnel

=============================================================

# ip rule list

0:    from all lookup local

32766:    from all lookup main

32767:    from all lookup default

# cat /etc/iproute2/rt_tables  

--上面的local对应数字255,在rhel5.7里ip rule list看到的不是local,而是255;这只是对应的两种名称而已

#

# reserved values

#

255    local

254    main

253    default

0    unspec

#

# local

#

#1    inr.ruhep

# ip route list/show table local/255

# ip route list/show table main/254

# ip route list/show table default/253

=====================================================================

基本家用网络拓扑图

               线

                   |

                  modem

               |

               |

                  路由器 (帮你拔号,dhcp,nat,安全,上网控制)

               |

           |---------|

           交换机        交换机

             |  

       |------|

          电脑1      电脑2

==============================================================

应用实例1:                  

               ----------》路由器1--》 猫1  (快网络)

               |  

               |  

     内网用户  ----linux路由

               |  

               |          

                ---------》路由器2 --》 猫2  (慢网络)

linux路由器有两条上网线路,一个快,一个慢

有这样的需求:内网用户需要给钱共享上网,有人给钱多,需要快线路,有人给钱少,需要快线路,这样的话,我们就可以使用策略路由了

模拟的话使用下面的图:

                       10.1.1.10

               ----------》VM2(bridge)

               |  

   1.1.1.128        |        10.1.1.9  eth0  

     VM1(hostonly1)----linux路由1.1.1.1   vmnet1        公网

               |        2.2.2.1   vmnet2  

               |

                ---------》VM3 (hostonly2)  

                       2.2.2.128

上图架构中:

1.把VM1网关指向1.1.1.1

2,把linux路由器的网关指向10.1.1.10

3.linux路由打开ip_forward

先测试:在VM1上ping一个外网IP(如 ping 8.8.8.8),这个时候只能在VM2上抓到相关的包,表示数据包从VM2出去

下面就是在linux路由上进行操作来实现:

操作命令:

echo 200 t1 >> /etc/iproute2/rt_tables

ip rule add from 1.1.1.128  table t1

ip route add default via 2.2.2.128 dev vmnet2 table t1

ip route flush cache

--如果加错了规则,想删掉,就使用ip rule del table t1删除规则,再ip route del table t1删除t1路由表

操作完后,测试

1,在内网ping 8.8.8.8

2,在两个模拟外网路由器的机器上抓包

# tcpdump -i eth0 -p icmp

3,结果这次只能在VM3上抓到包,OK

应用实例2:

                       10.1.1.10    线路一

               ----------》VM2(bridge)

               |  

   1.1.1.128        |        10.1.1.9  eth0  

     VM1(hostonly)----linux路由1.1.1.1   vmnet1        公网

               |        2.2.2.1   vmnet2  

               |

                ---------》VM3 (hostonly2)  

                       2.2.2.128    线路二

要实现不同类型的包走不同的线路:如80的访问走一条线,其它的走另外一条线路

实现不同类型的包的策略路由,就要借助于iptables的mangle表的set mark功能

1,在linux路由器上使用策略路由实现

# iptables -t mangle -A PREROUTING -i vmnet1 -p tcp --dport 80 -j MARK --set-mark 1        --把从内网进来要出去的80的包打标记为1

# echo 100 http.out >> /etc/iproute2/rt_tables    --建一张叫http.out的表,表编号100

# ip rule add fwmark 1 table http.out pref 20000  --指定打了标记为1的所有包都走http.out这张路由表,并指定优先级为20000(这里优先级可以不指,因为只有这一条策略)

# ip route add default via 2.2.2.128 dev vmnet2 table http.out  --指定http.out表从vmnet8出去找2.2.2.128

# ip route flush cache        --刷新路由缓存

2,测试

测试一:在内网1.1.1.128客户端上

elinks 8.8.8.8

在模拟两个线路的机器上都执行下面的命令

tcpdump -i eth0 tcp port 80

--只有线路二上能抓到包,OK

测试二:在内网1.1.1.128客户端上

ping 8.8.8.8

在模拟两个线路的机器上都执行下面的命令

tcpdump -i eth0 -p icmp

--只有线路一上能抓到包,OK

--从上面就可以看到出去的80端口的包和其它的包走的路线不一致

==========================================================

问题:

要求:写出这个电信用户访问到双线web服务器时的IP变化过程(只写源IP,目标IP,和做SNAT还是DNAT等)

你觉得有没有问题?

192.168.1.100                       192.168.2.100

       电信用户        网通用户

         |           |  

192.168.1.1      |          |            192.168.2.1

       电信用户家里路由器  网通用户家里路由器    

51.1.2.3      |         |        61.1.2.3

         |         |                

         |           |

71.1.2.3          |          |        81.1.2.3

        公司电信路由器   公司网通路由器

10.1.1.1      |              |        172.16.2.1

         |         |

         |         |

10.1.1.100     eth0 双线web服务器 eth1        172.16.2.100

电信用户和网通用户通过智能DNS分别去访问电信或网通线路

SIP:192.168.1.100    DIP:71.1.2.3

到达电信用户家用路由器手动SNAT

SIP:51.1.2.3        DIP:71.1.2.3

到达公司电信路由器手动DNAT

SIP:51.1.2.3        DIP:10.1.1.100

到达web服务器返回(网关指向10.1.1.1)

SIP:10.1.1.100        DIP:51.1.2.3

返回到公司电信路由器自动SNAT

SIP:71.1.2.3        DIP: 51.1.2.3

到达电信用户家用路由器自动DNAT

SIP:71.1.2.3        DIP:192.168.1.100

问题是:

电信的用户回去时,把双线web服务器网关要指向10.1.1.1

网通的用户回去时,把双线web服务器网关要指向172.16.2.1

那么按前面所学的知识,同一个路由表只能有一个可用网关,如果可用网关为电信路由器内网IP;那么实现的是电信进来的包从电信回,网通进来的包也从电信回.问题出现了

如果在双线web服务器上不加网关,用加路由的方式来做的话,

那么

route add -net 51的网段 netmask  x.x.x.x dev eth0

route add -net 61的网段 netmask  x.x.x.x dev eth1

同理还得加网通的,但是这也有一个问题,实际情况电信和网通的用户网段太多了,

你不可能全加上去

应用实例3:

实际情况下的图示,如果做实现得需要七台虚拟机

192.168.1.100                       192.168.2.100

       电信用户        网通用户

         |           |  

192.168.1.1      |          |            192.168.2.1

       电信用户家里路由器  网通用户家里路由器    

51.1.2.3      |         |        61.1.2.3

         |www.abc.com   |                

         |           |

71.1.2.3          |          |        81.1.2.3

        公司电信路由器   公司网通路由器

10.1.1.1      |              |        172.16.2.1

         |         |

         |         |

10.1.1.100     eth0 双线web服务器 eth1        172.16.2.100

精简一点可以使用下面的四台虚拟来做,并且要注意宿主机(真实机)不能在这里扮演角色,因为宿主机和任何虚拟机都是可以直接通的

下图中,电信客户端和网通客户端就没有使用去模拟路由器NAT,直接用一台虚拟机用两个网卡来模拟两个角色

172.16.2.51         bridge  客户端 hostonly2    91.1.1.129

         |         |

         |         |                

         |           |

172.16.2.41    bridge        hostonly2    91.1.1.128

        电信路由器1           网通路由器2

2.2.2.230    hostonly1     vmnet8        71.1.1.131

         |         |

         |         |

2.2.2.236    hostonly1 双线服务器 vmnet8    71.1.1.132

SIP:172.16.2.51

DIP:172.16.2.41

DNAT

SIP:172.16.2.51

DIP:2.2.2.236

回来

SIP:2.2.2.236

DIP:172.16.2.51

SNAT

sip:172.16.2.41

dip:172.16.2.51

进来

电信客户端

SIP:192.168.1.100

DIP:172.16.2.41

被客户端家里的路由器SNAT

SIP:172.16.2.51

DIP:172.16.2.41

被服务器端的电信路由器DNAT

SIP:172.16.2.51

DIP:2.2.2.236

我们下面所做的就是回去时,由两个不同ISP运营商进来的包,从两个不同的网关回去

回去:

SIP:2.2.2.236

DIP:172.16.2.51

被服务器端的电信路由器SNAT

SIP:172.16.2.41

DIP:172.16.2.51

被电信客户端家里的路由器DNAT

SIP:172.16.2.41

DIP:192.168.1.100

上图中:

客户端用虚拟机(linux或xp都可以,但不能使用真实机,因为真实机可以直接访问到上图中的服务器)

   eth0    172.16.2.51    bridge

   eth1    91.1.1.129    hostonly2  

电信路由器1用虚拟机

   eth0    172.16.2.41    bridge

   eth1    2.2.2.230    hostonly1

网通路由器2用虚拟机

   eth0    91.1.1.128    hostonly2

   eth1    71.1.1.131    nat

服务器用虚拟机

   eth0    2.2.2.236    hostonly1

   eth1    71.1.1.132    nat

--假设上图里的客户端为内网用户,服务器为公网服务器;

--因为是模拟环境,所以这里两个路由器打开ip_forward,但上面四台都不用指网关

--我们实现的是当客户端用电信线路访问,也只能从电信线路返回;网通线路访问,也只能从网通线路返回

先在电信路由器和网通路由器上做好SNAT和DNAT,这样就不用把电信客户端的外网IP的网关指向电信路由器的外网IP了

(因为实际的公网IP,不会把网关指向你的,这个在讲iptables的SNAT就讨论过)

电信路由器上写两条(还要打开ip_forward) --也可以只写DNAT,SNAT那条不写它包会自动回来SNAT的

iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 2.2.2.236

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.16.2.41

网通路由器上写两条(还要打开ip_forward)  --也可以只写DNAT,SNAT那条不写它包会自动回来SNAT的

iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 71.1.1.132

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 91.1.1.128

--上面四条当中的eth0自己换成对应的网卡名;电信路由器上的网卡名应该都为172.16.2.41的网卡名;网通路由器上的网卡名应该都为91.1.1.128的网卡名

做好上面四条和打开路由器的ip_forward后,并且默认上图所有的机器里现在都没有网关

在双线web服务器这台启动apache,随便做一个主页测试

验证:

1,在客户端elinks 172.16.2.41,得不到结果

 在客户端elinks 91.1.1.128,得不到结果

2,上面两个线路都得不到结果,是因为能到web服务器,但回不来

所以把web服务器网关指向2.2.2.230的话,则再测试,只有elinks 172.16.2.41能得到结果

   把web服务器网关指向71.1.1.131的话,则再测试,只有elinks 91.1.1.128能得到结果

3,也就是说,现在无法实现电信线路和网通线路都能访问成功;所以我们要借助于策略路由

1,在双线web服务器上使用策略路由实现

# ip rule

0:    from all lookup local

32766:    from all lookup main

32767:    from all lookup default

# echo 100 dianxin >> /etc/iproute2/rt_tables

# echo 200 wangtong >> /etc/iproute2/rt_tables

--下面这四条是告诉dianxin路由表找2.2.2.230出去;告诉wangtong路由表找71.1.1.131出去;eth0就是2.2.2.236的网卡;eth1就是71.1.1.132的网关

# ip route add 2.2.2.0 dev eth0 src 2.2.2.236 table dianxin

# ip route add default via 2.2.2.230 table dianxin

# ip route add 71.1.1.0 dev eth1 src 71.1.1.132 table wangtong

# ip route add default via 71.1.1.131 table wangtong

--下面这两条是加规则,指定从2.2.2.236回去的包找dianxin表;从71.1.1.132出去的包找wangtong表

# ip rule add from 2.2.2.236 table dianxin

# ip rule add from 71.1.1.132 table wangtong

# ip rule

0:    from all lookup local

32764:    from 71.1.1.132 lookup wangtong

32765:    from 2.2.2.236 lookup dianxin

32766:    from all lookup main

32767:    from all lookup default

测试:

再在客户端

elinks 172.16.2.41,能访问到web

elinks 91.1.1.128,也能访问到web

说明电信线路的包只走电信线路,网通线路的包只走网通线路

如果要深入测试的话,可以在客户端elinks电信线路的172.16.2.41时,去双线web服务器上双线路网卡都去tcpdump,会发现只有电信的网卡有包;网通的没有

反之,亦然

==================================

应用实例4:

有些情况一个服务器多张网卡配置成同一个网段(这种做法是不正确的),

因为同一个网段,那么这多张网卡使用的路由是同一条,无法将他们区分开来

(从不同网卡进来的包,一般都会从eth0出去)

如果你想要实现从哪里进,从哪里去,使用iproute2对多张网卡设定不同的网关就可以(优先级要高于main表,也就是route -n看到的)