5. 步骤 3:防火墙和设置访问策略

那么什么是“防火墙”呢? 这是一个模糊的术语,可以指代任何在我们和外部世界之间充当保护屏障的事物。 这可以是一个专用系统,或者是一个提供此功能的特定应用程序。 或者它可以是组件的组合,包括硬件和软件的各种组合。 防火墙由“规则”构建而成,这些规则用于定义允许什么进入和退出给定的系统或网络。 让我们看看 Linux 上可用的某些组件,以及我们如何实施合理的安全防火墙策略。

在上面的步骤 1 中,我们已经关闭了所有我们不需要的服务。 在我们的示例中,还有一些我们需要保持运行。 在本节中,我们将在此基础上迈出下一步,并决定哪些我们需要对外界保持开放。 以及哪些我们可以以某种方式限制。 如果我们可以全部阻止它们,那就更好了,但这并不总是实际的。

5.1. 策略

我们现在想要做的是限制连接和流量,以便我们仅允许我们特定情况下所需的最低限度。 在某些情况下,我们可能想要阻止所有传入的“新”连接尝试。 示例:我们想要运行 X,但不希望任何外部人员访问它,因此我们将完全阻止来自外部的连接。 在其他情况下,我们可能想要限制或约束传入连接,仅限于受信任的来源。 限制性越强越好。 示例:我们想从外部 ssh 进入我们的系统,但我们只从我们的工作场所执行此操作。 因此,我们将 sshd 连接限制为我们的工作场所地址范围。 有多种方法可以做到这一点,我们将研究最常见的方法。

我们也不希望将我们的防火墙限制为任何一个应用程序。 “分层”的深度防御方法没有错。 我们的第一道防线将是数据包过滤器——ipchainsiptables(见下文)。 然后我们可以使用其他工具和机制来加强我们的防火墙。

我们将包括一些简短的示例。 我们的经验法则是默认策略拒绝一切,然后仅开放我们需要的东西。 我们将尝试尽可能保持简单,因为它可能是一个复杂且复杂的主题,并且只坚持一些最基本的概念。 有关此主题的更多阅读材料,请参阅链接部分

5.2. 数据包过滤器——Ipchains 和 Iptables

“数据包过滤器”(如 ipchains)能够查看单个数据包,并根据它们发现的内容做出决策。 这些可以用于多种目的。 一个常见的目的是实现防火墙。

Linux 上常见的包过滤器是 ipchains,它是 2.2 内核的标准配置,以及 iptables,它可用于更新的 2.4 内核。iptables 具有更高级的数据包过滤功能,建议任何运行 2.4 内核的人使用。 但两者对于我们的目的都可能是有效的。ipfwadm 是 2.0 内核的类似实用程序(此处未讨论)。

如果构建您自己的 ipchainsiptables 防火墙规则看起来有点令人生畏,那么有各种站点可以自动化该过程。 请参阅链接部分。 此外,包含的示例可以用作起点。 截至 Red Hat 7.1,Red Hat 正在为 ipchainsiptables 提供 init 脚本,并为 gnome-lokkit 提供用于生成非常基本的防火墙规则集(见下文)。 这可能足够了,但仍然建议了解正确的语法以及各种机制的工作方式,因为此类工具很少做超过几个非常简单的规则。

Note

下面给出了各种示例。 这些示例仅用于说明目的,以演示此处讨论的一些概念。 虽然它们也可能用作您自己脚本的起点,但请注意,它们并非旨在涵盖所有内容。 强烈建议您了解脚本的工作原理,以便您可以创建更适合您自己情况的内容。

示例脚本仅保护到一个接口(连接到互联网的接口)的入站连接。 这对于许多简单的家庭类型的情况可能足够了,但是,反过来,这种方法并不适用于所有情况!

5.2.1. ipchains

ipchains 可以与 2.2 或 2.4 内核一起使用。 当 ipchains 就位时,它会检查通过系统的每个数据包。 数据包跨越不同的“链”移动,具体取决于它们的来源和去向。 将“链”视为规则集。 在高级配置中,我们可以定义我们自己的自定义链。 三个默认的内置链是input,即传入流量,output,即传出流量,以及forward,即从一个接口转发到另一个接口的流量(通常用于“伪装”)。 可以通过各种方式操作链来控制进出我们系统的流量。 可以根据我们的判断添加规则以达到期望的结果。

每个“链”的末尾都有一个“目标”。 目标使用-j命令的选项指定。 目标是决定数据包命运并从本质上终止该特定链的原因。 最常见的目标大多是不言自明的ACCEPT, DENY, REJECT,以及MASQ. MASQ用于“ipmasquerading”DENYREJECT本质上做同样的事情,尽管方式不同。 哪个更好? 这是许多争论的主题,并且取决于超出本文档范围的其他因素。 对于我们的目的,两者都应该足够了。

ipchains 具有非常灵活的配置。 可以指定端口(或端口范围)、接口、目标地址、源地址以及各种其他选项。 手册页充分解释了这些细节,我们在此不再赘述。

从互联网进入我们系统的流量,通过input链进入。 这是我们需要尽可能收紧的一个。

下面是一个假设系统的简短示例脚本。 让我们用注释来解释这个脚本的作用。 任何以 “#” 开头的内容都是注释。 ipchains 规则通常合并到 shell 脚本中,使用 shell 变量来帮助实现防火墙逻辑。

#!/bin/sh
#
# ipchains.sh
#
# An example of a simple ipchains configuration. 
#
# This script allows ALL outbound traffic, and denies 
# ALL inbound connection attempts from the outside.
#
###################################################################
# Begin variable declarations and user configuration options ######
#
IPCHAINS=/sbin/ipchains
# This is the WAN interface, that is our link to the outside world.
# For pppd and pppoe users.
# WAN_IFACE="ppp0"
WAN_IFACE="eth0"

## end user configuration options #################################
###################################################################

# The high ports used mostly for connections we initiate and return
# traffic.
LOCAL_PORTS=`cat /proc/sys/net/ipv4/ip_local_port_range |cut -f1`:\
`cat /proc/sys/net/ipv4/ip_local_port_range |cut -f2`

# Any and all addresses from anywhere.
ANYWHERE="0/0"

# Let's start clean and flush all chains to an empty state.
$IPCHAINS -F  

# Set the default policies of the built-in chains. If no match for any 
# of the rules below, these will be the defaults that ipchains uses.
$IPCHAINS -P forward DENY
$IPCHAINS -P output ACCEPT
$IPCHAINS -P input DENY 

# Accept localhost/loopback traffic.
$IPCHAINS -A input -i lo -j ACCEPT

# Get our dynamic IP now from the Inet interface. WAN_IP will be our
# IP address we are protecting from the outside world. Put this
# here, so default policy gets set, even if interface is not up
# yet.
WAN_IP=`ifconfig $WAN_IFACE |grep inet |cut -d : -f 2 |cut -d \  -f 1`

# Bail out with error message if no IP available! Default policy is 
# already set, so all is not lost here.
[ -z "$WAN_IP" ] && echo "$WAN_IFACE not configured, aborting." && exit 1

# Accept non-SYN TCP, and UDP connections to LOCAL_PORTS. These are
# the high, unprivileged ports (1024 to 4999 by default). This will
# allow return connection traffic for connections that we initiate
# to outside sources. TCP connections are opened with 'SYN' packets.
$IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS ! -y -j ACCEPT 

# We can't be so selective with UDP since that protocol does not
# know about SYNs.
$IPCHAINS -A input -p udp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS -j ACCEPT 

## ICMP (ping)
#
# ICMP rules, allow the bare essential types of ICMP only. Ping
# request is blocked, ie we won't respond to someone else's pings,
# but can still ping out. 
$IPCHAINS -A input  -p icmp  --icmp-type echo-reply \
   -s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPCHAINS -A input  -p icmp  --icmp-type destination-unreachable \
   -s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPCHAINS -A input  -p icmp  --icmp-type time-exceeded \
   -s $ANYWHERE -i $WAN_IFACE -j ACCEPT

###################################################################
# Set the catchall, default rule to DENY, and log it all. All other
# traffic not allowed by the rules above, winds up here, where it is
# blocked and logged. This is the default policy for this chain
# anyway, so we are just adding the logging ability here with '-l'.
# Outgoing traffic is allowed as the default policy for the 'output'
# chain. There are no restrictions on that.

$IPCHAINS -A input -l -j DENY

echo "Ipchains firewall is up `date`."

##-- eof ipchains.sh

 

要使用上述脚本,需要使其可执行(即chmod +x ipchains.sh),并由 root 运行以构建链,从而构建防火墙。

总结一下这个例子所做的事情是首先在顶部部分设置一些 shell 变量,以供稍后在脚本中使用。 然后我们设置了默认规则(ipchains 将这些称为“策略”),即拒绝所有入站和转发的流量,并允许我们自己的所有出站流量。 我们必须在高端口、非特权端口中打开一些漏洞,以便我们可以从 bigcat 发起与外部地址的连接的返回流量。 例如,如果我们连接到某人的 Web 服务器,我们希望 HTML 数据能够返回给我们。 这同样适用于其他网络流量。 然后我们允许了一些特定类型的 ICMP 协议(大多数仍然被阻止)。 我们还在记录任何违反我们规则的入站流量,以便我们知道是谁在做什么。 请注意,我们在这里仅使用 IP 地址,而不使用任何类型的主机名。 这是为了使我们的防火墙能够工作,即使在可能发生 DNS 故障的情况下也是如此。 此外,还可以防止任何类型的 DNS 欺骗。

有关语法的完整说明,请参阅 ipchains 手册页。 我们在这里使用的重要参数是

-A input:向 “input” 链添加规则。 默认链为 input、output 和 forward。

-p udp:此规则仅适用于 “UDP” “协议”-p选项可以与 tcp、udp 或 icmp 协议一起使用。

-i $WAN_IFACE:此规则仅适用于指定的接口,并适用于引用的任何链(input、output 或 forward)。

-s <IP 地址>[端口]:此规则仅适用于指定的源地址。 它可以选择在其后立即跟一个端口(例如 22)或端口范围,例如 1023:4999。

-d <IP 地址>[端口]:此规则仅适用于指定的目标地址。 此外,它可能包括端口或端口范围。

-l:任何命中带有此选项的规则的数据包都会被记录(小写 “L”)。

-j ACCEPT:跳转到 “ACCEPT” “目标”。 这有效地终止了此链,并决定了此特定数据包的最终命运,在本例中是 “ACCEPT” 它。 对于其他-j目标也是如此,例如DENY.

总的来说,命令行选项的指定顺序并不重要。 但是链名称(例如input)必须首先出现。

回想一下步骤 1,当我们运行 netstat 时,我们有 X 和打印服务器以及其他服务在运行。 我们不希望这些暴露在互联网上,即使是以有限的方式。 这些仍然在 bigcat 上快乐地运行,但现在安全地隐藏在我们基于 ipchains 的防火墙后面。 您可能还有其他服务也属于此类。

上面的例子是一种简单的一刀切方法。 我们允许我们自己的所有出站流量(不一定是好主意),并阻止来自外部的所有入站连接尝试。 它仅保护一个接口,并且实际上只是该接口的入站侧。 它很可能需要进行一些微调才能使其为您工作。 有关更高级的规则集,请参阅附录。 您可能还想阅读 https://tldp.cn/HOWTO/IPCHAINS-HOWTO.html

每当您对防火墙进行更改时,都应验证其完整性。 确保您的规则似乎在执行您预期操作的一个步骤是查看 ipchains 如何解释您的脚本。 您可以通过打开非常宽的 xterm 并发出以下命令来执行此操作

 # ipchains -L -n -v | less

 

输出按链分组。 您还应该找到一种扫描自己的方法(请参阅下面的验证部分)。 然后密切关注您的日志,以确保您阻止了预期的内容。

5.2.2. iptables

iptables 是 Linux 的下一代数据包过滤器,需要 2.4 内核。 它可以完成 ipchains 可以做的所有事情,但有许多值得注意的增强功能。 在许多方面,语法与 ipchains 相似。 有关详细信息,请参阅手册页。

最值得注意的增强功能是“连接跟踪”,也称为“状态检测”。 这使 iptables 更了解每个数据包的状态。 它不仅知道数据包是 TCP 数据包还是 UDP 数据包,或者它是否设置了 SYN 或 ACK 标志,还知道它是否是现有连接的一部分,或者以某种方式与现有连接相关。 防火墙的含义应该是显而易见的。

最重要的是,使用 iptables 比使用 ipchains 更容易获得严格的防火墙。 因此,这是推荐的方法。

这是与上面相同的脚本,针对 iptables 进行了修订

#!/bin/sh
#
# iptables.sh
#
# An example of a simple iptables configuration. 
#
# This script allows ALL outbound traffic, and denies 
# ALL inbound connection attempts from the Internet interface only.
#
###################################################################
# Begin variable declarations and user configuration options ######
#
IPTABLES=/sbin/iptables
# Local Interfaces
# This is the WAN interface that is our link to the outside world.
# For pppd and pppoe users.
# WAN_IFACE="ppp0"
WAN_IFACE="eth0"
#

## end user configuration options #################################
###################################################################

# Any and all addresses from anywhere.
ANYWHERE="0/0"

# This module may need to be loaded:
modprobe ip_conntrack_ftp

# Start building chains and rules #################################
#
# Let's start clean and flush all chains to an empty state.
$IPTABLES -F  

# Set the default policies of the built-in chains. If no match for any 
# of the rules below, these will be the defaults that IPTABLES uses.
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P INPUT DROP

# Accept localhost/loopback traffic.
$IPTABLES -A INPUT -i lo -j ACCEPT

## ICMP (ping)
#
# ICMP rules, allow the bare essential types of ICMP only. Ping
# request is blocked, ie we won't respond to someone else's pings,
# but can still ping out.
$IPTABLES -A INPUT  -p icmp  --icmp-type echo-reply \
   -s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPTABLES -A INPUT  -p icmp  --icmp-type destination-unreachable \
   -s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPTABLES -A INPUT  -p icmp  --icmp-type time-exceeded \
   -s $ANYWHERE -i $WAN_IFACE -j ACCEPT

###################################################################
# Set the catchall, default rule to DENY, and log it all. All other
# traffic not allowed by the rules above, winds up here, where it is
# blocked and logged. This is the default policy for this chain
# anyway, so we are just adding the logging ability here with '-j
# LOG'. Outgoing traffic is allowed as the default policy for the
# 'output' chain. There are no restrictions on that.

$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -m state --state NEW -i ! $WAN_IFACE -j ACCEPT
$IPTABLES -A INPUT -j LOG -m limit --limit 30/minute --log-prefix "Dropping: "

echo "Iptables firewall is up `date`."

##-- eof iptables.sh

 

这里使用了相同的脚本逻辑,因此这与上一节中的 ipchains 脚本几乎完全相同。 语法上有一些细微的差异。 注意链名称的大小写差异(例如 INPUT 与 input)。 日志记录的处理方式也不同。 它现在有自己的“目标”-j LOG),并且更加灵活。

还有一些非常根本的差异,可能不太明显。 回想一下 ipchains 脚本中的这一部分

# Accept non-SYN TCP, and UDP connections to LOCAL_PORTS. These are the high,
# unprivileged ports (1024 to 4999 by default). This will allow return
# connection traffic for connections that we initiate to outside sources.
# TCP connections are opened with 'SYN' packets. We have already opened 
# those services that need to accept SYNs for, so other SYNs are excluded here
# for everything else.
$IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS ! -y -j ACCEPT 

# We can't be so selective with UDP since that protocol does not know 
# about SYNs.
$IPCHAINS -A input -p udp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS -j ACCEPT 

 

我们通过 ipchains 进行了很多努力,以便我们可以尽可能多地限制不需要的传入连接。 实际上有点笨拙。

该部分在 iptables 版本中缺失了。 由于连接跟踪可以很好地处理这个问题,甚至更多,因此不需要它。 这是由于 iptables“状态性”。 它比 ipchains 更了解每个数据包。 例如,它知道数据包是“新”连接的一部分,还是“已建立”连接的一部分,还是“相关”连接的一部分。 这就是所谓的连接跟踪的“状态检测”

iptables 有许多许多功能,此处未涉及。 有关 Netfilter 项目和 iptables 的更多阅读材料,请参阅http://netfilter.samba.org。 有关更高级的规则集,请参阅附录

5.2.3. Red Hat 防火墙配置工具

Red Hat 在 7.1 之前没有包含防火墙配置工具,当时 GUI 实用程序 gnome-lokkit 开始捆绑。 gnome-lokkit 仅为 ipchains 执行最简化的规则集。 尽管默认内核是 2.4,但显式支持 iptables 配置不是一个选项。

gnome-lokkit 是非升级安装的一个选项,也可以在安装后的任何时间作为独立应用程序运行。 它会询问一些简单的问题,并将生成的规则集转储到/etc/sysconfig/ipchains.

如前所述,这是一个相当简化的规则集,可能是一个足够的起点。 一个例子/etc/sysconfig/ipchainsgnome-lokkit 创建

 # Firewall configuration written by lokkit
 # Manual customization of this file is not recommended.
 # Note: ifup-post will punch the current nameservers through the
 #       firewall; such entries will *not* be listed here.
 :input ACCEPT
 :forward ACCEPT
 :output ACCEPT
 -A input -s 0/0 -d 0/0 80 -p tcp -y -j ACCEPT
 -A input -s 0/0 -d 0/0 25 -p tcp -y -j ACCEPT
 -A input -s 0/0 -d 0/0 22 -p tcp -y -j ACCEPT
 -A input -s 0/0 -d 0/0 23 -p tcp -y -j ACCEPT
 -A input -s 0/0 -d 0/0 -i lo -j ACCEPT
 -A input -s 0/0 -d 0/0 -i eth1 -j ACCEPT
 -A input -s 127.0.0.1 53 -d 0/0 -p udp -j ACCEPT
 -A input -s 0/0 -d 0/0 -p tcp -y -j REJECT
 -A input -s 0/0 -d 0/0 -p udp -j REJECT

 

这是一种可以被 ipchains 命令 ipchains-restore 读取的格式。 因此,可以使用 ipchains-save 生成新的或修改的规则集,并将输出重定向到此文件。 ipchains-restore 实际上是 ipchains init 脚本处理此文件的方式。 因此,为了使其工作,必须激活 ipchains 服务

 # chkconfig ipchains on

 

相反,如果您想推出自己的 iptables 规则,则应确保禁用 ipchains init 服务。 还有一个 iptables init 脚本,其工作方式与 ipchains 版本非常相似。 目前 gnome-lokkit 没有提供支持。

5.3. Tcpwrappers (libwrap)

Tcpwrappers 提供了与上面的 ipchainsiptables 非常相似的期望结果,尽管工作方式截然不同。 Tcpwrappers 实际上会拦截连接尝试,然后检查其配置文件,并决定是接受还是拒绝请求。Tcpwrappers 在应用程序级别控制访问,而不是像 iptablesipchains 那样在套接字级别控制访问。 这可能非常有效,并且是大多数 Linux 系统上的标准组件。

Tcpwrappers 由配置文件组成/etc/hosts.allow/etc/hosts.deny。 该功能由 libwrap 库提供。

Tcpwrappers 首先查看是否在/etc/hosts.allow中允许访问,如果是,则授予访问权限。 如果不在/etc/hosts.allow中,则检查文件/etc/hosts.deny以查看是否允许访问。 如果是,则拒绝访问。 否则,授予访问权限。 因此,/etc/hosts.deny应仅包含一个未注释的行,即ALL: ALL。 然后应通过/etc/hosts.allow中的条目允许访问,其中列出了特定服务,以及允许访问这些服务的特定主机地址。 虽然此处可以使用主机名,但使用主机名会打开名称欺骗的有限可能性。

Tcpwrappers 通常用于保护通过 inetd(或 xinetd)启动的服务。 但是,任何已编译 libwrap 支持的程序都可以利用它。 只是不要假设所有程序都内置了 libwrap 支持——它们没有。 实际上,大多数可能没有。 因此,在我们的示例中,我们将仅使用它来保护通过 inetd 启动的服务。 然后依靠我们的数据包过滤防火墙或其他机制来保护非 (x)inetd 服务。

下面是典型的inetd.conf文件中的一小段代码

 # Pop and imap mail services et al
 #
 #pop-2   stream  tcp     nowait  root    /usr/sbin/tcpd ipop2d
 #pop-3   stream  tcp     nowait  root    /usr/sbin/tcpd ipop3d
 #imap    stream  tcp     nowait  root    /usr/sbin/tcpd imapd
 #

 

倒数第二列是 tcpwrappers 守护程序——/usr/sbin/tcpd。 紧随其后的是它正在保护的守护程序。 在这种情况下,是 POPIMAP 邮件服务器。 您的发行版可能已经为您完成了这一部分。 对于少数通过 libwrap 库内置支持 tcpwrappers 的应用程序,无需如上所述指定守护程序。

我们将在此处使用相同的原则:默认策略是拒绝一切,然后打开漏洞以允许必要的最小流量。

因此,现在使用您的文本编辑器,su 到 root 并打开/etc/hosts.deny。 如果它不存在,则创建它。 它只是一个纯文本文件。 我们想要以下行

 ALL: ALL

 

如果它已经在那里,那就很好。 如果没有,请添加它,然后保存并关闭文件。 就这么简单。“ALL”tcpwrappers 理解的关键字之一。 格式为$SERVICE_NAME : $WHO,因此我们在此处拒绝所有服务的所有连接。 至少是所有正在使用 tcpwrappers 的服务。 请记住,这主要将是 inetd 服务。 请参阅man 5 hosts_access以获取有关这些文件语法的详细信息。 请注意那里的 “5”

现在,让我们尽可能严格地开放我们需要的服务,并给出一个简短的示例

 ALL: 127.0.0.1
 sshd,ipop3d: 192.168.1.
 sshd: .myworkplace.com, hostess.mymomshouse.com 

 

第一行允许所有 “localhost” 连接。 您将需要这个。 第二行允许来自以192.168.1.开头的 IP 地址的 sshdipop3d 服务的连接,在本例中,它是我们假设的家庭 LAN 的私有地址范围。 请注意尾部的 “.”。 这很重要。 第三行仅允许来自与.myworkplace.com关联的任何主机的连接到我们的 sshd 守护程序。 请注意此示例中前导的 “.”。 然后还有,单个主机hostess.mymomshouse.com。 综上所述,localhost 和我们所有的 LAN 连接都可以访问 bigcat 上的任何和所有 tcpwrappered 服务。 但只有我们的工作场所地址和我们的母亲才能从外部连接使用 bigcat 上的 sshd。 其他所有人都会被/etc/hosts.deny.

中的默认策略拒绝以上类型的通配符(.myworkplace.com192.168.1.ipchainsiptables 或大多数其他 Linux 应用程序都不支持。 此外,tcpwrappers 可以使用主机名代替 IP 地址,这在某些情况下非常方便。 这不适用于 ipchainsiptables

您可以使用随附的 tcpdchk 实用程序测试您的 tcpwrappers 配置(请参阅手册页)。 请注意,此时这不适用于 xinetd,甚至可能不包含在这种情况下。

同时使用 tcpwrappers 和数据包过滤防火墙(如 ipchains)没有任何问题。 事实上,建议使用“分层”方法。 这有助于防止意外的错误配置。 在这种情况下,每个连接都将首先由数据包过滤器规则进行测试,然后由 tcpwrappers 进行测试。

请记住在编辑系统配置文件之前制作备份副本,之后重新启动守护程序,然后检查日志中是否有错误消息。

5.3.1. xinetd

如前所述,xinetd 是增强型的 inetd,并且从 Red Hat 7.0 开始取代了 inetd。 它具有许多相同的功能,并进行了一些值得注意的增强。 其中之一是 tcpwrappers 支持已编译到其中,从而无需显式引用 tcpd。 这意味着/etc/hosts.allow/etc/hosts.deny自动生效。

xinetd 的其他一些增强功能:指定要侦听的 IP 地址,这是一种非常有效的访问控制方法; 限制传入连接的速率和同时连接的总数; 将服务限制为每天的特定时间。 有关更多详细信息,请参阅 xinetdxinetd.conf 手册页。

但是语法却大相径庭。 来自/etc/xinetd.d/tftp:

 service tftp
 {
        socket_type     = dgram
        bind            = 192.168.1.1
        instances       = 2
        protocol        = udp
        wait            = yes
        user            = nobody
        only_from       = 192.168.1.0
        server          = /usr/sbin/in.tftpd
        server_args     = /tftpboot
        disable         = no
 }

 

的示例请注意bind192.168.1.0语句。 我们在这里仅侦听或“绑定”到私有 LAN 接口。 由于甚至没有打开外部端口,因此无法建立外部连接。 我们也只接受来自的连接,即我们的 LAN。 对于 xinetd 的目的,这表示任何以 “192.168.1” 开头的 IP 地址。 请注意,语法与 inetd 不同。server语句在本例中是 tftp 守护程序 in.tftpd。 同样,这假设 libwrap/tcpwrappers 支持已编译到 xinetd 中。 运行守护程序的user将是 “nobody”。 是的,有一个名为 “nobody” 的用户帐户,并且尽可能以非 root 用户身份运行此类守护程序是明智之举。 最后,disable

语句是 xinetd 打开或关闭服务的方式。 在这种情况下,它是 “on”。 这里只是作为一个例子。 不要将 tftp 作为公共服务运行,因为它不安全。

5.4. PortSentry Portsentry 的工作方式与迄今为止讨论的其他工具截然不同。Portsentry 完成了其名称所暗示的工作——它保护端口。Portsentry 使用/etc/portsentry/portsentry.conf

文件进行配置。与上面讨论的其他应用程序不同,它通过实际成为这些端口上的侦听服务器来做到这一点。 有点像诱饵陷阱。 在 portsentry 运行时以 root 身份运行netstat -taup将显示 portsentry 作为LISTENER

在为 portsentry 配置的任何端口上。 如果 portsentry 感应到连接尝试,它会完全阻止它。 然后更进一步,阻止到达该主机的路由以停止所有进一步的流量。 或者,可以使用 ipchainsiptables 完全阻止主机。 因此,它成为阻止端口范围扫描的绝佳工具。但是 portsentry 在是否允许给定连接方面的灵活性有限。 它几乎是全有或全无。 您可以在/etc/portsentry/portsentry.ignore

中定义它将忽略的特定 IP 地址。 但是您无法允许对单个端口的选择性访问。 这是因为一次只有一个服务器可以绑定到特定端口,在这种情况下,它是 portsentry 本身。 因此,作为独立的防火墙,它的用处有限。 作为整体防火墙策略的一部分,是的,它可能非常有用。 对于我们大多数人来说,它不应该是我们的第一道防线,我们应该仅将其与其他工具结合使用。

如果您非常确定您根本没有暴露的公共服务器,并且您只想知道谁在做什么。 但不要对 portsentry 正在保护什么做任何假设。 默认情况下,它不会监视所有端口,甚至可能会将一些非常常用的探测端口保持打开状态。 因此,请确保您进行了相应的配置。 并确保您已首先测试和验证了您的设置,并且没有任何东西暴露出来。

总而言之,数据包过滤器可以构成更好的防火墙。

5.5. 代理

词典将“代理”定义为“代表他人行事的权力或权力”。 这很好地描述了软件代理。 它是连接路径中的中介。 例如,如果我们使用像 “squid” 这样的 Web 代理(http://www.squid-cache.org/),那么每次我们浏览到网站时,实际上都是连接到我们本地运行的 squid 服务器。 Squid 反过来,会将我们的请求中继到最终的真实目的地。 然后 squid 会将网页中继回给我们。 它是一个中间人。 像“防火墙”一样,“代理”可以指代运行代理应用程序的特定应用程序或专用服务器。

代理可以执行各种职责,并非所有职责都与安全性有很大关系。 但它们是中介这一事实使它们成为实施访问控制策略、限制通过防火墙的直接连接以及控制代理后面的网络在互联网上的外观的好地方。 因此,这使它们成为整体防火墙策略的有力候选者。 事实上,有时会使用它们来代替数据包过滤防火墙。 基于代理的防火墙可能在许多用户位于同一防火墙后面时更有意义。 并且它可能不是家庭系统所需的组件列表中的首位。

配置和管理代理可能很复杂,这超出了本文档的范围。《防火墙和代理服务器 HOWTO》,https://tldp.cn/HOWTO/Firewall-HOWTO.html,有关于设置代理防火墙的示例。 Squid 的使用在 http://squid-docs.sourceforge.net/latest/html/book1.htm 中讨论。

5.6. 单个应用程序

与往常一样,在进行任何系统更改时,首先备份配置文件,之后重启相应的守护程序,然后检查相应的日志以查找错误消息。

5.7. 验证

在部署防火墙之后的最后一步是验证它是否按您的预期工作。在您对系统配置进行哪怕是细微的更改时,明智的做法是都进行验证。

那么如何做到这一点呢?您可以执行以下几项操作。

对于我们的数据包过滤器,如 ipchainsiptables,我们可以使用以下命令列出我们所有的规则、链和相关活动iptables -nvL | less(如果适用,请替换为 ipchains)。尽可能展开您的 xterm 终端,以避免长行换行。

这应该让您了解您的链是否按您认为应该的方式工作。您可能需要首先执行一些您通常执行的在线任务:打开一些网页、发送和接收邮件等。当然,这不会给您提供有关 tcpwrappersportsentry 的任何信息。tcpdchk 可用于验证 tcpwrappers 配置(xinetd 除外)。

然后,扫描您自己。nmap 是首选的扫描工具,包含在最新的 Red Hat 发行版中,或可从 http://www.insecure.org/nmap/nmap_download.html 获取。nmap 非常灵活,本质上是一个 “端口探测器”。换句话说,它会查找开放的端口以及其他内容。有关详细信息,请参阅 nmap 的 man 手册。

如果您确实针对自己运行 nmap(例如nmap localhost),这应该告诉您哪些端口是开放的——并且仅在本地可见!希望到目前为止,这与从外部看到的情况大相径庭。因此,扫描您自己,然后找一位信任的朋友或站点(请参阅 链接 部分),从外部扫描您。请确保您的端口扫描没有违反您的 ISP 服务条款。即使意图是善意的,也可能不允许这样做。从外部扫描是了解外界如何看待您的最佳方式。这应该告诉您防火墙的工作情况。有关 nmap 用法的一些示例,请参阅附录中的 nmap 部分。

关于这一点需要注意:一些 ISP 可能会过滤某些端口,您将无法确定您的防火墙工作得有多好。相反,他们可能会使用 Web 或其他代理,使某些端口看起来是开放的。扫描器可能会看到端口 80 上的 Web 代理,并错误地将其报告为系统上的开放端口。

另一种选择是找到一个提供全范围测试的网站。http://www.hackerwhacker.com 就是这样一个网站。请确保任何此类网站不仅仅扫描相对较少的知名端口。

每次防火墙更改、每次系统升级或新安装以及系统任何关键组件发生更改时,重复此过程。

您可能还希望启用所有被拒绝流量的日志记录。至少暂时启用。一旦验证防火墙按您认为应该的方式工作,并且如果日志不堪重负,您可能需要禁用日志记录。

如果完全依赖 portsentry,请阅读文档。根据您的配置,它将丢弃到扫描器的路由,或者实现执行相同操作的 ipchains/iptables 规则。此外,由于它在指定的端口上 “监听”,所有这些端口都将显示为 “开放”。在这种情况下,这是一个误报。

5.8. 日志记录

Linux 会进行大量日志记录。通常会记录到多个文件。并非总是很清楚如何处理所有这些条目——好、坏或无关紧要?防火墙日志往往会生成相当多的每种条目。当然,您只想阻止 “坏” 的流量,但您无疑也会捕获一些无害的流量。“网络”有很多背景噪音。

在许多情况下,几乎不可能知道传入数据包的意图。尝试入侵?行为不端的协议?错误输入的 IP 地址?可以根据诸如目标端口、源端口、协议和许多其他变量等因素得出结论。但是,在解释防火墙日志方面,经验是不可替代的。在许多情况下,这是一门黑魔法。

那么我们真的需要记录日志吗?我们应该尝试记录多少日志?日志记录的好处在于它告诉我们防火墙是正常运行的。即使我们不太了解其中的内容,我们也知道它在 “做一些事情”。如果需要,我们可以深入研究这些日志,并找到可能需要的任何数据。

另一方面,如果日志记录过多,可能很难找到相关数据,或者更糟的是,填满分区,那么日志记录也可能是不好的。或者,如果我们反应过度,并将每个条目都视为全面攻击。一定的视角非常有益,但这几乎是新用户天生缺乏的东西。同样,一旦您的防火墙经过验证,并且您感到困惑或不知所措,家庭桌面用户可能希望尽可能禁用日志记录。任何承担更大责任的人都应该记录日志,然后找到通过过滤掉无关信息来从日志中提取相关数据的方法。

不确定在哪里查找日志数据?需要关注的两个日志是/var/log/messages/var/log/secure。可能有其他特定于应用程序的日志,具体取决于您已安装或正在使用的应用程序。例如,FTP 会记录到/var/log/xfer在 Red Hat 上。

Portsentrytcpwrappers 会进行一定量的日志记录,这些日志记录是不可调整的。xinetd 具有可以打开的日志记录增强功能。另一方面,ipchainsiptables 在记录什么方面非常灵活。

对于 ipchains-l选项可以添加到任何规则。iptables 使用-j LOG目标,并且需要其自己的单独规则来代替。iptables 更进一步,允许自定义日志条目和速率限制。请参阅 man 手册。据推测,我们对记录被阻止的流量更感兴趣,因此我们会将日志记录限制为仅记录我们的DENYREJECT规则。

因此,是否记录日志、记录多少日志以及如何处理日志是一个个人决定,可能需要一些试错才能使其可管理。一些审计和分析工具可能会很有帮助

一些工具可以为您监控日志,并在必要时通知您。这些工具可能需要一些配置和试错才能充分利用它们

5.9. 从哪里开始

让我们快速了解一下从哪里运行我们的防火墙脚本。

Portsentry 可以像其他系统服务一样作为 init 进程运行。何时完成这一点并不那么重要。Tcpwrappers 将由 inetdxinetd 自动调用,因此也不必担心。

但是数据包过滤脚本必须在某个地方启动。许多脚本将具有使用本地 IP 地址的逻辑。这意味着脚本必须在接口启动并分配 IP 地址后启动。理想情况下,这应该在接口启动后立即进行。因此,这取决于您如何连接到 Internet。此外,对于像 PPPDHCP 这样的协议,它们可能是动态的,并且在每次重新连接时都会获得不同的 IP,最好让脚本由相应的守护程序运行。

Red Hat 使用/etc/ppp/ip-up.local用于任何用户定义的本地 PPP 配置。如果此文件不存在,请创建它并使其可执行(chmod +x)。然后使用您的文本编辑器,添加对您的防火墙脚本的引用。

对于 DHCP,这取决于客户端。dhcpcd 将在每次获得或续订租约时执行 /etc/dhcpcd/dhcpcd-<interface>.exe(例如 dhcpcd-eth0.exe)。因此,这是放置对您的防火墙脚本的引用的位置。对于 pump(Red Hat 上的默认客户端),主配置文件是/etc/pump.confPump 将在任何时候有新的或续订的租约时运行由 “script” 语句定义的任何脚本

 script /usr/local/bin/ipchains.sh

 

如果您有静态 IP 地址(即永不更改),则放置位置并不那么重要,并且应该接口启动之前

5.10. 步骤 3 的总结和结论

在本节中,我们研究了可用于构建 “防火墙” 的各种组件。并了解到防火墙既是一种策略和组件的组合,也是任何一个特定的应用程序或组件。我们研究了一些在大多数(如果不是全部)Linux 系统上可以找到的最常用的应用程序。这不是一个详尽的列表。

这是一次性消化大量信息,并期望任何人都能理解所有内容。希望这可以用作一个起点,也可以用作未来的参考。数据包过滤器防火墙示例也可以用作起点。只需使用您的文本编辑器,剪切并粘贴到具有适当名称的文件中,然后对其运行 chmod +x 以使其可执行。可能需要对变量进行一些小的编辑。另请查看 链接 部分,了解可用于生成自定义脚本的站点和实用程序。这可能会让人感觉不那么令人生畏。

现在我们完成了步骤 1、2 和 3。希望到目前为止,您已经采取了一些基本措施来保护您的系统免受网络上潜伏的各种威胁。如果您尚未实施上述任何步骤,那么现在是休息一下,回到顶部并开始行动的好时机。最重要的步骤是上述步骤。

一些快速结论……

iptablesipchainstcpwrappersportsentry 哪个最好?” 快速的答案是 iptables 比其他任何一个都做得更多。因此,如果您使用的是 2.4 内核,请使用 iptables。如果您使用的是 2.2 内核,则使用 ipchains。较长的答案是 “这只是取决于您正在做什么以及目标是什么”。抱歉。其他工具在任何给定情况下都有一些优点,并且在正确的情况下都可能有效。

“我真的需要所有这些软件包吗?” 不,但是请结合多种方法,并请遵循以上所有建议。iptables 本身就很好,但与其他一些方法结合使用,我们会更强大。不要依赖任何单一机制来提供安全保障。“分层”保护始终是最好的。健全的管理实践也是如此。世界上最好的 iptables 脚本只是难题的一部分,不应用于掩盖其他系统弱点。

“如果我有一个小型家庭 LAN,我需要在每台计算机上都安装防火墙吗?” 不,只要 LAN 网关具有正确配置的防火墙,就没有必要这样做。不需要的流量应该在该点被阻止。只要它按预期工作,LAN 上就不应该有不需要的流量。但是,同样地,这样做肯定没有坏处。在可能混合平台或有不受信任用户的更大 LAN 上,这将是明智的。