文章目录
iptables能干什么事儿:
1:帮助学习协议
输出网络通信日志(到syslog/messages)
返回指定的内容
2:了解最基础的网络安全防护设备
网络防火墙的作用,网络防火墙的原理
防火墙的日志是IPS,IDS等高级安全设备的基础
Netfilter是linux内核的功能,很多基于linux内核的安全设备都是使用Netfilter做的底层工作
3:若是只想保护linux服务器本身的安全就使用filter表的INPUT和OUTPUT链就行了,不需要使用FORWARD链
防火墙规则匹配原则 + 网络过滤动作分解
# 防火墙的 规则匹配 原则
匹配即可停止
匹配有先后顺序
默认规则的优先级最低
# 网络过滤的分解步骤
1:获取数据(嗅探,正常请求)
2:识别数据(协议头,具体内容)
3:过滤 (丢弃,修改,放过,记录日志等)
iptables的 (表、规则链、动作) 介绍
# 表名包括:-t
raw: # 高级功能, 如:网址过滤。(包含 PREROUTING,OUTPUT 链)
mangle: # 数据包修改,如:实现服务质量(QoS),(包含 PREROUTING,FORWARD,INPUT,OUTPUT,POSTROUTING 链)
nat: # 地址转换, 用于网关路由器,(包含 PREROUTING,OUTPUT,POSTROUTING 链)
filter: # 包过滤, 用于防火墙规则,(包含 INPUT,OUTPUT,FORWARD 链)
# 内置规则链名包括
INPUT链: # 入站规则 处理输入数据包
OUTPUT链: # 出站规则 处理输出数据包
PORWARD链: # 转发规则 处理转发数据包
PREROUTING链: # 路有前规则 用于目标地址转换(DNAT)
POSTOUTING链: # 路由后规则 用于源地址转换(SNAT)
# 动作包括:
ACCEPT: # 接收数据包。
DROP: # 丢弃数据包。
RETURN: # 防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain)中。
REJECT: # 拦截数据包,并可以指定返回值(目标主机不可到达,tcp-reset 关闭连接 等)。
--reject-with [ tcp-restet | net-unreach | host-unreach | icmp-net-unreachable 等]
REDIRECT: # 端口重定向、映射、透明代理。
MARK: # 做防火墙标记
SNAT: # 源地址转换。
DNAT: # 目标地址转换。
LOG: # 日志记录。
--log-level
--log-prefix "da" # 在日志里加个da前缀,方便查看(/var/log/message)
--log-ip-options
MASQUERADE: # IP伪装(NAT),用于ADSL。
自定义链:
附、如何查看匹配到的流量总计
iptables 语法、管理命令用法、配置文件介绍
# 指定表(不指定 就是操作 filter 表)
-t: # 可选 raw|mangle|nat|filter
# 规则管理
-A: # 在链尾部'追加'规则条目
-I CHAIN [n]: # 在链中'插入'规则条目;需要指明位置,插入对应 CHAIN 上的第 n 条,默认插到第一条
-D CHAIN [n]: # 从链中'删除'规则条目;删除指定链中的第 n 条规则
-R CHAIN [num]: # '替换'链中的指定规则条目;替换链中指定序号的规则
# 链管理
-F [CHAIN]: # 清空指定规则链,如果省略 CHAIN,则清空对应表中的所有链
-Z: # 置零计数器'匹配到的报文个数'和'匹配到的所有报文大小之和';
-N: # 创建自定义规则链;(用于对内置链的扩展和补充)
-X: # 删除自定义规则链
-P CHAIN TARGE: # 定义规则链中的默认策略(filter表的默认策略是accept,允许)
-E: # 重命名自定义链,(引用计数不为0的自定义链,不能被重命名,也不能被删除)
# 查看规则
-L: # 显示规则链中已有的条目
-n: # 以数字格式显式主机地址和端口号
-v: # 显式链及规则的详细信息(能查看到具体的流量数)
-x: # 显示计数器结果的精确值
--line-numbers: # 显式规则号码
# 基本匹配条件(无需加载任何模块,由iptables/netfilter自行提供)
-p: # 指定要匹配的数据包协议类型;[tcp|udp|icmp|gre|udplite|esp|sh|sctp|mh|all]
-s: # 指定要匹配的数据包源ip地址;
-d: # 指定要匹配的数据包目的ip地址;
--sport: # 指定要匹配的数据包源端口;(端口范围表示方法 80:83)(表示端口范围是80到83)
--dport: # 指定要匹配的数据包目的端口;
-j<目标>: # 指定要跳转的目标;
-i<网络接口>: # 指定数据包进入本机的网络接口;(只能用于:PREROUTING,INPUT,FORWARD链)
-o<网络接口>: # 指定数据包要离开本机所使用的网络接口。(只能用于:FORWARD,OUTPUT,POSTROUTING链)
# 配置文件位置
cat /etc/sysconfig/iptables
#保存iptables规则(不输入绝对地址无法保存哦)
/etc/rc.d/init.d/iptables save
#将iptables规则另存为一个叫ss的文件
iptables-save > ss
#将外部iptables规则文件导入到iptables规则中,并运行
iptables-restore < ss
iptables命令选项输入顺序:
iptables -t 表名 [-A|I|D|R] 规则链名 [规则号] [-i|o 网卡名] -p 协议名 [-s 源IP/源子网] --sport 源端口 [-d 目标IP/目标子网] --dport 目标端口 -j 动作
iptables常规用法(不指定,默认是filter表)(防火墙匹配是按序号进行匹配的)
iptables -t filter -L #查看filter表的规则
iptables -t filter -L INPUT #查看filter表里INPUT链的规则
iptables -L -nv #查看规则,带有地址和端口的输出
iptables -L -n --line-numbers #将所有iptables以序号标记显示,执行
iptables -D INPUT 7 #删除INPUT里序号为7的规则
iptables -t filter -P FORWARD DROP #将filter表里的FORWARD链的默认策略改成拒绝
iptables -t filter -R INPUT 2 -p icmp -j DROP #将第二条规则,修改为丢弃icmp
iptables -I INPUT -s 192.168.1.2/32 -j DROP #(插入一个规则,默认是最前面,变成1)屏蔽单个IP
iptables -I INPUT 5 -s 10.20.20.0/24 -j DROP #(在第5条规则后,插入一个规则)屏蔽某个段的IP
iptables -P FORWARD ACCEPT # 将 FORWARD 链中的默认策略改成 ACCEPT
iptables -t filter -R INPUT 2 -p icmp -j DROP #将第二条规则,修改为丢弃icmp
iptables -t filter -A INPUT -p icmp -j REJECT --reject-with host-unreach #当有ping包到达时,返回主机不可达
iptables -F #清空规则
iptables -Z #清空计数器
#注意,可以禁止本地网络访问www.baidu.com网站(注意,iptables会将其设置为禁止该域名解析的IP,若是不存在的解析则会添加失败)
iptables -I OUTPUT -d www.baidu.com -j DROP
自定义链的应用(注意:需要定义默认规则,或则返回规则)
iptables -t filter -N ICMP #创建自定义链
iptables -t filter -E ICMP IN-ICMP #重命名自定义链为IN-ICMP
iptables -t filter -p icmp --icmp-type 8 -j ACCEPT #为自定义IN-ICMP链添加规则
iptables -t filter -A INPUT -j IN-ICMP #将自定义IN-ICMP链依附于内置链INPUT上,(只有依附后才会生效)
iptables -t filter -A IN-ICMP -j RETURN #若是自定义规则链未匹配到数据,或则链里没有规则,即使用依附的内置链的默认策略
使用扩展匹配选项 -m 选项介绍
-m state # 实现基于状态检测的包过滤,指定检测哪种状态,(根据"连接追踪机制"去检查连接的状态)
--state STATE # 如下是可用的连接状态
NEW: # 新连接请求
ESTATBLISHED: # 已建立的连接
INVALID: # 非法连接报文(不确定的会话)
RELATED: # { 相关会话连接,适用于多通道协议,(如 ftp的命令连接和数据连接、如 h323)
# 当一个连接和某个已处于 ESTABLISHED 状态的连接有关系时,就被认为是 RELATED 的了。
# 换句话说,一个连接要想 是RELATED的,首先要有一个 ESTABLISHED 的连接。}
#查看当前连接追踪功能,能够容纳的最大连接数量(我的centos6.9好像没有这个文件)
cat /proc/net/nf_conntrack_max
#查看已经追踪到并已经记录下来的连接
cat /proc/net/nf_conntrack
优化:增大连接追踪记录数量
vi /etc/sysctl.conf
net.nf_conntrack_max = 393216
net.netfilter.nf_conntrack_max = 393216
# 使其修改生效
sysctl -p
-m icmp # 指定icmp类型
--icmp-type{echo-request,echo-reply} # 前者类型为8(发送方发出的),后者类型为0(接收方返回的)
-m iprange # 指定连续的ip地址范围,(但一般不用于整个网段)
--src-range ip-ip
--dst-range ip-ip
-m multiport # 指定多端口号
--sports
--dports
--ports
-m limit # 限速,平均每秒,每分钟,每小时或则每天平均一次多少个包允许通过
--limit 300/{second,minute,hour,day}
--limit-burst 5 # 指定瞬时流量(说明若是同时涌入超过5个数据包,超过的包将直接丢弃)(通常与 --limit 连用)
-m mac
--mac-source # 用来限定源mac地址(注意:这个参数不能用在OUTPUT,POSTROUTING链中)
-m connlimit # 限定连接数
--connlimit-upto 2 # 指定连接的数量小于等于2时,匹配
--connlimit-above 5 # 指定连接的数量大于5时,匹配
-m length # 指定数据包长度,单位字节
--length 1178
-m string # 对报文中的应用层数据做字符串模式匹配检测
--algo [bm|kmp] # 必须指定,字符串匹配
--string 'sd' # 指定要检查的字符串为sd(当字符串为中文时,要先转码为UTF-8)
--hex-string 'sd' # 指定要检测的字符串模式,16进制格式
--from 40 # 设置'起始'偏移位置,这里设为'起始偏移40',默认是0
--to 57 # 设置'结束'偏移位置
-m time # 根据时间段限定
--timestart 14:30 # 每天的14:30开始
--timestop 18:30 # 每天的18:30结束
--weekdays Sat,Sun # 每周的那几天(Mon,Tue,Wed,Thu,Fri,Sat,Sun)
--monthdays 2:15,19 # 每月的2到15号和19号
--kerneltz # 使用内核上正在使用的时区(而不是使用默认的UTC时区)
-m recent # recent扩展模块实现服务器网络安全(这个模块很有趣,用的好可以充分保证您服务器安全)
--name # 设定列表名称,默认是DEFAULT
--resource # 源地址,此为默认
--rdest # 目的地址
--seconds # 指定时间内
--hitcount # 命中次数
--set # 将地址添加进列表,并更新信息,包含地址加入的时间戳
--rcheck # 检查地址是否在列表,以第一个匹配开始计算时间
--update # 和rcheck类似,以最后一个匹配开始计算时间
--remove # 在列表删除相应地址,后跟列表名称及地址
扩展匹配选项 -m 的常见应用方式,和实现的功能
linux作为路由器时,不允许,源IP为192.168.31.110,向目的IP为192.168.1.25的主机发起连接(但是没有限制后者向前者发起连接)
iptables -t filter -I FORWARD -s 192.168.31.110/32 -d 192.168.1.25/24 -m state --state NEW -j DROP
linux作为服务器时,不允许,向目的地址为192.168.31.110的主机发起会话连接
iptables -t filter -I OUTPUT -d 192.168.31.110/32 -m state --state NEW -j DROP
拒绝192.168.10.0/24的主机ping通 192.168.80.0/24 段的主机
iptables -t filter -I FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -p icmp -m icmp --icmp-type echo-request -j DROP
禁止其他计算机ping本地linux
iptables -t filter -I INPUT -p icmp -m icmp --icmp-type 8 -j DROP
拒绝192.168.10.0/24 访问192.168.80.0/24的 1-1024还有3389端口
iptables -t filter -I FORWARD -p tcp -s 192.168.10.0/24 -d 192.168.80.0/24 -m multiport --dports 1:1024,3389 -j DROP
禁止 192.168.1.2-192.168.1.10这些个地址访问 服务器的80端口
iptables -t filter -A FORWARD -p tcp --dport 80 -m iprange --src-range 192.168.1.2-192.168.1.10 -j DROP
192.168.10.0/24网段每秒钟向192.168.80.0/24发送数据包不能超过300个(PS:按每个数据包1500字节算,1500*300=450000=450K)
iptables -t filter -I FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -m limit --limit 300/second -j ACCEPT
iptables -t filter -A FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -j DROP
允许192.168.10.2/32 ping 主机 192.168.80.2/32 4个包
iptables -t filter -I FORWARD -s 192.168.10.2/32 -d 192.168.80.2/32 -p icmp -m limit --limit-burst 4 -j ACCEPT
iptables -t filter -A FORWARD -s 192.168.10.2/32 -d 192.168.80.2/32 -p icmp -j DROP
拒绝源mac地址为00-0c-29-db-32-6f 的数据包访问 192.168.80.0/24
iptables -t filter -I FORWARD -d 192.168.80.0/24 -m mac --mac-source 00-0c-29-db-32-6f -j DROP
限定192.168.10.2主机不允许与192.168.80.2发起 超过2个远程桌面连接,(默认策略是允许)
iptables -t filter -I FORWARD -s 192.168.10.2/32 -d 192.168.80.2/32 -p tcp --dport 3389 -m connlimit --connlimit-above 2 -j DROP
当检测到出现'baidu'字符串时,进行拦截
#iptables -t filter -I INPUT -p tcp --dport 80 -m string --algo bm --string 'baidu' -j REJECT
iptables -t mangle -I INPUT -p tcp --dport 80 -m string --algo bm --string 'baidu' -j DROP
拒绝本地端口 80 发出的,含有 “communist” 关键字的响应报文的发出
iptables -A OUTPUT -p tcp --sport 80 -m string --algo kmp --string "communist" -j DROP
允许 Telnet 的 23 端口访问,并限制同时只能有 5 个连接
iptables -A INPUT -p tcp --dport 23 -m connlimit --connlimit-above 5 -j REJECT
周日的下午2点半到6点半,拒绝源IP为192.168.1.2的主机访问服务的80端口
iptables -t filter -A INPUT -s 192.168.1.2 --dport 80 -m time --timestart 14:30 --timestop 18:30 --weekdays Sun --kerneltz -j DROP
仅允许工作日的工作时间访问本机 UDP 53 端口
iptables -A INPUT -p udp --dport 53 -m time --timestart 08:00 --timestop 18:00 --weekdays Mon,Tue,Wen,Thu,Fri -j ACCEPT
linux服务器生产应用示例
1:保护服务器安全(基础版)
# 配置默认规则
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
# 丢弃非法连接
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
# web服务器的80端口对所有开放,22端口只允许特定IP(192.168.31.112)访问,其他的拒绝
iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -I INPUT -p tcp --dport 22 -s 192.168.31.112/32 -j ACCEPT
iptables -t filter -A INPUT -j DROP
2:在一定时间内限制ssh客户端连接的次数(使用recent模块限制同IP时间内新请求连接数)
# ssh连接,一个客户端在60秒内只允许连接2次
iptables -t filter -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --rcheck --seconds 60 --hitcount 2 -j DROP
iptables -t filter -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --set -j ACCEPT
iptables -t filter -A INPUT -m state --state ESTABLISHED -j ACCEPT #已经建立的连接,都允许
3:如何开放被动模式的FTP服务
# 装载ftp连接追踪的专业模块
modprobe nf_conntrack_ftp
# 放行命令连接(假设Server地址为192.168.1.2)
iptables -t filter -A INPUT -d 192.168.1.2 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -t filter -A OUTPUT -s 192.168.1.2 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
# 放行数据连接(假设Server地址为192.168.1.2)
iptables -t filter -A INPUT -d 192.168.1.2 -p tcp -m state RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -I OUTPUT -m state --state ESTABLISHED -j ACCEPT
4:防止SYN洪水攻击(recent 模块的应用)
# 限制TCP 80端口60秒内每个IP只能发起10个连接,超过记录日志及丢弃数据包,可防CC,及非伪造IP的syn flood
iptables -t filter -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j LOG --log-prefix "DDos" --log-ip-options
iptables -t filter -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j DROP
iptables -t filter -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --set -j ACCEPT
iptables -t filter -A INPUT -m state --state ESTABLISHED -j ACCEPT #已经建立的连接,都允许
5:设置打开ssh服务22端口的钥匙(使用指定大小的ICMP报文当钥匙)
# 记录ping数据包大小为1078和1178的icmp请求,并记录日志,前缀分别是SSHOPEN和SSHCLOSE
iptables -t filter -A INPUT -p icmp --icmp-type 8 -m length --length 1078 -j LOG --log-prefix "SSHOPEN"
iptables -t filter -A INPUT -p icmp --icmp-type 8 -m length --length 1178 -j LOG --log-prefix "SSHCLOSE"
# 指定数据包为1078字节,加入sshopen列表(其中包含IP头部 20字节,icmp头部 8字节)
iptables -t filter -A INPUT -p icmp --icmp-type 8 -m length --length 1078 -m recent --set --name sshopen --rsource -j ACCEPT
#检查sshopen表中 60秒内的记录,如果有源地址则允许这个源地址访问TCP的22 端口
iptables -t filter -A INPUT -p tcp --dport 22 --syn -m recent --rcheck --seconds 60 --name sshopen --rsource -j ACCEPT
# 发送ping包指定数据包大小为1178字节,将客户端地址从sshopen表中移除,客户端将不能对TCP的22端口建立新的连接
iptables -t filter -A INPUT -p icmp --icmp-type 8 -m length --length 1178 -m recent --name sshopen --remove -j ACCEPT
# 已经建立的会话连接,就放行
iptables -t filter -A INPUT -p icmp -j ACCEPT #放行所有的icmp数据包,方便检
# 查服务器存活情况
iptables -t filter -A INPUT -m state --state ESTABLISHED -j ACCEPT #已经建立的连接,都允许
# 将默认的入策略修改为拒绝
iptables -t filter -P INPUT DROP
# 打开,允许连接ssh,这个会在ping指定大小的数据包后,60秒内,可以任意多次连接ssh
#(ping时指定数据包大小,为什么是1050,因为他会自动加上 IP头20字节,和ICMP头8 字节,即1050+20+8=1078)
ping -s 1050 192.168.1.55 #linux下操作
ping -l 1050 192.168.1.55 #windows下操作
# 关闭,不允许连接ssh(ping时指定数据包大小,为什么是1050,因为他会自动加上 IP头20字节,和ICMP头8 字节,即1050+20+8=1078)
ping -s 1150 192.168.1.55 #linux下操作
ping -l 1150 192.168.1.55 #windows下操作
6:iptables过滤特定字符串数据流
拒绝带有qq.com这个字符串的流量
iptables -t mangle -I INPUT -p tcp -m string --string "qq.com" --algo bm -j DROP
# 算法有两种
--algo bm #基础算法,常用
--algo kmp #高级算法,我还未研究怎么玩(上面有个例子)
7:iptabes 变相实现 对流量进行限速(限制的是数据包数量pps)
#192.168.10.0/24网段每秒钟向192.168.80.0/24发送数据包不能超过300个(PS:按每个数据包1500字节算,1500*300=450000=450K)
iptables -t filter -I FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -m limit --limit 300/second -j ACCEPT
iptables -t filter -A FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -j DROP
linux路由器常规示例
1:配置NAT表 实现内部主机 NAT上网(在路由器的外网口出设置规则,NAT表,POSTROUTING链中)
#外网口是eth0,在网卡的出方向进行源地址转换,可用源地址是公网IP地址192.168.20.10和11
#需求:让内网192.168.10.0/24段的所有主机使用外网地址192.168.20.10和11上互联网.(-o 指定出站接口)
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j SNAT --to-source 192.168.20.10-192.168.20.11
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
#开启内核转发
cat /etc/sysctl.conf
net.ipv4.ip_forward = 1
2:配置NAT表 将外部端口 映射到内部端口(应用与内网有服务器向公网提供服务时,NAT表,PREROUTING链中)
#外网口是eth0,在入方向进行转换,目的地址是公网接口上的地址,内网服务器ip是192.168.10.10,内网提供80端口
#需求:将边界地址192.168.20.10的80端口映射到内网192.168.10.10的80端口上,实现公网可以访问内网的web站点(-i 指定入站接口)
iptables -t nat -A PREROUTING -i eth0 -d 192.168.20.10/32 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.10:80
iptables -t nat -A POSTROUTING -d 192.168.10.10/32 -p tcp --dport 80 -j SNAT --to-source 192.168.20.10
#iptables -t nat -A POSTROUTING -d 192.168.10.10/24 -j SNAT --to-source 192.168.20.10
3:使用mangle表 (应用于修改数据包的首部中的值)迷惑跟踪者
#注意windows的ttl 默认是128,linux是64,过一个路由器,就减1
--ttl-inc 1 #ttl加1
--ttl-dec 2 #ttl减2
--ttl-set 45 #直接将ttl修改为45
#迷惑原理,在中途某台路由器上,TTL先加1再减1(这样就跟踪不到这台路由器了)
#在数据包进入eth0之前,将ttl加1
iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-inc 1
附:路由跟踪原理(收集沿途返回数据的IP地址,这就是转发数据的路由器)
#第一种:发送ping包,逐渐加大ttl的值
ping 120.206.184.10 -t 1 #能知道本地网关是谁,本地网关会返回ttl耗尽数据
ping 120.206.184.10 -t 2 #能知道本地网关是谁,
.......
ping 120.206.184.10 -t 10 #假设当ttl为10是120.206.184.10正常返回数据,说明经过了10个路由器
如果文章对你有帮助,欢迎点击上方按钮打赏作者
暂无评论