下周就要考试了,先做个笔记。取自老师的笔记和自己实战。

已经考完了,还行吧。也不怎么难

参数:

(-t filter)-L 显示 INPUT/OUTPUT/FORWARD 链表的规则
-v 显示不同规则的匹配到的流量统计
--line-number 显示行数
-t nat -L 显示 NAT 链表的规则
-P ACCEPT/DROP 放行/拒绝某个链表的默认规则
-F 清空该表的所有规则
-Z 统计数据归零
! 非,除了
-R 链表 行数 规则:修改第几行的规则,规则跟 -A 一样

默认使用白名单模式(INPUT / OUTPUT 的默认规则皆为 DROP)

常规

除了 192.168.1.200 的其他主机都可以访问

iptables -A INPUT ! -s 192.168.1.200 -j ACCEPT
iptables -A OUTPUT ! -d 192.168.1.200 -j ACCEPT

如何让 iptables 的规则永久生效(保存)
service iptables save

更改默认规则
iptables -P INPUT DROP
iptables -P OUTPUT DROP

指定数据报文流入/流出接口

-i incoming_interface:指定数据报文流入接口,INPUT,PREROUTING,FORWARD可用
-o outing_interface:指定数据报文流出接口,OUTPUT,POSTROUTING,FORWARD可用

例:本机访问本机(不然自己都无法访问自己的服务)

[root@localhost named]# iptables -A INPUT -i lo -j ACCEPT
[root@localhost named]# iptables -A OUTPUT -o lo -j ACCEPT

服务

部分地方写上相关服务的配置,以防考试连最基本的设置也忘了

SSH

在 INPUT 和 OUTPUT 链表中放行 22 端口

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

HTTP

在 INPUT 和 OUTPUT 链表中放行 80 端口

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

FTP

主动模式

主动模式不用更改任何配置文件

iptables -A INPUT -p tcp -m multiport --dports 21,20 -m state --state NEW -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

被动模式

在 INPUT 和 OUTPUT 链表中放行 21,20 端口

//第一种
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 --sport 20 -j ACCEPT

//第二种
iptables -A INPUT -p tcp -m multiport --dports 21,20 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --sports 21,20 -m state --state NEW,ESTABLISHED -j ACCEPT

然后加载FTP模块

vi /etc/syconfig/iptables-config
任意地方加入 IPTABLES_MODULES="ip_nat_ftp"
service iptables save
service iptables restart

设定 PASV 模式的端口范围
vi /etc/vsftpd/vsftpd.conf

在最底下添加两段代码
pasv_min_port=30001
pasv_max_port=31000

最后再放行该范围的端口即可

iptables -A INPUT -p tcp --dport 30001:31000 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 30001:31000 -j ACCEPT

DNS

放行 53 端口

iptables -A OUTPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT

编辑 DNS 配置文件(/etc/named.conf)

listen-on port 53 { any; };
listen-on-v6 port 53 { ::1; };
.//中间的内容略
allow-query     { localhost;192.168.223.0/24 };  //允许 192.168.223.0/24 网段通过 dns

//新增需要解析的域名
zone "ha.ha" IN {
        type master;
        file "ha.ha.zone"
};

建立 DNS 区域数据文件(区域数据文件在 /var/named/,可以直接 cp named.localhost xxx.xx.zone),并 chmod 644 ha.ha.zone

$TTL 1D
@       IN SOA  @ www.ha.ha. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
        NS      @
www     A       192.168.223.16
@       A       192.168.223.16

ICMP

可互相访问

iptables -A INPUT -p icmp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT

单向

0:Echo Reply——回显应答(响应) ; 8:Echo request——回显请求(请求)

外网无法 ping 本机,本机可 ping 通外网

iptables -A OUTPUT -p icmp -icmp-type 8 -j ACCEPT

个人理解:外网无法ping本机的:外部(INPUT)对本机发送了(8),但我防火墙不吃你,就DROP你(但默认规则就是DROP,所以无视该条)
但本机想ping你,我自己(OUTPUT)发出个请求(8)给你,你外部没对我限制,所以可收到响应

外部可以 ping 本机,本机不能 ping 外网

iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

个人理解:外部对本机发送请求(8),我们防火墙进来的允许了8

疑问

为何不添加响应(0),因为我在 INPUT 和 OUTPUT 链表中添加了 ESTABLISHED 的状态,已经建立了三次握手的当然可以直接传输。

如果没添加 ESTABLISHED 状态的话,需要加上

//外网无法 ping 本机,本机可 ping 外网
 iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
//外部可以 ping 本机,本机不能 ping 外网
iptables -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT

扩展

基于模式

  • NEW:就是双方进行通信时第一个到来的报文;
  • ESTABLISHED:ESTABLISHED 已经注意到两个方向上的数据传输,而且会继续匹配这个连接的包。处于 ESTABLISHED 状态的连接是非常容易理解的。只要发送并接到应答,连接就是 ESTABLISHED 的了;
  • RELATED:在一个服务中,可能开启了两个进程,而且这两个进程都需要跟服务器进行通信,例如 FTP 有两个通信链路,命令链路和传输数据的链路,这两个链路就是存在关系的,所以他们属于 RELATED 状态;
  • INVALID:表示一个包不能被识别;
-m state --state NEW,ESTABLISHED.RELATED,INVALID

范围/限制/匹配

配置不连续端口

-m multiport:可以指定15个以内的离散端口
    --source-ports (sports)
    --destination-ports (dports)
    --ports

例:iptables -I INPUT -d 172.16.100.7 -p tcp -m multiport --dports 22,80 -j ACCEPT

配置IP地址的范围

`-m iprange` 
    ` --src-range` 或 `--dst-range`

例:iptables -A INPUT -d 172.16.100.7 -p tcp --dport 23 -m iprange --src-range 172.16.100.1-172.16.100.100 -j ACCEPT

时间限制

-m time 时间限制
        --datestart //开始的日期,年/月/日
        --datestop //结束的日期,年/月/日
        --timestart //开始的时间,XX:XX:XX
        --timestop //结束的时间,XX:XX:XX
        --weekdays //星期一到星期五的英文缩写,Mon/Tue/Wed/Thu/Fri/Sat/Sun
        --monthdays 

例:iptables -A input -d 192.168.1.1 -p tcp –-dport 80 -m time –- timestart 08:30:00 –-timestop 14:30:00 –-datestart 2012:07:20 –-datestop 2012:07:30 -j ACCEPT

限制速率

-m limit 
    --limit  30/min //限制每分钟30个数据包
    --limit-burst 5 //最大速率的时候每分钟只能发5个数据包(分钟和秒似乎看上面的limit的单位)

例:iptables -A INPUT -d 192.168.5.250 -p icmp --icmp-type 8 -m limit --limit 30/min --limit-burst 5 -j ACCEPT
(允许别人平均一分钟品ping服务器30个数据包,最多可以连续5个ping)

字符串匹配

    -m -string 字符串匹配
        -string "" //指定字符
        --algo {bm|kmp} //指定字符匹配算法

例:iptables -A output -p tcp --sport -m string --string "hello" --algo kmp -j DROP
(过滤带 hello 字符的数据包,除了“hello”以外的字符串都可以通过)

TCP标志位

--tcp-flags 要检查的标志位,必须为1标记
    --tcp-flags SYN,ACK,RST,FIN SYN,ACK(检查SYN,ACK,RST,FIN 其中SYN,ACK必须为1,其它为0)
                ALL
                NONE
                --SYN

例:拒绝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

NAT

由于对于 NAT 的理解我比较混乱,所以结果未必正确,但原理应该是这样的吧

做 SNAT,使用 POSTROUTING 链表
做 DNAT,使用 PREROUTING 链表

首先开启 Linux 的地址转发功能:

vim /etc/sysctl.conf
找到 net.ipv4.ip_forward=0 ,将 0 改为 1
sysctl -p //验证配置

然后在 FORWARD 链表添加转发规则
iptables -A FORWARD -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
(需要转发的目标地址再看情况另外添加)
iptables -A FORWARD -d 1.1.1.2 -j ACCEPT (转发数据到 1.1.1.2)

以下例子按照该拓扑图进行
topo.png

按我的理解,SNAT 和 DNAT 的用处和区别

SNAT 是用于网关的,而 DNAT 用于 IP 的映射(类似DMZ)

推荐阅读:SNAT 和 DNAT 的区别

SNAT(基于源地址)

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 1.1.1.2
表示在 postrouting 链上,将源地址为 192.168.1.0/24 网段的数据包的源地址都转换为 1.1.1.1

例:在没有 1.1.1.0/24 网段中访问 1.1.1.2

物理机想访问 1.1.1.2 ,刚好作为网关(防火墙,1.1.1.1)是双网卡可以直接访问 1.1.1.2,则开启转发功能即可
即 物理机访问 1.1.1.2 --> 网关(1.1.1.1)查询规则转发 --> 转发到内网 1.1.1.2 的服务器

FOWARD:

iptables -A FORWARD -s 192.168.223.0/24 -d 1.1.1.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A FORWARD -m state --state NEW,ESTABLISHED -j ACCEPT

NAT:

iptables -t nat -A POSTROUTING -s 192.168.223.0/24 -j SNAT --to-source 1.1.1.1

查看 access.log,结果如下:

1.1.1.1 - - [02/Jun/2018:08:21:34 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)""

如果想做到共享上网,则把目的地址和源地址交换即可

DNAT(基于目标地址)

iptables -t nat -A PREROUTING -d 10.0.0.1 -j DNAT –-to-destination 172.16.93.1
此条规则将请求 IP 为 10.0.0.1 的数据包转发到后端 172.16.93.1 主机上

例:访问公网 192.168.223.16 的 HTTP 以 DNAT 的方式将数据报文中发送到目的 IP 地址。

如果不加 NEW,ESTABLISHED,似乎无法建立连接。无法转发

一个公网 IP 想用于映射内网的一个 IP,当我们访问公网 IP 的时候,数据将会转发到内网的 IP

即 客户端外网 ---> 公网IP网关 --> 内网客户端

Forward:

iptables -A FORWARD -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -d 1.1.1.2 -j ACCEPT

PREROUTING:

iptables -t nat -A PREROUTING -d 192.168.223.16 -p tcp --dport 80 -j DNAT --to-destination 1.1.1.2:80

查看 access_log ,结果如下:

192.168.223.1 - - [02/Jun/2018:10:06:14 +0800] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"