Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

4.4. 保护网络访问

4.4.1. 使用 TCP wrapper 和 xinetd 保护服务

TCP 封装器比拒绝对服务的访问要多。本节介绍如何使用它们来发送连接横幅、来自特定主机的攻击警告,并增强日志记录功能。有关 TCP Wrapper 功能和控制语言的详情,请查看 hosts_options(5) man page。有关可用标记,请参阅 xinetd.conf(5) man page,它作为您可以应用到服务的选项。

4.4.1.1. TCP 包装器和连接标语

当用户连接到服务时,显示合适的横幅是让潜在攻击者知道系统管理员正在警觉的好方法。您还可以控制系统向用户呈现哪些信息。要为服务实施 TCP wrapper 横幅,请使用 横幅 选项。
此示例为 vsftpd 实施横幅。首先,创建一个横幅文件。它可以是系统上的任何位置,但它必须与守护进程的名称相同。在本例中,该文件名为 /etc/banners/vsftpd,包含以下行:
220-Hello, %c
220-All activity on ftp.example.com is logged.
220-Inappropriate use will result in your access privileges being removed.
%c 令牌提供各种客户端信息,如用户名和主机名,或者的用户名和 IP 地址,以便更方便连接。
要使此横幅显示在传入连接中,请在 /etc/hosts.allow 文件中添加以下行:
vsftpd : ALL : banners /etc/banners/

4.4.1.2. TCP 封装器和攻击警告

如果特定的主机或网络已被检测到对服务器进行攻击,可以使用 TCP wrapper 来警告管理员使用 generate 指令从该主机或网络发出后续攻击。
在本例中,假设已检测到来自 206.182.68.0/24 网络的 cracker 试图攻击服务器。将以下行放在 /etc/hosts.deny 文件中,以拒绝来自该网络的任何连接尝试,并将尝试记录到特殊文件:
ALL : 206.182.68.0 : spawn /bin/echo `date` %c %d >> /var/log/intruder_alert
%d 令牌提供攻击者试图访问的服务名称。
要允许连接并记录它,请将 generate 指令放在 /etc/hosts.allow 文件中。
注意
由于 generate 指令执行任何 shell 命令,因此最好创建一个特殊的脚本来通知管理员或在特定客户端尝试连接到服务器时执行一系列命令。

4.4.1.3. TCP wrapper 和 Enhanced Logging

如果某些类型的连接比其他连接更关注,则可使用 severity 选项为该服务提升日志级别。
在本例中,假设尝试连接到 FTP 服务器上的端口 23 ( Telnet 端口)的任何人都是攻击者。要表示这一点,请在日志文件中放置 emerg 标志,而不是默认的标志、info 和拒绝连接。
要做到这一点,请在 /etc/hosts.deny 中添加以下行:
in.telnetd : ALL : severity emerg
这使用默认的 authpriv 日志记录工具,但将默认值 info 的优先级提升为,这会将日志消息直接发布到控制台。

4.4.2. 验证正在列出哪些端口

关闭未使用的端口非常重要,以避免出现可能的攻击。对于处于侦听状态的意外端口,您应该调查可能的入侵签名。

使用 netstat 进行开放端口扫描

root 用户身份输入以下命令,以确定哪些端口正在侦听来自网络的连接:
~]# netstat -pan -A inet,inet6 | grep -v ESTABLISHED
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address       Foreign Address    State     PID/Program name
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      1/systemd
tcp        0      0 192.168.124.1:53        0.0.0.0:*               LISTEN      1829/dnsmasq
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1176/sshd
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      1177/cupsd
tcp6       0      0 :::111                  :::*                    LISTEN      1/systemd
tcp6       0      0 ::1:25                  :::*                    LISTEN      1664/master
sctp              0.0.0.0:2500                                      LISTEN   20985/sctp_darn
udp        0      0 192.168.124.1:53        0.0.0.0:*                           1829/dnsmasq
udp        0      0 0.0.0.0:67              0.0.0.0:*                           977/dhclient
...
使用 netstat 命令的 -l 选项仅显示侦听的服务器套接字:
~]# netstat -tlnw
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN
tcp        0      0 192.168.124.1:53        0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN
tcp6       0      0 :::111                  :::*                    LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 ::1:631                 :::*                    LISTEN
tcp6       0      0 ::1:25                  :::*                    LISTEN
raw6       0      0 :::58                   :::*                    7

使用 ss 进行开放端口扫描

或者,使用 ss 实用程序列出处于侦听状态的打开端口。它可以显示比 netstat 更多的 TCP 和状态信息。
~]# ss -tlw
etid State      Recv-Q Send-Q     Local Address:Port                      Peer Address:Port
udp   UNCONN     0      0                     :::ipv6-icmp                           :::*
tcp   LISTEN     0      128                    *:sunrpc                               *:*
tcp   LISTEN     0      5          192.168.124.1:domain                               *:*
tcp   LISTEN     0      128                    *:ssh                                  *:*
tcp   LISTEN     0      128            127.0.0.1:ipp                                  *:*
tcp   LISTEN     0      100            127.0.0.1:smtp                                 *:*
tcp   LISTEN     0      128                   :::sunrpc                              :::*
tcp   LISTEN     0      128                   :::ssh                                 :::*
tcp   LISTEN     0      128                  ::1:ipp                                 :::*
tcp   LISTEN     0      100                  ::1:smtp                                :::*
~]# ss -plno -A tcp,udp,sctp
Netid State      Recv-Q Send-Q       Local Address:Port                      Peer Address:Port
udp   UNCONN     0      0            192.168.124.1:53                                   *:*                   users:(("dnsmasq",pid=1829,fd=5))
udp   UNCONN     0      0                 *%virbr0:67                                   *:*                   users:(("dnsmasq",pid=1829,fd=3))
udp   UNCONN     0      0                        *:68                                   *:*                   users:(("dhclient",pid=977,fd=6))
...
tcp   LISTEN     0      5            192.168.124.1:53                                   *:*                   users:(("dnsmasq",pid=1829,fd=6))
tcp   LISTEN     0      128                      *:22                                   *:*                   users:(("sshd",pid=1176,fd=3))
tcp   LISTEN     0      128              127.0.0.1:631                                  *:*                   users:(("cupsd",pid=1177,fd=12))
tcp   LISTEN     0      100              127.0.0.1:25                                   *:*                   users:(("master",pid=1664,fd=13))
...
sctp  LISTEN     0      5                        *:2500                                 *:*                   users:(("sctp_darn",pid=20985,fd=3))
UNCONN 状态显示 UDP 侦听模式的端口。
从外部系统对 ss 输出中显示的每个 IP 地址进行扫描(除 localhost 127.0.0.0 或 ::1 范围除外)。使用 -6 选项扫描 IPv6 地址。
然后,使用 nmap 工具从通过网络连接到第一个系统的另一个远程机器进行外部检查。这可用于验证 firewalld 中的规则。以下是确定为 TCP 连接侦听哪些端口的示例:
~]# nmap -sT -O 192.168.122.65
    Starting Nmap 6.40 ( http://nmap.org ) at 2017-03-27 09:30 CEST
    Nmap scan report for 192.168.122.65
    Host is up (0.00032s latency).
    Not shown: 998 closed ports
    PORT    STATE SERVICE
    22/tcp  open  ssh
    111/tcp open  rpcbind
    Device type: general purpose
    Running: Linux 3.X
    OS CPE: cpe:/o:linux:linux_kernel:3
    OS details: Linux 3.7 - 3.9
    Network Distance: 0 hops

    OS detection performed. Please report any incorrect results at http://nmap.org/submit/ .
    Nmap done: 1 IP address (1 host up) scanned in 1.79 seconds
当 TCP SYN 扫描 (-sS) 不是选项时,TCP 连接扫描 (-sT) 是默认的 TCP 扫描类型。O 选项检测主机的操作系统。

使用 netstat s 扫描 Open SCTP 端口

netstat 实用程序打印有关 Linux 网络子系统的信息。要显示开放流控制传输协议(SCTP)端口的协议统计信息,以 root 用户身份输入以下命令:
~]# netstat -plnS
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address   Foreign Address  State    PID/Program name
sctp                127.0.0.1:250                    LISTEN   4125/sctp_darn
sctp       0      0 127.0.0.1:260   127.0.0.1:250    CLOSE    4250/sctp_darn
sctp       0      0 127.0.0.1:250   127.0.0.1:260    LISTEN   4125/sctp_darn
~]# netstat -nl -A inet,inet6 | grep 2500
sctp                0.0.0.0:2500                                    LISTEN
ss 工具也可以显示 SCTP 开放的端口:
~]# ss -an | grep 2500
sctp   LISTEN     0      5         *:2500                  *:*
如需更多信息,请参阅 ss(8)netstat(8)nmap(1)services(5) 手册页。

4.4.3. 禁用源路由

源路由是一种互联网协议机制,它允许 IP 数据包传输信息(地址列表),告知路由器数据包必须采用的路径。还有一个选项,可以在路由遍历时记录跃点。执行的跃点列表"路由记录"为目的地提供源的返回路径。这允许源(发送主机)指定路由,松散或严格,忽略部分或全部路由器的路由表。它可以允许用户重定向网络流量以进行恶意目的。因此,应该禁用基于源的路由。
accept_source_route 选项使网络接口接受设置了 Strict Source Routing (SSR)或 Loose Source Routing (LSR)选项的数据包。接收源路由数据包由 sysctl 设置控制。以 root 用户身份发出以下命令来丢弃设置了 SSR 或 LSR 选项的数据包:
~]# /sbin/sysctl -w net.ipv4.conf.all.accept_source_route=0
禁用数据包转发也应该尽可能与上述操作进行(禁用转发可能会影响到虚拟化)。以 root 身份运行以下命令:
这些命令禁用所有接口上 IPv4 和 IPv6 数据包的转发:
~]# /sbin/sysctl -w net.ipv4.conf.all.forwarding=0
~]# /sbin/sysctl -w net.ipv6.conf.all.forwarding=0
这些命令禁用所有接口上所有多播数据包的转发:
~]# /sbin/sysctl -w net.ipv4.conf.all.mc_forwarding=0
~]# /sbin/sysctl -w net.ipv6.conf.all.mc_forwarding=0
接受 ICMP 重定向有一些合法用途。禁用接受并发送 ICMP 重定向数据包,除非特别需要。
这些命令禁用接受所有接口上的所有 ICMP 重定向数据包:
~]# /sbin/sysctl -w net.ipv4.conf.all.accept_redirects=0
~]# /sbin/sysctl -w net.ipv6.conf.all.accept_redirects=0
此命令禁用接受所有接口上的安全 ICMP 重定向数据包:
~]# /sbin/sysctl -w net.ipv4.conf.all.secure_redirects=0
此命令禁用接受所有接口上的所有 IPv4 ICMP 重定向数据包:
~]# /sbin/sysctl -w net.ipv4.conf.all.send_redirects=0
重要
如果至少有一个 net.ipv4.conf.all.send_redirects 或 net.ipv4.conf.接口.send_redirects 选项被设置为 enabled,则发送 ICMP 重定向仍保持活动状态。确保将 net.ipv4.conf.接口.send_redirects 选项设为每个接口的 0 值。要在添加新接口时自动禁用 ICMP 请求发送,请输入以下命令:
~]# /sbin/sysctl -w net.ipv4.conf.default.send_redirects=0
只有 指令可以禁用发送 IPv4 重定向数据包。有关 IPv6 节点要求 的说明,请参阅 RFC4294,这会导致 IPv4 和 IPv6 之间的差别。
注意
要使这些设置在重启后持久保留,请修改 /etc/sysctl.conf 文件。例如,要禁用接受所有接口上所有 IPv4 ICMP 重定向数据包,请使用以 root 用户身份运行的编辑器打开 /etc/sysctl.conf 文件并添加以下行:
net.ipv4.conf.all.send_redirects=0
如需更多信息,请参阅 sysctl 手册页 sysctl (8)。有关基于源的路由及其变体的相关互联网选项的说明,请参阅 RFC791
警告
以太网网络提供额外的重定向流量的方法,如 ARP 或 MAC 地址欺骗、未经授权的 DHCP 服务器和 IPv6 路由器或邻居公告。另外,单播流量偶尔会广播,从而导致信息泄漏。这些弱点只能由网络操作器实施的特定计数器解决。基于主机的计数器无效。

4.4.3.1. 反向路径转发

反向路径转发用于防止到达一个接口的数据包通过不同的接口离开。当传出 路由和传入的路由不同时,它有时被称为非对称路由。路由器通常会以这种方式路由数据包,但大多数主机都不需要这样做。例外是,涉及通过一个链接发送流量并通过不同服务提供商的另一个链接接收流量的应用程序。例如,将租期行与 xDSL 或 satellite 链接与 3G 模式ms 结合使用。如果此类场景适用于您,则需要在传入接口上关闭反向路径转发。简而言之,除非您知道需要它,否则最好被启用,因为它会阻止用户使用本地子网的 IP 地址,并减少了 DDoS 攻击的机会。
注意
Red Hat Enterprise Linux 7 默认使用 Strict Reverse 路径转发,遵循 RFC 3704, Ingress Filtering for Multihomed Networks 的建议。
警告
如果启用了转发,则只有在有其他方法进行 source-address 验证(例如 iptables 规则)时,才应禁用反向路径转发。
rp_filter
通过 rp_filter 指令启用反向路径转发。sysctl 工具可用于更改正在运行的系统,并通过向 /etc/sysctl.conf 文件中添加行来进行永久更改。rp_filter 选项用于指示内核从三种模式之一中进行选择。
要进行临时的全局更改,请以 root 用户身份输入以下命令:
sysctl -w  net.ipv4.conf.default.rp_filter=integer
sysctl -w net.ipv4.conf.all.rp_filter=integer
其中 integer 是以下之一:
  • 0 - 没有源验证。
  • 1 - RFC 3704 中定义的严格模式。
  • 2 - RFC 3704 中定义的松散模式。
可使用 net.ipv4.conf.接口.rp_filter 命令覆盖每个网络接口的设置,如下所示:
sysctl -w net.ipv4.conf.interface.rp_filter=integer
注意
要使这些设置在重启后持久保留,请修改 /etc/sysctl.conf 文件。例如,要更改所有接口的模式,请使用以 root 用户身份运行的编辑器打开 /etc/sysctl.conf 文件,并添加以下行:
net.ipv4.conf.all.rp_filter=2
IPv6_rpfilter
如果 IPv6 协议,firewalld 守护进程默认适用于 Reverse 路径转发。可以在 /etc/firewalld/firewalld.conf 文件中检查设置。您可以通过设置 IPv6_rpfilter 选项来更改 firewalld 行为。
如果您需要反向路径转发的自定义配置,您可以使用 ip6tables 命令 在不 firewalld 守护进程的情况下执行它:
ip6tables -t raw -I PREROUTING -m rpfilter --invert -j DROP
此规则应插入原始/PREROUTING 链的开头,以便它应用到所有流量,特别是在有状态匹配规则之前。有关 iptablesip6tables 服务的详情请参考 第 5.13 节 “使用 iptables设置和控制 IP 集”
启用数据包转发
要启用来自系统外部的数据包转发到另一个外部主机,必须在内核中启用 IP 转发。以 root 身份登录,并将 /etc/sysctl.conf 文件中显示为 net.ipv4.ip_forward = 0 的行改为以下内容:
net.ipv4.ip_forward = 1
要载入 /etc/sysctl.conf 文件中的更改,请输入以下命令:
/sbin/sysctl -p
要检查是否已打开 IP 转发,以 root 身份运行以下命令:
/sbin/sysctl net.ipv4.ip_forward
如果上述命令返回 1,则启用 IP 转发。如果返回 0,您可以使用以下命令手动打开:
/sbin/sysctl -w net.ipv4.ip_forward=1

4.4.3.2. 其它资源

以下是解释 Reverse 路径转发的更多资源。
  • 安装的文档
    /usr/share/doc/kernel-doc-version/Documentation/networking/ip-sysctl.txt - 此文件包含目录中可用文件和选项的完整列表。第一次访问内核文档前,以 root 用户身份输入以下命令:
    ~]# yum install kernel-doc
  • 在线文档
    有关 Multihomed Networks 的 Ingress Filtering 的说明,请参阅 RFC 3704