我们将包括一些简短的示例。 我们的经验法则是默认策略拒绝一切,然后仅开放我们需要的东西。 我们将尝试尽可能保持简单,因为它可能是一个复杂且复杂的主题,并且只坚持一些最基本的概念。 有关此主题的更多阅读材料,请参阅链接部分。
“数据包过滤器”(如 ipchains)能够查看单个数据包,并根据它们发现的内容做出决策。 这些可以用于多种目的。 一个常见的目的是实现防火墙。
如果构建您自己的 ipchains 或 iptables 防火墙规则看起来有点令人生畏,那么有各种站点可以自动化该过程。 请参阅链接部分。 此外,包含的示例可以用作起点。 截至 Red Hat 7.1,Red Hat 正在为 ipchains 和 iptables 提供 init 脚本,并为 gnome-lokkit 提供用于生成非常基本的防火墙规则集(见下文)。 这可能足够了,但仍然建议了解正确的语法以及各种机制的工作方式,因为此类工具很少做超过几个非常简单的规则。
![]() | 下面给出了各种示例。 这些示例仅用于说明目的,以演示此处讨论的一些概念。 虽然它们也可能用作您自己脚本的起点,但请注意,它们并非旨在涵盖所有内容。 强烈建议您了解脚本的工作原理,以便您可以创建更适合您自己情况的内容。 示例脚本仅保护到一个接口(连接到互联网的接口)的入站连接。 这对于许多简单的家庭类型的情况可能足够了,但是,反过来,这种方法并不适用于所有情况! |
ipchains 具有非常灵活的配置。 可以指定端口(或端口范围)、接口、目标地址、源地址以及各种其他选项。 手册页充分解释了这些细节,我们在此不再赘述。
从互联网进入我们系统的流量,通过input链进入。 这是我们需要尽可能收紧的一个。
#!/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 运行以构建链,从而构建防火墙。
有关语法的完整说明,请参阅 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 |
输出按链分组。 您还应该找到一种扫描自己的方法(请参阅下面的验证部分)。 然后密切关注您的日志,以确保您阻止了预期的内容。
最重要的是,使用 iptables 比使用 ipchains 更容易获得严格的防火墙。 因此,这是推荐的方法。
#!/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 脚本中的这一部分
# 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 有许多许多功能,此处未涉及。 有关 Netfilter 项目和 iptables 的更多阅读材料,请参阅http://netfilter.samba.org。 有关更高级的规则集,请参阅附录。
gnome-lokkit 是非升级安装的一个选项,也可以在安装后的任何时间作为独立应用程序运行。 它会询问一些简单的问题,并将生成的规则集转储到/etc/sysconfig/ipchains.
如前所述,这是一个相当简化的规则集,可能是一个足够的起点。 一个例子/etc/sysconfig/ipchains由 gnome-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 |
# chkconfig ipchains on |
Tcpwrappers 由配置文件组成/etc/hosts.allow和/etc/hosts.deny。 该功能由 libwrap 库提供。
# 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 # |
我们将在此处使用相同的原则:默认策略是拒绝一切,然后打开漏洞以允许必要的最小流量。
因此,现在使用您的文本编辑器,su 到 root 并打开/etc/hosts.deny。 如果它不存在,则创建它。 它只是一个纯文本文件。 我们想要以下行
ALL: ALL |
现在,让我们尽可能严格地开放我们需要的服务,并给出一个简短的示例
ALL: 127.0.0.1 sshd,ipop3d: 192.168.1. sshd: .myworkplace.com, hostess.mymomshouse.com |
您可以使用随附的 tcpdchk 实用程序测试您的 tcpwrappers 配置(请参阅手册页)。 请注意,此时这不适用于 xinetd,甚至可能不包含在这种情况下。
请记住在编辑系统配置文件之前制作备份副本,之后重新启动守护程序,然后检查日志中是否有错误消息。
如前所述,xinetd 是增强型的 inetd,并且从 Red Hat 7.0 开始取代了 inetd。 它具有许多相同的功能,并进行了一些值得注意的增强。 其中之一是 tcpwrappers 支持已编译到其中,从而无需显式引用 tcpd。 这意味着/etc/hosts.allow和/etc/hosts.deny自动生效。
xinetd 的其他一些增强功能:指定要侦听的 IP 地址,这是一种非常有效的访问控制方法; 限制传入连接的速率和同时连接的总数; 将服务限制为每天的特定时间。 有关更多详细信息,请参阅 xinetd 和 xinetd.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
5.4. PortSentry Portsentry 的工作方式与迄今为止讨论的其他工具截然不同。Portsentry 完成了其名称所暗示的工作——它保护端口。Portsentry 使用/etc/portsentry/portsentry.conf
文件进行配置。与上面讨论的其他应用程序不同,它通过实际成为这些端口上的侦听服务器来做到这一点。 有点像诱饵陷阱。 在 portsentry 运行时以 root 身份运行netstat -taup将显示 portsentry 作为LISTENER
在为 portsentry 配置的任何端口上。 如果 portsentry 感应到连接尝试,它会完全阻止它。 然后更进一步,阻止到达该主机的路由以停止所有进一步的流量。 或者,可以使用 ipchains 或 iptables 完全阻止主机。 因此,它成为阻止端口范围扫描的绝佳工具。但是 portsentry 在是否允许给定连接方面的灵活性有限。 它几乎是全有或全无。 您可以在/etc/portsentry/portsentry.ignore
中定义它将忽略的特定 IP 地址。 但是您无法允许对单个端口的选择性访问。 这是因为一次只有一个服务器可以绑定到特定端口,在这种情况下,它是 portsentry 本身。 因此,作为独立的防火墙,它的用处有限。 作为整体防火墙策略的一部分,是的,它可能非常有用。 对于我们大多数人来说,它不应该是我们的第一道防线,我们应该仅将其与其他工具结合使用。
关于何时 portsentry 可能有用的建议
作为第二层防御,位于 ipchains 或 iptables 之后。 数据包过滤将首先捕获数据包,因此任何到达 portsentry 的数据包都将表明配置错误。 不要与 inetd 服务结合使用——它不起作用。 他们会发生冲突。
作为捕获全范围端口扫描的一种方法。 在数据包过滤器中打开一两个针孔,让 portsentry 捕获这些并做出相应的反应。
如果您非常确定您根本没有暴露的公共服务器,并且您只想知道谁在做什么。 但不要对 portsentry 正在保护什么做任何假设。 默认情况下,它不会监视所有端口,甚至可能会将一些非常常用的探测端口保持打开状态。 因此,请确保您进行了相应的配置。 并确保您已首先测试和验证了您的设置,并且没有任何东西暴露出来。
5.5. 代理
词典将“代理”定义为“代表他人行事的权力或权力”。 这很好地描述了软件代理。 它是连接路径中的中介。 例如,如果我们使用像 “squid” 这样的 Web 代理(http://www.squid-cache.org/),那么每次我们浏览到网站时,实际上都是连接到我们本地运行的 squid 服务器。 Squid 反过来,会将我们的请求中继到最终的真实目的地。 然后 squid 会将网页中继回给我们。 它是一个中间人。 像“防火墙”一样,“代理”可以指代运行代理应用程序的特定应用程序或专用服务器。
代理可以执行各种职责,并非所有职责都与安全性有很大关系。 但它们是中介这一事实使它们成为实施访问控制策略、限制通过防火墙的直接连接以及控制代理后面的网络在互联网上的外观的好地方。 因此,这使它们成为整体防火墙策略的有力候选者。 事实上,有时会使用它们来代替数据包过滤防火墙。 基于代理的防火墙可能在许多用户位于同一防火墙后面时更有意义。 并且它可能不是家庭系统所需的组件列表中的首位。
options { directory "/var/named"; listen-on { 127.0.0.1; 192.168.1.1; }; version "N/A"; }; |
# SMTP daemon options O DaemonPortOptions=Port=smtp,Addr=127.0.0.1, Name=MTA |
的底部附近最新版本的 sendmail 可以被告知仅侦听指定的地址可以使用文本编辑器小心地添加。sendmail.mc指令是
dnl This changes sendmail to only listen on the loopback device 127.0.0.1 dnl and not on any other network devices. DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA') |
bind interfaces = true interfaces = 192.168.1. 127. hosts allow = 192.168.1. 127. |
可以告知 CUPS 打印守护程序监听连接的位置。添加到/etc/cups/cupsd.conf:
Listen 192.168.1.1:631 |
xinetd 可以使用其 “bind” 配置指令强制守护程序仅在指定的地址上监听。例如,内部 LAN 接口地址。请参阅man xinetd.conf以了解此语法和其他语法。还有各种其他控制机制。
在部署防火墙之后的最后一步是验证它是否按您的预期工作。在您对系统配置进行哪怕是细微的更改时,明智的做法是都进行验证。
然后,扫描您自己。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 规则。此外,由于它在指定的端口上 “监听”,所有这些端口都将显示为 “开放”。在这种情况下,这是一个误报。
因此,是否记录日志、记录多少日志以及如何处理日志是一个个人决定,可能需要一些试错才能使其可管理。一些审计和分析工具可能会很有帮助
一些工具可以为您监控日志,并在必要时通知您。这些工具可能需要一些配置和试错才能充分利用它们
来自 Manfred Bartz 的一个用于 ipchains 和 iptables 的优秀日志条目分析器:http://www.logi.cc/linux/NetfilterLogAnalyzer.php3。所有这些东西到底是什么意思呢?
LogSentry(以前称为 logcheck)可从 http://www.psionic.org/products/logsentry.html 获取,该组织也负责 portsentry。LogSentry 是一款通用的日志监控工具,具有灵活的配置,可以处理多个日志。
http://freshmeat.net/projects/firelogd/,来自 Ian Jones 的 Firewall Log Daemon,旨在监视 iptables 或 ipchains 日志数据并发送警报。
http://freshmeat.net/projects/fwlogwatch/,由 Boris Wesslowski 开发,是一个类似的想法,但支持更多日志格式。
Portsentry 可以像其他系统服务一样作为 init 进程运行。何时完成这一点并不那么重要。Tcpwrappers 将由 inetd 或 xinetd 自动调用,因此也不必担心。
script /usr/local/bin/ipchains.sh |
这是一次性消化大量信息,并期望任何人都能理解所有内容。希望这可以用作一个起点,也可以用作未来的参考。数据包过滤器防火墙示例也可以用作起点。只需使用您的文本编辑器,剪切并粘贴到具有适当名称的文件中,然后对其运行 chmod +x 以使其可执行。可能需要对变量进行一些小的编辑。另请查看 链接 部分,了解可用于生成自定义脚本的站点和实用程序。这可能会让人感觉不那么令人生畏。
现在我们完成了步骤 1、2 和 3。希望到目前为止,您已经采取了一些基本措施来保护您的系统免受网络上潜伏的各种威胁。如果您尚未实施上述任何步骤,那么现在是休息一下,回到顶部并开始行动的好时机。最重要的步骤是上述步骤。
一些快速结论……
“iptables、ipchains、tcpwrappers 或 portsentry 哪个最好?” 快速的答案是 iptables 比其他任何一个都做得更多。因此,如果您使用的是 2.4 内核,请使用 iptables。如果您使用的是 2.2 内核,则使用 ipchains。较长的答案是 “这只是取决于您正在做什么以及目标是什么”。抱歉。其他工具在任何给定情况下都有一些优点,并且在正确的情况下都可能有效。
“我真的需要所有这些软件包吗?” 不,但是请结合多种方法,并请遵循以上所有建议。iptables 本身就很好,但与其他一些方法结合使用,我们会更强大。不要依赖任何单一机制来提供安全保障。“分层”保护始终是最好的。健全的管理实践也是如此。世界上最好的 iptables 脚本只是难题的一部分,不应用于掩盖其他系统弱点。
“如果我有一个小型家庭 LAN,我需要在每台计算机上都安装防火墙吗?” 不,只要 LAN 网关具有正确配置的防火墙,就没有必要这样做。不需要的流量应该在该点被阻止。只要它按预期工作,LAN 上就不应该有不需要的流量。但是,同样地,这样做肯定没有坏处。在可能混合平台或有不受信任用户的更大 LAN 上,这将是明智的。