iptables/netfilter:
Packets Filter Firewall:
包过滤型防火墙:
Firewall:隔离工具,工作于主机或网络的边缘处,对经由的报文根据预先定义的规则(识别标准)进行检测,对于能够被规则匹配到的报文实行某种预定义的处理机制的一组套件:
硬件防火墙:CPU级别就可以封包和解包,提供26个字母,硬件逻辑;在硬件级别实现部分功能的防火墙。
软件防火墙:应用软件逻辑在通用硬件基础上实现。
主机防火墙:
网络防火墙:
ipfw --> ipchians -->iptables(ip6tables)
iptables(管控机制,内核中的功能)/netfilter(框架 网络过滤器的规则)
iptables:规则管理工具
netfilter: 防火墙框架,承载并生效的规则;
hook functions(netfilter): 钩子规则
prerouting:进入/离开本机的外网接口
input: 数据包从内核流入用户空间的
forward:从一个网络接口进来,到另一个网络接口去的
output: 数据包从用户空间流出的
postrouting:进入/离开本机的内网接口
iptables:內键链
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
允许用户自定义规则链:他们需要手动关联至指定的“钩子”;
钩子和链是有特定对应关系
netfilter: 功能
filter防火:包过滤
NAT: Network Address Translation(网络地址转换)
mangle: 拆解报文,做出修改,而后重新封装。
raw : 关闭nat表上启用的连接追踪机制
功能(表) <--> 钩子
filter: input, forward, output
nat: prerouting, input, output, postrouting
mangle: prerouting, input, forward, output, postrouting
raw: pretouting, output
优先级(由高而低): raw --> mangle --> nat --> filter
iptables规则的组成部分:
匹配条件:处理机制
网络层首部(IP):SourceIP , DestinationIP;
传输层首部(TCP):SourcePort, DestinationPort目标端口, TCP Flags(SYN请求,ACK响应,FIN结束,URG,PSH推送,RST重置)
跳转目标:target
內键的处理机制:ACCEPT接受, DROP丢弃, REJECT拒绝,SNAT本地转发, DNAT远程转发,MASQUERADE, MARK, LOG, ...
用户自定义链:
添加规则时需要考量的因素:
(1)实现的功能:用于判断将规则添加至哪个表;
(2)报文流经的位置:用于判断规则添加至哪个链;
(3)报文的流向:判定规则中何为“源”,何为“目标”;
(4)匹配条件:用于编写正确的匹配规则;
(a)专用于某种应用的同类规则,匹配范围小的放前面;
(b)专用于某些应用的不同类规则,匹配到的可能性较多的放前面;同一类别的规则可使用自定义链单独存放;
(c)用于通用目的的规则放前面;
filter表:过滤,防火墙意义的核心所在;
INPUT, FORWARD, OUTPUT
man iptables-extensions
man iptables
安装:
netfilter:位于内核中的tcp/ip协议栈报文处理框架;
iptables:
CentOS 5/6: iptables命令生成规则,可保存于文件中以反复装载生效;
# iptables -t filter -F 先清空规则
# service iptables save 再保存
man iptables
CentOS 7: firewalld, firewall-cmd, firewall-config
# systemctl disable firewall.service 关闭firewall,只使用iptables
man iptables
man iptables-extensions
iptables命令:
iptables [-t table] {-A|-C|-D} chain rule-specification
-A: append
-C: check
-D: delete
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
rule-specification = [matches...] [target]
match = -m matchname [per-match-options]
target = -j targetname [per-target-options]
COMMANDS:
链管理:
-N: --new-chain chain: 新建一个自定义规则链
iptables -N input-http
iptables -nL
-X: --delete-chain [chain] :删除用户自定义的被应用为0的空链,
-F: --flush [chain] :清空指定的规则链上的规则,不指定链就清空所有链上的规则;
-E: --rename-chain old-chain new-chain: 重命名自定义链;
-Z: --zero [chain [rulenum]]: 置零计数器;
注意:每个规则都有两个计数器
packets:被本规则所匹配到的所有报文的个数;
bytes:被本规则所匹配到的所有报文的大小之和;
-P: --policy chain target: 更改默认策略,
示例:
iptables -t filter -P DROP
iptables -t filter -P ACCEPT
注意,一般生产中不设置默认策略,一般是自定义策略;
规则管理:
-A :--append chain rule-specification: 追加新规则于指定链的尾部;
-I: --insert chain [rulennum] rule-specification :插入新规则于指定连的指定位置,默认为首部;
-R:--replace chain rulenum rule-specification: 替换指定的规则为新的规则;
-D: --delete chain rulenum: 根据规则编号删除规则;
rulenum:表示第几条规则
-D:--delete chain rule-specification: 根据规则本身删除规则;
规则显示:
-L:--list [chain]: 列出规则;
-v, --verbose: 详细信息;
-vv:更详细;
-n, --numeric: 以数字显示主机地址和端口号;
-x, --exact: 显示计数器的精确数值,而非圆整后的数据;
--line-numbers: 列出规则时,显示其在链上的响应的规则编号;
示例:iptables -vnL
iptables -vnxL --line-numbers
-S, --list-rules [chain]: 显示指定链的所有规则;
示例:iptables -S
rule-specification = [matches...] [target]
matches: 匹配条件
target: 跳转目标;
匹配条件:match = -m matchname [per-match-options]
-m matchname [per-match-options]
通用匹配(PARAMETERS)参数,大写字母是target跳转目标扩展,小写字母是match扩展
[!] -s, --source address[/mask][,...]:检查报文的源IP地址是否符合此处指定的范围,或是否等于此处给定的地址;如果有多个地址,需要用逗号","隔开;
[!] -d, --destination address[/mask][,...]:检查报文的目标IP地址是否符合此处指定的范围,或是否等此处给定的地址; 如果有多个地址,需要用逗号","隔开;
示例:
iptables -A INPUT -s 172.16.0.0/16,127.0.0.0/8 -d172.16.73.101,127.0.0.1 -j ACCEPT
iptables -A OUTPUT -s 172.16.73.101 -d 172.16.0.0/16 -j ACCEPT
[!] -p, --protocol protocol:匹配报文中的协议,可用值:tcp, udp, udplite, icmp, esp, ah, sctp or all,也可以使用数字表示:
示例:
iptables -R INPUT 1 -s 172.16.0.0/16 -d 172.16.73.101 -p tcp -j ACCEPT
iptables -R OUTPUT 1 -s 172.16.73.101 -d 172.16.0.0/16 -p tcp -j ACCEPT
[!] -i, --in-interface name:限定报文仅能从指定接口流入,only for packets entering the INPUT, FORWARD and PREROUTING chains 只能用于这三个链:INPUT, FORWARD and PREROUTING
[!] -o, --out-interface name:限定报文仅能从指定接口流出,for packets entering the FORWARD, OUTPUT and POSTROUTING chains ,只能用于这三个链:FORWARD, OUTPUT and POSTROUTING
-m,--match match:调用指定的扩展匹配模块来扩展匹配条件检查机制;
扩展匹配(MATCH EXTENSIONS)
跳转目标:target = -j targetname [per-target-options]
-j targetname [per-target-options]
ACCEPT:接受
DROP:丢弃
PREJECT:拒绝
回顾:
iptables/netfilter:
netfilter: 防火墙框架
iptables: 管理规则的工具;
四表:filter, nat, mangle, raw
五链:PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
iptables命令:
iptables [-t table] COMMAND [chain] [PARAMETERS] [-m matchname] [per-match-options] [-j targetname [per-target-options]]
PARAMETERS:
-s, -d, -p {tcp|dup|icmp|sctp|udplite|...}, -i, -o
COMMAND:
连管理:-P, -X, -N, -E, -F, -Z,
规则管理:-A, -I, -R, -D,
查看:-L, -S
-L: -n, -v,-x , --line-numbers
-j targetname
ACCEPT, DROP, REJECT
iptables(2)
iptables [-t table] COMMAND [chain] [PARAMETERS] [-m matchname] [per-match-options] [-j targetname [per-target-options]]
匹配条件:
基本匹配条件:PARAMETERS
扩展匹配条件:-m matchname
隐式扩展:由协议本身生成的扩展条件由 -p引出,在使用-p选项指明了特定的协议时,无需再用-m选项指明扩展模块的扩展机制;
显式扩展:必须使用-m选项指明要调用的扩展模块的扩展机制;
隐式扩展:
-p tcp: 可直接使用tcp扩展模块的专用选项:
[!] --source-port:--sport port[:port]:匹配报文源端口;可以给出多个端口,但只能是连续的端口范围;
示例:iptables -t filter -A INPUT -s 192.168.199.0/24 -d 192.168.199.152 -p tcp --dport 22 -j ACCEPT 允许199这个网段的主机访问本机
iptables -I INPUT -s 192.168.199.151 -d 192.168.199.152 -p tcp --dport 22 -j ACCEPT -I插入这条记录
iptables -R INPUT 1 -s 192.168.199.151 -d 192.168.199.152 -p tcp --dport 22 -j REJECT 拒绝151主机使用22端口访问本机,-R表示修改这条记录,
[!] --destination-port:--dport port[:port]:匹配报文目标端口;可以给出多个端口,但只能是连续的端口范围;
示例:iptables -t filter -A OUTPUT -s 192.168.199.152 -d 192.168.199.0/24 -p tcp --sport 22 -j ACCEPT
[!] --tcp-flags mask comp:匹配报文中的tcp协议的标志位;Flags are标志位: SYN ACK FIN RST URG PSH ALL NONE.
mask:要检查的FLAGS LIST,以逗号分隔:
comp: 在mask给定的诸多FLAGS中,其值必须为1的FLAGS列表,余下的其值必须为0;
--tcp-flags SYN,ACK,FUB,RST SYN 三次握手的第一次请求;SYN为1,其他为0,;
--tcp-flags ALL ALL 所有标识位都为1
--tcp-flags ALL NONE 所有标识位都为0
示例:
iptables -N clean_invalid_packets 使用-N添加一条自定义链
iptables -A clean_invalid_packets -p tcp --tcp-flags ALL ALL -j DROP 在自定义链上添加拒绝所有TCP标识位为1的包;
iptables -A clean_invalid_packets -p tcp --tcp-flags ALL NONE -j DROP 添加拒绝所有标识位为0的包,
说明:以上这三条记录是为了拒绝恶意攻击;并且添加自定义链,必须在调用时才生效,调用方法:
iptables -I INPUT -d 192.168.199.152 -j clean_invalid_packets
不使用自定义链,删除方法:
iptables -X clean_invalid_packets 执行这条命令后
iptables: Too many links. 这表示自定义链有引用。,需要先拆除引用。
iptables -D INPUT 表示拆除引用,然后再执行上一条命令
iptables -X clean_invalid_packets
iptables: Directory not empty. 提示链非空,需要先清空这条自定义链
iptables -F clean_invalid_packets, 清空以后,在执行一次上面的命令
iptables -X clean_invalid_packets 这样就删除了这条自定义链。
[!] --syn: --tcp-flags SYN,ACK,FUB,RST SYN 开放三次握手的第一次,生产中会用到。
-p udp:可直接只用udp协议扩展模块的专用选项:
[!] --source-port:--sport port[:port]
[!] --destination-port:--dport port[:port]
示例:yum安装samba服务,mkdir -p /samba/data
配置:vim /etc/samba/smb.conf
[files]
comment = Files
path = /samba/data
public = yes
语法检查:testparm
创建用户:useradd centos
设定密码:smbpasswd -a centos
启动服务:systemctl start smb
systemctl start nmb
查看端口是否启动:ss -tunl
在另外一台主机上访问这台主机的共享目录
smbclient -L //192.168.199.152 -U centos
Enter centos's password:
Connection to 192.168.199.152 failed (Error NT_STATUS_UNSUCCESSFUL) 提示出现错误
再开启这台主机的samba服务的端口:
先将这台主机的防火墙默认规则改为接受
iptables -P INPUT ACCEPT 修改默认规则
iptables -P OUTPUT ACCEPT
另外的主机上再次访问共享目录
smbclient -L //192.168.199.152 -U centos
Enter centos's password:
Domain=[SAMBA] OS=[Windows 6.1] Server=[Samba 4.4.4]
Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
files Disk Files
IPC$ IPC IPC Service (Samba 4.4.4)
centos Disk Home Directories
Domain=[SAMBA] OS=[Windows 6.1] Server=[Samba 4.4.4]
Server Comment
--------- -------
LUFEI Samba 4.4.4
Workgroup Master
--------- -------
表示访问成功
这时,可以添加自定义的访问规则
iptables -A INPUT -d 192.168.199.152 -j REJECT 自定义修改默认规则为拒绝,
iptables -A OUTPUT -s 192.168.199.152 -j REJECT
再次访问这台主机的共享目录:
smbclient -L //192.168.199.152 -U centos
Enter centos's password:
Connection to 192.168.199.152 failed (Error NT_STATUS_UNSUCCESSFUL)
定义这种默认规则的好处:1、如果失误将规则清空的话,默认规则依然是ACCEPT ,不会影响访问。 2、本机对本机的通信并未阻止。使用ping 127.0.0.1可以测试;
现在开放本机的udp的137,138端口和tcp的139,445端口
iptables -I INPUT -d 192.168.199.152 -p udp --dport 137:138 -j ACCEPT
iptables -I OUTPUT -s 192.168.199.152 -p udp --sport 137:138 -j ACCEPT
iptables -I INPUT 2 -d 192.168.199.152 -p tcp --dport 139 -j ACCEPT
iptables -I INPUT 2 -d 192.168.199.152 -p tcp --dport 445 -j ACCEPT
iptables -I OUTPUT 2 -s 192.168.199.152 -p tcp --sport 445 -j ACCEPT
iptables -I OUTPUT 2 -s 192.168.199.152 -p tcp --sport 139 -j ACCEPT
再次使用另外的主机访问这台主机的共享目录
smbclient -L //192.168.199.152 -U centos
Enter centos's password:
Domain=[SAMBA] OS=[Windows 6.1] Server=[Samba 4.4.4]
Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
files Disk Files
IPC$ IPC IPC Service (Samba 4.4.4)
centos Disk Home Directories
Domain=[SAMBA] OS=[Windows 6.1] Server=[Samba 4.4.4]
Server Comment
--------- -------
LUFEI Samba 4.4.4
Workgroup Master
--------- -------
这时可以成功访问。
添加访问httpd 的控制规则:
[!] --icmp-type {type[/code]|typename} 互联网报文控制选项,比如ping命令 ICMP Types and Codes
0/0:echo reply
8/0: echo request
示例:如何开发ping请求
iptables -I INPUT 3 -d 192.168.199.152 -p icmp --icmp-type 8 -j ACCEPT 这时ping 的入栈规则,请求要设为8
iptables -I OUTPUT 2 -s 192.168.199.152 -p icmp --icmp-type 0 -j ACCEPT 响应要设为0
tcpdump -i eth1 -nn icmp 使用抓包工具可以查看请求和响应过程
tcpdump -i eno16777736 -nn 抓包命令
tcpdump -i eno16777736 -nn tcp port 22
显示扩展:必须使用-m选项指明要调用的扩展模块的扩展机制;
1、multiport
以离散或连续的方式定义多端口匹配条件,最多15个;
protocols: tcp, udp, udplite, dhcp and sctp. 支持的协议类型
[!] --source-ports:--sports port[,port|,port:port].. :指定多个源端口,port:port这种情况是只记录两个端口
[!] --destination-ports:--dports port[,port|,port:port]...:指定多个目标端口;port:port这种情况是只记录两个端口
[!] --ports port[,port|,port:port]...:当源端口和目标端口相同时,使用;
示例:
iptables -I INPUT -d 192.168.199.152 -p tcp -m multiport --dports 22,80,139,445,3306 -j ACCEPT
iptables -I OUTPUT -s 192.168.199.152 -p tcp -m multiport --sports 22,80,139,445,3306 -j ACCEPT
iptables -I INPUT 2 -d 192.168.199.152 -j REJECT
iptables -I OUTPUT 2 -s 192.168.199.152 -j REJECT
2、iprange
以连续地址块的方式来指明多个IP地址匹配条件;
[!] --src-range from [-to] 源地址范围
[!] --dst-range from [-to] 目标地址范围,本机有多个IP时,容易演示。
示例:iptables -I INPUT -d 192.168.199.152 -p tcp -m multiport --dports 22,80,139,445,3306 -m iprange --src-range 192.168.199.180-192.168.199.254 -j REJECT 表示拒绝180-254之间的地址访问152的主机的22,80,139,445,3306端口的服务。
3、time
This matches if the packet arrival time/date is within a given range. 控制时间
--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...] 指定周几,
--kerneltz: 使用内核配置时区而非默认UTC时间
示例:iptables -I INPUT -d 192.168.199.152 -p tcp --dport 80 -m time --timestart 09:00 --timestop 18:00 --weekdays 6,7 -j REJECT
4、string
This modules matches a given string by using some pattern matching strategy. 基于给定的匹配策略来检查模式,
--algo {bm|kmp}
bm = Boyer-Moore, kmp = Knuth-Pratt-Morris
[!] --string pattern
[!] --hex-string pattern 直接给定16进制格式
--from offset 偏移量,from不指定,表示检查整个报文
--to offset
示例:iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string 'GET/index.html' -j LOG
iptables -p udp --dport 53 -m string --algo bm --from 40 --to 57 --hex-string '|03|www|09|netfilter|03|org|00|'
示例:iptables -I OUTPUT -m string --algo bm --string "gay" -j REJECT
5、connlimit:限制单客户端最大并发连接数,
--connlimit-upto n: 限制的上限,小于等于n
--connlimit-above n: 限制的至少为n,大于n
示例:
allow 2 telnet connections per client host
iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT 仅检查新连接
you can also match the other way around:
iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-upto 2 -j ACCEPT
iptables -I INPUT -d 192.168.199.152 -p tcp --syn --dport 22 -m connlimit --connlimit-above 2 -j REJECT 最多允许两个ssh客户端同时连接本机 ,仅检查新连接。
6、limit: 限定速率,This module matches at a limited rate using a token bucket filter.令牌桶过滤器机制来完成过滤,
--limit rate[/second|/minute|/hour|/day]
--limit-burst number 空闲桶,limit峰值,最大容纳量,
iptables -I INPUT -d 192.168.199.152 -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 5 -j ACCEPT
iptables -I OUTPUT -s 192.168.199.152 -p icmp --icmp-type 0 -j ACCEPT
7、state 状态检测,运行检查内部状态,状态追踪功能机制:
The "state" extension is a subset of the "conntrack" module.
conntrack:探查内部连接状态
[!] --state state:
recognized: INVALID, ESTABLISHED, NEW, RELATED or UNTRACKED 五种状态
NEW:新连接请求;一般在入栈中放行,
ESTABLISHED:已建立的连接; 一般在入栈和出栈中放行。
INVALID: 无法识别的连接;
RELATED:相关联的连接,当前连接是一个新请求,但附属于某个已存在的连接;
UNTRACKED: 未追踪的连接;
state: conntrack
/proc/net/nf_ocnntrack
/proc/sys/net/nf_conntrack_max
示例:万能的匹配策略
iptables -A INPUT -d 192.168.199.152 -j REJECT
iptables -A OUTPUT -s 192.168.199.152 -j REJECT
iptables -I INPUT -d 192.168.199.152 -p tcp -m multiport --dports 22,80,139,445,3306 -m state --state NEW -j ACCEPT
iptables -I INPUT -m state --state ESTABLISHED -j ACCEPT
iptables -I OUTPUT -m state --state ESTABLISHED -j ACCEPT
iptables -I INPUT 2 -d 192.168.199.152 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT 开放禁ping的策略
以上示例就可更优化之前设置的限制策略。
iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
330 24472 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED
0 0 ACCEPT tcp -- * * 0.0.0.0/0 192.168.199.152 multiport dports 22,80,139,445,3306 state NEW
5 420 REJECT all -- * * 0.0.0.0/0 192.168.199.152 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
127 11680 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED
14 1176 ACCEPT icmp -- * * 192.168.199.152 0.0.0.0/0 icmptype 0
5 560 REJECT all -- * * 192.168.199.152 0.0.0.0/0 reject-with icmp-port-unreachable
规则调用逻辑:
当报文入栈以后,正常是在主链上检查报文的,如果主链上某条规则匹配到,跳转至其他链上的规则,则由其他链上的规则,自上而下进行检查,若在这条链上匹配到规则以后就会直接处理报文,若在这条链上没有匹配到规则,则会返回主链上再次自上而下匹配其他规则;
回顾:iptables规则
iptables [-t table] SUBCOMMAND [CHAIN] [PARAMETERS] [-m matchname [per-match-options]] [-j targetname [per-target-options]]
match:
multiport, iprange, time, connlimit, limit, string,
state:
conntrack:一般在服务器很繁忙的情况下不要开启这一项。
五中状态:NEW, ESTABLISHED, RELATED, INVALID, UNTRACKED
能追踪到的最大连接数量定义在:/proc/sys/net/nf_conntrack_max
追踪到的连接:/proc/net/nf_conntrack
iptables(3)
state扩展:
centos7:内核模块的装载,以下两个是可以调用state模块
nf_conntrack
nf_conntrack_ipv4
手动装载:
modprobe nf_conntrack_ftp
centos6:如何装载nf_conntrack模块
处理动作(跳转目标)
-j targetname [per-target-options]
简单target:
ACCEPT, DROP
扩展target:
REJECT
--reject-with type
icmp-net-unreachable, icmp-host-unreachable,
icmp-port-unreachable, icmp-proto-unreachable, icmp-net-prohibited,
icmp-host-prohibited, or icmp-admin-prohibited
LOG
turn on kernel
--log-level
--log-prefix
保存和载入规则:
保存:iptables-save
centos7的方法:iptables-save >/PATH/TO/somefile 直接从定向到文件。
centos6的方法:service iptables save = iptables-save >/etc/sysconfig/iptables 每次都是覆盖保存。
载入:iptables-restore < /etc/sysconfig/iptables 使用输入重定向。
-n, --noflush: 不清除原有规则,就是和已有的合并。
-t, --test:仅分析生成规则集,但不提交。
centos6: service iptables resttart
默认重载/etc/sysconfig/iptables文件中的规则。
配置文件:/etc/sysconfig/iptables-config
IPTABLES_MODULES="nf_conntrack_ftp" 开机加载ftp模块。
centos7开机自动载入:
1,自定义Unit File,进行iptables-restore;
2, firewalld服务;
3, 自定义脚本。
lsmod查看加载的模块
规则优化的思路:
1,使用自定义链管理特定应用的相关规则。
2,优先放行双方向状态为ESTABLEISHED的报文。
3,服务于不同类别的功能的规则,匹配到报文的可能性更大的放前面。
4,服务于同一类别的功能的规则,匹配条件较严格的放在前面。
5,设置默认策略,白名单机制:
iptables -P,不建议。
建议在规则的最后定义规则作为默认策略。
iptables/netfilter网络防火墙:
1,网关;
2,filter表的FORWARD链;
要注意的问题:
1, 请求-响应报文均会经由FORWARD链,要注意规则的方向性。
2,如果要启用conntrack机制,建议将双方向的状态为ESTABLISHED的报文直接报文。
目标地址时私网地址不能被互联网转发。
NAT:Network Address Translation 网络地址转换
请求报文:由管理员定义
响应报文:由NAT的conntrack机制自动实现
请求报文:
改原地址:SNAT 本地内网地址是客户端,访问远端的服务器端,只能发生在POSTROUTING,本机内部的私有地址发生在OUTPUT
改目标地址:DNAT 内网是服务端,远端是客户端,只能发生在PREROUTING,要指定某服务。
PNAT:port nat 端口地址转换。
iptables/netfilter:
NAT定义在nat表;
PREROUTING, INPUT, OUTPUT, POSTROUTING四个链上。
nat表的target分类:
SNAT:
This target is only valid in the nat table, in the POSTROUTING and INPUT chains, and user-defined chains which are only called from those chains.
--to-source [ipaddr[-ipaddr]] [:port[-port]] 多地址多端口转换。
DNAT:
This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains.
--to-destination [ipaddr[-ipaddr]][:port[-port]] 多地址多端口转换
MASQUERADE :地址伪装,拨号上网时,IP地址不固定,动态地址获取的,也是原地址转换的。可直行判断要转换为的地址。
This target is only valid in the nat table, in the POSTROUTING chain.
--to-ports [:port[-port]]
SNAT场景中应用于POSTROUTING链上的规则实现源地址转换,但外网地址不固定时,使用此target.
REDIRECT:端口重定向。
This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains.
--to-ports port[-port]
测试实例:利用iptables 做路由转发实验,并做防火墙策略。
转发服务并且是网络防火墙,6.8的两个地址分别为:内网IP:192.168.199.153,外网IP:172.16.73.135
内网的两台服务器7.2地址分别为:192.168.199.152;192.168.199.101
外网的服务器6.7地址为:172.16.73.120
1,首先设置路由服务器6.8,添加两块网卡;内网配置IP配置为192.168.199.153,外网地址配置为:172.16.73.135
ip addr add 172.16.73.153/16 dev eth0
ip addr add 192.168.199.135/24 dev eth1
2、配置6.7主机的网关为6.8的外网IP
配置7.2的两台主机的网关为6.8的内网IP。
7.2的两台主机使用vmnet1的网卡,
6.8主机的内网网卡使用vmnet1的网卡
6.7主机的网卡使用桥接,
6.8主机的外网网卡也使用桥接。
nmtui是centos7的图形界面网卡配置。
7.2主机配置网IP后,重启网卡就可以,不要重启网络。
ip link set eno16777736 down
ip link set eno16777736 up
或者添加默认路由:route add default gw 192.168.199.153
6.7主机添加网关
route add default gw 172.16.73.135
route del -net 0.0.0.0 gw 172.16.0.1
测试一下:
7.2主机使用ping命令:
ping 172.16.73.135 看是否能通
ping 192.168.199.153
6.7主机使用ping命令测试:
ping 192.168.199.153 看是否能通
经过测试可以通。
ip route show 查看网关指向。
3、测试一下7.2主机是否能ping通6.7主机
ping 172,16,73,120 结果是不通,
可以在6.7上使用抓包功能看一下是否有7.2主机的包
tcpdump -i eth1 -nn 结果没有。
4,在6.8主机上开通路由转发功能
cat /proc/sys/net/ipv4/ip_forward 的内容是1还是0, 0表示没开启路由转发,1表示已经开启路由转发功能。
echo 1 > /proc/sys/net/ipv4/ip_forward 表示开启了路由转发功能。
或使用:sysctl -w net.ipv4.ip_forward=1
tcpdump -i eth1 -nn icmp 再抓包查看。
-X 显示16进制格式内容。
以上的配置为路由功能,路由转发的过程。
5、在6.7服务器上配置一个httpd服务 yum -y install httpd vsftpd
并编辑一个网页内容
vim /var/www/html/index.html
<h1>www.lufei.com</h1>
service httpd start 启动服务
并在浏览器查看内容。或使用curl命令查看。
curl http://172.16.73.120
service vsftpd start
6、在6.8主机上设置防火墙的forword链,来控制6.7主机上的哪些服务允许7.2访问,哪些不允许访问。
centos6系统需要配置的地方
配置文件:/etc/sysconfig/iptables-config
IPTABLES_MODULES="nf_conntrack_ftp" 开机加载ftp模块。
如果是centos7的系统,需要关闭firewalld的服务。systemctl stop firewalld。
01、先在6.8上设置默认拒绝所有服务的规则
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
02、开放7.2可以访问6.7的web服务
在6.8主机上添加请求转发的规则:iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp --dport 80 -j ACCEPT 添加请求的入链规则,这里只知道目标端口是80,所以使用--dport 80.
7.2主机curl http://172.16.73,120 测试是否有响应。
6.7主机tcpdump -i eth1 -nn tcp port 80 抓包测试一下
tail /var/log/httpd/access_log 也可以查看httpd的日志
在6.8添加响应转发的规则:
ptables -A FORWARD -s 172.16.0.0/16 -d 192.168.199.0/24 -p tcp --sport 80 -j ACCEPT 将源地址和目标地址改一些,修改成源端口 --sport ,这里只知道源端口是80,目标端口不知道,所有只设定源端口就可以。
测试:
7.2主机curl http://172.16.73,120 测试是否有响应。
6.7主机tcpdump -i eth1 -nn tcp port 80 抓包测试一下
03、添加其他服务访问,例如ftp, mysql, ssh等
iptables -I FORWARD 1 -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp -m multiport --dports 80,22,3306,20,21 -j ACCEPT
iptables -I FORWARD 2 -s 172.16.0.0/16 -d 192.168.199.0/24 -p tcp -m multiport --sports 80,22,3306,20,21 -j ACCEPT
再次测试:方法同02步骤
04、添加ping 请求
iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p icmp --icmp-type 8 -j ACCEPT
iptables -A FORWARD -s 172.16.0.0/16 -d 192.168.199.0/24 -p icmp --icmp-type 0 -j ACCEPT
以上两条实现7.2主机可以ping通6.7主机的规则。
05、添加ftp服务规则:
iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT 这里要去掉端口。以上两条是ftp入栈的规则。
iptables -A FORWARD -d 172.16.0.0/16 -s 192.168.199.0/24 -p tcp -m state --state ESTABLISHED -j ACCEPT 这一条是响应的规则
06、查看链接记录:
cat /proc/net/nf_conntrack
07、保存iptables 规则记录
iptables-save > /tmp/iptables.rules.1
然后清空iptables -F
7、重新写一个规则,使用-m state,为了简化规则条数。
01、添加默认规则
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT 保持现状的默认规则,也就是都不放行。
iptables -A FORWARD -s 192.168.199.0/24 -d 172.16.0.0/16 -p tcp -m multiport --dports 22,21,80,3306 -m state --state NEW -j ACCEPT 放行这些服务。
iptables -A FORWARD -p icmp -m state --state NEW -j ACCEPT
放行ping操作。
8、添加本机的ssh服务
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m state --state NEW -j ACCEPT
私网地址不能直接被公网地址访问,必须通过网关转发才能实现。
目标地址转换实验,源端口和目标端口转换实验。解决安全问题,还有解决公网地址不够用的问题。
6.7主机是远程互联网主机,7.2是本机的内网主机,6.8是路由主机且是网络防火墙服务器
6.7 IP:172.16.73.120
7.2 IP:192.168.199.152
7.2 IP:192.168.199.101
6.8 IP内网:192.168.199.153
6.8 IP内网:172.16.73.135
1、iptables -F 清空所有规则
iptables -A INPUT -j ACCEPT
iptables -A OUTPUT -j ACCEPT
iptables -A FORWARD -j ACCEPT
以上是设置默认规则都允许的。
iptables -t filter -vnL
iptables -t nat -vnL
查看filter和nat 表的规则。
2、使用7.2主机访问6.7主机。让显示的IP结果为6.8的外网地址,实现源地址转换。
01、先测试一下不做源地址转换时,6.7服务器查看来访IP是什么
curl http://172.16.73.120
tail /var/log/httpd/access_log
02、在6.8上做源地址转换,在6.8主机上操作
iptables -t nat -A POSTROUTING -s 192.168.199.9/24 -j SNAT --to-source 172.16.73.135
回应时是自动做的转换。不需要再添加规则。
03,只允许7.2访问6.7的web服务,实现方式:白名单(先将默认规则设置为DROP)或黑名单(先将默认规则设置为ACCEPT)。
A、白名单实现方式:
iptables -P FORWARD DROP :设置FORWARD链为全部拒绝。
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT 允许所有已建立的连接
iptables -A FORWARD -s 192.168.199.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT 允许第一次访问web的新建的连接。
iptables -t filter -F
iptables -t nat -F
iptables -P FORWARD ACCEPT
3、使用MASQUERADE做源地址转换,在静态场景中不建议使用。
01、默认规则不变
02、iptables -t nat -A POSTROUTING -s 192.168.199.0/24 -j MASQUERADE
4,DNAT示例:目标地址转换
iptables -t nat -A PREROUTING -d 172.16.73.135 -p tcp --dport 22 -j DNAT --to-destination 192.168.199.152
iptables -A FORWARD -s 172.16.249.12 -j DROP 拒绝这台主机访问。
5、
7.2主机是内网段IP,需要安装软件,但yum厂库在外网,需要在6.8的路由服务上做源地址转换来实现
iptables -t nat -A POSTROUTING -s 192.168.199.0/24 -j SNAT --to-source 172.16.73.135
6、7.2的两台主机是一台内网的web服务,一台ssh服务,其中一台199.152的web服务的监听端口是8080,一台199.101的ssh端口是22,但是外网用户访问这个web服务器时,访问的是192.168.199.152:8080端口,但是这时是内网IP,互联网无法访问,所以就需要让外网6.7直接访问6.8这台连接外网的服务器,但是这台服务器是没有web服务的,所以就需要做目标地址转换和接口映射,所以6.7就是访问172.16.73.135:80地址时,就会直接映射到192.168.199.152:8080 。同理:6.7的外网要连接101主机的ssh服务,也需要在6.8上做目标地址转换和端口映射。
实现方案:
01、
修改两台web服务器的监听端口后重启web服务
vim /etc/httpd/conf/httpd.conf
Listen 8080
Listen 808
service httpd restart
systemctl restart httpd.service
02、
iptables -t nat -A PREROUTING -d 172.16.73.135 -p tcp --dport 80 -j DNAT --to-destination 192.168.199.152:8080 将目标地址135转换为152的地址,并将135的80端口映射为152的8080端口
iptables -t nat -A PREROUTING -d 172.16.73.135 -p tcp --dport 22012 -j DNAT --to-destination 192.168.199.101:22 将135的ssh的端口映射为101主机的22端口,并将其目标地址转换为101地址
03、测试
在6.7主机使用curl http://172.16.73.137:80(默认端口可以省略)
然后就直接返回了192.168.199.152的主页,这就实现了目标地址转换和端口映射的功能。
ssh -p 22012 root@172.16.73.135 会直接映射到192.168.199.101的ssh的22端口
补充:利用iptables 的recent模块来抵御DOS攻击:22,建立一个列表,保存有所有访问过指定的服务的客户端IP
ssh: 远程连接。
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
1、利用connlimit模块将单IP的并发设置为3, 会误杀使用NAT上网的用户,可以根据实际情况增大该值。
2、利用recent和state模块限制单IP在300s内只能与本机建立2个新连接,被限制五分钟后即可恢复访问。
下面对最后两句做一个说明:
1,第二句是记录访问TCP 22端口的新连接,记录名为SSH
--set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目。
2, 第三句是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。
--update: 是指每次建立连接都更新列表。
--seconds 必须与--rcheck或者--update同事使用。
--hitcount 必须与--rcheck或者--update同时使用。
3.iptables的记录: /proc/net/xt_recent/SSH
也可以使用下面的这句记录日志:
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "