3、Iptables网络防火墙

3、Iptables网络防火墙

TOC

网络防火墙

    对任何一个局域网来讲,我们都需要网关设备,只有跨网络设备都得经过网关,网关设备内部有诸多客户端主机,网关内的主机,任何经由非内部网络通信,都需要网关设备进行转发的,所以这个关网主要的作用是报文转发。

实验一
    保护内网主机,内网可以出外网,但是外网无法进入;
# 默认拒绝所有
[root@node1 ~]# iptables -I FORWARD -j REJECT
# 允许源地址来自172.16.1.3的所有转发请求
[root@node1 ~]# iptables -I FORWARD 1 -s 172.16.1.3 -j ACCEPT
# 允许所有以与主机建立连接的请求(也就是回应的请求)
# 也可以用这个 [root@node1 ~]# iptables -I FORWARD 1 -s 172.16.1.3 -j ACCEPT
[root@node1 ~]# iptables -I FORWARD 1 -m state --state ESTABLISHED -j ACCEPT

NAT

    用到nat的主要目的在于隐藏主机,所谓隐藏主机指的是,期望任何内外主机进行通信时,网关设备只是将网络进行转发的,他不会修改报文的源IP和目标IP。任何主机要接入外部网络,必然要经过网关转发来实现,如果这个网关向外进行转发的时候,把报文的源IP地址,通通改为网关自己的IP地址,所以外部主机所能看到的请求报文的源地址也只是网关地址,而不会包含内网真实主机的地址。很显然,我们改源地址就行了。这就叫地址转换。
    而我们如果直接像上面进行网关转发,那么报文的地址就是真实的内网IP和端口,所以这有一定的隐患存在;
SNAT
    源地址转换,当我们内网客户端请求外部主机服务的时候,我们的网关可以在报文真正转发出去之前,将它的源地址改为网关的IP地址,目标地址不变,目标主机收到报文之后源IP是我们的网关,因此相应报文回给网关,那么因为我们的网关是没有发出这种请求的,而是我们的内部主机发出的请求通过网关转发出去的,所以我们的网关服务器得需要一个连接追踪表,来记录哪个客户端通过哪个端口访问了外部的哪个主机的哪个端口,通过这张表网关就知道将这个报文回复给谁的,所以在查询这个表之后发现是内网中的某一台主机,所以真正在交由内网主机之前,得做地址转换源IP还是外部主机的IP,目标IP得修改为内网主机的IP;
    那么在这种方式下,请求报文修改了源地址,响应报文修改了目标地址,但是我们通常只关注请求报文,因为响应报文是安原来的请求报文对应改过去的,向这种方式我们就叫做SNAT,所以外部主机想访问内部主机是无法到达的;
    SNAT之内在POSTROUTING上做,因为当内部主机需要访问外部主机的时候,必须得经过路由,因为经过了路由我们的iptables才知道,网关服务器的四块网卡,到底是走哪一块网卡出去,那么就将源IP修改为这个网卡的IP;
# 将内网的node2服务器做请求地址转换,每次匹配到这个请求就直接修改源地址
[root@node1 ~]# iptables -t nat -I POSTROUTING -s 172.16.1.3 -j SNAT --to-source 192.168.1.104
# 测试内网服务器是否能访问公网
[root@node2 ~]# curl -I https://blog.doorta.com
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 30 Sep 2019 02:18:49 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/7.1.12
Link: <https://blog.doorta.com/index.php?rest_route=/>; rel="https://api.w.org/"
DNAT
    目标地址转换,客户端需要地址转换,那么我们内网的服务器也需要做地址转换,一样的,在服务器前端放一个网关,这个网关拥有公网地址,同时也拥有私网地址,我们服务器主机就隐藏在私网内,假设外部客户端需要访问我们私网内部的服务器提供是http服务的时候,那么这个时候访问的应该是我们的网关,那么我们的网关接收到这个请求后,就会通过PREROUTING的SNAT规则进行目标地址转换,最后转换为我们的私网服务器IP地址,最终响应的时候,也需要查询这个连接追踪表,来记录哪个客户端通过哪个端口访问了外部的哪个主机的哪个端口,通过这张表网关就知道将这个报文回复给谁的,所以在查询这个表之后发现是公网中的某一台主机,所以真正在交由外网主机之前,得在响应报文里面修改源标IP得修改为内网服务器的IP,目标主机还是外网主机的IP,所以向这种我们就叫做目标地址转换DNAT;
    DNAT之内在PREROUTING上做,因为路由之后会发现请求报文的IP是网关的地址,这就来不及了,那这就送到网关的用户空间进程了,所以就需要在PREROUTING上修改,然后就知道到底是发送给谁;
# 开放内网服务器http服务
[root@node1 ~]# iptables -t nat -I PREROUTING -p tcp -m multiport --dports 80 -j DNAT --to-destination 172.16.1.3
# 测试访问
root@node0:~# curl -I http://192.168.1.104
HTTP/1.1 200 OK
Date: Mon, 30 Sep 2019 02:36:10 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Mon, 30 Sep 2019 02:08:36 GMT
ETag: "14-593bbb6ab6476"
Accept-Ranges: bytes
Content-Length: 20
Content-Type: text/html; charset=UTF-8
REDIRECT
    我们用户空间有一个httpd程序监听了8080端口,很显然,外部请求应该通过8080进来,但是正常的服务都是80进来,它却监听的8080,那么这个时候我们可以在本地主机之上做一个端口映射,如果访问本机的80那么就转为本机内部的8080端口;
# 所有进入本机的tcp协议80端口的服务都重定向为8080
[root@node2 ~]# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
# 测试
[root@node1 ~]# curl -I http://172.16.1.3
HTTP/1.1 200 OK
Date: Mon, 30 Sep 2019 03:02:24 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Mon, 30 Sep 2019 02:08:36 GMT
ETag: "14-593bbb6ab6476"
Accept-Ranges: bytes
Content-Length: 20
Content-Type: text/html; charset=UTF-8
MASQUERADE
    假设我们的公网IP是动态的,那么我们是SNAT使用起来就比较吃力,要频繁的更换sourceIP,那这样体验就不是很好了,虽然SNAT可以指定多个地址,但是,不管是几个地址,必须明确的指定要SNAT的ip,假如当前系统用的是ADSL动态拨号方式,那么每次拨号,出口ip192.168.5.3都会改变,而且改变的幅度很大,不一定是192.168.5.3到192.168.5.5范围内的地址,这个时候如果按照现在的方式来配置iptables就会出现问题了,因为每次拨号后,服务器地址都会变化,而iptables规则内的ip是不会随着自动变化的,每次地址变化后都必须手工修改一次iptables,把规则里边的固定ip改成新的ip,这样是非常不好用,所以这就是MASQUERADE解决的问题,MASQUERADE就是针对这种场景而设计的,他的作用是,从服务器的网卡上,自动获取当前ip地址来做NAT。
# 来自172.16.1.3的请求,全部做地址伪装
[root@node1 ~]# iptables -t nat -A POSTROUTING -s 172.16.1.3 -j MASQUERADE
# 测试
[root@node2 ~]# curl -I https://www.baidu.com
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: keep-alive
Content-Length: 277
Content-Type: text/html
Date: Mon, 30 Sep 2019 03:13:50 GMT
Etag: "575e1f60-115"
Last-Modified: Mon, 13 Jun 2016 02:50:08 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
PAT
    不仅能转换源或目的IP还能修改源或目的端口,当然我们也可以只修改端口,那么这个时候我们就需要用到一个redirect来实现;

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]]

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
    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.

    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]

layer7

发表评论