使用Iptables将CentOS 6 Linux服务器设置为路由器

时间:2020-03-21 11:47:03  来源:igfitidea点击:

将CentOS Linux服务器配置为路由器。

什么是Iptables?

iptables是一个用户空间应用程序,允许用户配置Linux内核防火墙提供的表(实现为不同的Netfilter模块)以及它存储的链和规则。
换句话说,iptables是用于管理Linux防火墙规则的工具。

Iptables应该随所有Linux发行版一起提供。

Linux路由器配置

我们的CentOS服务器具有如下配置的2个网卡:

  • eth0:从eth1的角度来看网络的外部,配置了静态IP地址10.10.1.20,
  • eth1:内部(LAN)网络,配置了静态IP地址10.8.8.2.

然后,通过家用路由器自然对10.10.1.0/24网络进行进一步的NAT,以可以访问Internet。
这不在这里。

我们想要实现的是:

  • 专用网络10.8.8.0/24上的服务器必须能够ping通外部IP,
  • 专用网络10.8.8.0/24上的服务器必须能够通过HTTP/HTTPS访问公共网络服务器,
  • 从私有网络10.8.8.0/24到公众的所有其他传出流量都应被拒绝,
  • 公用网络10.10.1.0/24上的服务器必须能够通过HTTP/HTTPS访问专用网络10.8.8.0/24上的网络服务器,
  • 公用网络10.10.1.0/24上的服务器必须能够通过SSH连接到专用网络,
  • 从公用网络10.10.1.0/24到专用10.8.8.0/24的所有其他传入流量都应记录并拒绝。

下图可能有助于了解网络配置。

有关更多信息,请使用VirtualBox检查Linux测试环境环境。

启用转发

在CentOS服务器上启用IP转发:

# sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/' /etc/sysctl.conf
# sysctl -p

路由表如下所示:

# ip ro 
10.10.1.0/24 dev eth0  proto kernel  scope link  src 10.10.1.20 
10.8.8.0/24 dev eth1  proto kernel  scope link  src 10.8.8.2 
default via 10.10.1.1 dev eth0

默认网关在“公共” eth0接口上。

配置正向链(过滤器表)

我们希望内部网络(eth1)上的计算机能够ping通公共服务器。
因此,我们需要允许所有源自eth1的新ICMP流量都通过eth0离开:

# iptables -A FORWARD -i eth1 -o eth0 -p icmp -m state --state NEW -j ACCEPT

我们还希望内部(eth1)网络上的服务器能够在HTTP和HTTPS端口上启动与公共Web服务器的连接:

# iptables -A FORWARD -s 10.8.8.0/24 -i eth1 -o eth0 -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT

请注意,此处不是强制性的源网络地址定义。

另一方面,如果我们要自己托管一些私有Web服务器,我们希望能够从公共(eth0)网络访问它们:

# iptables -A FORWARD -d 10.8.8.0/24 -i eth0 -o eth1 -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT

我们还希望能够通过SSH连接到专用(eth1)网络:

# iptables -A FORWARD -d 10.8.8.0/24 -i eth0 -o eth1 -p tcp -m multiport --dports 22 -m state --state NEW -j ACCEPT

然后,我们要允许所有已经建立的或者相关的连接,两种方式:

# iptables -A FORWARD -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT

最后,在删除之前,我们将记录其他所有内容以进行故障排除:

# iptables -A FORWARD -p tcp -j LOG --log-prefix "iptables_forward " 
# iptables -A FORWARD -p tcp -j DROP

这是过滤器表正向链的最终iptables配置:

# iptables -S FORWARD
-P FORWARD ACCEPT
-A FORWARD -i eth1 -o eth0 -p icmp -m state --state NEW -j ACCEPT 
-A FORWARD -s 10.8.8.0/24 -i eth1 -o eth0 -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT 
-A FORWARD -d 10.8.8.0/24 -i eth0 -o eth1 -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT 
-A FORWARD -d 10.8.8.0/24 -i eth0 -o eth1 -p tcp -m multiport --dports 22 -m state --state NEW -j ACCEPT 
-A FORWARD -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -p tcp -j LOG --log-prefix "iptables_forward " 
-A FORWARD -p tcp -j DROP

配置NAT表:预路由链

预路由链有助于将数据包的目标IP地址转换为与本地服务器上的路由相匹配的内容。
这用于目标NAT(DNAT)。

在以下示例中,我们要将端口22043上的所有SSH通信转发到10.8.8.43计算机的本地端口22:

# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22043 -m comment --comment "DNAT SSH for .43" -j DNAT --to-destination 10.8.8.43:22

现在,如果我们尝试初始化从外部(eth0)网络到10.10.1.20:22043的SSH连接,我们应该能够在端口22上访问10.8.8.43的计算机。

可以添加与上述类似的更多DNAT规则,例如,访问位于10.8.8.44:80上的端口8080上的HTTP Web服务器:

# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.8.44:80

我们应该知道这个主意。

配置NAT表:路由后链

后路由链有助于将数据包的源IP地址转换为可能与目标服务器上的路由匹配的地址。
这用于源NAT(SNAT)。

现在,为了允许具有私有IP地址的私有(eth1)网络节点与外部公共网络进行通信,我们必须配置防火墙以进行IP伪装,该防火墙可以屏蔽来自具有防火墙外部设备IP地址的LAN节点的请求(在这种情况下, ,eth0):

# iptables -t nat -A POSTROUTING -o eth0 -p icmp -j MASQUERADE 
# iptables -t nat -A POSTROUTING -o eth0 -p tcp -m multiport --dports 80,443 -j MASQUERADE

这是NAT表(所有链)的最终iptables配置:

# iptables -t nat -S
-P PREROUTING ACCEPT
-P POSTROUTING ACCEPT
-P OUTPUT ACCEPT
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22043 -m comment --comment "DNAT SSH for .43" -j DNAT --to-destination 10.8.8.43:22 
-A POSTROUTING -o eth0 -p icmp -j MASQUERADE 
-A POSTROUTING -o eth0 -p tcp -m multiport --dports 80,443 -j MASQUERADE

不要忘记保存iptables规则:

# service iptables save

Puppet类来管理防火墙规则

以下Puppet类可以用作管理防火墙规则的示例。
查看此教程 文章,了解如何在CentOS上配置Puppet服务器。

class fw_router_forward_puppet {
  firewall { '001R ICMP':
    chain    => 'FORWARD',
    state    => ['NEW'],
    iniface  => 'eth1',
    outiface => 'eth0',
    proto    => 'icmp',
    action   => 'accept'
  }
  firewall { '002R Outgoing HTTP/S':
    chain    => 'FORWARD',
    state    => ['NEW'],
    iniface  => 'eth1',
    outiface => 'eth0',
    proto    => 'tcp',
    source   => '10.8.8.0/24',
    dport    => [ 80, 443 ],
    action   => 'accept'
  }
  firewall { '003R Incoming HTTP/S':
    chain    => 'FORWARD',
    state    => ['NEW'],
    iniface  => 'eth0',
    outiface => 'eth1',
    proto    => 'tcp',
    destination => '10.8.8.0/24',
    dport    => [ 80, 443 ],
    action   => 'accept'
  }
  firewall { '004R Incoming SSH':
    chain    => 'FORWARD',
    state    => ['NEW'],
    iniface  => 'eth0',
    outiface => 'eth1',
    proto    => 'tcp',
    destination => '10.8.8.0/24',
    dport    => [ 22 ],
    action   => 'accept'
  }
  firewall { '997R ':
    chain    => 'FORWARD',
    state    => ['RELATED', 'ESTABLISHED'],
    action   => 'accept',
  }
  firewall { '998R LOG sessions':
    chain  => 'FORWARD',
    jump    => 'LOG',
    log_level => '4',
    log_prefix => 'iptables_forward ',
  }
  firewall { '999R Drop all':
    chain    => 'FORWARD',
    action   => 'drop',
  }
}
class fw_router_prerouting_puppet {
 firewall { '005R Route ICMP':
    chain    => 'POSTROUTING',
    table    => 'nat',
    outiface => 'eth0',
    proto    => 'icmp',
    jump     => 'MASQUERADE'
  }
  firewall { '006R Route HTTP/S':
    chain    => 'POSTROUTING',
    table    => 'nat',
    outiface => 'eth0',
    proto    => 'tcp',
    dport    => [ 80, 443 ],
    jump     => 'MASQUERADE'
  }
  firewall { '007R NAT HTTP for VIP .35':
    chain    => 'PREROUTING',
    table    => 'nat',
    iniface  => 'eth0',
    proto    => 'tcp',
    dport    => [ 8035 ],
    todest   => '10.8.8.35:80',
    jump     => 'DNAT'
  }
  firewall { '008R NAT HTTPS for VIP .35':
    chain    => 'PREROUTING',
    table    => 'nat',
    iniface  => 'eth0',
    proto    => 'tcp',
    dport    => [ 8835 ],
    todest   => '10.8.8.35:443',
    jump     => 'DNAT'
  }
  firewall { '011R NAT SSH for .43':
    chain    => 'PREROUTING',
    table    => 'nat',
    iniface  => 'eth0',
    proto    => 'tcp',
    dport    => [ 22043 ],
    todest   => '10.8.8.43:22',
    jump     => 'DNAT'
  }
}