4.18. 安全的网络访问

FIXME: More (Debian-specific) content needed.

4.18.1. 配置内核的网络特性

Many features of the kernel can be modified while running by echoing something into the /proc file system or by using sysctl. By entering /sbin/sysctl -A you can see what you can configure and what the options are, and it can be modified running

  1. /sbin/sysctl -w variable=value

(see sysctl(8)). Only in rare cases do you need to edit something here, but you can increase security that way as well. For example:

  1. net/ipv4/icmp_echo_ignore_broadcasts = 1

This is a Windows emulator because it acts like Windows on broadcast ping if this option is set to 1. That is, ICMP echo requests sent to the broadcast address will be ignored. Otherwise, it does nothing.

如果您想拦截系统里所有的 ICMP 回送请求, 启用这个配置选项:

  1. net/ipv4/icmp_echo_ignore_all = 1

记录您网络中的地址不可用的数据包(由于错误路由):

  1. /proc/sys/net/ipv4/conf/all/log_martians = 1

For more information on what things can be done with /proc/sys/net/ipv4/* read /usr/src/linux/Documentation/filesystems/proc.txt. All the options are described thoroughly under /usr/src/linux/Documentation/networking/ip-sysctl.txt[31].

4.18.2. Configuring syncookies

这个选项是一把双刃剑. 一方面它保护您的系统免受 syn 湮灭; 另一方面它违背了定义的标准(RFCs).

  1. net/ipv4/tcp_syncookies = 1

If you want to change this option each time the kernel is working you need to change it in /etc/network/options by setting syncookies=yes. This will take effect when ever /etc/init.d/networking is run (which is typically done at boot time) while the following will have a one-time effect until the reboot:

  1. echo 1 > /proc/sys/net/ipv4/tcp_syncookies

此选项只有编译内核时启用 CONFIG_SYNCOOKIES 才会有效. 所有的 Debian 内核都是内置此选项编译的, 您可以运行下边的命令来确认:

  1. $ sysctl -A |grep syncookies
  2. net/ipv4/tcp_syncookies = 1

有关 TCP syncookies 的更多信息, 参阅 http://cr.yp.to/syncookies.html.

4.18.3. 增强启动时网络的安全性

当设置了您需要的内核网络选项后, 那么每次重起时这些参数都会被加载. 下边的例子启用了很多前边提到的选项和其他有用的选项.

There are actually two ways to configure your network at boot time. You can configure /etc/sysctl.conf (see: sysctl.conf(5)) or introduce a script that is called when the interface is enabled. The first option will be applied to all interfaces, whileas the second option allows you to configure this on a per-interface basis.

An example of a /etc/sysctl.conf configuration that will secure some network options at the kernel level is shown below. Notice the comment in it, /etc/network/options might override some values if they contradict those in this file when the /etc/init.d/networking is run (which is later than procps on the startup sequence).

  1. #
  2. # /etc/sysctl.conf - Configuration file for setting system variables
  3. # See sysctl.conf (5) for information. Also see the files under
  4. # Documentation/sysctl/, Documentation/filesystems/proc.txt, and
  5. # Documentation/networking/ip-sysctl.txt in the kernel sources
  6. # (/usr/src/kernel-$version if you have a kernel-package installed)
  7. # for more information of the values that can be defined here.
  8.  
  9. #
  10. # Be warned that /etc/init.d/procps is executed to set the following
  11. # variables. However, after that, /etc/init.d/networking sets some
  12. # network options with builtin values. These values may be overridden
  13. # using /etc/network/options.
  14. #
  15. #kernel.domainname = example.com
  16.  
  17. # Additional settings - adapted from the script contributed
  18. # by Dariusz Puchala (see below)
  19. # Ignore ICMP broadcasts
  20. net/ipv4/icmp_echo_ignore_broadcasts = 1
  21. #
  22. # Ignore bogus ICMP errors
  23. net/ipv4/icmp_ignore_bogus_error_responses = 1
  24. #
  25. # Do not accept ICMP redirects (prevent MITM attacks)
  26. net/ipv4/conf/all/accept_redirects = 0
  27. # _or_
  28. # Accept ICMP redirects only for gateways listed in our default
  29. # gateway list (enabled by default)
  30. # net/ipv4/conf/all/secure_redirects = 1
  31. #
  32. # Do not send ICMP redirects (we are not a router)
  33. net/ipv4/conf/all/send_redirects = 0
  34. #
  35. # Do not forward IP packets (we are not a router)
  36. # Note: Make sure that /etc/network/options has 'ip_forward=no'
  37. net/ipv4/conf/all/forwarding = 0
  38. #
  39. # Enable TCP Syn Cookies
  40. # Note: Make sure that /etc/network/options has 'syncookies=yes'
  41. net/ipv4/tcp_syncookies = 1
  42. #
  43. # Log Martian Packets
  44. net/ipv4/conf/all/log_martians = 1
  45. #
  46. # Turn on Source Address Verification in all interfaces to
  47. # prevent some spoofing attacks
  48. # Note: Make sure that /etc/network/options has 'spoofprotect=yes'
  49. net/ipv4/conf/all/rp_filter = 1
  50. #
  51. # Do not accept IP source route packets (we are not a router)
  52. net/ipv4/conf/all/accept_source_route = 0

To use the script you need to first create the script, for example, in /etc/network/interface-secure (the name is given as an example) and call it from /etc/network/interfaces like this:

  1. auto eth0
  2. iface eth0 inet static
  3. address xxx.xxx.xxx.xxx
  4. netmask 255.255.255.xxx
  5. broadcast xxx.xxx.xxx.xxx
  6. gateway xxx.xxx.xxx.xxx
  7. pre-up /etc/network/interface-secure

In this example, before the interface eth0 is enabled the script will be called to secure all network interfaces as shown below.

  1. #!/bin/sh -e
  2. # Script-name: /etc/network/interface-secure
  3. #
  4. # Modifies some default behavior in order to secure against
  5. # some TCP/IP spoofing & attacks for all interfaces.
  6. #
  7. # Contributed by Dariusz Puchalak.
  8. #
  9. echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
  10. # Broadcast echo protection enabled.
  11. echo 0 > /proc/sys/net/ipv4/conf/all/forwarding
  12. # IP forwarding disabled.
  13. echo 1 > /proc/sys/net/ipv4/tcp_syncookies # TCP syn cookies protection enabled.
  14. echo 1 >/proc/sys/net/ipv4/conf/all/log_martians # Log strange packets.
  15. # (this includes spoofed packets, source routed packets, redirect packets)
  16. # but be careful with this on heavy loaded web servers.
  17. echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
  18. # Bad error message protection enabled.
  19.  
  20. # IP spoofing protection.
  21. echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
  22.  
  23. # Disable ICMP redirect acceptance.
  24. echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
  25. echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
  26.  
  27. # Disable source routed packets.
  28. echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
  29.  
  30. exit 0

Notice that you can actually have per-interface scripts that will enable different network options for different interfaces (if you have more than one), just change the pre-up line to:

  1. pre-up /etc/network/interface-secure $IFACE

And use a script which will only apply changes to a specific interface, not to all of the interfaces available. Notice that some networking options can only be enabled globally, however. A sample script is this one:

  1. #!/bin/sh -e
  2. # Script-name: /etc/network/interface-secure
  3. #
  4. # Modifies some default behavior in order to secure against
  5. # some TCP/IP spoofing & attacks for a given interface.
  6. #
  7. # Contributed by Dariusz Puchalak.
  8. #
  9.  
  10. IFACE=$1
  11. if [ -z "$IFACE" ] ; then
  12. echo "$0: Must give an interface name as argument!"
  13. echo "Usage: $0 <interface>"
  14. exit 1
  15. fi
  16.  
  17. if [ ! -e /proc/sys/net/ipv4/conf/$IFACE/ ]; then
  18. echo "$0: Interface $IFACE does not exit (cannot find /proc/sys/net/ipv4/conf/)"
  19. exit 1
  20. fi
  21.  
  22. echo 0 > /proc/sys/net/ipv4/conf/$IFACE/forwarding # IP forwarding disabled.
  23. echo 1 >/proc/sys/net/ipv4/conf/$IFACE/log_martians # Log strange packets.
  24. # (this includes spoofed packets, source routed packets, redirect packets)
  25. # but be careful with this on heavy loaded web servers.
  26.  
  27. # IP spoofing protection.
  28. echo 1 > /proc/sys/net/ipv4/conf/$IFACE/rp_filter
  29.  
  30. # Disable ICMP redirect acceptance.
  31. echo 0 > /proc/sys/net/ipv4/conf/$IFACE/accept_redirects
  32. echo 0 > /proc/sys/net/ipv4/conf/$IFACE/send_redirects
  33.  
  34. # Disable source routed packets.
  35. echo 0 > /proc/sys/net/ipv4/conf/$IFACE/accept_source_route
  36.  
  37. exit 0

An alternative solution is to create an init.d script and have it run on bootup (using update-rc.d to create the appropriate rc.d links).

4.18.4. 配置防火墙

In order to have firewall capabilities, either to protect the local system or others behind it, the kernel needs to be compiled with firewall capabilities. The standard Debian 2.2 kernel (Linux 2.2) provides the packet filter ipchains firewall, Debian 3.0 standard kernel (Linux 2.4) provides the stateful packet filter iptables (netfilter) firewall.

In any case, it is pretty easy to use a kernel different from the one provided by Debian. You can find pre-compiled kernels as packages you can easily install in the Debian system. You can also download the kernel sources using the kernel-source-X and build custom kernel packages using make-kpkg from the kernel-package package.

第 5.14 节 “增加防火墙” 处有关于在 Debian 中配置防火墙的更详细的讨论.

4.18.5. 禁用弱客户主机问题

Systems with more than one interface on different networks can have services configured so that they will bind only to a given IP address. This usually prevents access to services when requested through any other address. However, this does not mean (although it is a common misconception) that the service is bound to a given hardware address (interface card). [32]

It seems, however, not to work with services bound to 127.0.0.1, you might need to write the tests using raw sockets.

This is not an ARP issue and it’s not an RFC violation (it’s called weak end host in RFC1122, (in the section 3.3.4.2). Remember, IP addresses have nothing to do with physical interfaces.

在 2.2 (和更早)的内核中, 可以做如下修正:

  1. # echo 1 > /proc/sys/net/ipv4/conf/all/hidden
  2. # echo 1 > /proc/sys/net/ipv4/conf/eth0/hidden
  3. # echo 1 > /proc/sys/net/ipv4/conf/eth1/hidden
  4. .....

在最新的内核中, 还可以做如下操作:

  • iptables 规则.

  • properly configured routing. [33]

  • kernel patching. [34]

Along this text there will be many occasions in which it is shown how to configure some services (sshd server, apache, printer service…) in order to have them listening on any given address, the reader should take into account that, without the fixes given here, the fix would not prevent accesses from within the same (local) network. [35]

FIXME: Comments on Bugtraq indicate there is a Linux specific method to bind to a given interface.

FIXME: 提交一个 netbas 的错误, 使得 routing fix 成为Debian标准的动作?

4.18.6. 保护系统免受 ARP 攻击

当您不再信任您的局域网内(经常会出现这种情况, 因为这才是安全的态度)的其他系统时, 您需要保护自己免受各种各样的 ARP 攻击.

As you know the ARP protocol is used to link IP addresses to MAC addresses (see ftp://ftp.isi.edu/in-notes/rfc826.txt for all the details). Every time you send a packet to an IP address an ARP resolution is done (first by looking into the local ARP cache then if the IP isn’t present in the cache by broadcasting an ARP query) to find the target’s hardware address. All the ARP attacks aim to fool your box into thinking that box B’s IP address is associated to the intruder’s box’s MAC address; Then every packet that you want to send to the IP associated to box B will be send to the intruder’s box…

Those attacks (ARP cache poisoning, ARP spoofing…) allow the attacker to sniff the traffic even on switched networks, to easily hijack connections, to disconnect any host from the network… ARP attacks are powerful and simple to implement, and several tools exists, such as arpspoof from the dsniff package or http://arpoison.sourceforge.net/.

但是, 总有一个解决办法:

  • Use a static ARP cache. You can set up “static” entries in your ARP cache with:

    1. arp -s host_name hdwr_addr

    By setting static entries for each important host in your network you ensure that nobody will create/modify a (fake) entry for these hosts (static entries don’t expire and can’t be modified) and spoofed ARP replies will be ignored.

  • Detect suspicious ARP traffic. You can use arpwatch, karpski or more general IDS that can also detect suspicious ARP traffic (snort, http://www.prelude-ids.org…).

  • 实行确认主机MAC地址的IP通讯过滤.


[31] In Debian the kernel-source-version packages copy the sources to /usr/src/kernel-source-`version`.tar.bz2, just substitute version to whatever kernel version sources you have installed

[32] To reproduce this (example provided by Felix von Leitner on the Bugtraq mailing list):

  1. host a (eth0 connected to eth0 of host b):
  2. ifconfig eth0 10.0.0.1
  3. ifconfig eth1 23.0.0.1
  4. tcpserver -RHl localhost 23.0.0.1 8000 echo fnord
  5.  
  6. host b:
  7. ifconfig eth0 10.0.0.2
  8. route add 23.0.0.1 gw 10.0.0.1
  9. telnet 23.0.0.1 8000

[33] The fact that this behavior can be changed through routing was described by Matthew G. Marsh in the Bugtraq thread:

  1. eth0 = 1.1.1.1/24
  2. eth1 = 2.2.2.2/24
  3.  
  4. ip rule add from 1.1.1.1/32 dev lo table 1 prio 15000
  5. ip rule add from 2.2.2.2/32 dev lo table 2 prio 16000
  6.  
  7. ip route add default dev eth0 table 1
  8. ip route add default dev eth1 table 2

[34] There are some patches available for this behavior as described in Bugtraq’s thread at http://www.linuxvirtualserver.org/~julian/#hidden and http://www.fefe.de/linux-eth-forwarding.diff.

[35] An attacker might have many problems pulling the access through after configuring the IP-address binding while not being on the same broadcast domain (same network) as the attacked host. If the attack goes through a router it might be quite difficult for the answers to return somewhere.