设置好ip地址主要是放置ip地址开机关机的时候发生更改,而且设置内网ip与外网ip的方式也不同(在这里虽然172.18.0.1网络也是私网网络,不过我们为了实验方便,把它当作公网网络,而把10.0.1.0网络当作私网网络)。
对于172.18.47.11,按照上面的步骤和配置信息一步步设置即可
1.2 设置内网主机ip
对于内网的10.0.1.22,这台主机的网卡要设置为仅主机模式(Host-Only),开机后直接用nmtui设置ip,设置信息如下:
对于内网主机来说,由于要与外界进行通信,那么就需要有一个中介,而这个终结就是中间主机,所以它的Gateway要设置成10.0.1.1,不然无法与外机进行通信,只能与10.0.1.1进行通信。
1.3 设置中间主机
对于中间主机,要设置两个网卡的ip,10.0.1.1与172.18.47.10
设置10.0.1.1
10.0.1.1与10.0.1.22不同,不需要设置Gateway,直接通过172.18.47.10与外界进行通信
route -n查看路由信息,可以看到:
对于172.18.47.10的设置参考172.18.47.11即可。
1.4 主机间连通性测试
使用ping操作测试各主机之间的连通性
对于内外网主机10.0.1.22
从上面可以看出,此时内网主机可以ping通中间主机的两个ip地址,而对于172.18.47.11主机ping操作并不能连通
此时使用tcpdump在中间主机上进行抓包分析,如下:
对于172.18.47.11抓包分析如下:
通过上面的抓包分析可以看到,10.0.1.22发出的ping包,中间主机的两个网卡都已经收到了,而外网主机却没有收到,所以一直没有返回结果。此时就涉及到另一个概念:核心转发功能
核心转发功能是由/proc/sys/net/ipv4/ip_forward文件来控制,cat一下文件,内容为1表示核心转发功能打开,为0表示关闭。
此时对于中间主机而言我们需要打开核心转发功能。
echo 1 >> /proc/sys/net/ipv4/if_forward #覆盖重定向
此时对于172.18.47.11抓包分析可以看到:
此时可以看到172.18.47.11已经可以收到172.18.47.10转发的来自于10.0.1.22的ping包,但是对10.0.1.22的ping请求没有回应,10.0.1.22一直收不到返回的ping包
此时查看172.18.47.11的路由信息,可以看到
可以看到对于172.18.47.11这台主机而言,它把所有的转发信息全部转给了172.18.0.0,而不是转给172.18.47.10,所以我们是收不到转发的ping回复信息,此时需要添加一个路由条目,使得来自于10.0.1.0/24网络的请求全部转发给172.18.47.10
route add -net 10.0.1.0/24 gw 172.18.47.10
route -n,查看路由条目
此时就可以看到:
在10.0.1.22主机中,已经收到172.18.47.11的响应信息
在172.18.47.11主机中已经把10.0.1.22主机的信息转发给了对方
在中间主机中网卡172.18.47.10也收到了相应的转发信息,把来自于172.18.47.11的ping回应信息转发给10.0.1.22
linux主机如何实现网络防火墙功能?把linux主机当成局域网防火墙,网关,路由器,主机本身打开核心转发功能
OUTPUT,INPUT,PREROUTING,FORWARD,POSTROUTING只与输入输出有关
可以同时作为网络防火墙与主机防火墙
网络防火墙:规则添加在forward
主机防火墙:规则添加在input,output
思考一:控制内网主机不能通过操作linux主机访问外网,对请求拒绝
思考二:控制内网主机访问外网,forward
防火墙:客户端防火墙,服务器端防火墙,局域网路由防火墙(要同时控制进出的资源)
打开网卡间转发:cat /proc/sys/net/ipv4/ip_forward,为0则没有打开,为1则打开
对于linux,地址属于内核,而不属于网卡
抓包分析:tcpdump -i eno16777736 -nn icm
自己可以ping别人,别人不能ping自己
iptables -A FORWARD -s 10.0.0.1/24 -d 0/0 -p icmp --icmp-type 8 -j ACCEPT
iptables -A
核心转发功能:/proc/sys/net/ipv4/if_forward,1为打开,0为关闭
如果10.0.1.22没有把网关指向10.0.1.1,那么虽然10.0.1.22可以ping通10.0.1.1(因为是本地网络通信),但是不能ping通172.18.47.10,因为10.0.1.22不知道非本地通信,自己的报文应该交给谁,而当它的网关指向10.0.1.1的时候,虽然没有打开核心转发功能,但10.0.1.1与172.18.47.10在一台主机上,所以这台主机可以直接响应对于172.18.47.10的ping操作。所以网关必须指向转发的主机。而此时由于没有打开核心转发功能,虽然发出了信息,但是此时ping172.18.47.11还是不能响应10.0.1.22的ping操作
当打开中间主机的核心转发功能,此时10.0.1.22对于172.18.47.11的ping操作,通过抓包分析可以看到172.18.47.11能够收到,172.18.47.11也给与了响应,但是由于172.18.47.11的默认网关是指向172.18.0.1的,而不是指向172.18.47.10,所以10.0.1.22还是接收不到响应
此时在172.18.47.11上添加路由条目,对于10.0.1.0/24网络的响应全部转发给172.18.47.10,到其他主机的还是通过172.18.0.1
route add -net 10.0.1.0/24 gw
172.18.47.10
route -n,查看路由条目
再次由10.0.1.22发起对172.18.47.11的ping操作就可以收到回应了
所以此时我们就建立了一个小型的网络。
对于不同的连接,我们可以添加不同的路由条目,增加不同的下一跳
如何控制访问?
iptables -P FORWARD DROP,将核心转发的内容全部丢弃,ping操作也不能转发了
iptables -A FORWARD -s 10.0.1.0/24 -d 0/0 -p icmp --icmp-type 8 -j ACCEPT,自左而右放行请求
现在ping请求可以出去,但是不能得到回应
iptables -A FORWARD -s 0/0 -d 10.0.1.0/24 -p icmp --icmp-type 0 -j ACCEPT,此时就可以收到ping响应了
但是ping请求自右而左还是ping不通,172.18.47.11对于10.0.1.22的ping请求没有任何回应
允许外网主机ping内网:
iptables -A FORWARD -s 0/0 -d 10.0.1.0/24 -p icmp --icmp-type 8 -j ACCEPT
iptables -A FORWARD -s 10.0.1.0/24 -d 0/0 -p icmp --icmp-type 0 -j ACCEPT
但是从上面可以看出,需要四条规则,检查比较麻烦,如果用状态检查就比较快
iptables -F
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.0.1.0/24 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
此时自左而右还是能ping通
此时的规则相对于上面的哪个更加安全
现在把172.18.47.11当作服务器主机,实验能够让内网主机访问外网服务,此时
iptables -F
iptables -nvL
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT
测试能否访问:curl 172.18.47.11,显示能够访问
命令连接与数据连接?主动模式,被动模式,related状态
modprobe nf_conntrack_ftp
第一次请求related
改第一条规则,iptables -R FORWARD 1 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -nvL,可以看到,此时不需要再使用OUTPUT或INPUT,直接使用FORWARD即可,比较简练
使规则永久有效,就要保存规则:iptables-save, iptables-restore
iptables-reatore < /etc/sysconfig/iptables.v2(后面的文件名自己设置)
开机自己启动,将规则保存在/etc/rc.local文件中
对于centos6:service iptables save(保存),chkconfig iptables on(开机启动)
设置规则时,要考虑清楚需要什么样的服务,对什么请求进行屏蔽
iptables的处理动作:
ACCEPT/DROP/REJECT
LOG:
RETURN:从自定义返回
REDIRECT:端口重定向
MARK:防火墙标记
DNAT:地址转换
SNAT
MASQUERADE:地址伪装
...
LOG:专门用于做日志记录的target
Turn on kernel logging of matching packets. if you want to LOG the packets you refuse, use two separate rules with the same matching criteria, first using target LOG then DROP (or REJECT).
开启内核当中关于报文记录的功能
--log-level level,日志级别选项,有默认值为4
当我们指定某个级别之后,包括这个级别,以及比他高的级别的日志信息会被全部记录下来
emerg, alert, crit, error, warning, notice, info or debug.
--log-prefix prefix
对应的日志信息是由谁产生的,即给这个日志加一个日志行前缀
~]# iptables -I FORWARD 2 -s 10.0.1.0/24 -p tcp -m multiport --dports 80,21,22,23 -m state --state NEW -j LOG --log-prefix "(new connctions)"
对于10.0.1.0网络中端口为80、21、22、23的服务连接新请求进行记录,标记为new connections
测试:在10.0.1.22网络中发起curl请求172.18.47.11,查看日志就可以看到/var/log/messages最后一行即可看到内核的记录
RETURN:
主要是从被调用的用户自定义链返回主链
返回调用者;
例:iptables -N web,新定义链
iptables -A web -s 10.0.1.0/24 -p tcp --dport 80 -j ACCEPT,对于10.0.1.0/24内的主机对于web服务的访问,全部放行
iptables -I web 1 -m string --algo kmp --string "old" -j REGECT,对于页面中含有old字符的,不能显示
iptables -I web 2 -p tcp -m state --state ESTABLISHED -j ACCEPT
在10.0.1.22请求172.18.47.11的服务,此时发现响应没有回应
原因:对于用户自定义链需要进行加载才能生效
iptables -A FORWARD -p tcp -j web
被调用之后,访问就可以正常进行了
iptables -A 10.0.1.0/24 -p tcp --dport 22 -m state NEW -j ACCEPT,ssh登录外网主机
iptables -A web -j RETURN,对于web链匹配不到的就return返回调用者
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.
只有在入栈报文请求刚刚到达时才有用,在其他场景中去调用是没有任何意义的
It redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface
能够实现指明的端口完成映射,实现端口重定向,端口伪装
--to-ports port[-port],映射到哪个端口上
如果本机是一个web服务器,不能监听在80端口上(普通用户是没有权限启动80端口的),此时就可以使用映射,把80端口重定向到8080端口上,而这个规则要加到nat的PROROUTING上面,其实就是一种地址转换机制
例:把web服务器监听的端口改为8080,那么此时就要在服务器端加一条规则,在访问入栈时,实现端口重定向
~]# iptables -t nat -A PREROUTING -d 172.18.47.11 -p tcp --dport 80 -j REDIRECT --to-ports 8080
输入地址进行访问,还是能正常访问网站,对于端口的指定,可以使用其他未使用的端口
NAT:Network Address Translation,网络地址转换
SNAT: source NAT
我们有一台net主机,有两个接口,外网与内网,与路由模型不同的是
测试:首先打开限制
iptables -t nat -F
iptables -t filter -F
iptables -P FORWARD ACCEPT
iptables -nvL
此时规则全部清空
修改IP报文中的源IP地址;
私网地址与公网地址
私网地址:只能在本地网络中
公网地址:路由是根据公网地址进行数据请求交换的,只能用公网地址
所以在本地的请求需要通过离自己最近的私网的服务器进行地址转换将私网地址转换为公网地址才能与互联网通信,返回的结果由私网的服务器,依靠自己保存的一个nat追踪会话表,进行地址转换后发给客户端,所以只要启动nat功能,contrack机制必定会用到
连接追踪表
上面解决了ipv4资源池资源缺乏的困境
dnat最初出现是为了地址伪装,而非上面的私网与公网
让本地网络中的主机可使用统一地址与外部主机通信,从而实现地址伪装;
请求:由内网主机发起,修改源IP,如何修改则由管理员定义;不需要用户自己更改
响应:修改目标IP,由nat自动根据会话表中追踪机制实现相应修改;
DNAT: destination NAT
修改IP报文中的目标IP地址;
对自己的服务器进行伪装,真正响应用户请求的是另一台主机,当请求发过来时,中间的负责地址转换的主机(网关)把请求进行转发,这样可以防止真正的服务器主机被攻击。回应请求时,再转换地址
让本地网络中服务器使用统一的地址向外提供服务(发布服务),但隐藏了自己的真实地址;
请求:由外网主机发起,修改其目标地址,由管理员定义;
响应:修改源地址,但由nat自动根据会话表中的追踪机制实现对应修改;
其他功用:把本地的服务器利用私网地址建成集群,将不同的服务分布在不同的主机上,有访问请求时就可以通过网关的地址转换进行响应,
负载均衡:对于请求进行分化响应,lvs
PNAT: port NAT,一般在进行dnat与snat的同时就实现了pnat的转换
SNAT: 用来转换客户端地址,设置在POSTROUTING
DNAT: 用来转换服务器地址,设置在RPEROUTING
客户端要过滤就要在forward上设置
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.
在centos6中snat是不能用在input链上的,只能用在POSTROUTING上面
只能用在nat表上,用在POSTROUTING与INPUT上
--to-source [ipaddr[-ipaddr]],指明转换为哪个地址,可以时范围内的地址,也可以转源端口
测试:在网关(172.18.47.10)上设置规则
iptables -t nat -F
iptables -t filter -F
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j SNAT --to-source 172.18.47.10
设置好之后用10.0.1.22去ping服务器172.18.47.11
此时在172.18.47.11进行抓包分析后看到是由172.18.47.10进行的响应
在172.18.47.10上抓包分析,tcpdump -i eno16777736 -nn icmp,可以看到是由172.18.47.10向172.18.47.11发起的ping操作
在172.18.47.10上抓包分析,tcpdump -i eno33449960 -nn icmp,可以看到是由172.18.47.10向172.18.47.11发起的ping操作
此时还可以用ssh对172.18.47.11操作
禁止22号端口操作:iptables -t filter -A FORWARD -s 10.0.1.0/24 -p tcp --dport 22 -j REJECT
其他服务同样使用
其他问题:如果我们的公网地址是通过PPoE协议动态获得的,那么说明我们的公网地址一直在变换,如果在防火墙规则上设定一个固定地址,那么当地址变化时如何获取地址?
解决方式:
1.使用脚本开机启动,周期性任务,对于ip的变化进行比对,然后随之变化,低效!!!
2.使用MASQUERADE:
MASQUERADE:
This target is only valid in the nat table, in the POSTROUTING chain. It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target.
仅用在动态拨号获得ip地址的场景中,此时就不需要使用sant,使用MASQUERADE
在静态场景中也可以使用
例:
iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j MASQUERADE
iptables -t nat -nvL
进行验证
查看日志
MASQUERADE,需要消耗更多的计算资源
注意:centos6上的nat表只包含3个链:OUTPUT,POSTROUTING,PREROUTING
centos7上包含4个链:INPUT,OUTPUT,POSTROUTING,PREROUTING
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]],目标端口还可以做端口映射
测试:将10.0.1.22变为服务器,172.18.47.11变为客户端主机
iptables -t nat -F PROROUTING
iptables -t nat -A PREROUTING -s 0/0 172.18.47.10 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22
此时访问10.0.1.22,输入172.18.47.10,显示的是10.0.1.22中设置的内容
还可以进行端口转换:(直接添加)
iptables -t nat -A PREROUTING -s 0/0 172.18.47.10 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22:8090
端口抓包分析指明协议和端口:tcpdump -i eno16777736 -nn tcp port 8090
此时对于ssh的访问还是在172.18.47.10主机上
此时删除规则1,iptables -t nat -D PREROUTING 1
iptables -t nat -A PREROUTING -s 0/0 172.18.47.10 -p tcp --dport 0 -j DNAT --to-destination 10.0.1.22
此时就不能在访问服务了,没有0端口,与lvs不同,此时并没有通配机制
目标地址转换,仅转换目标地址不转换源地址
recent模块:对于本机的某个访问的速率做控制,当访问次数超过限制时,可以直接进行限制。此时可以使用这个模块可以抵挡一部分对于ssh的字典攻击。但是也不能依赖它
对于较早期的版本,有一个第三方模块layer7,现在的更新基本停止
功能:识别大多数常见的应用层协议,例如http、qq等协议;不论是什么端口,直接基于协议做控制
可以尝试编译内核,对内核打补丁