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

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

在上面的第 1 步中,我们关闭了所有我们不需要的服务。在我们的例子中,有一些我们仍然需要运行。在本节中,我们将采取下一步,决定哪些服务需要对外界开放,以及哪些服务我们可以以某种方式进行限制。如果我们能阻止所有服务,那就更好了,但这样做并不总是实际的。

5.1. 策略

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

我们也不希望将我们的防火墙限制于任何一个应用程序。采用“分层”的深度防御方法是没有错的。我们的第一道防线将是数据包过滤器——无论是 ipchains(数据包链,2.2内核的标准)还是 iptables(互联网数据包表,见下文)。然后我们可以使用其他工具和机制来加强我们的防火墙。

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

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

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

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

如果构建您自己的 ipchainsiptables 防火墙规则似乎有点令人生畏,那么有很多网站可以自动完成该过程。请参阅链接部分。此外,包含的示例可以用作起点。并且您的发行版可能包含某种用于生成防火墙脚本的实用程序。这可能是足够的,但仍然建议了解正确的语法以及各种机制的工作方式,因为这些工具很少做超过几个非常简单的规则。

Note

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

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

5.2.1. ipchains

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

在每个“链”的末尾是一个“目标”。目标使用-j命令选项指定。目标决定数据包的命运,并基本上终止该特定链。最常见的目标大多是不言自明的ACCEPT(接受), DENY(拒绝), REJECT(驳回),以及MASQ. MASQ用于“IP地址伪装”DENY(拒绝)REJECT(驳回)本质上做的是同一件事,尽管方式不同。一个比另一个更好吗?这是一个备受争议的话题,取决于超出本文档范围的其他因素。就我们的目的而言,任何一个都应该足够了。

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

从 Internet 进入我们系统的流量,通过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 address>[port]:此规则仅适用于指定的源地址。它可以选择在其后立即包含一个端口(例如 22),或端口范围,例如 1023:4999。

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

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

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

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

还记得在第 1 步中,当我们运行 netstat 时,我们除了其他东西之外,还在运行 X 和打印服务器。我们不希望这些暴露于 Internet,即使是以有限的方式。这些仍然在 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.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”连接。 你将需要这个。 第二行允许从以下 IP 地址开始的连接到 sshdipop3d 服务192.168.1.,在本例中,是我们的假设家庭 LAN 的专用地址范围。 请注意末尾的“.”。 这很重要。 第三行仅允许从与以下相关联的任何主机连接到我们的 sshd 守护程序.myworkplace.com。 请注意本示例中的前导“.”。 还有,单个主机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。 它具有许多相同的功能,但有一些值得注意的增强功能。 一种是可以编译 tcpwrappers 支持,从而无需显式引用 tcpd。 这意味着/etc/hosts.allow/etc/hosts.deny会自动生效。 尽管如此,请不要假设这是真的。 进行一些测试,然后查看日志应该可以告诉您 tcpwrappers 支持是自动的还是非自动的。

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
 }

 

注意bind声明。 我们仅在此处侦听或“绑定”到专用 LAN 接口。 由于甚至没有打开外部端口,因此无法建立外部连接。 我们也只接受来自192.168.1.0,我们的局域网的连接。 就 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文件进行配置。

与上面讨论的其他应用程序不同,它通过实际成为这些端口上的侦听服务器来实现此目的。 有点像引诱陷阱。 运行netstat -taup作为 root,同时 portsentry 正在运行,会将 portsentry 显示为LISTENER在为 portsentry 配置的任何端口上。 如果 portsentry 感应到连接尝试,它会完全阻止它。 然后更进一步,阻止到该主机的路由以停止所有进一步的流量。 或者,可以使用 ipchainsiptables 完全阻止主机。 因此,它成为停止对一系列端口进行端口扫描的绝佳工具。

但是,portsentry 在是否允许给定的连接方面灵活性有限。 它几乎是全部或全无。 您可以在/etc/portsentry/portsentry.ignore但是,你不能允许对单个端口进行选择性访问。 这是因为在同一时间,只有一个服务器可以绑定到特定端口,在这种情况下,这个服务器就是 portsentry 本身。 因此,它作为独立的防火墙的实用性有限。 作为整体防火墙策略的一部分,是的,它可能非常有用。 对于我们大多数人来说,它不应该是我们的第一道防线,我们应该只将其与其他工具结合使用。

关于何时 portsentry 可能有用的建议

总而言之,数据包过滤器是一个更好的防火墙。

5.5. 代理

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

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

配置和管理代理可能很复杂,并且超出了本文档的范围。《防火墙和代理服务器 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 是首选的扫描工具,可以通过你的发行版获得,也可以从 http://www.insecure.org/nmap/nmap_download.html 获得。 nmap 非常灵活,本质上是一个 "端口探测器"。 换句话说,它会查找开放端口,以及其他内容。 有关详细信息,请参见 nmap 手册页。

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

对此的一个警告是:某些 ISP 可能会过滤某些端口,并且你将无法确定你的防火墙的工作情况。 相反,他们通过使用 Web 或其他代理,使某些端口看起来是开放的。 扫描程序可能会在端口 80 处看到 Web 代理,并错误地将其报告为系统上的开放端口。

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

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

你可能还需要启用记录所有被拒绝的流量。 至少暂时启用。 一旦验证了防火墙正在执行你认为应该执行的操作,并且如果日志非常繁重,你可能需要禁用日志记录。

如果完全依赖 portsentry,请阅读文档。 根据你的配置,它将删除到扫描程序的路由,或者执行执行相同操作的 ipchains/iptables 规则。 此外,由于它在指定的端口上 "监听",因此所有这些端口都将显示为 "开放"。 在这种情况下是虚惊一场。

5.8. 日志记录

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

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

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

另一方面,如果日志记录过于频繁,导致难以找到相关数据,或者更糟,填满分区,那么日志记录也可能是不利的。或者如果我们反应过度,把每一个条目都当作一次全面的攻击。一定的视角是非常有益的,但这是新手几乎必然缺乏的。再次强调,一旦你的防火墙经过验证,并且你感到困惑或不知所措,家庭桌面用户可能希望尽可能地禁用日志记录。任何肩负更大责任的人都应该进行日志记录,然后找到方法通过过滤掉无关信息,从日志中提取相关数据。

不确定在哪里查找日志数据?这可能有很多地方,具体取决于你的发行版如何配置各种守护进程和 syslogd。大多数日志记录都在/var/log/*中完成。使用以下命令检查该目录:ls -l /var/log/并查看是否可以通过大小和时间戳来判断哪些日志最活跃。此外,请查看/etc/syslog.conf以查看默认日志的位置。/var/log/messages是一个不错的入门位置。

Portsentrytcpwrappers 会进行一定数量的日志记录,这些日志记录是无法调整的。xinetd 具有可以启用的日志记录增强功能。另一方面,ipchainsiptables 在日志记录方面非常灵活。

对于 ipchains,可以将-l选项添加到任何规则。iptables 使用-j LOGtarget,并且需要它自己的单独规则。 iptables 更进一步,允许自定义日志条目和速率限制。请参阅手册页。据推测,我们对记录被阻止的流量更感兴趣,因此我们会将日志记录限制在我们的DENY(拒绝)REJECT(驳回)规则中。

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

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

5.9. 从哪里开始

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

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

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

对于 PPP,你可能有一个/etc/ppp/ip-up文件。 每次连接或重新连接时都会执行此操作。 你应该在此处放置防火墙脚本的完整路径。 检查本地文档以获取正确的位置。 Debian 使用/etc/ppp/ip-up.d/中的文件,因此将脚本本身放在那里,或将其符号链接到那里。 Red Hat 使用/etc/ppp/ip-up.local用于任何用户定义的本地 PPP 配置。

对于 DHCP,这取决于哪个客户端。 每当获得或续订租约时,dhcpcd 将执行 /etc/dhcpcd/dhcpcd-<interface>.exe(例如 dhcpcd-eth0.exe)。 因此,这是放置对你的防火墙脚本的引用的地方。 对于 pump,主配置文件是/etc/pump.conf。 任何时候有新的或续订的租约,Pump 都会运行 "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 上,这将是明智之举。