GNU/Linux 系统下 nftables 防火墙的本地 IPS 能力部署实例
随着各 GNU/Linux 系统厂商以及社区逐步开始采用新的内核作为其发行版本的默认内核，防火墙机制采用了更新的 nftables 防火墙机制。尽管红帽公司提供了 firewalld.service 防火墙服务组件以及相关的配置管理命令 firewall-config、firewall-cmd 来对防火墙进行管理，但该服务组件目前还没有在其他发行版或者社区版本内得到统一使用。为了更好的帮助读者朋友们理解该防火墙机制，笔者将自己在工作中直接使用 nftables 进行手工创建配置，从而使系统具有本地 IPS 能力的过程进行总结。目前多数主流的新发行版 GNU/Linux 系统，默认安装完成后 systemd 系统和服务管理器中已经添加了新的 nftables.serivce 子服务配置文件。同时依然支持 iptables 规则和 iptables 命令，不过为了彻底将防火墙升级到 nftables 机制，我们可以在没有 firewalld.service 的发行版系统中直接启用 nftables.service 服务来使用新的防火墙。通过执行命令 vi /lib/systemd/system/nftables.service，从该文件中的语句 ExecStart=/usr/sbin/nft -f /etc/nftables.conf 我们可以清楚的看到，nftables 防火墙的默认配置和规则文件一般都放置在系统的 /etc/nftables.conf 目录中，不过该默认配置文件中只包含一个名为 inet filter 的简单 IPv4/IPv6 防火墙列表。inet 过滤器可以同时适用于 IPv4 和 IPv6 的规则，但不能用于 NAT 类型的链，只能用于过滤器类型的链。为了保持和 iptables 防火墙的规则类比，便于用户熟悉，我们可以使用如下 nftables 命令创建相应的表和链来建立一个类似于传统 iptables 防火墙框架，创建过程如下：1、创建 nft 表与 iptables 中的表不同，nftables 中没有内置表，表的数量和名称由用户决定。但是，每个表只有一个地址簇，并且只适用于该簇的数据包。表可以指定五个（ip、ip6、inet、arp、bridge）簇中的一个，用户可以依次执行如下命令：nft add table ip filter nft add table ip6 filter nft add table bridge filter”nftables 将为我们分别建立三个 ip、ipv6、bridge 簇并且表名均为 filter 的防火墙框架。2、创建链表包含链，链的目的是保存规则。与 iptables 中的链不同，nftables 也没有内置链。这意味着与 iptables 不同，如果链不匹配 nftables 框架中的簇或钩子，则流经这些链的数据包不会被 nftables 触及。链有两种类型。基础链是来自网络栈的数据包的入口点，其中指定了钩子，其实可以理解为 iptables 防火墙的默认规则。常规链可以理解为其它用户自定义的规则链。使用如下命令为每一个表建立 INPUT、FORWARD、OUTPUT 链，并且设置基础链，其中 ip 簇 filter 表 INPUT 链默认为丢弃所有数据包的相应的命令格式如下。添加 ip 簇 filter 表相应链命令集：nft add chain ip filter INPUT { type filter hook input priority 0\; policy drop\; } nft add chain ip filter FORWARD { type filter hook forward priority 0\; policy accept\; } nft add chain ip filter OUTPUT { type filter hook output priority 0\; policy accept\; }添加 ipv6 簇 filter 表相应链命令集：nft add chain ip6 filter INPUT { type filter hook input priority 0\; policy accept\; } nft add chain ip6 filter FORWARD { type filter hook forward priority 0\; policy accept\; } nft add chain ip6 filter OUTPUT { type filter hook output priority 0\; policy accept\; }添加 bridge 簇 filter 表相应链命令集：nft add chain bridge filter INPUT { type filter hook input priority 0\; policy accept\; } nft add chain bridge filter FORWARD { type filter hook forward priority 0\; policy accept\; } nft add chain bridge filter OUTPUT { type filter hook forward priority 0\; policy accept\; }3、添加规则规则由语句或表达式构成，包含在链中。将一条规则添加到链中使用如下语法：nft add rule family table chain handle statement规则添加到 handle 处，这是可选的。如果不指定，则规则添加到链的末尾，类似于 iptables -A 方法。将规则插入到指定位置使用如下语法：nft insert rule family table chain handle statement如果未指定handle，则规则插入到链的开头，类似于 iptables -I 方法。以下是用户根据自己的实际情况添加的具体规则：放行本地回环接口 lo 的所有流量：nft add rule ip filter INPUT iif lo accept放行 established、related 状态的数据包，这一点很重要，因为多数对外访问的数据包在收到对端主机回包时多为这两种状态，如果在 INPUT 链中不放行该类型数据包，即使本机的 OUTPUT 链默认为 ACCEPT，让所有数据包出站，系统也会主动在 INPUT 链中丢弃掉相应的回包而导致数据无法交互。具体命令如下：nft add rule ip filter INPUT ct state established,related accept阻断存在重大安全隐患的系统端口，包括已经公布的比如勒索病毒等端口。nftables 在配置过程中，当用户使用端口进行添加后，nftables 会自动将端口转换为 service 模式，用户可以通过使用命令 nft describe tcp dport 对照查看。阻断安全隐患的系统端口具体命令如下：nft add rule ip filter INPUT meta l4proto tcp tcp dport { loc-srv, 136, netbios-ns, netbios-dgm, netbios-ssn, microsoft-ds, 3389, radmin-port } counter drop nft add rule ip filter INPUT meta l4proto udp udp dport { loc-srv, 136, netbios-ns, netbios-dgm, netbios-ssn, microsoft-ds, 3389, radmin-port } counter drop对服务进行限流控制，防止 DDoS 攻击或者 CC 攻击造成系统服务中断，可以通过 limit 限制通信速率，以下是接受一个每秒最多 10 个 web 或者 https 或者 dns 查询请求的数据包，同时可以有 2 个包超出限制的规则具体命令：nft add rule ip filter INPUT meta l4proto tcp tcp dport { 80,443,53 } ct state new limit rate 10/second burst 4 packets accept nft add rule ip filter INPUT meta l4proto udp udp dport { 80,443,53 } ct state new limit rate 10/second burst 4 packets accept总结经过以上配置后，我们的主机就具有了很好的本机 IPS 能力。应对不论是面向南北跨路由器的访问流量，还是本地网络内的东西访问流量，常规的恶意扫描或者恶意攻击基本是够用了。之后用户可以使用命令 nft list ruleset > /etc/nftables.conf 将这些规则保存在 nftables 的默认配置文件中，并使用 systemctl enable nftables.service 打开该服务的默认启动模式，之后系统将在开机时自动启动 nftables 防火墙并应用相应规则。用户也可以通过命令 vi /etc/nftables.conf 来直接按照相应规则编辑该文件来修改防火墙配置，以确保自己的系统处于本机防火墙 IPS 能力的保护之下。希望本文对你有用并能帮助到你。
iptables 是一款控制系统进出流量的强大配置工具。现代 Linux 内核带有一个叫 Netfilter 的数据包过滤框架。Netfilter 提供了允许、丢弃以及修改等操作来控制进出系统的流量数据包。基于 Netfilter 框架的用户层命令行工具 iptables 提供了强大的防火墙配置功能，允许你添加规则来构建防火墙策略。iptables 丰富复杂的功能以及其巴洛克式命令语法可能让人难以驾驭。我们就来探讨一下其中的一些功能，提供一些系统管理员解决某些问题需要的使用技巧。避免封锁自己应用场景：假设你将对公司服务器上的防火墙规则进行修改，你需要避免封锁你自己以及其他同事的情况（这将会带来一定时间和金钱的损失，也许一旦发生马上就有部门打电话找你了）技巧 #1: 开始之前先备份一下 iptables 配置文件。用如下命令备份配置文件：/sbin/iptables-save > /root/iptables-works技巧 #2: 更妥当的做法，给文件加上时间戳。用如下命令加时间戳：/sbin/iptables-save > /root/iptables-works-`date +%F`然后你就可以生成如下名字的文件：/root/iptables-works-2018-09-11这样万一使得系统不工作了，你也可以很快的利用备份文件恢复原状：/sbin/iptables-restore < /root/iptables-works-2018-09-11技巧 #3: 每次创建 iptables 配置文件副本时，都创建一个指向最新的文件的链接。ln –s /root/iptables-works-`date +%F` /root/iptables-works-latest技巧 #4: 将特定规则放在策略顶部，底部放置通用规则。避免在策略顶部使用如下的一些通用规则：iptables -A INPUT -p tcp --dport 22 -j DROP你在规则中指定的条件越多，封锁自己的可能性就越小。不要使用上面非常通用的规则，而是使用如下的规则：iptables -A INPUT -p tcp --dport 22 –s 10.0.0.0/8 –d 192.168.100.101 -j DROP此规则表示在 INPUT 链尾追加一条新规则，将源地址为 10.0.0.0/8、 目的地址是 192.168.100.101、目的端口号是 22 （--dport 22 ） 的 TCP（-p tcp ）数据包通通丢弃掉。还有很多方法可以设置更具体的规则。例如，使用 -i eth0 将会限制这条规则作用于 eth0 网卡，对 eth1 网卡则不生效。技巧 #5: 在策略规则顶部将你的 IP 列入白名单。这是一个有效地避免封锁自己的设置：iptables -I INPUT -s <your IP> -j ACCEPT你需要将该规则添加到策略首位置。-I 表示则策略首部插入规则，-A 表示在策略尾部追加规则。技巧 #6: 理解现有策略中的所有规则。不犯错就已经成功了一半。如果你了解 iptables 策略背后的工作原理，使用起来更为得心应手。如果有必要，可以绘制流程图来理清数据包的走向。还要记住：策略的预期效果和实际效果可能完全是两回事。设置防火墙策略应用场景：你希望给工作站配置具有限制性策略的防火墙。技巧 #1: 设置默认规则为丢弃# Set a default policy of DROP *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0]技巧 #2: 将用户完成工作所需的最少量服务设置为允许该策略需要允许工作站能通过 DHCP（-p udp --dport 67:68 -sport 67:68）来获取 IP 地址、子网掩码以及其他一些信息。对于远程操作，需要允许 SSH 服务（-dport 22），邮件服务（--dport 25），DNS 服务（--dport 53），ping 功能（-p icmp），NTP 服务（--dport 123 --sport 123）以及 HTTP 服务（-dport 80）和 HTTPS 服务（--dport 443）。# Set a default policy of DROP *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] # Accept any related or established connections -I INPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT -I OUTPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT # Allow all traffic on the loopback interface -A INPUT -i lo -j ACCEPT -A OUTPUT -o lo -j ACCEPT # Allow outbound DHCP request -A OUTPUT –o eth0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT # Allow inbound SSH -A INPUT -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT # Allow outbound email -A OUTPUT -i eth0 -p tcp -m tcp --dport 25 -m state --state NEW -j ACCEPT # Outbound DNS lookups -A OUTPUT -o eth0 -p udp -m udp --dport 53 -j ACCEPT # Outbound PING requests -A OUTPUT –o eth0 -p icmp -j ACCEPT # Outbound Network Time Protocol (NTP) requests -A OUTPUT –o eth0 -p udp --dport 123 --sport 123 -j ACCEPT # Outbound HTTP -A OUTPUT -o eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT -A OUTPUT -o eth0 -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT COMMIT限制 IP 地址范围应用场景：贵公司的 CEO 认为员工在 Facebook 上花费过多的时间，需要采取一些限制措施。CEO 命令下达给 CIO，CIO 命令 CISO，最终任务由你来执行。你决定阻止一切到 Facebook 的访问连接。首先你使用 host 或者 whois 命令来获取 Facebook 的 IP 地址。host -t a www.facebook.com www.facebook.com is an alias for star.c10r.facebook.com. star.c10r.facebook.com has address 31.13.65.17 whois 31.13.65.17 | grep inetnum inetnum: 31.13.64.0 - 31.13.127.255然后使用 CIDR 到 IPv4 转换 页面来将其转换为 CIDR 表示法。然后你得到 31.13.64.0/18 的地址。输入以下命令来阻止对 Facebook 的访问：iptables -A OUTPUT -p tcp -i eth0 –o eth1 –d 31.13.64.0/18 -j DROP按时间规定做限制 - 场景1应用场景：公司员工强烈反对限制一切对 Facebook 的访问，这导致了 CEO 放宽了要求（考虑到员工的反对以及他的助理提醒说她负责更新他的 Facebook 页面）。然后 CEO 决定允许在午餐时间访问 Facebook（中午 12 点到下午 1 点之间）。假设默认规则是丢弃，使用 iptables 的时间功能便可以实现。iptables –A OUTPUT -p tcp -m multiport --dport http,https -i eth0 -o eth1 -m time --timestart 12:00 –timestop 13:00 –d 31.13.64.0/18 -j ACCEPT该命令中指定在中午12点（--timestart 12:00）到下午 1 点（--timestop 13:00）之间允许（-j ACCEPT）到 Facebook.com （-d [31.13.64.0/18][5]）的 http 以及 https （-m multiport --dport http,https）的访问。按时间规定做限制 - 场景2应用场景：在计划系统维护期间，你需要设置凌晨 2 点到 3 点之间拒绝所有的 TCP 和 UDP 访问，这样维护任务就不会受到干扰。使用两个 iptables 规则可实现：iptables -A INPUT -p tcp -m time --timestart 02:00 --timestop 03:00 -j DROP iptables -A INPUT -p udp -m time --timestart 02:00 --timestop 03:00 -j DROP该规则禁止（-j DROP）在凌晨2点（--timestart 02:00）到凌晨3点（--timestop 03:00）之间的 TCP 和 UDP （-p tcp and -p udp）的数据进入（-A INPUT）访问。限制连接数量应用场景：你的 web 服务器有可能受到来自世界各地的 DoS 攻击，为了避免这些攻击，你可以限制单个 IP 地址到你的 web 服务器创建连接的数量：iptables –A INPUT –p tcp –syn -m multiport -–dport http,https –m connlimit -–connlimit-above 20 –j REJECT -–reject-with-tcp-reset分析一下上面的命令。如果单个主机在一分钟之内新建立（-p tcp -syn）超过 20 个（-connlimit-above 20）到你的 web 服务器（--dport http,https）的连接，服务器将拒绝（-j REJECT）建立新的连接，然后通知对方新建连接被拒绝（--reject-with-tcp-reset）。监控 iptables 规则应用场景：由于数据包会遍历链中的规则，iptables 遵循 “首次匹配获胜” 的原则，因此经常匹配的规则应该靠近策略的顶部，而不太频繁匹配的规则应该接近底部。 你怎么知道哪些规则使用最多或最少，可以在顶部或底部附近监控？技巧 #1: 查看规则被访问了多少次使用命令：iptables -L -v -n –line-numbers用 -L 选项列出链中的所有规则。因为没有指定具体哪条链，所有链规则都会被输出，使用 -v 选项显示详细信息，-n 选项则显示数字格式的数据包和字节计数器，每个规则开头的数值表示该规则在链中的位置。根据数据包和字节计数的结果，你可以将访问频率最高的规则放到顶部，将访问频率最低的规则放到底部。技巧 #2: 删除不必要的规则哪条规则从来没有被访问过？这些可以被清除掉。用如下命令查看：iptables -nvL | grep -v "0 0"注意：两个数字 0 之间不是 Tab 键，而是 5 个空格。技巧 #3: 监控正在发生什么可能你也想像使用 top 命令一样来实时监控 iptables 的情况。使用如下命令来动态监视 iptables 中的活动，并仅显示正在遍历的规则：watch --interval=5 'iptables -nvL | grep -v "0 0"'watch 命令通过参数 iptables -nvL | grep -v “0 0“ 每隔 5 秒输出 iptables 的动态。这条命令允许你查看数据包和字节计数的变化。输出日志应用场景：经理觉得你这个防火墙员工的工作质量杠杠的，但如果能有网络流量活动日志最好了。有时候这比写一份有关工作的报告更有效。使用工具 FWLogwatch 基于 iptables 防火墙记录来生成日志报告。FWLogwatch 工具支持很多形式的报告并且也提供了很多分析功能。它生成的日志以及月报告使得管理员可以节省大量时间并且还更好地管理网络，甚至减少未被注意的潜在攻击。这里是一个 FWLogwatch 生成的报告示例：不要满足于允许和丢弃规则本文中已经涵盖了 iptables 的很多方面，从避免封锁自己、配置 iptables 防火墙以及监控 iptables 中的活动等等方面介绍了 iptables。你可以从这里开始探索 iptables 甚至获取更多的使用技巧。via: https://opensource.com/article/18/10/iptables-tips-and-tricks作者：Gary Smith 选题：lujun9972 译者：jrg 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
以下是如何使用 iptables 和 firewalld 工具来管理 Linux 防火墙规则。这篇文章摘自我的书《Linux in Action》，尚未发布的第二个曼宁出版项目。防火墙防火墙是一组规则。当数据包进出受保护的网络区域时，进出内容（特别是关于其来源、目标和使用的协议等信息）会根据防火墙规则进行检测，以确定是否允许其通过。下面是一个简单的例子:防火墙可以根据协议或基于目标的规则过滤请求。一方面， iptables 是 Linux 机器上管理防火墙规则的工具。另一方面，firewalld 也是 Linux 机器上管理防火墙规则的工具。你有什么问题吗？如果我告诉你还有另外一种工具，叫做 nftables，这会不会糟蹋你的美好一天呢？好吧，我承认整件事确实有点好笑，所以让我来解释一下。这一切都从 Netfilter 开始，它在 Linux 内核模块级别控制访问网络栈。几十年来，管理 Netfilter 钩子的主要命令行工具是 iptables 规则集。因为调用这些规则所需的语法看起来有点晦涩难懂，所以各种用户友好的实现方式，如 ufw 和 firewalld 被引入，作为更高级别的 Netfilter 解释器。然而，ufw 和 firewalld 主要是为解决单独的计算机所面临的各种问题而设计的。构建全方面的网络解决方案通常需要 iptables，或者从 2014 年起，它的替代品 nftables (nft 命令行工具)。iptables 没有消失，仍然被广泛使用着。事实上，在未来的许多年里，作为一名管理员，你应该会使用 iptables 来保护的网络。但是 nftables 通过操作经典的 Netfilter 工具集带来了一些重要的崭新的功能。从现在开始，我将通过示例展示 firewalld 和 iptables 如何解决简单的连接问题。使用 firewalld 配置 HTTP 访问正如你能从它的名字中猜到的，firewalld 是 systemd 家族的一部分。firewalld 可以安装在 Debian/Ubuntu 机器上，不过，它默认安装在 RedHat 和 CentOS 上。如果您的计算机上运行着像 Apache 这样的 web 服务器，您可以通过浏览服务器的 web 根目录来确认防火墙是否正在工作。如果网站不可访问，那么 firewalld 正在工作。你可以使用 firewall-cmd 工具从命令行管理 firewalld 设置。添加 –state 参数将返回当前防火墙的状态:# firewall-cmd --state running默认情况下，firewalld 处于运行状态，并拒绝所有传入流量，但有几个例外，如 SSH。这意味着你的网站不会有太多的访问者，这无疑会为你节省大量的数据传输成本。然而，这不是你对 web 服务器的要求，你希望打开 HTTP 和 HTTPS 端口，按照惯例，这两个端口分别被指定为 80 和 443。firewalld 提供了两种方法来实现这个功能。一个是通过 –add-port 参数，该参数直接引用端口号及其将使用的网络协议（在本例中为TCP）。 另外一个是通过 –permanent 参数，它告诉 firewalld 在每次服务器启动时加载此规则：# firewall-cmd --permanent --add-port=80/tcp # firewall-cmd --permanent --add-port=443/tcp–reload 参数将这些规则应用于当前会话：# firewall-cmd --reload查看当前防火墙上的设置，运行 –list-services：# firewall-cmd --list-services dhcpv6-client http https ssh假设您已经如前所述添加了浏览器访问，那么 HTTP、HTTPS 和 SSH 端口现在都应该是和 dhcpv6-client 一样开放的 —— 它允许 Linux 从本地 DHCP 服务器请求 IPv6 IP 地址。使用 iptables 配置锁定的客户信息亭我相信你已经看到了信息亭——它们是放在机场、图书馆和商务场所的盒子里的平板电脑、触摸屏和 ATM 类电脑，邀请顾客和路人浏览内容。大多数信息亭的问题是，你通常不希望用户像在自己家一样，把他们当成自己的设备。它们通常不是用来浏览、观看 YouTube 视频或对五角大楼发起拒绝服务攻击的。因此，为了确保它们没有被滥用，你需要锁定它们。一种方法是应用某种信息亭模式，无论是通过巧妙使用 Linux 显示管理器还是控制在浏览器级别。但是为了确保你已经堵塞了所有的漏洞，你可能还想通过防火墙添加一些硬性的网络控制。在下一节中，我将讲解如何使用iptables 来完成。关于使用 iptables，有两件重要的事情需要记住：你给出的规则的顺序非常关键；iptables 规则本身在重新启动后将无法保持。我会一次一个地在解释这些。信息亭项目为了说明这一切，让我们想象一下，我们为一家名为 BigMart 的大型连锁商店工作。它们已经存在了几十年；事实上，我们想象中的祖父母可能是在那里购物并长大的。但是如今，BigMart 公司总部的人可能只是在数着亚马逊将他们永远赶下去的时间。尽管如此，BigMart 的 IT 部门正在尽他们最大努力提供解决方案，他们向你发放了一些具有 WiFi 功能信息亭设备，你在整个商店的战略位置使用这些设备。其想法是，登录到 BigMart.com 产品页面，允许查找商品特征、过道位置和库存水平。信息亭还允许进入 bigmart-data.com，那里储存着许多图像和视频媒体信息。除此之外，您还需要允许下载软件包更新。最后，您还希望只允许从本地工作站访问 SSH，并阻止其他人登录。下图说明了它将如何工作：*信息亭业务流由 iptables 控制。 *脚本以下是 Bash 脚本内容：#!/bin/bash iptables -A OUTPUT -p tcp -d bigmart.com -j ACCEPT iptables -A OUTPUT -p tcp -d bigmart-data.com -j ACCEPT iptables -A OUTPUT -p tcp -d ubuntu.com -j ACCEPT iptables -A OUTPUT -p tcp -d ca.archive.ubuntu.com -j ACCEPT iptables -A OUTPUT -p tcp --dport 80 -j DROP iptables -A OUTPUT -p tcp --dport 443 -j DROP iptables -A INPUT -p tcp -s 10.0.3.1 --dport 22 -j ACCEPT iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 22 -j DROP我们从基本规则 -A 开始分析，它告诉 iptables 我们要添加规则。OUTPUT 意味着这条规则应该成为输出链的一部分。-p 表示该规则仅使用 TCP 协议的数据包，正如 -d 告诉我们的，目的地址是 bigmart.com。-j 参数的作用是当数据包符合规则时要采取的操作是 ACCEPT。第一条规则表示允许（或接受）请求。但，往下的规则你能看到丢弃（或拒绝）的请求。规则顺序是很重要的。因为 iptables 会对一个请求遍历每个规则，直到遇到匹配的规则。一个向外发出的浏览器请求，比如访问 bigmart.com 是会通过的，因为这个请求匹配第一条规则，但是当它到达 dport 80 或 dport 443 规则时——取决于是 HTTP 还是 HTTPS 请求——它将被丢弃。当遇到匹配时，iptables 不再继续往下检查了。（LCTT 译注：此处原文有误，径改。）另一方面，向 ubuntu.com 发出软件升级的系统请求，只要符合其适当的规则，就会通过。显然，我们在这里做的是，只允许向我们的 BigMart 或 Ubuntu 发送 HTTP 或 HTTPS 请求，而不允许向其他目的地发送。最后两条规则将处理 SSH 请求。因为它不使用端口 80 或 443 端口，而是使用 22 端口，所以之前的两个丢弃规则不会拒绝它。在这种情况下，来自我的工作站的登录请求将被接受，但是对其他任何地方的请求将被拒绝。这一点很重要：确保用于端口 22 规则的 IP 地址与您用来登录的机器的地址相匹配——如果不这样做，将立即被锁定。当然，这没什么大不了的，因为按照目前的配置方式，只需重启服务器，iptables 规则就会全部丢失。如果使用 LXC 容器作为服务器并从 LXC 主机登录，则使用主机 IP 地址连接容器，而不是其公共地址。如果机器的 IP 发生变化，请记住更新这个规则；否则，你会被拒绝访问。在家玩（是在某种一次性虚拟机上）？太好了。创建自己的脚本。现在我可以保存脚本，使用 chmod 使其可执行，并以 sudo 的形式运行它。不要担心“igmart-data.com 没找到”之类的错误 —— 当然没找到；它不存在。chmod +X scriptname.sh sudo ./scriptname.sh你可以使用 cURL 命令行测试防火墙。请求 ubuntu.com 奏效，但请求 manning.com 是失败的 。curl ubuntu.com curl manning.com配置 iptables 以在系统启动时加载现在，我如何让这些规则在每次信息亭启动时自动加载？第一步是将当前规则保存。使用 iptables-save 工具保存规则文件。这将在根目录中创建一个包含规则列表的文件。管道后面跟着 tee 命令，是将我的sudo 权限应用于字符串的第二部分：将文件实际保存到否则受限的根目录。然后我可以告诉系统每次启动时运行一个相关的工具，叫做 iptables-restore 。我们在上一章节（LCTT 译注：指作者的书）中看到的常规 cron 任务并不适用，因为它们在设定的时间运行，但是我们不知道什么时候我们的计算机可能会决定崩溃和重启。有许多方法来处理这个问题。这里有一个：在我的 Linux 机器上，我将安装一个名为 anacron 的程序，该程序将在 /etc/ 目录中为我们提供一个名为 anacrontab 的文件。我将编辑该文件并添加这个 iptables-restore 命令，告诉它加载那个 .rule 文件的当前内容。当引导后，规则每天（必要时）01:01 时加载到 iptables 中（LCTT 译注：anacron 会补充执行由于机器没有运行而错过的 cron 任务，因此，即便 01:01 时机器没有启动，也会在机器启动会尽快执行该任务）。我会给该任务一个标识符（iptables-restore），然后添加命令本身。如果你在家和我一起这样，你应该通过重启系统来测试一下。sudo iptables-save | sudo tee /root/my.active.firewall.rules sudo apt install anacron sudo nano /etc/anacrontab 1 1 iptables-restore iptables-restore < /root/my.active.firewall.rules我希望这些实际例子已经说明了如何使用 iptables 和 firewalld 来管理基于 Linux 的防火墙上的连接问题。via: https://opensource.com/article/18/9/linux-iptables-firewalld作者：David Clinton 选题：lujun9972 译者：heguangzhi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
了解如何在 Linux 中暂时禁用 iptables 防火墙来进行故障排除。还要学习如何保存策略以及如何在启用防火墙时恢复它们。有时你需要关闭 iptables 防火墙来做一些连接故障排除，然后你需要重新打开它。在执行此操作时，你还需要保存所有防火墙策略。在本文中，我们将引导你了解如何保存防火墙策略以及如何禁用/启用 iptables 防火墙。有关 iptables 防火墙和策略的更多详细信息请阅读我们的文章。保存 iptables 策略临时禁用 iptables 防火墙的第一步是保存现有的防火墙规则/策略。iptables-save 命令列出你可以保存到服务器中的所有现有策略。root@kerneltalks # # iptables-save # Generated by iptables-save v1.4.21 on Tue Jun 19 09:54:36 2018 *nat :PREROUTING ACCEPT [1:52] :INPUT ACCEPT [1:52] :OUTPUT ACCEPT [15:1140] :POSTROUTING ACCEPT [15:1140] :DOCKER - [0:0] ---- output trucated---- root@kerneltalks # iptables-save > /root/firewall_rules.backup 因此，iptables-save 是可以用来备份 iptables 策略的命令。停止/禁用 iptables 防火墙对于较老的 Linux 内核，你可以选择使用 service iptables stop 停止 iptables 服务，但是如果你在用新内核，则只需清除所有策略并允许所有流量通过防火墙。这和你停止防火墙效果一样。使用下面的命令列表来做到这一点。root@kerneltalks # iptables -F root@kerneltalks # iptables -X root@kerneltalks # iptables -P INPUT ACCEPT root@kerneltalks # iptables -P OUTPUT ACCEPT root@kerneltalks # iptables -P FORWARD ACCEPT 这里 –-F：删除所有策略链-X：删除用户定义的链-P INPUT/OUTPUT/FORWARD ：接受指定的流量完成后，检查当前的防火墙策略。它应该看起来像下面这样接受所有流量（和禁用/停止防火墙一样）# iptables -L 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 恢复防火墙策略故障排除后，你想要重新打开 iptables 的所有配置。你需要先从我们在第一步中执行的备份中恢复策略。root@kerneltalks # iptables-restore </root/firewall_rules.backup 启动 iptables 防火墙然后启动 iptables 服务，以防止你在上一步中使用 service iptables start 停止了它。如果你已经停止服务，那么只有恢复策略才能有用。检查所有策略是否恢复到 iptables 配置中：# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy DROP) target prot opt source destination DOCKER-USER all -- anywhere anywhere DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere -----output truncated----- 就是这些了！你已成功禁用并启用了防火墙，而不会丢失你的策略规则。via: https://kerneltalks.com/howto/how-to-disable-iptables-firewall-temporarily/作者：kerneltalks 选题：lujun9972 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
如何使用 Linux 防火墙隔离本地欺骗地址
如何使用 iptables 防火墙保护你的网络免遭黑客攻击。即便是被入侵检测和隔离系统所保护的远程网络，黑客们也在寻找各种精巧的方法入侵。IDS/IPS 不能停止或者减少那些想要接管你的网络控制权的黑客攻击。不恰当的配置允许攻击者绕过所有部署的安全措施。在这篇文章中，我将会解释安全工程师或者系统管理员该怎样避免这些攻击。几乎所有的 Linux 发行版都带着一个内建的防火墙来保护运行在 Linux 主机上的进程和应用程序。大多数防火墙都按照 IDS/IPS 解决方案设计，这样的设计的主要目的是检测和避免恶意包获取网络的进入权。Linux 防火墙通常有两种接口：iptables 和 ipchains 程序（LCTT 译注：在支持 systemd 的系统上，采用的是更新的接口 firewalld）。大多数人将这些接口称作 iptables 防火墙或者 ipchains 防火墙。这两个接口都被设计成包过滤器。iptables 是有状态防火墙，其基于先前的包做出决定。ipchains 不会基于先前的包做出决定，它被设计为无状态防火墙。在这篇文章中，我们将会专注于内核 2.4 之后出现的 iptables 防火墙。有了 iptables 防火墙，你可以创建策略或者有序的规则集，规则集可以告诉内核该如何对待特定的数据包。在内核中的是Netfilter 框架。Netfilter 既是框架也是 iptables 防火墙的项目名称。作为一个框架，Netfilter 允许 iptables 勾连被设计来操作数据包的功能。概括地说，iptables 依靠 Netfilter 框架构筑诸如过滤数据包数据的功能。每个 iptables 规则都被应用到一个表中的链上。一个 iptables 链就是一个比较包中相似特征的规则集合。而表（例如 nat 或者 mangle）则描述不同的功能目录。例如， mangle 表用于修改包数据。因此，特定的修改包数据的规则被应用到这里；而过滤规则被应用到 filter 表，因为 filter 表过滤包数据。iptables 规则有一个匹配集，以及一个诸如 Drop 或者 Deny 的目标，这可以告诉 iptables 对一个包做什么以符合规则。因此，没有目标和匹配集，iptables 就不能有效地处理包。如果一个包匹配了一条规则，目标会指向一个将要采取的特定措施。另一方面，为了让 iptables 处理，每个数据包必须匹配才能被处理。现在我们已经知道 iptables 防火墙如何工作，让我们着眼于如何使用 iptables 防火墙检测并拒绝或丢弃欺骗地址吧。打开源地址验证作为一个安全工程师，在处理远程的欺骗地址的时候，我采取的第一步是在内核打开源地址验证。源地址验证是一种内核层级的特性，这种特性丢弃那些伪装成来自你的网络的包。这种特性使用反向路径过滤器方法来检查收到的包的源地址是否可以通过包到达的接口可以到达。（LCTT 译注：到达的包的源地址应该可以从它到达的网络接口反向到达，只需反转源地址和目的地址就可以达到这样的效果）利用下面简单的脚本可以打开源地址验证而不用手工操作：#!/bin/sh #作者: Michael K Aboagye #程序目标: 打开反向路径过滤 #日期: 7/02/18 #在屏幕上显示 “enabling source address verification” echo -n "Enabling source address verification…" #将值0覆盖为1来打开源地址验证 echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter echo "completed" 上面的脚本在执行的时候只显示了 Enabling source address verification 这条信息而不会换行。默认的反向路径过滤的值是 0，0 表示没有源验证。因此，第二行简单地将默认值 0 覆盖为 1。1 表示内核将会通过确认反向路径来验证源地址。最后，你可以使用下面的命令通过选择 DROP 或者 REJECT 目标之一来丢弃或者拒绝来自远端主机的欺骗地址。但是，处于安全原因的考虑，我建议使用 DROP 目标。像下面这样，用你自己的 IP 地址代替 IP-address 占位符。另外，你必须选择使用 REJECT 或者 DROP 中的一个，这两个目标不能同时使用。iptables -A INPUT -i internal_interface -s IP_address -j REJECT / DROP iptables -A INPUT -i internal_interface -s 192.168.0.0/16 -j REJECT / DROP 这篇文章只提供了如何使用 iptables 防火墙来避免远端欺骗攻击的基础知识。via: https://opensource.com/article/18/2/block-local-spoofed-addresses-using-linux-firewall作者：Michael Kwaku Aboagye 译者：leemeans 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
现在的新闻里充斥着服务器被攻击和数据失窃事件。对于一个阅读过安全公告博客的人来说，通过访问错误配置的服务器，利用最新暴露的安全漏洞或通过窃取的密码来获得系统控制权，并不是件多困难的事情。在一个典型的 Linux 服务器上的任何互联网服务都可能存在漏洞，允许未经授权的系统访问。因为在应用程序层面上强化系统以防范任何可能的威胁是不可能做到的事情，而防火墙可以通过限制对系统的访问提供了安全保证。防火墙基于源 IP、目标端口和协议来过滤入站包。因为这种方式中，仅有几个 IP/端口/协议的组合与系统交互，而其它的方式做不到过滤。Linux 防火墙是通过 netfilter 来处理的，它是内核级别的框架。这十几年来，iptables 被作为 netfilter 的用户态抽象层（LCTT 译注： userland，一个基本的 UNIX 系统是由 kernel 和 userland 两部分构成，除 kernel 以外的称为 userland）。iptables 将包通过一系列的规则进行检查，如果包与特定的 IP/端口/协议的组合匹配，规则就会被应用到这个包上，以决定包是被通过、拒绝或丢弃。Firewalld 是最新的 netfilter 用户态抽象层。遗憾的是，由于缺乏描述多区域配置的文档，它强大而灵活的功能被低估了。这篇文章提供了一个示例去改变这种情况。Firewalld 的设计目标firewalld 的设计者认识到大多数的 iptables 使用案例仅涉及到几个单播源 IP，仅让每个符合白名单的服务通过，而其它的会被拒绝。这种模式的好处是，firewalld 可以通过定义的源 IP 和/或网络接口将入站流量分类到不同 区域 zone 。每个区域基于指定的准则按自己配置去通过或拒绝包。另外的改进是基于 iptables 进行语法简化。firewalld 通过使用服务名而不是它的端口和协议去指定服务，使它更易于使用，例如，是使用 samba 而不是使用 UDP 端口 137 和 138 和 TCP 端口 139 和 445。它进一步简化语法，消除了 iptables 中对语句顺序的依赖。最后，firewalld 允许交互式修改 netfilter，允许防火墙独立于存储在 XML 中的永久配置而进行改变。因此，下面的的临时修改将在下次重新加载时被覆盖：# firewall-cmd <some modification> 而，以下的改变在重加载后会永久保存：# firewall-cmd --permanent <some modification> # firewall-cmd --reload 区域在 firewalld 中最上层的组织是区域。如果一个包匹配区域相关联的网络接口或源 IP/掩码 ，它就是区域的一部分。可用的几个预定义区域：# firewall-cmd --get-zones block dmz drop external home internal public trusted work 任何配置了一个网络接口和/或一个源的区域就是一个 活动区域 active zone 。列出活动的区域：# firewall-cmd --get-active-zones public interfaces: eno1 eno2 Interfaces （接口）是系统中的硬件和虚拟的网络适配器的名字，正如你在上面的示例中所看到的那样。所有的活动的接口都将被分配到区域，要么是默认的区域，要么是用户指定的一个区域。但是，一个接口不能被分配给多于一个的区域。在缺省配置中，firewalld 设置所有接口为 public 区域，并且不对任何区域设置源。其结果是，public 区域是唯一的活动区域。Sources （源）是入站 IP 地址的范围，它也可以被分配到区域。一个源（或重叠的源）不能被分配到多个区域。这样做的结果是产生一个未定义的行为，因为不清楚应该将哪些规则应用于该源。因为指定一个源不是必需的，任何包都可以通过接口匹配而归属于一个区域，而不需要通过源匹配来归属一个区域。这表示通过使用优先级方式，优先到达多个指定的源区域，稍后将详细说明这种情况。首先，我们来检查 public 区域的配置：# firewall-cmd --zone=public --list-all public (default, active) interfaces: eno1 eno2 sources: services: dhcpv6-client ssh ports: masquerade: no forward-ports: icmp-blocks: rich rules: # firewall-cmd --permanent --zone=public --get-target default 逐行说明如下：public (default, active) 表示 public 区域是默认区域（当接口启动时会自动默认），并且它是活动的，因为，它至少有一个接口或源分配给它。interfaces: eno1 eno2 列出了这个区域上关联的接口。sources: 列出了这个区域的源。现在这里什么都没有，但是，如果这里有内容，它们应该是这样的格式 xxx.xxx.xxx.xxx/xx。services: dhcpv6-client ssh 列出了允许通过这个防火墙的服务。你可以通过运行 firewall-cmd --get-services 得到一个防火墙预定义服务的详细列表。ports: 列出了一个允许通过这个防火墙的目标端口。它是用于你需要去允许一个没有在 firewalld 中定义的服务的情况下。masquerade: no 表示这个区域是否允许 IP 伪装。如果允许，它将允许 IP 转发，它可以让你的计算机作为一个路由器。forward-ports: 列出转发的端口。icmp-blocks: 阻塞的 icmp 流量的黑名单。rich rules: 在一个区域中优先处理的高级配置。default 是目标区域，它决定了与该区域匹配而没有由上面设置中显式处理的包的动作。一个简单的单区域配置示例如果只是简单地锁定你的防火墙。简单地在删除公共区域上当前允许的服务，并重新加载：# firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client # firewall-cmd --permanent --zone=public --remove-service=ssh # firewall-cmd --reload 在下面的防火墙上这些命令的结果是：# firewall-cmd --zone=public --list-all public (default, active) interfaces: eno1 eno2 sources: services: ports: masquerade: no forward-ports: icmp-blocks: rich rules: # firewall-cmd --permanent --zone=public --get-target default 本着尽可能严格地保证安全的精神，如果发生需要在你的防火墙上临时开放一个服务的情况（假设是 ssh），你可以增加这个服务到当前会话中（省略 --permanent），并且指示防火墙在一个指定的时间之后恢复修改：# firewall-cmd --zone=public --add-service=ssh --timeout=5m 这个 timeout 选项是一个以秒（s）、分（m）或小时（h）为单位的时间值。目标当一个区域处理它的源或接口上的一个包时，但是，没有处理该包的显式规则时，这时区域的 目标 target 决定了该行为：ACCEPT：通过这个包。%%REJECT%%：拒绝这个包，并返回一个拒绝的回复。DROP：丢弃这个包，不回复任何信息。default：不做任何事情。该区域不再管它，把它踢到“楼上”。在 firewalld 0.3.9 中有一个 bug （已经在 0.3.10 中修复），对于一个目标是除了“default”以外的源区域，不管允许的服务是什么，这的目标都会被应用。例如，一个使用目标 DROP 的源区域，将丢弃所有的包，甚至是白名单中的包。遗憾的是，这个版本的 firewalld 被打包到 RHEL7 和它的衍生版中，使它成为一个相当常见的 bug。本文中的示例避免了可能出现这种行为的情况。优先权活动区域中扮演两个不同的角色。关联接口行为的区域作为接口区域，并且，关联源行为的区域作为源区域（一个区域能够扮演两个角色）。firewalld 按下列顺序处理一个包：相应的源区域。可以存在零个或一个这样的区域。如果这个包满足一个 富规则 rich rule 、服务是白名单中的、或者目标没有定义，那么源区域处理这个包，并且在这里结束。否则，向上传递这个包。相应的接口区域。肯定有一个这样的区域。如果接口处理这个包，那么到这里结束。否则，向上传递这个包。firewalld 默认动作。接受 icmp 包并拒绝其它的一切。这里的关键信息是，源区域优先于接口区域。因此，对于多区域的 firewalld 配置的一般设计模式是，创建一个优先源区域来允许指定的 IP 对系统服务的提升访问，并在一个限制性接口区域限制其它访问。一个简单的多区域示例为演示优先权，让我们在 public 区域中将 http 替换成 ssh，并且为我们喜欢的 IP 地址，如 1.1.1.1，设置一个默认的 internal 区域。以下的命令完成这个任务：# firewall-cmd --permanent --zone=public --remove-service=ssh # firewall-cmd --permanent --zone=public --add-service=http # firewall-cmd --permanent --zone=internal --add-source=1.1.1.1 # firewall-cmd --reload 这些命令的结果是生成如下的配置：# firewall-cmd --zone=public --list-all public (default, active) interfaces: eno1 eno2 sources: services: dhcpv6-client http ports: masquerade: no forward-ports: icmp-blocks: rich rules: # firewall-cmd --permanent --zone=public --get-target default # firewall-cmd --zone=internal --list-all internal (active) interfaces: sources: 1.1.1.1 services: dhcpv6-client mdns samba-client ssh ports: masquerade: no forward-ports: icmp-blocks: rich rules: # firewall-cmd --permanent --zone=internal --get-target default 在上面的配置中，如果有人尝试从 1.1.1.1 去 ssh，这个请求将会成功，因为这个源区域（internal）被首先应用，并且它允许 ssh 访问。如果有人尝试从其它的地址，如 2.2.2.2，去访问 ssh，它不是这个源区域的，因为和这个源区域不匹配。因此，这个请求被直接转到接口区域（public），它没有显式处理 ssh，因为，public 的目标是 default，这个请求被传递到默认动作，它将被拒绝。如果 1.1.1.1 尝试进行 http 访问会怎样？源区域（internal）不允许它，但是，目标是 default，因此，请求将传递到接口区域（public），它被允许访问。现在，让我们假设有人从 3.3.3.3 拖你的网站。要限制从那个 IP 的访问，简单地增加它到预定义的 drop 区域，正如其名，它将丢弃所有的连接：# firewall-cmd --permanent --zone=drop --add-source=3.3.3.3 # firewall-cmd --reload 下一次 3.3.3.3 尝试去访问你的网站，firewalld 将转发请求到源区域（drop）。因为目标是 DROP，请求将被拒绝，并且它不会被转发到接口区域（public）。一个实用的多区域示例假设你为你的组织的一台服务器配置防火墙。你希望允许全世界使用 http 和 https 的访问，你的组织（1.1.0.0/16）和工作组（1.1.1.0/8）使用 ssh 访问，并且你的工作组可以访问 samba 服务。使用 firewalld 中的区域，你可以用一个很直观的方式去实现这个配置。public 这个命名，它的逻辑似乎是把全世界访问指定为公共区域，而 internal 区域用于为本地使用。从在 public 区域内设置使用 http 和 https 替换 dhcpv6-client 和 ssh 服务来开始：# firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client # firewall-cmd --permanent --zone=public --remove-service=ssh # firewall-cmd --permanent --zone=public --add-service=http # firewall-cmd --permanent --zone=public --add-service=https 然后，取消 internal 区域的 mdns、samba-client 和 dhcpv6-client 服务（仅保留 ssh），并增加你的组织为源：# firewall-cmd --permanent --zone=internal --remove-service=mdns # firewall-cmd --permanent --zone=internal --remove-service=samba-client # firewall-cmd --permanent --zone=internal --remove-service=dhcpv6-client # firewall-cmd --permanent --zone=internal --add-source=1.1.0.0/16 为容纳你提升的 samba 的权限，增加一个富规则：# firewall-cmd --permanent --zone=internal --add-rich-rule='rule family=ipv4 source address="1.1.1.0/8" service name="samba" accept' 最后，重新加载，把这些变化拉取到会话中：# firewall-cmd --reload 仅剩下少数的细节了。从一个 internal 区域以外的 IP 去尝试通过 ssh 到你的服务器，结果是回复一个拒绝的消息。它是 firewalld 默认的。更为安全的作法是去显示不活跃的 IP 行为并丢弃该连接。改变 public 区域的目标为 DROP，而不是 default 来实现它：# firewall-cmd --permanent --zone=public --set-target=DROP # firewall-cmd --reload 但是，等等，你不再可以 ping 了，甚至是从内部区域！并且 icmp （ping 使用的协议）并不在 firewalld 可以列入白名单的服务列表中。那是因为，icmp 是第 3 层的 IP 协议，它没有端口的概念，不像那些捆绑了端口的服务。在设置公共区域为 DROP 之前，ping 能够通过防火墙是因为你的 default 目标通过它到达防火墙的默认动作（default），即允许它通过。但现在它已经被删除了。为恢复内部网络的 ping，使用一个富规则：# firewall-cmd --permanent --zone=internal --add-rich-rule='rule protocol value="icmp" accept' # firewall-cmd --reload 结果如下，这里是两个活动区域的配置：# firewall-cmd --zone=public --list-all public (default, active) interfaces: eno1 eno2 sources: services: http https ports: masquerade: no forward-ports: icmp-blocks: rich rules: # firewall-cmd --permanent --zone=public --get-target DROP # firewall-cmd --zone=internal --list-all internal (active) interfaces: sources: 1.1.0.0/16 services: ssh ports: masquerade: no forward-ports: icmp-blocks: rich rules: rule family=ipv4 source address="1.1.1.0/8" service name="samba" accept rule protocol value="icmp" accept # firewall-cmd --permanent --zone=internal --get-target default 这个设置演示了一个三层嵌套的防火墙。最外层，public，是一个接口区域，包含全世界的访问。紧接着的一层，internal，是一个源区域，包含你的组织，它是 public 的一个子集。最后，一个富规则增加到最内层，包含了你的工作组，它是 internal 的一个子集。这里的关键信息是，当在一个场景中可以突破到嵌套层，最外层将使用接口区域，接下来的将使用一个源区域，并且在源区域中额外使用富规则。调试firewalld 采用直观范式来设计防火墙，但比它的前任 iptables 更容易产生歧义。如果产生无法预料的行为，或者为了更好地理解 firewalld 是怎么工作的，则可以使用 iptables 描述 netfilter 是如何配置操作的。前一个示例的输出如下，为了简单起见，将输出和日志进行了修剪:# iptables -S -P INPUT ACCEPT ... (forward and output lines) ... -N INPUT_ZONES -N INPUT_ZONES_SOURCE -N INPUT_direct -N IN_internal -N IN_internal_allow -N IN_internal_deny -N IN_public -N IN_public_allow -N IN_public_deny -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -j INPUT_ZONES_SOURCE -A INPUT -j INPUT_ZONES -A INPUT -p icmp -j ACCEPT -A INPUT -m conntrack --ctstate INVALID -j DROP -A INPUT -j REJECT --reject-with icmp-host-prohibited ... (forward and output lines) ... -A INPUT_ZONES -i eno1 -j IN_public -A INPUT_ZONES -i eno2 -j IN_public -A INPUT_ZONES -j IN_public -A INPUT_ZONES_SOURCE -s 1.1.0.0/16 -g IN_internal -A IN_internal -j IN_internal_deny -A IN_internal -j IN_internal_allow -A IN_internal_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT -A IN_internal_allow -s 1.1.1.0/8 -p udp -m udp --dport 137 -m conntrack --ctstate NEW -j ACCEPT -A IN_internal_allow -s 1.1.1.0/8 -p udp -m udp --dport 138 -m conntrack --ctstate NEW -j ACCEPT -A IN_internal_allow -s 1.1.1.0/8 -p tcp -m tcp --dport 139 -m conntrack --ctstate NEW -j ACCEPT -A IN_internal_allow -s 1.1.1.0/8 -p tcp -m tcp --dport 445 -m conntrack --ctstate NEW -j ACCEPT -A IN_internal_allow -p icmp -m conntrack --ctstate NEW -j ACCEPT -A IN_public -j IN_public_deny -A IN_public -j IN_public_allow -A IN_public -j DROP -A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT -A IN_public_allow -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT 在上面的 iptables 输出中，新的链（以 -N 开始的行）是被首先声明的。剩下的规则是附加到（以 -A 开始的行） iptables 中的。已建立的连接和本地流量是允许通过的，并且入站包被转到 INPUT_ZONES_SOURCE 链，在那里如果存在相应的区域，IP 将被发送到那个区域。从那之后，流量被转到 INPUT_ZONES 链，从那里它被路由到一个接口区域。如果在那里它没有被处理，icmp 是允许通过的，无效的被丢弃，并且其余的都被拒绝。结论firewalld 是一个文档不足的防火墙配置工具，它的功能远比大多数人认识到的更为强大。以创新的区域范式，firewalld 允许系统管理员去分解流量到每个唯一处理它的分类中，简化了配置过程。因为它直观的设计和语法，它在实践中不但被用于简单的单一区域中也被用于复杂的多区域配置中。via: https://www.linuxjournal.com/content/understanding-firewalld-multi-zone-configurations作者：Nathan Vance 译者：qhwdw 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
无论你使用的哪种 Linux 发行版，你都需要使用基于 iptables 的防火墙来保护它。啊哈！你已经设置好了你的第一台 Linux 服务器并且已经准备发车了！是么？嗯，慢着。默认情况下，你的 Linux 系统对攻击者来说并非是足够安全的。当然，它比 Windows XP 要安全多了，但这说明不了什么。想要使你的 Linux 系统真正稳固，你需要按照 Linode 的 服务器安全指南 来操作。总的来说，首先你必须关闭那些你不需要的服务。当然要这样做的话，你先要知道你正在使用哪些网络服务。你可以使用 shell 命令来找到是哪些服务：netstat -tulpn netstat 将会告诉你正在运行哪些服务和这些服务正在使用的端口是什么。如果你不需要其中的某项服务或端口，你就应该关闭它。例如，除非你正在运行一个网站，否则你是不需要运行中的 Apache 或 Nginx 服务器，也不需要开启 80 或 8080 端口。总之一句话，不确定的话，就关了它先。在一个最简单的，没有做过任何额外更改的 Linux 服务器上，你会看到 SSH、 RPC 和 NTPdate 运行在它们的公开端口上。不要添加像 telnet 这样陈旧而不安全的 shell 程序，否则老司机就会在你不经意间将你的 Linux 小跑车开走了。也许，在上世纪 80 年代的时候你喜欢把 telnet 当作你 SunOS 机器上的备份登录方式，但是那早已成为了过去。就 SSH 来说，你应该使用 RSA 密钥 和 Fail2Ban 来加固。除非你需要 RPC，否则就卸载它——如果你不知道需要不需要它的话，那就是不需要。关于如何关门已经说的够多了；让我们来聊聊利用 iptables 来锁定进来的流量吧。当你启动 Linux 服务器的时候它是没有任何规则的。这就意味着所有的流量都是被允许的。这当然是不好的。因此，你需要及时的设置你的防火墙。Iptables 是一种用来给 netfilter 设置网络策略规则的 shell 工具，netfilter 是Linux 系统下的默认防火墙，它利用一组规则来允许或禁止流量。当有人尝试连接上你的系统——有些人无时不刻地尝试这么干，而且从不气馁——iptables 就会检查这些请求是否与规则列表相匹配。如果没有匹配到任何的规则，它就会采取默认操作。这个默认操作应该是将连接“Drop”掉，即禁掉这些意图闯入者。而且这不会让他们知道这些网络探测行为发生了什么。（你也可以将链接“Reject”掉，但是这会同时让他们知道你有一个正在运行的 Linux 防火墙。就目前而言，让陌生人能获取到我们系统的信息越少越好。至少，我是这么认为的。）现在，你可以用 iptables 来设置你的防火墙了。我已经这么做了。就像以前，我骑着自行车去六英里外上班，并且两边都是上坡。而现在，我开车去。这其实比喻的是我使用 Fedora 发行版的 FirewallD 和 Debian 系发行版的 UFW（Uncomplicated Firewall）。这些都是易用的 iptables 的 shell 前端。你可以在以下的 Linode 指南中找到适合的使用方式：FirewallD 和 UFW。从本质上来说设置这些规则就是在你的服务器上放置“非请勿入”的告示牌。用起来吧。但是也别太兴奋地把所有的链接都关闭了。例如：sudo ufw default deny incoming 看起来是个好主意哦。别忘了，它禁止了所有链接，包括你自己哦！很好，它就是这么干的。这意味着它也同样禁止了 SSH 的登录。也就是说你再也不能登录你那新服务器了。哇哦！不过，如果你犯了错，错误的将更多的链接都禁止了。你看，老司机也同样被你挡在门外了。或者，更准确得说，这不是你或你的服务器所遇到的个别现象。当然，你也不是每天受到 3 亿多次攻击尝试的美国国家安全局（NSA）。但是攻击脚本根本不在乎你是谁。它只是不断的检查寻找网络中存在已知漏洞的服务器。在平常的一天中我自己的小服务器就会受到数以百计的攻击。都这样了，你还在等什么呢？去吧，加固你的网络服务吧。安装 FirewallD 或者 UFW 来加固你的服务器吧。你会愿意去做的。关于作者：Steven J. Vaughan-Nichols 是一位资深的 IT 专栏作家，他的作品出现在许多行业领袖媒体上，包括 ZDNet.com、PC Magazine、InfoWorld、ComputerWorld、Linux Today 和 eWEEK 等。Steven 在 IT 专业方面的见解犀利，虽然他的观点和云计算方面的认识，并不代表 Linode 观点，但是我们仍然非常感谢他的贡献。你可以在 Twitter 上关注他 （@sjvn）。via: https://medium.com/linode-cube/locking-down-your-linux-server-24d8516ae374#.qy8qq4bx2作者：Steven J. Vaughan-Nichols 译者：wcnnbdk1 校对：wxy本文由 LCTT 组织编译，Linux中国 荣誉推出
如何在 Linux 中根据国家位置来阻断网络流量
作为一名维护 Linux 生产服务器的系统管理员，你可能会遇到这样一些情形：你需要根据地理位置，选择性地阻断或允许网络流量通过。 例如你正经历一次由注册在某个特定国家的 IP 发起的 DoS 攻击；或者基于安全考虑，你想阻止来自未知国家的 SSH 登录请求；又或者你的公司对某些在线视频有分销权，它要求只能在特定的国家内合法发行；抑或是由于公司的政策，你需要阻止某个本地主机将文件上传至任意一个非美国的远程云端存储。所有的上述情形都需要设置防火墙，使之具有基于国家位置过滤流量的功能。有几个方法可以做到这一点，其中之一是你可以使用 TCP wrappers 来为某个应用（例如 SSH，NFS， httpd）设置条件阻塞。但其缺点是你想要保护的那个应用必须以支持 TCP wrappers 的方式构建。另外，TCP wrappers 并不总是能够在各个平台中获取到（例如，Arch Linux 放弃了对它的支持）。另一种方式是结合基于国家的 GeoIP 信息，设置 ipset，并将它应用到 iptables 的规则中。后一种方式看起来更有希望一些，因为基于 iptables 的过滤器是与应用无关的，且容易设置。在本教程中，我将展示 另一个基于 iptables 的 GeoIP 过滤器，它由 xtables-addons 来实现。对于那些不熟悉它的人来说， xtables-addons 是用于 netfilter/iptables 的一系列扩展。一个包含在 xtables-addons 中的名为 xt\_geoip 的模块扩展了 netfilter/iptables 的功能，使得它可以根据流量来自或流向的国家来进行过滤，IP 掩蔽（NAT）或丢包。若你想使用 xt\_geoip，你不必重新编译内核或 iptables，你只需要使用当前的内核构建环境（/lib/modules/uname -r/build）以模块的形式构建 xtables-addons。同时也不需要进行重启。只要你构建并安装了 xtables-addons ， xt\_geoip 便能够配合 iptables 使用。至于 xt\_geoip 和 ipset 之间的比较，xtables-addons 的官方网站 上是这么说的： 相比于 ipset，xt\_geoip 在内存占用上更胜一筹，但对于匹配速度，基于哈希的 ipset 可能更有优势。在教程的余下部分，我将展示如何使用 iptables/xt\_geoip 来根据流量的来源地或流入的国家阻断网络流量。在 Linux 中安装 xtables-addons下面介绍如何在各种 Linux 平台中编译和安装 xtables-addons。为了编译 xtables-addons，首先你需要安装一些依赖软件包。在 Debian，Ubuntu 或 Linux Mint 中安装依赖$ sudo apt-get install iptables-dev xtables-addons-common libtext-csv-xs-perl pkg-config 在 CentOS，RHEL 或 Fedora 中安装依赖CentOS/RHEL 6 需要事先设置好 EPEL 仓库（为 perl-Text-CSV\_XS 所需要）。$ sudo yum install gcc-c++ make automake kernel-devel-`uname -r` wget unzip iptables-devel perl-Text-CSV_XS 编译并安装 xtables-addons从 xtables-addons 的官方网站 下载源码包，然后按照下面的指令编译安装它。$ wget http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.10.tar.xz $ tar xf xtables-addons-2.10.tar.xz $ cd xtables-addons-2.10 $ ./configure $ make $ sudo make install 需要注意的是，对于基于红帽的系统（CentOS、RHEL、Fedora），它们默认开启了 SELinux，所以有必要像下面这样调整 SELinux 的策略。否则，SELinux 将阻止 iptables 加载 xt\_geoip 模块。$ sudo chcon -vR --user=system_u /lib/modules/$(uname -r)/extra/*.ko $ sudo chcon -vR --type=lib_t /lib64/xtables/*.so 为 xtables-addons 安装 GeoIP 数据库下一步是安装 GeoIP 数据库，它将被 xt\_geoip 用来查询 IP 地址与国家地区之间的对应关系。方便的是，xtables-addons 的源码包中带有两个帮助脚本，它们被用来从 MaxMind 下载 GeoIP 数据库并将它转化为 xt\_geoip 可识别的二进制形式文件；它们可以在源码包中的 geoip 目录下找到。请遵循下面的指导来在你的系统中构建和安装 GeoIP 数据库。$ cd geoip $ ./xt_geoip_dl $ ./xt_geoip_build GeoIPCountryWhois.csv $ sudo mkdir -p /usr/share/xt_geoip $ sudo cp -r {BE,LE} /usr/share/xt_geoip 根据 MaxMind 的说明,他们的 GeoIP 数据库能够以 99.8% 的准确率识别出 ip 所对应的国家，并且每月这个数据库将进行更新。为了使得本地安装的 GeoIP 数据是最新的，或许你需要设置一个按月执行的 cron job 来时常更新你本地的 GeoIP 数据库。阻断来自或流向某个国家的网络流量一旦 xt\_geoip 模块和 GeoIP 数据库安装好后，你就可以在 iptabels 命令中使用 geoip 的匹配选项。$ sudo iptables -m geoip --src-cc country[,country...] --dst-cc country[,country...] 你想要阻断流量的那些国家是使用2个字母的 ISO3166 代码 来特别指定的（例如 US（美国）、CN（中国）、IN（印度）、FR（法国））。例如，假如你想阻断来自也门（YE） 和 赞比亚（ZM）的流量，下面的 iptabels 命令便可以达到此目的。$ sudo iptables -I INPUT -m geoip --src-cc YE,ZM -j DROP 假如你想阻断流向中国（CN） 的流量，可以运行下面的命令：$ sudo iptables -A OUTPUT -m geoip --dst-cc CN -j DROP 匹配条件也可以通过在 --src-cc 或 --dst-cc 选项前加 ! 来达到相反的目的：假如你想在你的服务器上阻断来自所有非美国的流量，可以运行：$ sudo iptables -I INPUT -m geoip ! --src-cc US -j DROP 对于使用 Firewall-cmd 的用户某些发行版本例如 CentOS/RHEL7 或 Fedora 已经用 firewalld 替代了 iptables 来作为默认的防火墙服务。在这些系统中，你可以类似使用 xt\_geoip 那样，使用 firewall-cmd 来阻断流量。利用 firewall-cmd 命令，上面的三个例子可被重新写为：$ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -m geoip --src-cc YE,ZM -j DROP $ sudo firewall-cmd --direct --add-rule ipv4 filter OUTPUT 0 -m geoip --dst-cc CN -j DROP $ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -m geoip ! --src-cc US -j DROP 总结在本教程中，我展示了使用 iptables/xt\_geoip 来根据流量的来源地或流入的国家轻松地阻断网络流量。假如你有这方面的需求，把它部署到你的防火墙系统中可以使之成为一个实用的办法。作为最后的警告，我应该提醒你的是：在你的服务器上通过基于 GeoIP 的流量过滤来禁止特定国家的流量并不总是万无一失的。GeoIP 数据库本身就不是很准确或齐全，且流量的来源或目的地可以轻易地通过使用 VPN、Tor 或其他任意易受攻击的中继主机来达到欺骗的目的。基于地理位置的过滤器甚至可能会阻止本不该阻止的合法网络流量。在你决定把它部署到你的生产环境之前请仔细考虑这个限制。via: http://xmodulo.com/block-network-traffic-by-country-linux.html作者：Dan Nanni 译者：FSSlc 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
很多情况下，你可能需要在Linux下屏蔽IP地址。比如，作为一个终端用户，你可能想要免受间谍软件或者IP追踪的困扰。或者当你在运行P2P软件时。你可能想要过滤反P2P活动的网络链接。如果你是一名系统管理员，你可能想要禁止垃圾IP地址访问你们的公司邮件服务器。或者你因一些原因想要禁止某些国家访问你的web服务。在许多情况下，然而，你的IP地址屏蔽列表可能会很快地增长到几万的IP。该如何处理这个？Netfilter/IPtables 的问题在Linux中，可以很简单地用netfilter/iptables框架禁止IP地址：$ sudo iptables -A INPUT -s 1.1.1.1 -p TCP -j DROP 如果你想要完全屏蔽一个IP地址段，你可以用下面的命令很简单地做到：$ sudo iptables -A INPUT -s 1.1.2.0/24 -p TCP -j DROP 然而，当你有1000个独立IP地址，且不带CIDR（无类别域间路由）前缀，你该怎么做？你要有1000条iptable规则！这显然这并不适于大规模屏蔽。$ sudo iptables -A INPUT -s 1.1.1.1 -p TCP -j DROP $ sudo iptables -A INPUT -s 2.2.2.2 -p TCP -j DROP $ sudo iptables -A INPUT -s 3.3.3.3 -p TCP -j DROP . . . . 什么是IP集?这时候就是IP集登场了。IP集是一个内核特性，它允许多个（独立）IP地址、MAC地址或者甚至是端口号被编码和有效地存储在位图/哈希内核数据结构中。一旦IP集创建之后，你可以创建一条iptables规则来匹配这个集合。你马上就会看见IP集合的好处了，它可以让你用一条iptable规则匹配多个ip地址！你可以用多个IP地址和端口号的方式来构造IP集，并且可以动态地更新规则而没有性能影响。在Linux中安装IPset工具为了创建和管理IP集，你需要使用称为ipset的用户空间工具。要在Debian、Ubuntu或者Linux Mint上安装：$ sudo apt-get install ipset Fedora或者CentOS/RHEL 7上安装：$ sudo yum install ipset 使用IPset命令禁止IP让我通过简单的示例告诉你该如何使用ipset命令。首先，让我们创建一条新的IP集，名为banthis（名字任意）：$ sudo ipset create banthis hash:net 第二个参数(hash:net)是必须的，代表的是集合的类型。IP集有多个类型。hash:net类型的IP集使用哈希来存储多个CIDR块。如果你想要在一个集合中存储单独的IP地址，你可以使用hash:ip类型。一旦创建了一个IP集之后，你可以用下面的命令来检查：$ sudo ipset list 这显示了一个可用的IP集合列表，并有包含了集合成员的详细信息。默认上，每个IP集合可以包含65536个元素（这里是CIDR块）。你可以通过追加"maxelem N"选项来增加限制。$ sudo ipset create banthis hash:net maxelem 1000000 现在让我们来增加IP块到这个集合中：$ sudo ipset add banthis 1.1.1.1/32 $ sudo ipset add banthis 1.1.2.0/24 $ sudo ipset add banthis 1.1.3.0/24 $ sudo ipset add banthis 1.1.4.10/24 你会看到集合成员已经改变了。$ sudo ipset list 现在是时候去创建一个使用IP集的iptables规则了。这里的关键是使用"-m set --match-set "选项。现在让我们创建一条让之前那些IP块不能通过80端口访问web服务的iptable规则。可以通过下面的命令：$ sudo iptables -I INPUT -m set --match-set banthis src -p tcp --destination-port 80 -j DROP 如果你愿意，你可以保存特定的IP集到一个文件中，以后可以从文件中还原：$ sudo ipset save banthis -f banthis.txt $ sudo ipset destroy banthis $ sudo ipset restore -f banthis.txt 上面的命令中，我使用了destory选项来删除一个已有的IP集来看看我是否可以还原它。自动IP地址禁用现在你应该看到了IP集合的强大了。维护IP黑名单是一件繁琐和费时的工作。实际上，有很多免费或者收费的服务可以来帮你完成这个。一个额外的好处是，让我们看看如何自动将IP黑名单加到IP集中。首先让我们从iblocklist.com得到免费的黑名单，这个网站有不同的免费和收费的名单。免费的版本是P2P格式。接下来我要使用一个名为iblocklist2ipset的开源Python工具来将P2P格式的黑名单转化成IP集。首先，你需要安装了pip（参考这个指导来安装pip）。使用的下面命令安装iblocklist2ipset。$ sudo pip install iblocklist2ipset 在一些发行版如Fedora，你可能需要运行：$ sudo python-pip install iblocklist2ipset 现在到iblocklist.com，抓取任何一个P2P列表的URL（比如"level1"列表）。粘帖URL到下面的命令中。$ iblocklist2ipset generate \ --ipset banthis "http://list.iblocklist.com/?list=ydxerpxkpcfqjaybcssw&fileformat=p2p&archiveformat=gz" \ > banthis.txt 上面的命令运行之后，你会得到一个名为banthis.txt的文件。如果查看它的内容，你会看到像这些：create banthis hash:net family inet hashsize 131072 maxelem 237302 add banthis 1.2.4.0/24 add banthis 1.2.8.0/24 add banthis 1.9.75.8/32 add banthis 1.9.96.105/32 add banthis 1.9.102.251/32 add banthis 1.9.189.65/32 add banthis 1.16.0.0/14 你可以用下面的ipset命令来加载这个文件：$ sudo ipset restore -f banthis.txt 现在可以查看自动创建的IP集：$ sudo ipset list banthis 在写这篇文章时候，“level1”类表包含了237,000个屏蔽的IP列表。你可以看到很多IP地址已经加入到IP集中了。最后，创建一条iptables命令来屏蔽这些坏蛋！总结这篇文章中，我描述了你该如何用强大的ipset来屏蔽不想要的IP地址。同时结合了第三方工具iblocklist2ipset，这样你就可以流畅地维护你的IP屏蔽列表了。那些对ipset的性能提升好奇的人，下图显示了iptables在使用和不使用ipset的基准测试结果（注意时间坐标轴）。告诉我你多么喜欢这个。:-)via: http://xmodulo.com/block-unwanted-ip-addresses-linux.html作者：Dan Nanni 译者：geekpi 校对：wxy本文由 LCTT 原创翻译，Linux中国 荣誉推出
问题：我在CentOS系统上运行一台网页或文件服务器，打算远程访问服务器。因此，我需要更改防火墙规则以允许访问系统上的某个TCP端口。那么，有什么好方法在CentOS或RHEL系统的防火墙上开启TCP/UDP端口？如果希望在服务器上提供服务，诸如CentOS或RHEL的企业级Linux发行版包含内置的强大防火墙，它们默认的防火墙规则十分严格。因此，如果你安装了任何定制的服务（比如web服务器、NFS和Samba），那么它们的流量很有可能被防火墙规则阻塞。所以需要在防火墙上开启必要的端口以允许流量通过。在CentOS/RHEL 6或更早的版本上，iptables服务允许用户与netfilter内核模块交互来在用户空间中配置防火墙规则。然而，从CentOS/RHEL 7开始，一个叫做firewalld新用户空间接口被引入以取代iptables服务。使用这个命令察看当前的防火墙规则：$ sudo iptables -L 现在，让我们看看如何在CentOS/RHEL上修改防火墙来开启一个端口。在CentOS/RHEL 7上开启端口启动CentOS/RHEL 7后，防火墙规则设置由firewalld服务进程默认管理。一个叫做firewall-cmd的命令行客户端支持和这个守护进程通信以永久修改防火墙规则。使用这些命令来永久打开一个新端口（如TCP/80）。$ sudo firewall-cmd --zone=public --add-port=80/tcp --permanent $ sudo firewall-cmd --reload 如果不使用“--permanent”标记，把么防火墙规则在重启后会失效。在CentOS/RHEL 6上开启端口在CentOS/RHEL 6甚至更早版本系统上，iptables服务负责维护防火墙规则。使用iptables的第一条命令可以通过防火墙开启一个新TCP/UDP端口。为了永久保存修改过的规则，还需要第二条命令。$ sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT $ sudo service iptables save 另一种方法是通过一个名为system-config-firewall-tui的命令行用户接口（TUI）的防火墙客户端。$ sudo system-config-firewall-tui 选择位于中间的“Customize”按钮，按下ENTER键即可。如果想要为任何已知的服务（如web服务器）修改防火墙，只需勾选该服务，然后关闭工具。如果想要开启任意一个TCP/UDP端口，选择“Forward”按钮，然后进入下一个界面。选择“Add”按钮添加一条新规则。指定一个端口（如80）或者端口范围（如3000-3030）和协议（如tcp或udp）。最后，保存修改过的配置，关闭工具。这样，防火墙就永久保存了。via: http://ask.xmodulo.com/open-port-firewall-centos-rhel.html译者：KayGuoWhu 校对：wxy本文由 LCTT 原创翻译，Linux中国 荣誉推出