Iptables 实例收藏

#!/bin/sh
#
modprobe ipt_MASQUERADE
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
iptables -F
iptables -t nat -F
iptables -X
iptables -t nat -X
###########################INPUT链###################################
iptables -P INPUT DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 110,80,25 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.0.0/24 --dport 139 -j ACCEPT
#允许内网samba,smtp,pop3,连接

iptables -A INPUT -i eth1 -p udp -m multiport --dports 53 -j ACCEPT
#允许dns连接

iptables -A INPUT -p tcp --dport 1723 -j ACCEPT
iptables -A INPUT -p gre -j ACCEPT
#允许外网vpn连接

iptables -A INPUT -s 192.186.0.0/24 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i ppp0 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP
#为了防止DOS太多连接进来,那么可以允许最多15个初始连接,超过的丢弃

iptables -A INPUT -s 192.186.0.0/24 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP
#为了防止DOS太多连接进来,那么可以允许最多15个初始连接,超过的丢弃

iptables -A INPUT -p icmp -m limit --limit 3/s -j LOG --log-level INFO --log-prefix "ICMP packet IN: "
iptables -A INPUT -p icmp -j DROP
#禁止icmp通信-ping 不通

iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/24 -j MASQUERADE
#内网转发

iptables -N syn-flood
iptables -A INPUT -p tcp --syn -j syn-flood
iptables -I syn-flood -p tcp -m limit --limit 3/s --limit-burst 6 -j RETURN
iptables -A syn-flood -j REJECT
#防止SYN攻击 轻量

#######################FORWARD链###########################
iptables -P FORWARD DROP
iptables -A FORWARD -p tcp -s 192.168.0.0/24 -m multiport --dports 80,110,21,25,1723 -j ACCEPT
iptables -A FORWARD -p udp -s 192.168.0.0/24 --dport 53 -j ACCEPT
iptables -A FORWARD -p gre -s 192.168.0.0/24 -j ACCEPT
iptables -A FORWARD -p icmp -s 192.168.0.0/24 -j ACCEPT
#允许 vpn客户走vpn网络连接外网

iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I FORWARD -p udp --dport 53 -m string --string "tencent" -m time --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的8:00-12:30禁止qq通信

iptables -I FORWARD -p udp --dport 53 -m string --string "TENCENT" -m time --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的8:00-12:30禁止qq通信

iptables -I FORWARD -p udp --dport 53 -m string --string "tencent" -m time --timestart 13:30 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
iptables -I FORWARD -p udp --dport 53 -m string --string "TENCENT" -m time --timestart 13:30 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的13:30-20:30禁止QQ通信

iptables -I FORWARD -s 192.168.0.0/24 -m string --string "qq.com" -m time --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的8:00-12:30禁止qq网页

iptables -I FORWARD -s 192.168.0.0/24 -m string --string "qq.com" -m time --timestart 13:00 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的13:30-20:30禁止QQ网页

iptables -I FORWARD -s 192.168.0.0/24 -m string --string "ay2000.net" -j DROP
iptables -I FORWARD -d 192.168.0.0/24 -m string --string "宽频影院" -j DROP
iptables -I FORWARD -s 192.168.0.0/24 -m string --string "色情" -j DROP
iptables -I FORWARD -p tcp --sport 80 -m string --string "广告" -j DROP
#禁止ay2000.net,宽频影院,色情,广告网页连接 !但中文 不是很理想

iptables -A FORWARD -m ipp2p --edk --kazaa --bit -j DROP
iptables -A FORWARD -p tcp -m ipp2p --ares -j DROP
iptables -A FORWARD -p udp -m ipp2p --kazaa -j DROP
#禁止BT连接

iptables -A FORWARD -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 24

#######################################################################
sysctl -w net.ipv4.ip_forward=1 &>/dev/null
#打开转发
#######################################################################
sysctl -w net.ipv4.tcp_syncookies=1 &>/dev/null
#打开 syncookie (轻量级预防 DOS 攻击)
sysctl -w net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=3800 &>/dev/null
#设置默认 TCP 连接痴呆时长为 3800 秒(此选项可以大大降低连接数)
sysctl -w net.ipv4.ip_conntrack_max=300000 &>/dev/null
#设置支持最大连接树为 30W(这个根据你的内存和 iptables 版本来,每个 connection 需要 300 多个字节)
#######################################################################
iptables -I INPUT -s 192.168.0.50 -j ACCEPT
iptables -I FORWARD -s 192.168.0.50 -j ACCEPT
#192.168.0.50是我的机子,全部放行!
############################完#########################################

Iptables – 记录日志

Iptables工作在内核。

Iptable可以使用LOG来记录日志,但是还需要syslog服务能处理它。

系统日志配置

CentOS5 — syslog, /etc/syslog.conf
CentOS6 — rsyslog,/etc/rsyslog.conf

1. 在rsyslog.conf 添加配置
/etc/rsyslog.conf中添加不同的日志级别(默认warn(=4))

kern.warning     /var/log/iptables.log
kern.debug       /var/log/iptables.log
kern.info        /var/log/iptables.log

kern.*           /var/log/iptables.log

重启服务:/etc/init.d/rsyslogd restart

2. 日志滚动(可选)

vim /etc/logrotate.d/syslog
#添加
/var/log/iptables

3. 在Iptables添加日志选项

iptables -A INPUT  -j LOG --log-prefix "iptables"

保存配置

iptables-save
iptables-restart

Iptables – 应用实例 – 修改出口数据包的默认IP

服务器有多IP,如果服务器发起请求,外网看到的来源IP总是服务器的第一个(或默认)IP。

有些工具,我们希望它出去的数据包的源IP不是默认IP,期望是指定IP。 这里涉及到了修改数据包的源IP,需要依靠Iptables来完成。

这里的问题是,某工具发起的数据包,怎么标记它? 最终要的是,某工具发起的数据包,把源地址修改为指定地址。Iptables中并没有办法识别某某工具发起的数据包,但是可以识别是某用户发起的数据包,所以可以指定某个用户运行某个工具,只要是这个用户发起的数据包,就标记一下,然后在路由后把源地址修改掉。

# 添加用户
# 接收6666端口进来的数据(这个步骤不是必须的)
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 6666 -j ACCEPT
# 用户6666发出的数据,修改数据包,添加6666标记
iptables -t mangle -A OUTPUT -m owner --uid-owner 6666 -j MARK --set-mark 6666
# 对于标记了6666的数据,源地址修改为x.x.x.x
iptables -t nat -A POSTROUTING -m mark --mark 6666 -j SNAT --to-source x.x.x.x

看起来,后面两天语句可以写成一条:(把用户6666的数据源地址修改为x.x.x.x)

iptables -t nat -A POSTROUTING -m owner --uid-owner 6666 -j SNAT --to-source x.x.x.x

Iptables – NAT实验

Host3中添加默认路由:

# 如果配置IP时已经配置了网关,这个步骤忽略
route add defalut gw 172.16.109.129

在Host3中ping Router1的172.16.195.131是不通,那是因为响应数据没有返回路由。

Router1中添加默认网关(响应数据)

route add default gw 172.16.195.132

在Host3中ping Router1的172.16.195.131是可以正常通信。

在Router2中添加:(把来源是172.16.109.0/24的数据包来源改为172.16.195.132)

iptables -t nat -A POSTROUTING -o eht0 -s 172.16.109.0/24 -j SNAT --to 172.16.195.132

如果在Router1中拦截目标为172.16.195.132的数据包,那么Host3中ping Router1的172.16.195.131将无法得到响应。因为这个时候发送的响应包目标就是172.16.195.132。

iptables -A OUTPUT -d 172.16.195.132 -j REJECT

在Host3中ping 172.16.195.131,数据无法响应,说明响应地址为172.16.195.132,数据被拦截(也说明了源地址被修改)。

由于被修改了源地址,那么响应数据包目标都是172.16.195.132,对于172.16.195.131来说,是内网通信,不需要在Router1上设置网关(原来需要设置网关把数据送回来)。

iptables -D OUTPUT -d 172.16.195.132 -j REJECT
route del default

Host3上ping 172.16.195.131,数据正常响应。说明响应数据目标是172.16.195.132。

由于修改了源地址,响应时到达Router2,这时Router2必须把目标地址对应回去,Ping得到响应就已经说明自动进行了DNAT。

在实际的环境中,Router2可能有多个出口网卡(多WAN),或一个WAN上分配了多个IP(虚拟WAN),这个时候出去的IP就有多个,这时需要做修改:

iptables -t nat -A POSTROUTING -o eth0 -s 172.16.109.0/24 -j SNAT --to-source 172.16.195.132-172.16.195.142

WAN上的IP可能不是静态分配的,比如是通过拨号产生的,所以分配的IP地址会发送变化,所以以上的做法无法满足这个情况,需要使用MASQUERADE:

iptables -t nat -A POSTROUTING -o eth0 -s 172.16.109.0/24 -j MASQUERADE

这里的MASQUERADE是指伪装,具体来说就是把源IP改为eth0网卡一样的地址(出口接口),这样就实现了动态绑定。

DNAT

DNAT是修改目标地址,修改地址时还可以修改端口号。所以一般的应用场景是内网IP或端口映射到外网IP或端口。
在Router1上添加映射关系:

iptables -t nat -A PREROUTING -d 172.16.108.129 -p tcp -m tcp --dport 80 -j DNAT --to-destination 162.16.195.130:80 

当访问172.16.108.129的80端口时,修改目标为162.16.195.130的80端口,这样数据就进入到162.16.195.130这个机器。

如果不指定端口号,那么就是针对地址,目标地址可以指定一个段:

iptables -t nat -A PREROUTING -d 172.16.108.129 -j DNAT --to-destination 162.16.195.130-162.16.195.140 

访问到达172.16.108.129的数据包,表修改为162.16.195.130-162.16.195.140段中的其中一个IP,这个场景用法,加上转发时使用规则(主要设置权重),那就可以做一个简单的负载均衡集群。

REDIRECT
REDIRECT也是NAT的内容,不过REDIRECT修改的是目标端口号(也涉及到修改数据包地址),由于只是修改目标端口号,所以它是本机端口转发。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j redirect --to-ports 8080

主要注意的是这里的端口转发,端口自然是要开放的,否则数据无法进来,端口转发不过是把某个端口的数据改为另一个端口而已。

SNAT是数据出去时修改源地址,所以应该是NAT表的POSTROUTING链中进行。DNAT和REDIRECT都是在进入进入时对目标地址或端口进行修改,所以需要在NAT表的PREROUTING链中进行。

Iptables工作原理与实践

Iptables默认有5条链,这些链按照表(table)来进行组织:

表:
	raw			数据跟踪
	mangle		数据表修改
	nat			网络地址转换
	filter		包过滤(用最多)
链:
	prerouting
	input
	forward
	output
	postrouting

表链对应关系:
	raw
		prerouting
		output
		postrouting
	mangle
		prerouting
		input
		forward
		output
		postrouting
        nat
		prerouting
		output
		postrouting
	filter
		input
		forward
                output

链表对应(看上图)

数据包经过的链是在内核空间中进行的。数据包只会经过链,表是提供功能的分类,举例说就是如果要操作地址端口映射,需要操作nat表,nat表只能往prerouting,output,postrouting这三个链上添加规则,如果要操作包过滤,需要操作filter表,filter表只能往input,forward,output的链上添加规则。

比如这里都往output链上添加了规则,就需要区分优先级,规则总是根据表定位链然后往链上附加规则的,所以规则是属于什么链和什么表是已知的。按照表优先级:raw – manage – nat – filter,所以通过nat表添加到output链上的规则,优于通过filter表添加到output链上的规则。

另外,表是根据功能划分的,比如需要操作地址转换,必须通过nat表操作,通过其它表是无法操作(表现为某些命令选项不能用,或者说是某些命令选项是针对特定表的)

数据包进入时会到达内核空间,首先执行prerouting链上的规则,然后判断数据包的目标是否是本机,如果是就进入input链,否则就进入forward链。

# CentOS 7 中关闭默认的firewall防火墙,和iptables冲突
systemctl stop firewalld.service
systemctl disable firewalld.service

# CentOS 7 安装iptables服务
yum install iptables
yum install iptables-services

# CentOS 7 中启动服务 
systemctl start iptables.service
systemctl enable iptables.service

# CentOS 7 以下版本
service iptables restart
chkconfig iptables on

Iptables启动总时会读取/etc/sysconfig/iptables文件,需要注意表的默认策略,可以使用iptables -F刷新所有规则,然后使用iptales-save保存(会在/etc/sysconfig下面产生iptables.old, iptables文件)

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*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 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

这是默认配置,INPUT和FORWARD和OUTPUT默认都是ACCEPT,如果修改过就需要注意。后面的中括号表示经过这个链的数据包和字节数。默认的规则是运行已经建立了链接的数据进来,允许icmp协议,允许lo接口数据进来,运行链接22端口,其它的全部禁止。建议先把规则去掉。

命令使用格式:

#格式
iptables -t table command chain parameter target

###########
table
	raw
	mangle
	nat
	filter
command
	-A 在指定链尾巴添加规则(append)
	-D 删除匹配的规则
	-I 在指定位置插入规则(iptables -t filter -I INPUT 1 --dport 80 -j ACCEPT)
	-R 替换匹配的规则
	-L 显示列表规则(--list)
	-n 地址和端口号以数字方式显示
	-F 刷新规则(--flush)
	-Z 将指定链或所有链的计数器清零
	-N 创建自定义链(iptables -N allowed)
	-X 删除自定义链
	-E 更改自定义链的名称(iptables -E allowed disallowed,从什么改为什么)
	-P 修改默认策略(对自定义链不起作用 iptales -P OUTPUT DROP)
chain
	INPUT
	FORWARD
	OUTPUT
	PREROUTING
	POSTROUTING
parameter
	-p	
		TCP
		UDP
		ICMP
		/etc/protocols中定义的列表
		all
	-s
		网络名称
		主机名称
		子网(192.168.0.0/24, 192.168.0.0/255.255.255.0)
		IP地址
	-d
		网络名称
		主机名称
		子网(192.168.0.0/24, 192.168.0.0/255.255.255.0)
		IP地址	
	-i	--匹配入口网卡(只能在PREROUTING INPUT FORWARD)
		接口名称(etho)
		以+结尾的接口名称
	-o	--匹配出口网卡(FORWARD POSTROUTING OUTPUT)
		接口名称(etho)
		以+结尾的接口名称
	--sport
		服务名称
		端口号
		端口范围(1024:65535)
	--dport
		服务名称
		端口号
		端口范围(1024:65535)
	--icmp-type
		ICMP类型(用iptables -p icmp -h可查看)
	--tcp-flags mask xxx
		匹配TCP标记,mask表示检查范围,xxx表示匹配mask中的哪些标记
		(iptables -A FORWARD -p tcp --tcp-flags ALL SYN,ACK -j ACCEPT)
target
	-j ACCEPT
	-j DROP
	-j REJECT
	-j REDIRECT 目标端口转换(iptables -t nat -D PREROUTING -p tcp -dport 8080 -i eth2.2 -j REDIRECT -to 80)
	-j MASQUERADE
	-j LOG 
	-j DNAT 目标地址转换 (iptables -t nat -A PREROUTING -d 202.202.202.202 -j DNAT -to-destination 192.168.1.100)
	-j SNAT 源地址转换(iptables -t nat -A POSTROUTING -d 192.168.1.100 -j SNAT -to 192.168.1.1)
	-j MIRROR 
	-j QUEUE 
	-j RETURN 
	-j MARK 将数据包打上标记(iptables -t mangle -A PREROUTING -s 192.168.1.3 -j MARK --set-mark 60)

定义表的链的默认策略
默认策略针对链,也针对表。同样根据优先级来执行。默认测试只有ACCEPT和DROP,可以理解为链中的规则不符合时,执行什么策略(接受或丢弃)。 对应一个链对应对个表的情况,如果默认策略不同,可能遇到问题。默认情况设置的是ACCEPT,而且一般只需要针对filter表中的链进行操作。

iptables -t filter -P INPUT 

使用实例:

#1 显示filter表链与链规则(默认不指定表就是filter表)
iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination  

# 2 查看NAT表
iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination  

 

Linux中的路由

cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=172.16.108.128
NETMASK=255.255.255.0
GATEWAY=172.16.108.129


route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.16.108.0	0.0.0.0		255.255.255.0	U     0      0        0 eth0
169.254.0.0	0.0.0.0		255.255.0.0	U     1002   0        0 eth0
0.0.0.0         172.16.108.129  0.0.0.0         UG    0      0        0 eth0

这里的最后一条就是默认路由,表示到达任意网络(目标0.0.0.0表示任意,掩码0.0.0.0表示0位掩码,相当0.0.0.0/0),Flags后面带有G的表示是网关,Gateway地址必须是本机可达的地址。

但是第一和第二条路由就有点看不明白,尤其第二条。

注意到如果有多网卡,169.254.0.0这个路由会出现多次。实际上,Gateway是0.0.0.0(或“*”)是本地直通路由,直接对应接口,不需要网关(所以是0.0.0.0)。准确来说,这里是指定了172.16.108.128这个IP地址,于是产生了172.16.108.0这条直通路由(直接到达eth0接口)。而指定的网关未172.16.108.129则自动产生了默认路由。

169.254.0.0这个直通路由时在使用DHCP分配IP时,在分配失败时,主机会自动分配一个169.254.0.0网段的和其它主机不重复的IP地址,所以就产生了这个路由。
如果不希望出现这个路由,只需要保证不分配这种IP即可:

vi /etc/sysconfig/network-scripts/ifcfg-eth0

NOZEROCONF=yes

这样就不会分配这种地址,自然也不会产生这种默认路由了。

Route命令的输出项说明

输出项
Destination	目标网段或者主机
Gateway		网关地址,”0.0.0.0”或“*”,表示目标是本主机所属的网络,不需要路由(通常意味着本机直通路由)
Genmask		网络掩码
Flags		标记
		U 路由是活动的
		H 目录是一个主机
		G 路由指向网关
		R 
		D
		M
		! 拒绝路由
Metric		路由距离
Ref		路由项引用次数
Use 		此路由项被路由软件查找的次数
Iface		该路由表项对应的输出接口

路由类型
1 主机路由
目标是一个IP地址,Flags有H标记。
2 网络路由
目标是一个网络,经过网关,Flags有G标记。直通路由也是网络路由,网关是0.0.0.0,Flags没有G,可以认为就是专门为网卡IP而设置的路由。
3 默认路由
目标是0.0.0.0,经过网关,Flags有G标记

注:路由匹配有顺序,最匹配的优先,所以目标是0.0.0.0的路由放最后。


配置静态路由

# route  [add|del] [-net|-host] target [netmask Nm] [gw Gw] [[dev] If]
    add : 添加一条路由规则
    del : 删除一条路由规则
    -net : 目的地址是一个网络
    -host : 目的地址是一个主机
    target : 目的网络或主机
    netmask : 目的地址的网络掩码
    gw : 路由数据包通过的网关
    dev : 为路由指定的网络接口

# 添加主机路由

# 添加网络路由
route add -net 10.10.10.0 netmask 255.255.255.0 eth0
route add -net 10.10.10.0 netmask 255.255.255.0 gw 10.10.10.254
route add -net 10.10.10.0/24 eth1

# 添加默认路由
route add default gw 10.10.10.254

# 删除路由
route del default gw 192.168.1.1

场景一:单个路由器,一个外网一个内网
外网:172.16.108.0/24
内网:172.16.195.0/24

关注设备:Host1 Router1 Host2
Host1网关设置为172.16.108.129, Host2网关设置为172.16.195.131。Router1只配置IP地址,不设置网关。

Router1上开启IP转发就可以实现两个网段互通:

#
vi /etc/sysctrl.conf
net.ipv4.ip_forward = 1

#修改生效
sysctl -p

每个接口配置IP时都分配了接口路由(直通路由,理解为接口所在的网络,直接从接口出去),这种和网关路由有本质不一样,接口路由是本机接口之间的包转发,而网关路由是把数据吧发送到网关。

当172.16.195.130向172.16.108.128发送数据时,数据首先发送到172.16.195.131这个网关,网关接收到数据后发现不是本机地址,直接转发,然后选择路由,得到172.16.108.129所在的接口,然后把数据发送出去(这里类似中介,什么不做,仅仅过手了一道而已)。 注:这里的接口路由就发挥了作用。

当172.16.195.130向172.16.108.129发送数据时,情况有点不同,数据首先发送到172.16.195.131这个网关,网关接收到数据后发现是本机地址(不转发),进行路由选择,匹配到172.16.108.129的接口路由,数据从接口路由的接口输出给用户空间,用户空间响应数据,选择172.16.195.131这个接口路由把数据送回去。

所以,路由链接的两个网络,是互通的。这个模型的应用主要是NAT方案,假设172.16.195.0是内网,172.16.109.0是外网,路由器上的eth1接口的IP地址必须是公网IP,所以路由器需要以某种方式从运营商那边取到这个公网IP(拨号或者静态分配,静态分配跟这里的模型一样。拨号的结果是给接口分配IP,由于信号要进行远程传输,所以还需要一个转换设备),所有从内网过来的数据,需要把来源地址更换为这个公网IP,因为内网的数据包来源不是公网IP,无法在公网路由中传递。这里描述的就是SNAT,另一让人困惑的地方是:这种方式出去的数据包,响应时如何进入内网,实际上SNAT会把数据包的目标地址自动修改为数据包到达时未修改前的来源地址,接下来是就是路由器的路由选择问题。

如果路由器有多个外网口(多wan,或虚拟多个wan),然后在多个wan口上取到公网IP后,数据从内网到达路由器时,会选择路由,这时可能产生随机匹配,那么上行将产生叠加,具体说就是一个文件分成了10个包,有10个wan口,那么这10个包同时从10个口出去,原来是一个个传,这里是批量传。 所以这里涉及到负载均衡的问题,比如某个或某些内网从某个wan口出去,另一些从另一个口出去。多wan口,路由器性能就有一些要求。

主要注意的是:如果内网就是公网IP,不需要SNAT,但是还是涉及负载均衡的问题,负载均衡的问题实际是一个路由选择问题。

另外,如果需要把内网的服务器对外开放时,需要在路由器上做DNAT,就是外部访问路由器时,路由器把IP修改为内网服务器IP地址,内网服务响应数据到路由器时,路由自动把数据包的源地址修改回来。

可见,SNAT后的响应数据会自动进行DNAT,而DNAT出去的数据会自动进行SNAT。

场景二:内网中接一个路由器,实现网络隔离,构建专用网络。
在Host3配置IP为172.16.109.128,网关配置为172.16.109.129。Router2中配置一条目录默认路由,网关指定为Router1的172.16.195.131。

这样172.16.109.0网络的数据就可以正常送到Router1,Router1再把数据送出去,响应数据到达Router1后,需要路由到Router2,所以需要在Router1中把建一条默认路由,把数据路由到Router2的172.16.195.132。

由于现在的智能路由器基本都是NAT路由器,所以内网接入路由,就跟正确配置一台机器的IP一样(正确设置网关,上层路由器的内网IP)。而上层路由器也不需要设置默认路由,因为NAT会修改目标地址。进入到子路由器时,子路由器NAT继续修改目标地址。

Fail2ban工具实践

Fail2ban可以监视系统日志,然后匹配日志的错误信息(正则式匹配)执行相应的屏蔽动作,而且可以发送邮件。

官网地址http://www.fail2ban.org
下载:
https://github.com/fail2ban/fail2ban

在Centos中,使用YUM安装:

#CentOS内置源并未包含fail2ban,需要先安装epel源
yum install epel-release
#安装fail2ban
yum install fail2ban
#确认安装
rpm -qa | grep fail
fail2ban-0.9.7-1.el7.noarch
fail2ban-server-0.9.7-1.el7.noarch
fail2ban-firewalld-0.9.7-1.el7.noarch
fail2ban-sendmail-0.9.7-1.el7.noarch

#确认安装
rpm -ql fail2ban-0.9.7-1.el7.noarch
(没有包含文件)

#确认安装
rpm -ql fail2ban-server-0.9.7-1.el7.noarch
/etc/fail2ban
/etc/fail2ban/action.d
/etc/fail2ban/action.d/*	-----动作文件夹 
/etc/fail2ban/fail2ban.conf    	-----日志级别、日志位置及Sock文件位置
/etc/fail2ban/fail2ban.d
/etc/fail2ban/filter.d
/etc/fail2ban/filter.d/*	------匹配规则
/etc/fail2ban/jail.conf		------主配置文件
/etc/fail2ban/jail.d
/etc/fail2ban/paths-common.conf
/etc/fail2ban/paths-debian.conf
/etc/fail2ban/paths-fedora.conf
/etc/fail2ban/paths-freebsd.conf
/etc/fail2ban/paths-opensuse.conf
/etc/fail2ban/paths-osx.conf
/etc/logrotate.d/fail2ban
/run/fail2ban
/run/fail2ban/fail2ban.pid
/usr/bin/fail2ban-client
/usr/bin/fail2ban-python
/usr/bin/fail2ban-regex
/usr/bin/fail2ban-server
/usr/lib/python2.7/site-packages/fail2ban
/usr/lib/systemd/system/fail2ban.service
/usr/lib/tmpfiles.d/fail2ban.conf
/var/lib/fail2ban

#确认安装
rpm -ql fail2ban-firewalld-0.9.7-1.el7.noarch
/etc/fail2ban/jail.d/00-firewalld.conf

#确认安装
rpm -ql fail2ban-sendmail-0.9.7-1.el7.noarch
/etc/fail2ban/action.d/sendmail-buffered.conf
/etc/fail2ban/action.d/sendmail-common.conf
/etc/fail2ban/action.d/sendmail-geoip-lines.conf
/etc/fail2ban/action.d/sendmail-whois-ipjailmatches.conf
/etc/fail2ban/action.d/sendmail-whois-ipmatches.conf
/etc/fail2ban/action.d/sendmail-whois-lines.conf
/etc/fail2ban/action.d/sendmail-whois-matches.conf
/etc/fail2ban/action.d/sendmail-whois.conf

关键文件说明:
1 /etc/fail2ban/fail2ban.conf
这个配置文件是对Fail2ban进程的配置文件,主要是日志级别位置及Sock文件位置等,一般不需要修改,如果需要修改,可以在/etc/fail2ban下建立/etc/fail2ban/fail2ban.local,然后覆盖对应的值。按照惯例,也可以在/etc/fail2ban/fail2ban.d/下建立对应的文件进行覆盖。

2 /etc/fail2ban/paths-xxxx.conf
这里的输入的日志文件,根据系统不同,会被对应包含到/etc/fail2ban/jail.conf中,覆盖原则也是一样的,可以建立paths-xxx.local文件

3 /etc/fail2ban/jail.conf
这个是主要的配置文件,一般都不需要修改它。如果需要修改,只需要建立/etc/fail2ban/jail.local即可。注意,也可以在/etc/fail2ban/jail.d中建立单个以conf结尾的文件对jail.conf进行覆盖,或者在jail.d中建立单个以local结尾的文件对应jail.local进行覆盖(jail.conf -> jail.d/xxx.conf -> jail.local -> jail.d/xxx.local)

注: 一般只需要建立jail.local即可。

4 /etc/fail2ban/filter.d/*
这里包含了内置的过滤器,所谓过滤器就是怎么过滤数据,比如/etc/fail2ban/filter.d/ssh.conf,里面包括了提取信息的正则。如果内置的过滤器不符合要求,需要自己添加。

5 /etc/fail2ban/action.d/*
如果过滤器匹配了,将采取什么动作。比如/etc/fail2ban/action.d/iptables.conf,定义了如果禁用一个IP。如果没有符合的动作也需要自己添加。

配置关键点:
1 设置一个块,用中括号括起来,名字随意
[ssh-iptables]
2 启用这个快
enabled = true
3 指定过滤模块(在/etc/fail2ban/filter.d中必须存在sshd)
filter = sshd
4 指定动作
action = iptables[name=SSH, port=ssh, protocal=tcp]
5 发送邮件
sendmail-whois[name=SSH, dest=your@email.com, sender=fail2ban@email.com]
mail[name=SSH, dest=xxx@xx.com]
mail-whois[name=SSH, dest=xxx@xx.com]
6 要监控的日志文件(过滤器用到)
logpath = /var/log/secure
7 定义最大尝试次数
maxretry = 3

配置例子:

vi /etc/fail2ban/jail.conf
[DEFAULT]
# 忽略IP列表
ignoreip = 127.0.0.1 172.31.0.0/24 10.10.0.0/24 192.168.0.0/24
# 禁止时长(秒)
bantime = 86400
# 允许失败次数
maxretry = 5
# 查找失败次数时长(秒): 间隔多长时间,比如10分钟超过maxretry就采取action,这里应该填600
findtime = 600
# 日志修改检测机制(gamin polling auto)
backend = auto

[ssh-iptables]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
sendmail-whois[name=SSH, dest=your@email.com, sender=fail2ban@email.com]
logpath = /var/log/secure
maxretry = 3

注:每个配置块都是可以往上覆盖的。

配置使用SMTP发送邮件:
首先安装mailx, 参考:http://blog.ifeeline.com/2809.html

vi /etc/fail2ban/action.d/mail.conf

# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
#

[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
#actionstart = printf %%b "Hi,\n
#              The jail <name> has been started successfully.\n
#              Regards,\n
#              Fail2Ban"|mailx -s "[Fail2Ban] <name>: started  on `uname -n`" <dest>
actionstart = 

# Option:  actionstop
# Notes.:  command executed once at the end of Fail2Ban
# Values:  CMD
#
#actionstop = printf %%b "Hi,\n
#             The jail <name> has been stopped.\n
#             Regards,\n
#             Fail2Ban"|mailx -s "[Fail2Ban] <name>: stopped on `uname -n`" <dest>
actionstop = 

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck = 

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionban = printf %%b "Hi,\n
            The IP <ip> has just been banned by Fail2Ban after
            <failures> attempts against <name>.\n
            Regards,\n
            Fail2Ban"|mailx -s "[Fail2Ban] <name>: banned <ip> from `uname -n`" <dest>

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionunban = 

[Init]

# Default name of the chain
#
name = default

# Destination/Addressee of the mail
#
dest = root

注意这里把mail替换成了mailx。另外,actionstart和actionstop清理掉。这两个命令对应的是fail2ban启动和关闭时发送邮件,看起来不需要。

另外,如果重启,如果原来已经ban了一批IP,那么会发送一批邮件,这个看起来比较不适应。

如果需要使用whois查询一下ip,那么需要安装whois,然后使用mail-whois.conf这个动作(需要到源码库中拷贝下来,配置与mail.conf一样,把mail改为mailx)

——————————————-常用命令
#启动关闭,默认启动
systemctl status fail2ban
systemctl start fail2ban
systemctl stop fail2ban
systemctl enable fail2ban
systemctl disable fail2ban

#查看版本
fail2ban-client version

#查询当前状态,可以看到哪些规则存在拦截状态
fail2ban-client status

#根据规则命令查询具体的拦截状态新,可以查看具体拦截了哪些IP
fail2ban-client status ssh-iptables

#手动添加屏蔽IP
fail2ban-client set ssh-iptables banip 192.168.1.111

#删除被屏蔽的IP
fail2ban-client set ssh-iptables unbanip 192.168.1.111

#查看日志
tail /var/log/fail2ban.log

遇到问题:
1 重启iptables后,fail2ban无法工作,出现:Couldn’t load target `f2b-SSH’

#重启iptable后fail2ban无法工作
systemctl restart iptables

#先停止fail2ban
systemctl stop fail2ban
#然后启动fail2ban
systemctl start fail2ban

2 Centos 7下注意点
在CentOS 7下,由于默认没有启动iptables服务,启动的是firewalld,所以需要先关闭firewalld,然后启动iptables:

yum install iptables
yum install iptables-services

systemctl enable iptables.service

#注意默认情况,Iptable限制了访问
vi # sample configuration for iptables service

# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

去掉-A的规则,保存。

CentOS 7中通过SMTP发送邮件 – mailx

yum install mailx

rpm -qa | grep mailx
mailx-12.5-19.el7.x86_64

rpm -ql mailx-12.5-19.el7.x86_64
/bin/mail
/bin/mailx
/etc/mail.rc
/usr/bin/Mail
/usr/bin/nail

配置文件是/etc/mail.rc,修改:

vi /etc/mail.rc

set from=xx
set smtp=smtp.mxhichina.com
set smtp-auth-user=xx
set smtp-auth-password=xx
set smtp-auth=login

发送邮件:

echo 'xxxxx' | mailx -s "hello" xxx@xx.com

以上配置默认链接25端口,非安全,如果需要链接安全端口,需要修改:

set from=xx
set smtp=smtps://smtp.mxhichina.com:465
set smtp-auth-user=xx
set smtp-auth-password=xx
set smtp-auth=login
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb

发送邮件报错:
Error in certificate: Peer’s certificate issuer has been marked as not trusted by the.
但是邮件可以正确发送。大体上就是证书签发人被标记为未授信。

那么换一种方式,把证书取回来:

mkdir -p /root/.certs/
echo -n | openssl s_client -connect smtp.mxhichina.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/.certs/mxhichina.crt
certutil -A -n "GeoTrust Global CA" -t "C,," -d ~/.certs -i ~/.certs/mxhichina.crt
certutil -L -d /root/.certs

配置改为:

set from=xx
set smtp=smtps://smtp.mxhichina.com:465
set smtp-auth-user=xx
set smtp-auth-password=xx
set smtp-auth=login
set ssl-verify=ignore
set nss-config-dir=/root/.certs

还是提示:Error in certificate: Peer’s certificate issuer has been marked as not trusted by the. 不过邮件已经发送出去。

继续做如下修改:

certutil -A -n "GeoTrust SSL CA - G3" -t "Pu,Pu,Pu" -d ~/.certs -i ~/.certs/mxhichina.crt

Notice: Trust flag u is set automatically if the private key is present.

提示消失,邮件也发送成功。

注:其它邮件服务商,取证书的方式类似。

QQ邮箱:

echo -n | openssl s_client -connect smtp.exmail.qq.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/.certs/exmail.crt

certutil -A -n "GeoTrust Global CA" -t "C,," -d ~/.certs -i ~/.certs/exmail.crt

certutil -L -d /root/.certs

certutil -A -n "GeoTrust SSL CA - G3" -t "Pu,Pu,Pu" -d ~/.certs -i ~/.certs/exmail.crt

第三方账户登录 – Facebook

注册账户:

这里使用邮箱注册,所以需要登录邮箱激活:

打开开发者网站:
https://developers.facebook.com

如果没有登录,右上角出现”Log In”,点击登录,输入账户和密码,重新回到开发者页面。点击右上角的”Get Started”,开始注册成为开发者。

接下来验证账户,建立第一个APP:

填写“Site URL”,保存后,接下来是一系列的关于如何使用JS来控制登录的说明(如果不是通过JS来控制登录可忽略)。

然后完成:

然后开始往APP里面添加产品:

选择Facebook Login。然后选择类型:

然后回到左边上角导航处,选择”Settings -> Basic“:

保存相关信息后,把APP ID和APP Secret拷贝下来。

APP ID: xxxxx
App Secret: xxxxxxxxxxxxxx

最后还有重要的一个步骤,需要把APP开发模式关闭。因为默认是关闭的。否则将出现:

App Review,Do you want to make this app and all its live features available to the general public? Yes

在使用第三方账户登录时,授权提示:

Laravel 实践 – 访问跟踪 pragmarx/tracker

https://github.com/antonioribeiro/tracker

依赖的包:

    "require": {
        "php": ">=5.3.7",
        "doctrine/dbal": "^2.6",
        "laravel/framework": "~4|~5",
        "pragmarx/support": "~0.6|~0.7",
        "ramsey/uuid": "~3",
        "jenssegers/agent": "~2.1",
        "ua-parser/uap-php" : "~3.4",
        "pragmarx/datatables": "1.4.11",
        "snowplow/referer-parser": "~0.1",
        "jaybizzle/crawler-detect": "~1.0",
        "psr/log": "~1.0"
    },

这个包只针对Laravel应用。依赖jaybizzle/crawler-detect来进行机器人检查。

安装使用:

composer require pragmarx/tracker

// Laravel5.5以下需要
vi app/config/app.php
PragmaRX\Tracker\Vendor\Laravel\ServiceProvider::class,

vi app/config/app.php
'Tracker' => 'PragmaRX\Tracker\Vendor\Laravel\Facade',

// 发布(产生config/chacker.php文件和对应的数据库迁移文件)
php artisan vendor:publish --provider=PragmaRX\\Tracker\\Vendor\\Laravel\\ServiceProvider

// 启用中间件(在web组添加)
vi app/Http/Kernel.php
\PragmaRX\Tracker\Vendor\Laravel\Middlewares\Tracker::class,

// 修改配置文件,启动该插件,并启用中间件
vi config/tracker.php
'enabled' => true,

'use_middleware' => true,

// 继续编辑配置件,启动一个新的mysql链接(链接到相同库,原因可以查看配置中的说明)
// 名称可以不叫tracker,需要到config/tracker.php中做对应修改
vi config/database.php
'tracker' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],

// 运行迁移,产生数据表
php artisan migrate --database=tracker

// 如果需要跟踪地理位置,需要安装额外依赖包(注意这个包和PHP的geoip扩展冲突)
composer require "geoip2/geoip2":"~2.0"

// 然后运行以下文件产生IP数据库(config/geoip),文件几十兆,不需要提交版本库
php artisan tracker:updategeoip

// 然后修改配置,让其记录geoip
vi config/tracker.php

'log_geoip' => true,

基本配置就完成了。这里需要配置中间件的主要原因是让Laravel可以自动调用chacker来进行记录。提供了一个Facade: Tracker,可以方便的取回数据,或者手动记录:

$visitor = Tracker::currentSession();
var_dump( $visitor->client_ip );

var_dump( $visitor->device->is_mobile );

var_dump( $visitor->device->platform );

var_dump( $visitor->geoIp->city );

var_dump( $visitor->language->preference );

数据结构:

流程描述:

Web工具:
这个包还提供了一个基于Bootstrap的Web管理程序,可以查看相对应的信息:

git clone https://github.com/BlackrockDigital/startbootstrap-sb-admin-2.git public/templates/sb-admin-2
cd public/templates/sb-admin-2
git checkout tags/v3.3.7+1
git checkout -b v3.3.7+1

首先克隆一个管理面板,Web管理程序调用了这个模板里面的样式JS等。对应的路径实际是配置中指定的:

vi config/chacker.php
    /*
     * Enable the Stats Panel?
     */
    'stats_panel_enabled' => true,

    /*
     * Stats Panel routes middleware
     *
     */
    'stats_routes_middleware' => 'web',

    /*
     * Stats Panel template path
     */
    'stats_template_path' => '/tracker/tracker-admin',

这里把下载的模板改名为tracker/tracker-admin。

然后通过方法/stats就可以访问改Web程序,不过会提示要授权,需要在对应的用户表中,添加一个is_admin字段,然后标识某个用户的is_admin字段为1。

由于这个包的视图加载了一些CDN资源,这些可能对我们不友好,所以需要对这个包提供的视图做覆盖修改,所以拷贝:

cp -a vendor/pragmarx/tracker/views/* resources/pragmarx/tracker/

使用的加载使用了pragmarx/tracker::xxx,所以会首先使用覆盖的版本(Laravel的机制)。

对应对模板进行修改,把资源下载回来,适当调整一下模板,基本还是可用的。