我们将包含一些简短的例子。我们的经验法则是拒绝一切作为默认策略,然后只开放我们需要的东西。我们将尽量保持简单,因为它可能是一个复杂的主题,并且只坚持一些最基本的概念。有关此主题的更多阅读材料,请参见链接部分。
“数据包过滤器”(如 ipchains)有能力查看单个数据包,并根据它们发现的内容做出决定。这些可以用于许多目的。一个常见的目的是实现一个防火墙。
如果构建您自己的 ipchains 或 iptables 防火墙规则似乎有点令人生畏,那么有很多网站可以自动完成该过程。请参阅链接部分。此外,包含的示例可以用作起点。并且您的发行版可能包含某种用于生成防火墙脚本的实用程序。这可能是足够的,但仍然建议了解正确的语法以及各种机制的工作方式,因为这些工具很少做超过几个非常简单的规则。
![]() | 下面给出各种示例。这些示例仅用于说明目的,以演示此处讨论的一些概念。虽然它们也可能有用作您自己的脚本的起点,但请注意,它们并非旨在包含所有内容。强烈建议您了解脚本的工作方式,以便您可以创建更适合您自己情况的内容。 示例脚本只是保护到单个接口(连接到 Internet 的接口)的入站连接。对于许多简单的家庭类型的情况,这可能是足够的,但是,相反,这种方法并不适用于所有情况! |
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 运行以构建链,从而构建防火墙。
有关语法的完整说明,请参阅 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 |
输出按链分组。 您还应该找到扫描自己的方法(请参阅下面的验证部分)。 然后密切关注您的日志,以确保您正在阻止预期的内容。
最重要的是,使用 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。 有关更高级的规则集,请参见附录。
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。 它具有许多相同的功能,但有一些值得注意的增强功能。 一种是可以编译 tcpwrappers 支持,从而无需显式引用 tcpd。 这意味着/etc/hosts.allow和/etc/hosts.deny会自动生效。 尽管如此,请不要假设这是真的。 进行一些测试,然后查看日志应该可以告诉您 tcpwrappers 支持是自动的还是非自动的。
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 } |
注意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 作为公共服务运行,因为它是不安全的。
Portsentry 的工作方式与到目前为止讨论的其他工具完全不同。 Portsentry 的作用如其名称所示 - 它保护端口。Portsentry 使用/etc/portsentry/portsentry.conf文件进行配置。
与上面讨论的其他应用程序不同,它通过实际成为这些端口上的侦听服务器来实现此目的。 有点像引诱陷阱。 运行netstat -taup作为 root,同时 portsentry 正在运行,会将 portsentry 显示为LISTENER在为 portsentry 配置的任何端口上。 如果 portsentry 感应到连接尝试,它会完全阻止它。 然后更进一步,阻止到该主机的路由以停止所有进一步的流量。 或者,可以使用 ipchains 或 iptables 完全阻止主机。 因此,它成为停止对一系列端口进行端口扫描的绝佳工具。
但是,portsentry 在是否允许给定的连接方面灵活性有限。 它几乎是全部或全无。 您可以在/etc/portsentry/portsentry.ignore但是,你不能允许对单个端口进行选择性访问。 这是因为在同一时间,只有一个服务器可以绑定到特定端口,在这种情况下,这个服务器就是 portsentry 本身。 因此,它作为独立的防火墙的实用性有限。 作为整体防火墙策略的一部分,是的,它可能非常有用。 对于我们大多数人来说,它不应该是我们的第一道防线,我们应该只将其与其他工具结合使用。
关于何时 portsentry 可能有用的建议
作为第二层防御,位于 ipchains 或 iptables 之后。 数据包过滤将首先捕获数据包,因此任何到达 portsentry 的数据都表明存在配置错误。 不要与 inetd 服务结合使用,因为它不起作用。 它们会互相冲突。
作为捕获全范围端口扫描的一种方法。 在数据包过滤器中打开一两个针孔,让 portsentry 捕获这些并做出相应的反应。
如果你非常确定你根本没有暴露的公共服务器,并且你只是想知道谁在做什么。 但不要对 portsentry 正在保护什么做出任何假设。 默认情况下,它不会监视所有端口,甚至可能会留下一些非常常用的探测端口处于打开状态。 因此,请确保你已进行相应的配置。 并确保你已首先测试和验证你的设置,并且没有任何暴露。
总而言之,数据包过滤器是一个更好的防火墙。
字典将 "代理" 定义为 "代表他人行事的权限或权力"。 这很好地描述了软件代理。 它是连接路径中的中介。 例如,如果我们使用像 "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中讨论。
但是,它可以安装,并且在仅缓存模式下可能很有用。 这不需要完全暴露到 Internet。 通过编辑来限制它 "监听" 的接口/etc/named.conf(显示随机示例)
options { directory "/var/named"; listen-on { 127.0.0.1; 192.168.1.1; }; version "N/A"; }; |
如果使用 xdm(或类似物)在启动时自动启动 X,/etc/inittab可以修改为xdm -udpPort 0,以进一步限制连接。 这通常位于/etc/inittab.
的底部。 可以告诉最新版本的 sendmail 仅监听指定的地址
# SMTP daemon options O DaemonPortOptions=Port=smtp,Addr=127.0.0.1, Name=MTA |
上面的摘录来自/etc/sendmail.cf,可以使用你的文本编辑器仔细添加。
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') |
如果你希望构建新的sendmail.cf,而不是编辑现有的文件。 其他邮件服务器守护程序可能具有类似的配置选项。 检查你的本地文档。
bind interfaces = true interfaces = 192.168.1. 127. hosts allow = 192.168.1. 127. |
这将仅打开并允许来自 localhost (127.0.0.1) 和本地 LAN 地址范围的连接。 根据需要调整 LAN 地址。
可以告诉 CUPS 打印守护程序在哪里监听连接。 添加到/etc/cups/cupsd.conf:
Listen 192.168.1.1:631 |
xinetd 可以使用其 "bind" 配置指令强制守护程序仅监听指定的地址。 例如,内部 LAN 接口地址。 见man xinetd.conf获取此语法和其他语法。 还有各种其他控制机制。
将防火墙安装到位后的最后一步是验证它是否正在执行你想要的操作。 每当你对系统配置进行细微更改时,都应该明智地这样做。
然后,扫描你自己。 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 规则。 此外,由于它在指定的端口上 "监听",因此所有这些端口都将显示为 "开放"。 在这种情况下是虚惊一场。
因此,是否记录日志,记录多少,以及如何处理日志,这是一个个人决定,可能需要一些尝试和错误,才能使其可管理。一些审计和分析工具可能很有帮助
有些工具可以监控你的日志并在必要时通知你。这些可能需要一些配置和尝试,才能充分利用它们
来自 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 上,这将是明智之举。