首先,没有哪个程序能做到让你的网络或服务器永久地安全,安全是一个不断改进、评估、再改进的持续过程,幸运的是,在linux下有许多好的 工具在这个过程中能帮助你,在这篇文章中,我将向你推荐5款我最喜爱的安全工具,它们能帮助你预防,检查,响应 入侵行为。尽管它更容易预防随时可能发生的问题,但某些时候你遇到问题时,你还是需要检查和响应的,这就意味着在形式危及你需要它们之前,你得先熟悉它们的用法。

  1、Nmap

  为了评估一个机器的是否容易遵守攻击,你需要知道有多少服务是暴露给攻击者的。有一个优秀的工具就是Fyodor的网络映射器Nmap,Debian用户可以通过apt-get install nmap来获取它,务必要运行它检查服务器上究竟运行了些什么服务—即使你认为你已经知道了也要运行,很明显,如果ssh端口已经关闭,那么通过ssh密码猜测就对你没什么影响。

  Nmap最简单的用法就是在你本地的网络上探测主机,在这个实例中,我们要求nmap发送ICMP echo请求包(ping)到某段ip地址范围内的所有主机:

  $ nmap -sP 10.0.0.1-254

  Starting nmap 3.81 ( http://www.insecure.org/nmap/ )

  at 2006-11-01 14:46

  NZDT

  Host 10.0.0.25 appears to be up.

  MAC Address: 00:0C:F1:AE:E6:08 (Intel)

  Host 10.0.0.51 appears to be up.

  MAC Address: 08:00:09:9A:1A:AA (Hewlett Packard)

  Host 10.0.0.70 appears to be up.

  MAC Address: 00:0F:EA:64:4E:1E (Giga-Byte Tech Co.)

  ...

  不过nmap最常用的是用来探测哪个服务正在运行。因为TCP建立一个连接使用了3次握手,我们能检查到无真实连接到它们但又被打开的端口,这就是著名的SYN或半打开扫描,当用root登陆执行时这是默认的模式,如果作为一个正常用户执行,nmap尝试全连接来测试是否每个端口是否是打开的。(题外话:在半打开模式下,我们发送初始化SYN数据包并监听响应,RST表明端口是关闭的,SYN+ACK表示端口是打开的,如果没有收到响应,nmap标记这个端口是被过滤了,某些防火墙会丢掉不该有的数据包,产生一个过滤状态标记,其他的将发送RST使得端口看起来是关闭的)典型地,如果一个服务器正在监听你不希望监听的端口,你应该仔细检查一下:

  #nmap -sS 10.0.0.89

  Starting nmap 3.81 ( http://www.insecure.org/nmap/ )

  at 2006-11-01 14:52

  NZDT

  Interesting ports on 10.0.0.89:

  (The 1637 ports scanned but not shown

  below are in state: closed)

  PORT STATE SERVICE

  21/tcp open ftp

  22/tcp open ssh

  42/tcp open nameserver

  80/tcp open http

  110/tcp open pop3

  ...

  Fyodor也添加了许多服务的指纹,你可以要求nmap标识出特定的服务,在命令后加上-sV选项即可:

  # nmap -sV 10.0.0.89

  Starting nmap 3.81 ( http://www.insecure.org/nmap/ )

  at 2006-11-01 14:47

  NZDT

  Interesting ports on 10.0.0.89:

  (The 1637 ports scanned but not shown

  below are in state: closed)

  PORT STATE SERVICE VERSION

  21/tcp open ftp?

  22/tcp open ssh OpenSSH 3.8.1p1

  Debian-8.sarge.4 (protocol 2.0)

  42/tcp open nameserver?

  80/tcp open http Apache httpd 1.3.33

  ((Debian GNU/Linux) mod_gzip/1.3.26.1a PHP/4.3.10-16)

  110/tcp open pop3?

  ...

  其他难以置信的用法是操作系统的探测,在命令后加上-O参数即可,如果这个机器有至少一个端口打开和至少一个端口关闭的话,你就能准确地获取操作系统的信息:

  # nmap -O -sS 10.0.0.89

  Starting nmap 3.81 ( http://www.insecure.org/nmap/ )

  at 2006-11-02 09:02

  NZDT

  Interesting ports on 10.0.0.89:

  (The 1637 ports scanned but not shown

  below are in state: closed)

  PORT STATE SERVICE

  21/tcp open ftp

  ...

  Device type: general purpose

  Running: Linux 2.4.X|2.5.X|2.6.X

  OS details: Linux 2.5.25 - 2.6.3 or

  Gentoo 1.2 Linux 2.4.19 rc1-rc7), Linux 2.6.3 - 2.6.8

  Uptime 30.906 days (since Mon Oct 2 11:18:59 2006)

  因此,请使用nmap在你的网络上检查所有机器,看是否存在有临时安装的但又被忘记删除的服务,你也可以用它从你的网络范围之外来检查你的防火墙是否正确地配置了。

  2、OpenSSH

  当你关心你的网络时,你需要一个安全的办法来管理你的机器,这就意味着不能使用telnet或rcp,或其他任何无保护措施进行数据和密码传输的协议,OpenSSH是大多数人选择用来替代telnet/rcp的协议,它在传输过程中对所有数据都进行加密处理,并且在连接的另一端校验每一个数据包是否被欺骗,Debian用户可以通过apt-get install openssh-server来获取它。

  首先,我建议转换到另一个端口,仅使用密语,不是密码,或者用基础规则审核你的密码,记住sshd保护数据的传输—这就意味着如果你的访问控制非常弱的话,攻击者能够用一个安全的方法控制你的机器,这应该不是你想要的,我见过太多的Linux通过临时帐户被泄密,如upload/upload。要改变这个端口,编辑/etc/ssh/sshd_config文件,修改#Port 22为Port 12345,然后重新启动服务。

  在下面的例子中,我们展示如何用密语替代密码,你在这里要做的是允许你客户端机器用户帐户能读取和写入远程机器的任何文件。

  你可以忽略密语和不使用ssh-agent(ssh-add命令),登陆客户端兵输入下面的命令:

  client% ssh-keygen -t rsa

  Generating public/private rsa key pair.

  Enter file in which to save the key【译者注:输入密钥保存的位置路径】

  (/usr/local/sss/jriden/.ssh/id_rsa):

  Enter passphrase (empty for no passphrase):【译者注:输入密语】

  MY PASSPHRASE

  Enter same passphrase again: MY PASSPHRASE【译者注:再输入一次密语】

  Your identification has been saved in

  /usr/local/sss/jriden/.ssh/id_rsa.

  Your public key has been saved in

  /usr/local/sss/jriden/.ssh/id_rsa.pub.

  The key fingerprint is:

  75:65:36:2b:ed:38:9f:4a:6d:c4:d8:ec:25:ed:ff:31

  jriden@its-dev2

  client% ssh-add

  Enter passphrase for /usr/local/sss/jriden

  /.ssh/id_rsa:【译者注:给你的证书输入密语】

  MY PASSPHRASE

  Identity added: /usr/local/sss/jriden/.ssh/id_rsa

  (/usr/local/sss/jriden/.ssh/id_rsa)

  client%

  现在,取得~/.ssh/id_rsa.pub,将其内容添加到服务器上~/.ssh/authorized_keys中或者~/.ssh/authorized_keys2中,确保移除了无关的新行,它们可能导致复制和粘贴变慢:

  client% scp server:~/testfile .

  The authenticity of host 'server (130.123.128.86)'

  can't be established.

  RSA key fingerprint is

  97:7b:e0:12:c2:f8:8e:05:cc:2b:74:50:9b:00:28:0e.

  Are you sure you want to continue connecting

  (yes/no)? yes

  Warning: Permanently added 'server,130.123.128.86'

  (RSA) to the list

  of known hosts.

  testfile

  |************************************************* **|

  81940 00:00

  这里之所以出现提示是因为服务器是一个不认识的主机,这是ssh尝试与主机欺骗的格斗,下一次连接的时候就不会出现这个提示了。

  3、Tcpdump

  tcpdump可能是检查网络通讯原始数据构成最著名的应用程序了,Debian用户可以通过apt-get install tcpdump来获取,tcpdump文件就是著名的pcap文件,因为pcap是实现包捕获的库。

  在这个例子中,我们dump来自源端口53或目标端口53的所有通讯,意味着,所有的DNS通讯,我使用的-n参数,如果你想更详细一点,你可以使用src port 53或者dst port 53,除此之外,tcpdump尝试ip地址到域名的解析,以便于打印出比较友好的名字,那些DNS请求也将在我们的捕获中显示出来:

  # tcpdump -n 'port 53'

  tcpdump: verbose output suppressed,

  use -v or -vv for full protocol

  decode

  listening on eth0, link-type EN10MB (Ethernet),

  capture size 96 bytes

  11:19:58.302298 IP 192.168.0.8.1037 >

  192.168.128.1.53: 36224+ A?

  www.slashdot.org. (34)

  11:19:58.360227 IP 192.168.128.1.53 >

  192.168.0.8.1037: 36224 1/5/5 A

  66.35.250.151 (239)

  ...

  在其他事情中,snort能存储tcpdump格式的捕获数据,你需要用-r <文件名>和-w <文件名>参数来读取和写入存储的文件。

  4、Snort

  snort是一款最重要的开源网络入侵检测系统,基本上意味着它留意坏的通讯并给你提供警告,它始终保存你读取原始tcpdump内容的输出,Debian用户可以通过apt-get install snort来获取它,默认情况下,它将网络接口设置为混杂模式,也就是说,所有在线路上的数据包都被检查。

  如果你正在尝试保护一个网络,通常你的snort传感器应该放在主路由器的SPAN端口上,这样它就能查看到所有经过那个路由器的网络通讯内容。(SPAN端口提供了所有经过路由器的通讯的一个总和)如果你正在尝试保护一个单独的主机,只需要在主机上简单地按照它即可。

  Snort依靠一个规则数据库来检查数据包,/etc/snort/rules/bad-traffic.rules中有一个例子标记出了一个tcp端口号为0的无效通讯:

  alert tcp $EXTERNAL_NET any <> $HOME_NET 0

  (msg:"BAD-TRAFFIC tcp port 0 traffic"; flow:stateless;

  classtype:misc-activity; sid:524; rev:8;)

  snort将它的警告信息记录到一个文件中,典型地是/var/log/snort/alert,看起来象是这样,表明一个策略规则已经生效,因为来自Google Desktop用户代理的web通讯被观察到了:

  [**] [1:2002801:3] BLEEDING-EDGE WEB

  Google Desktop User-Agent Detected

  [**]

  [Classification: Potential Corporate Privacy

  Violation] [Priority: 1]

  11/02-11:27:58.855143 10.0.0.82:3449 ->

  66.35.250.209:80

  TCP TTL:128 TOS:0x0 ID:35935 IpLen:20

  DgmLen:399 DF

  ***AP*** Seq: 0x847921EE Ack: 0x1A7D5C20

  Win: 0xFFFF TcpLen: 20

  [Xref => http://news.com.com/2100-1032_3-6038197.html]

  Snort也能被配置为记录匹配tcpdump格式的数据包,如下:

  # log_tcpdump: log packets in binary tcpdump format

  # -------------------------------------------------

  # The only argument is the output file name.

  #

  output log_tcpdump: tcpdump.log

  当上面的选项生效后,snort将记录与tcpdump文件匹配的数据包并将其保存到警告文件中,这样就允许你更容易地判断哪个警告是需要担心的哪个警告是错误的警告,你可以象下面这样来阅读它们:

  # tcpdump -r /var/log/snort/tcpdump.log.1161106015

  reading from file /var/log/snort/

  ?tcpdump.log.1161106015, link-type

  EN10MB (Ethernet)

  06:37:50.839942 IP 10.0.0.82.1410 >

  10.10.218.95.www: P

  2352360050:2352360119(69) ack 1723804156 win 65535

  06:53:07.792492 IP 10.0.0.82.1421 >

  10.10.218.95.www: P

  2124589760:2124589829(69) ack 2684875377 win 65535

  ...

  如果你象查看数据包的内容,使用-X参数,tcpdump –X –r /var/log/snort/tcpdump.log.1161106015,snort也有一些功能来中断基于规则匹配(灵活的响应)的连接,也有许多第三方的规则,可以在 http://www.bleedingthreats.net/找到。

  5、Iptables

  iptables是一款状态防火墙几乎集成到所有Linux发行版中了,这就意味着你可以使用它基于ip地址的规则来控制远程机器访问你的服务器,以及连接请求的类型。(旧的无状态的防火墙让你只能根据数据包的内容来做出判断,因此你被端口号限制,不能跟踪会话的存在,如FTP数据流),Debian用户可以通过apt-get install iptables conntrack来获取它。

  当你从终端登陆到机器上时请完成你的初始化测试,用一个错误的规则将你自己锁在外面,然后你亲自恢复,当所有数据包被允许通过,因此这如果不被接受,观察iptables-save和iptables-restore命令,这里有一个加上注释的例子脚本,它非常基础,但是基本上它可以告诉你iptables是如何工作的:

  #!/bin/bash

  # example iptables script

  # flush the old rules

  iptables -F

  # set the default policy of the chain to accept

  iptables -P INPUT ACCEPT

  # create a new table for logging and discarding

  # unwanted packets

  iptables -N LOGDROP

  # use rate limiting on the logging, and

  # add a prefix of 'filter: '

  iptables -A LOGDROP -m limit -j LOG

  ?--log-prefix "filter: "

  # drop unwanted TCP connections with a

  # TCP ReSeT packet

  iptables -A LOGDROP -p tcp -j REJECT

  ?--reject-with tcp-reset

  # drop other packets by sending an ICMP

  # port unreachable in response

  iptables -A LOGDROP -j REJECT

  ?--reject-with icmp-port-unreachable

  # now drop the packet

  iptables -A LOGDROP -j DROP

  #allow anything on the local interface

  iptables -A INPUT -i lo -j RETURN

  # allow packets that are related to

  # an on-going conversation

  iptables -A INPUT -p tcp -m conntrack

  ?--ctstate RELATED,ESTABLISHED -j

  RETURN

  iptables -A INPUT -p udp -m conntrack

  ?--ctstate RELATED,ESTABLISHED -j

  RETURN

  # allow SSH traffic

  iptables -A INPUT -p tcp -m tcp

  ?--dport 22 -j RETURN

  # allow HTTP and HTTPS traffic

  iptables -A INPUT -p tcp -m tcp

  ?--dport 443 -j RETURN

  iptables -A INPUT -p tcp -m tcp

  ?--dport 80 -j RETURN

  # accept the following ICMP types -

  # echo, echo reply, source quench,

  ttl exceeded,

  # destination unreachable - and drop the rest

  iptables -A INPUT -p icmp -m icmp

  ?--icmp-type 0 -j RETURN

  iptables -A INPUT -p icmp -m icmp

  ?--icmp-type 3 -j RETURN

  iptables -A INPUT -p icmp -m icmp

  ?--icmp-type 4 -j RETURN

  iptables -A INPUT -p icmp -m icmp

  ?--icmp-type 8 -j RETURN

  iptables -A INPUT -p icmp -m icmp

  ?--icmp-type 11 -j RETURN

  # if we haven't accepted it, drop and log it.

  iptables -A INPUT -j LOGDROP

  如果你正在疑惑日志在哪里,象什么样子,这里有一个例子,来自系统日志/var/log/messages,一个来自192.168.50.40的UDP数据包,源端口30766,目标服务器是192.168.0.8,目标端口是1026,这个数据包被丢掉了,它可能是windows机器上了信使服务发出的垃圾信息:

  Nov 22 06:24:00 localhost kernel: filter: IN=eth0

  OUT=MAC=00:0a:e6:4e:6d:49:00:14:6c:67:cc:9a:08:00

  SRC=192.168.50.40 DST=192.168.0.8 LEN=402

  TOS=0x00 PREC=0x00 TTL=47 ID=3345 PROTO=UDP

  SPT=30766 DPT=1026 LEN=382

  日志输出看起来有点恐怖,但是你能容易地拣出你想要的信息,首先,你看到的是日期和主机名,IN和OUT描述了数据包是来自哪个端口和通过哪个端口出去的,MAC给出了源和目标MAC地址,SRC和DST是源和目标ip地址,PROTO是UDP,TCP,ICMP等等,SPT和DPT是源和目标端口号,例如:大部分到服务的连接如ssh都有一个临时的源端口,如35214,和一个目标端口22,那么象前面说道的windows机器的信使服务数据包,你可以安全地忽略它。

  当你安装号防火墙后,务必再从另外一台机器上运行一次nmap,来检查是否只打开了正确的端口。

  总结

  安全是不断提高、评估你的保护尺度的一个循环过程,上面的工具允许你保护你的服务器,确保它按需要进行工作,分析意外事件的网络通讯,记住,意外总是让人不愉快的!正如Larry Niven说的:“你不理解的任何事情都是危险的除非你理解了它”。

  当你正在使用这些工具时,尝试思考安全的3个步骤:预防,检查和响应。如果可能你最好预防事情的发生,发生入侵后清除的代价是昂贵的,并且你可能丢失掉有用的数据,无论如何,你将理解一些入侵的知识,因此尽你所能做好预防工作。

  TCP 3次握手

  UDP是一个无连接的协议,相反,TCP在传输失败时会重新再发送一次数据,它的设置比UDP更复杂,以3次握手开始,初始化一个连接,客户端发送一个SYN(开始同步)数据包,服务器然后用一个SYN+ACK数据包进行响应(如果端口是打开的情况下),然后客户端响应一个ACK(告知收到)数据包,连接就这样建立了,这些数据包携带数据序列号,它允许协议检查和重新发送丢失的数据包,如果端口是关闭的或被防火墙过滤了,响应可能是RST或没有响应,更多信息可以查看nmap文档。

  相关日志

  Redhat AS 系列的 OpenSSH RPM 升级包

  Linux下rootkit-ddrk

  Linux kernel 2.6 < 2.6.19 (32bit) ip_append_data() local ring0 root exploit

  黑客再爆Linux内核高危漏洞

  Linux爆本地提权漏洞 请立即更新udev程序