前言
接续系统加固第一部分未完的内容,第二部分主要涉及关闭多余的服务,用户账户的安全策略,系统日志配置与分析,以及内核网络参数的优化等等。
《修改系统默认的账户密码策略》
这是通过编辑 /etc/login.defs 文件相关内容实现的。和前面一样的道理,修改前需要备份,然后把“鸡蛋”放在多个“篮子”里:
[root@centos6-5vm 桌面]# cp -p /etc/login.defs /etc/login.defs_backup
使用 vim 文本编辑器编辑 /etc/login.defs 文件,首先找到 PASS_MAX_DAYS 这一参数,根据文档的英语注释,应该是“新建账户的密码的最大有效天数”,默认值为99999,对于系统上有多个普通账户,而且频繁创建账户的公用计算机而言,这个设置明显不合理,根据你的实际情况,将其改为30~90天之间的范围较合适。
PASS_MIN_DAYS 0
很多网上文章将其解释为新创建账户的密码的最短有效期。只要稍微用一点逻辑推理,就知道这个解释不正确:例如密码到了最小有效期限,但是还没到最大有效期限,那么系统究竟是要以那个为基准?
按照该文档的英语注释直译,应该是“新建账户首次设置密码后,最少应该间隔多少天,才允许再次修改密码”,默认值是0,即没有修改间隔时间限制,这个值可以根据你实际的需求来设定。
PASS_MIN_LEN 5
系统要求的密码最小长度,默认为5,不够安全,将其设置为8以上,可以有效防止一些没有安全意识的用户设置“弱口令”。
PASS_WARN_AGE 7
很多文章对于该参数的解释也很绕。举个简单的例子来理解:
假设你在 2014-8-12 8:00 新建一个用户,将其 PASS_MAX_DAYS 参数的值设置为30天,并且将其 PASS_WARN_AGE 参数的值设为7天(默认值),结果是:
该账户的密码将在 2014-9-12 8:00过期,系统将在 2014-9-5 8:00 开始,持续的提醒你,密码即将到期,需要更换。
《限制所有普通账户切换成root用户》
默认情况下,以普通用户登录系统后,执行 su root 命令,然后键入 root 用户的密码,就可以切换成 root 用户,这违反“最小权限原则”。
要限制所有普通用户切换成 root 用户,首先必须保证:只有 root 用户在 root组,不能有其它任何用户属于该组。
查看 /etc/passwd 的第4列,如果为0则表示属于 root组,这就是为什么我们在第一部分博文中提到,这些用户必须删除,因为它们的 GID=0 ( 组ID为0,可以切换到 root 用户):
确保所有用户排除在root组外后,通过编辑 /etc/pam.d/su 文件,来限制仅有root组才能切换到root用户:
[root@centos6-5vm 桌面]# cp -p /etc/pam.d/su /etc/pam.d/su_backup [root@centos6-5vm 桌面]# vim /etc/pam.d/su
执行完上述操作后,注销root用户,或者重启系统,以任何普通用户身份登录,然后尝试执行 su root 命令切换成root用户,可以发现,系统已禁止切换操作。
还有一点要注意,passwd 文件中的最后一个字段指出该用户登录进系统后执行的命令,通常是启动交互式终端shell,例如 /bin/bash,除了root和一些已知的普通用户外,其它任何用户都不应该执行 /bin/bash,通常是禁止登录,即 /sbin/nologin,如果发现一个陌生的用户账户从 /sbin/nologin 变成 /bin/bash 就要引起警惕了。
与此相关的还有 sudo 命令,该命令允许键入用户自己的密码后,以root用户的权限执行其它命令。因此,必须限制任何普通用户进行这一操作。
幸运的是,在 /etc/sudoers 文件中,系统默认禁止任何用户执行该操作。
我们只需确保该文件没有被篡改:
进一步来讲,下面是 sudoers 文件需要重点关注的部分(正常状态),在该部分添加的任何用户都能够免口令就切换到 root用户:
## Allow root to run any commands anywhere root ALL=(ALL) ALL ## Allows members of the 'sys' group to run networking, software, ## service management apps and more. # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS ## Allows people in group wheel to run all commands # %wheel ALL=(ALL) ALL ## Same thing without a password # %wheel ALL=(ALL) NOPASSWD: ALL ## Allows members of the users group to mount and unmount the ## cdrom as root # %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom ## Allows members of the users group to shutdown this system # %users localhost=/sbin/shutdown -h now ## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment) #includedir /etc/sudoers.d
《备份系统的启动文件》
为了避免安装一些流氓或者恶意程序后,修改系统的启动相关文件,实现启动自动运行,我们需要检查并且备份 /etc/rc.d/rc.local 这个文件,这里给出新安装完系统后的 rc.local 文件的正常配置情况,确保你的系统的 rc.local 除了进行生产业务必需启动的程序外,应该和截图里的一样“干净”:
[root@centos6-5 桌面]# cp -p /etc/rc.d/rc.local /etc/rc.d/rc.local_backup
注意,由于 /etc/rc.local 这个符号链接,实际指向上面的原始文件,因此,在用副本替换后,为了确保万无一失,可以删除后重建一个相同的符号链接指向替换后的原始文件。这个动作等同于“更新”符号链接。
《取消某些文件默认的 suid 位》
linux 中的某些文件,需要用所有者的身份来执行,才有完整的访问权限。
为了让其它用户以该文件所有者的身份来执行,这些文件的所有者的执行权限被设置了 s 位( 即 suid 位 )。
这本来是方便普通用户在必要时执行越权操作,但是同样也带来了安全隐患;如果普通用户执行带有 suid 位,所有者为 root 的各种服务器进程,
例如 apache web server ,那么实质上就是以 root 身份来执行,一旦 apache web server 的缓冲区溢出漏洞被用于远程执行恶意代码, 那么攻击者获取到的权限也会是 root ,因为 apache 是(某个普通用户)以 root 权限运行的。
这就是我们必须找出系统中那些带有 suid 位的文件,取消掉它们的 s 位的原因,这样,即便该文件的其他人执行权限启用,也会因其不是所有者而无法执行。
举个例子:
[root@centos6-5vm 桌面]# ll /bin/ping -rwsr-sr-x. 1 root root 36892 9月 26 2013 /bin/ping
ping 命令启用了 suid 位,并且所有者为 root,意味着所有其它的用户能以 root 的权限来执行 ping 命令:
[root@centos6-5vm 桌面]# su - shayi [shayi@centos6-5vm ~]$ ping -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.065 ms --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.065/0.065/0.065/0.000 ms
我们回到 root 用户,将 ping 文件的 suid 位取消,再次切换到其他用户,执行ping 命令,此时因权限不够而无法执行:
[shayi@centos6-5vm ~]$ exit logout [root@centos6-5vm 桌面]# chmod u-s,g-s /bin/ping [root@centos6-5vm 桌面]# ll /bin/ping -rwxr-xr-x. 1 root root 36892 9月 26 2013 /bin/ping [root@centos6-5vm 桌面]# su - shayi [shayi@centos6-5vm ~]$ ping -c 1 127.0.0.1 ping: icmp open socket: 不允许的操作
从上面的输出可以看到,将 ping 文件的所有者,所属组的 suid 位取消后,即使 ping 文件的其他人执行权限(最后一个x)启用,其他用户也无法运行该命令。
我们使用下面的命令来找出系统中默认带有 suid 位的文件。
值得一提的是: /bin/su 默认也启用了 suid 位,并且所有者是 root。
如果禁用它的 suid 位,就表示所有其它用户都不能通过执行 su 命令来切换到 root 用户,这也是安全加固中常见的操作:
查找“所有者”设置了 suid 位的文件:
[root@centos6-5vm 桌面]# find / -perm -4000 -ls
查找“所属组”设置了 suid 位的文件:
[root@centos6-5vm 桌面]# find / -perm -2000 -ls
《使用 chattr / lsattr,getfacl / setfacl 来控制文件的访问权限》
chattr 命令用以限制特定文件的读写,执行权限。默认情况下,任何其他用户对该命令都有执行权限,
因此首先要将该命令的权限改为仅有 root 有读写,执行权限,对于 lsattr (用于查看特定文件的权限限制状态)也是同理:
[root@centos6-5vm ~]# whereis chattr chattr: /usr/bin/chattr /usr/share/man/man1/chattr.1.gz [root@centos6-5vm ~]# ll /usr/bin/chattr -rwxr-xr-x. 1 root root 11372 11月 22 2013 /usr/bin/chattr [shayi@centos6-5vm ~]$ ll /usr/bin/lsattr -rwxr-xr-x. 1 root root 11372 11月 22 2013 /usr/bin/lsattr [root@centos6-5vm ~]# su - shayi [shayi@centos6-5vm ~]$ /usr/bin/chattr Usage: /usr/bin/chattr [-RVf] [-+=AacDdeijsSu] [-v version] files... [shayi@centos6-5vm ~]$ /usr/bin/lsattr -------------e- ./音乐 -------------e- ./模板 -------------e- ./文档 -------------e- ./下载 -------------e- ./图片 -------------e- ./桌面 -------------e- ./视频 -------------e- ./公共的 [shayi@centos6-5vm ~]$ exit logout [root@centos6-5vm ~]# chmod 700 /usr/bin/chattr [root@centos6-5vm ~]# chmod 700 /usr/bin/lsattr [root@centos6-5vm ~]# ll /usr/bin/chattr -rwx------. 1 root root 11372 11月 22 2013 /usr/bin/chattr [root@centos6-5vm ~]# ll /usr/bin/lsattr -rwx------. 1 root root 11372 11月 22 2013 /usr/bin/lsattr [root@centos6-5vm ~]# su - shayi [shayi@centos6-5vm ~]$ /usr/bin/lsattr -bash: /usr/bin/lsattr: 权限不够 [shayi@centos6-5vm ~]$ /usr/bin/chattr -bash: /usr/bin/chattr: 权限不够
从上面的整个操作过程不难看出:默认情况下,shayi 用户可以执行 chattr 和 lsattr 命令,回到 root 用户将这2个文件权限改为 700 以后,再次切换到 shayi 用户,此时就没有权限执行这2个命令了。
上面的准备工作完成以后,我们可以将系统上比较重要的文件,通过 chattr 命令,将其设置为不能修改(写)以及删除,或者仅能“追加”,不能删除。注意,设置后即便是 root 用户,也不能修改或者删除。除非执行相应的取消设置命令:
[root@centos6-5vm ~]# ll /etc/ssh/sshd_config -rw-------. 1 root root 3879 11月 23 2013 /etc/ssh/sshd_config [root@centos6-5vm ~]# lsattr /etc/ssh/sshd_config -------------e- /etc/ssh/sshd_config [root@centos6-5vm ~]# chattr +i /etc/ssh/sshd_config [root@centos6-5vm ~]# lsattr /etc/ssh/sshd_config ----i--------e- /etc/ssh/sshd_config [root@centos6-5vm ~]# rm -rf /etc/ssh/sshd_config rm: 无法删除"/etc/ssh/sshd_config": 不允许的操作 [root@centos6-5vm ~]# cat /dev/null > /etc/ssh/sshd_config bash: /etc/ssh/sshd_config: 权限不够 [root@centos6-5vm ~]# chattr -i /etc/ssh/sshd_config [root@centos6-5vm ~]# lsattr /etc/ssh/sshd_config -------------e- /etc/ssh/sshd_config
一般而言,sshd 的配置文件在首次配置完成后,就不需要变动了。从上面的操作输出可以看到,使用 chattr 的 +i 选项,将其设置为包括 root 在内的所有用户都不能删除,或者通过空字符设备文件将其内容清空。
这种方式最大的弱点在于,攻击者使用 chattr -i 选项,就可以解除限制,随意删除了。因此,仅适用于防范普通用户无意之间的误操作。
例如,我们在审查 /var/log 目录下的众多日志文件时,假设发现某些日志文件,如 message 等,被莫名其妙地清空,那就说明服务器已经被入侵并且攻击者很可能获取到 root 权限,此时应该将主机断开网络连接,进行深度的分析,排查工作。
另外一种叫做 lcap 的工具,甚至可以限制 root 用户操作 chattr / lsattr,不过这种限制在系统重启后就解除了,因此,如果使用了 lcap ,在分析 /var/log/lastlog,/var/log/wtmp 日志时,发现系统“非预期”的重启,就必须将服务器被入侵的可能性列入考虑,从而查找 /var/log/secure 中的登录有关信息。
下面的操作演示了将 /var/log 目录下的所有日志文件通过 chattr 设置成“仅允许追加内容”的属性,在一定程度上保障了系统日志的安全。
注意,删除操作是以 root 用户执行的,同样被禁止:
[root@centos6-5vm 桌面]# lsattr /var/log -------------e- /var/log/sa -------------e- /var/log/lastlog -------------e- /var/log/maillog -------------e- /var/log/cups -------------e- /var/log/ntpstats -------------e- /var/log/messages-20140824 -------------e- /var/log/wtmp -------------e- /var/log/btmp -------------e- /var/log/maillog-20140824 -------------e- /var/log/spice-vdagent.log -------------e- /var/log/samba -------------e- /var/log/spooler-20140818 -------------e- /var/log/yum.log -------------e- /var/log/cron-20140824 -------------e- /var/log/maillog-20140818 -------------e- /var/log/anaconda.log -------------e- /var/log/dmesg.old -------------e- /var/log/Xorg.0.log -------------e- /var/log/Xorg.0.log.old -------------e- /var/log/anaconda.xlog -------------e- /var/log/cron-20140818 [root@centos6-5vm 桌面]# chattr -R +a /var/log [root@centos6-5vm 桌面]# lsattr /var/log -----a-------e- /var/log/sa -----a-------e- /var/log/lastlog -----a-------e- /var/log/maillog -----a-------e- /var/log/cups -----a-------e- /var/log/ntpstats -----a-------e- /var/log/messages-20140824 -----a-------e- /var/log/wtmp -----a-------e- /var/log/btmp -----a-------e- /var/log/maillog-20140824 -----a-------e- /var/log/spice-vdagent.log -----a-------e- /var/log/samba -----a-------e- /var/log/spooler-20140818 -----a-------e- /var/log/yum.log -----a-------e- /var/log/cron-20140824 -----a-------e- /var/log/maillog-20140818 -----a-------e- /var/log/anaconda.log -----a-------e- /var/log/dmesg.old -----a-------e- /var/log/Xorg.0.log -----a-------e- /var/log/Xorg.0.log.old -----a-------e- /var/log/anaconda.xlog -----a-------e- /var/log/cron-20140818 [root@centos6-5vm 桌面]# rm -rf /var/log rm: 无法删除"/var/log/sa/sar22": 不允许的操作 rm: 无法删除"/var/log/sa/sa21": 不允许的操作 rm: 无法删除"/var/log/sa/sa09": 不允许的操作 rm: 无法删除"/var/log/sa/sa23": 不允许的操作 rm: 无法删除"/var/log/sa/sa27": 不允许的操作 rm: 无法删除"/var/log/sa/sa20": 不允许的操作 rm: 无法删除"/var/log/sa/sar20": 不允许的操作 rm: 无法删除"/var/log/sa/sar12": 不允许的操作 rm: 无法删除"/var/log/sa/sa10": 不允许的操作 rm: 无法删除"/var/log/sa/sa28": 不允许的操作 rm: 无法删除"/var/log/sa/sa14": 不允许的操作 rm: 无法删除"/var/log/sa/sa13": 不允许的操作 rm: 无法删除"/var/log/sa/sa12": 不允许的操作 rm: 无法删除"/var/log/sa/sar18": 不允许的操作 rm: 无法删除"/var/log/sa/sar21": 不允许的操作 rm: 无法删除"/var/log/sa/sa25": 不允许的操作 rm: 无法删除"/var/log/sa/sa08": 不允许的操作 rm: 无法删除"/var/log/sa/sar19": 不允许的操作 rm: 无法删除"/var/log/sa/sar08": 不允许的操作 rm: 无法删除"/var/log/sa/sa22": 不允许的操作 rm: 无法删除"/var/log/sa/sar23": 不允许的操作 rm: 无法删除"/var/log/sa/sa11": 不允许的操作 rm: 无法删除"/var/log/sa/sar27": 不允许的操作 rm: 无法删除"/var/log/sa/sa18": 不允许的操作 rm: 无法删除"/var/log/sa/sa19": 不允许的操作 rm: 无法删除"/var/log/sa/sar24": 不允许的操作 rm: 无法删除"/var/log/sa/sa24": 不允许的操作 rm: 无法删除"/var/log/lastlog": 不允许的操作 rm: 无法删除"/var/log/maillog": 不允许的操作 rm: 无法删除"/var/log/cups": 不允许的操作 rm: 无法删除"/var/log/ntpstats": 不允许的操作 rm: 无法删除"/var/log/messages-20140824": 不允许的操作 rm: 无法删除"/var/log/wtmp": 不允许的操作 rm: 无法删除"/var/log/btmp": 不允许的操作 rm: 无法删除"/var/log/maillog-20140824": 不允许的操作 rm: 无法删除"/var/log/spice-vdagent.log": 不允许的操作 rm: 无法删除"/var/log/samba/old": 不允许的操作 rm: 无法删除"/var/log/spooler-20140818": 不允许的操作 rm: 无法删除"/var/log/yum.log": 不允许的操作 rm: 无法删除"/var/log/cron-20140824": 不允许的操作 rm: 无法删除"/var/log/maillog-20140818": 不允许的操作 rm: 无法删除"/var/log/anaconda.log": 不允许的操作 rm: 无法删除"/var/log/dmesg.old": 不允许的操作 rm: 无法删除"/var/log/Xorg.0.log": 不允许的操作 rm: 无法删除"/var/log/Xorg.0.log.old": 不允许的操作 rm: 无法删除"/var/log/anaconda.xlog": 不允许的操作 rm: 无法删除"/var/log/cron-20140818": 不允许的操作
*****由于 linux 文件系统的基本权限(包括使用 chmod 及其类似命令实现的权限控制)是针对文件所有者,所属组,其他人进行控制的 ,并无法针对特定的普通用户设置访问权限。
使用 getfacl 可以查看文件的 ACL(account control list,账户控制列表)权限;使用 setfacl 可以设定,修改文件的 ACL 权限。
同样的道理,我们首先要确保这2个命令仅有 root 用户可以执行,也就是讲,避免其他普通用户通过执行这2个命令,查看或修改任何其它系统文件与命令的权限:
[root@centos6-5vm 桌面]# ll /usr/bin/getfacl -rwxr-xr-x. 1 root root 24140 12月 8 2011 /usr/bin/getfacl [root@centos6-5vm 桌面]# ll /usr/bin/setfacl -rwxr-xr-x+ 1 root root 32432 12月 8 2011 /usr/bin/setfacl [root@centos6-5vm 桌面]# chmod 700 /usr/bin/getfacl [root@centos6-5vm 桌面]# ll /usr/bin/getfacl -rwx------. 1 root root 24140 12月 8 2011 /usr/bin/getfacl [root@centos6-5vm 桌面]# chmod --reference=/usr/bin/getfacl /usr/bin/setfacl [root@centos6-5vm 桌面]# ll /usr/bin/setfacl -rwx------+ 1 root root 32432 12月 8 2011 /usr/bin/setfacl
在上面的操作中,我们先将 getfacl 命令设置成仅有 root 用户有权限读写执行,接着,使用 chmod 的 --reference=[基准参考权限的文件A] [要修改权限的文件B] 选项,将 B( setfacl )的权限改成和 A( getfacl ) 相同。
假设我们要让 root 用户与 shayi2 用户有权限读写执行
/var/log/message-20140826 这个日志文件,但是其他用户都没有权限。
首先将 /var/log 目录本身及其下层所有的文件基本权限改为 700,仅 root 用户可以读写执行,然后找出 shayi2 用户的 uid ,通过使用 setfacl 指定 uid ,依序让 shayi2 用户有权限读写执行 /var/log,/var/log/messages-20140818,
注意,要设定 ACL 的文件或命令的所有上层父目录,都需要有相同的 ACL 权限设定,否则会因为某个中间目录的 ACL 权限错误导致无法访问最终文件/命令。
并且,设定前确认 chattr 命令没有限制相应文件/命令的删除修改权限,否则会因规则冲突导致 setfacl 命令失败。
下面的操作演示了整个过程:
[root@centos6-5vm 桌面]# ls -ld /var/log drwxr-xr-x. 13 root root 4096 8月 26 16:27 /var/log [root@centos6-5vm 桌面]# chmod -R 700 /var/log [root@centos6-5vm 桌面]# ls -ld /var/log drwx------. 13 root root 4096 8月 26 16:27 /var/log [root@centos6-5vm 桌面]# id shayi2 uid=501(shayi2) gid=501(shayi2) 组=501(shayi2) [root@centos6-5vm 桌面]# lsattr /usr/bin/setfacl -------------e- /usr/bin/setfacl [root@centos6-5vm 桌面]# lsattr /var/log/messages-20140826 -------------e- /var/log/messages-20140826 [root@centos6-5vm 桌面]# ll /usr/bin/setfacl -rwxr-xr-x. 1 root root 32432 12月 8 2011 /usr/bin/setfacl [root@centos6-5vm 桌面]# chmod 700 /usr/bin/setfacl [root@centos6-5vm 桌面]# ll /usr/bin/setfacl -rwx------. 1 root root 32432 12月 8 2011 /usr/bin/setfacl [root@centos6-5vm 桌面]# getfacl /var/log getfacl: Removing leading '/' from absolute path names # file: var/log # owner: root # group: root user::rwx group::--- other::--- [root@centos6-5vm 桌面]# su - shayi2 [shayi2@centos6-5vm ~]$ tail -n 5 /var/log/message-20140826 tail: 无法打开"/var/log/message-20140826" 读取数据: 权限不够 [shayi2@centos6-5vm ~]$ exit logout [root@centos6-5vm 桌面]# setfacl -m u:501:rwx /var/log [root@centos6-5vm 桌面]# setfacl -m u:501:rwx /var/log/messages-20140826 [root@centos6-5vm 桌面]# getfacl /var/log getfacl: Removing leading '/' from absolute path names # file: var/log # owner: root # group: root user::rwx user:shayi2:rwx group::--- mask::rwx other::--- [root@centos6-5vm 桌面]# getfacl /var/log/messages-20140826 getfacl: Removing leading '/' from absolute path names # file: var/log/messages-20140826 # owner: root # group: root user::rwx user:shayi2:rwx group::--- mask::rwx other::--- [root@centos6-5vm 桌面]# su - shayi2 [shayi2@centos6-5vm ~]$ tail -n 5 /var/log/messages-20140826 Aug 26 16:08:15 centos6-5vm ntpd[2175]: 0.0.0.0 c618 08 no_sys_peer Aug 26 16:23:45 centos6-5vm ntpd[2175]: 0.0.0.0 c612 02 freq_set kernel -34.836 PPM Aug 26 16:23:45 centos6-5vm ntpd[2175]: 0.0.0.0 c61c 0c clock_step +0.404820 s Aug 26 16:23:45 centos6-5vm ntpd[2175]: 0.0.0.0 c615 05 clock_sync Aug 26 16:23:46 centos6-5vm ntpd[2175]: 0.0.0.0 c618 08 no_sys_peer [shayi2@centos6-5vm ~]$ ll /var/log/messages-20140826 -rwxrwx---+ 1 root root 343388 8月 26 16:23 /var/log/messages-20140826 [shayi2@centos6-5vm ~]$ exit logout [root@centos6-5vm 桌面]# su - shayi [shayi@centos6-5vm ~]$ tail -n 5 /var/log/messages-20140826 tail: 无法打开"/var/log/messages-20140826" 读取数据: 权限不够 [shayi@centos6-5vm ~]$ exit logout [root@centos6-5vm 桌面]#
从上面的输出可以看到:我们实现了仅允许 root 以及 shayi2 用户读写执行
/var/log/messages-20140826 这个日志文件,其它用户,例如 shayi ,则没有权限访问这个日志文件。
《日志分析常用的命令汇总》
假设下面场景:要找出你的一个用于公网访问的SSH服务器,除了你自己外,还有哪些非法用户和IP地址,在暴力破解SSH密码,尝试远程登录?
这些命令可以帮助快速定位攻击者以及入侵者:
[root@centos6-5 桌面]# more /var/log/messages | grep Failed [root@centos6-5 桌面]# tail -f /var/log/messages | grep Failed [root@centos6-5 桌面]# more /var/log/messages | grep Accepted [root@centos6-5 桌面]# tail -f /var/log/messages | grep Accepted [root@centos6-5 桌面]# more /var/log/secure | grep Failed [root@centos6-5 桌面]# tail -f /var/log/secure | grep Failed [root@centos6-5 桌面]# more /var/log/secure | grep Accepted [root@centos6-5 桌面]# tail -f /var/log/secure | grep Accepted [root@centos6-5 桌面]# more /var/log/secure | grep refused [root@centos6-5 桌面]# tail -f /var/log/secure | grep refused [root@centos6-5 桌面]# more /var/log/secure | grep Illegal [root@centos6-5 桌面]# tail -f /var/log/secure | grep Illegal
*****将 /var/log 目录下的所有文件的权限变更为仅有root用户可以读写,这可以防止攻击者以较低权限用户修改,删除该目录下的关键日志文件,例如 messages,secure,wtmp,lastlog,等等:
[root@centos6-5vm 桌面]# chomd -R 600 /var/log [root@centos6-5vm 桌面]# ls -ld /var/log drw-------. 13 root root 4096 8月 12 10:29 /var/log [root@centos6-5vm log]# cd /var/log && ls -ail 1569813 -rw------- 1 root root 3256 8月 12 10:23 boot.log 1572234 -rw------- 1 root root 22012 8月 12 20:20 cron 1571072 drw-------. 2 4 sys 4096 8月 17 2013 cups 1569806 -rw------- 1 root root 71232 8月 12 10:23 dmesg 1571115 drw-------. 2 root root 4096 8月 14 2013 httpd 1571062 -rw-------. 1 root root 146584 8月 11 10:10 lastlog 1572297 -rw------- 1 root root 0 8月 10 08:47 maillog 1572307 -rw------- 1 root root 1305831 8月 12 12:52 messages 1572308 -rw------- 1 root root 62855 8月 12 18:23 secure 1572309 -rw------- 1 root root 0 8月 10 08:47 spooler 1570980 -rw-------. 1 root root 0 6月 25 16:57 tallylog 1571067 -rw-------. 1 root utmp 288000 8月 12 10:29 wtmp
取决于这些日志文件的“文件类型”,调用查看它们的命令也不同。首先,获取这些文件的类型:
[root@centos6-5vm log]# file boot.log boot.log: ASCII English text, with CRLF, CR line terminators, with escape sequences [root@centos6-5vm log]# file cron cron: ASCII text [root@centos6-5vm log]# file dmesg dmesg: ASCII C++ program text [root@centos6-5vm log]# file lastlog lastlog: ISO-8859 text, with no line terminators [root@centos6-5vm log]# file maillog maillog: empty [root@centos6-5vm log]# file messages messages: UTF-8 Unicode English text [root@centos6-5vm log]# file secure secure: UTF-8 Unicode English text [root@centos6-5vm log]# file spooler spooler: empty [root@centos6-5vm log]# file tallylog tallylog: empty [root@centos6-5vm log]# file wtmp wtmp: data
其中, ASCII,ASCII C++,UTF-8,等类型的文本文件,如 boot.log,cron,dmesg,messages,secure,等,可以用 cat,more,tail,head,等命令读取并打印内容;ISO-8859类型的 lastlog 文件需要专属命令 lastlog 才能读取,其它命令读取会输出乱码字符;
data类型的 wtmp 文件需要专属命令 last,或者 who 才能读取。可以在不同的shell中,分别执行2个命令,对输出结果相互参照:
[root@centos6-5vm 桌面]# last root@centos6-5vm 桌面]# who /var/log/wtmp
从上面可以看出,要让who命令读取 wtmp 文件,必须指定后者的绝对路径,否则:
直接执行who命令时,它会对 /var/run/utmp 文件进行统计当前登录的每个用户的状态,命令 users 有类似的功能,因此我们常对2个命令的输出结果进行交叉验证:应该得出相同的结果,否则就有可能是其中之一或两者都被入侵者篡改了:
[root@centos6-5vm 桌面]# users root root root [root@centos6-5vm 桌面]# who root tty7 2014-08-12 10:29 (:0) root pts/0 2014-08-12 10:29 (:0.0) root pts/1 2014-08-12 10:29 (:0.0)
补充知识: wtmp 与 utmp (引用 http://www.centoscn.com/CentosSecurity/CentosSafe/2014/0304/2490.html 的内容)
/var/log/wtmp
该日志文件永久记录每个用户登录、注销及系统的启动、停机的事件。因此随着系统正常运行时间的增加该文件的大小也会越来越大。增加的速度取决于系统用户登录的次数。该日志文件可以用来查看用户的登录记录。
last命令就通过访问这个文件获得这些信息并以反序从后向前显示用户的登录记录(即从最近的时间往前显示)
last也能根据用户、终端 tty或时间显示相应的记录。
/var/run/utmp
该日志文件记录有关当前登录的每个用户的信息。因此这个文件会随着用户登录和注销系统而不断变化。它只保留当时联机的用户记录,不会为用户保留永久的记录。
系统中需要查询当前用户状态的程序如 who、w、users、finger等就需要访问这个文件。该日志文件并不能包括所有精确的信息:因为某些突发错误会终止用户登录会话而系统没有及时更新 utmp记录,因此该日志文件的记录不是百分之百值得信赖的。
utmp以及wtmp文件都是二进制文件,不能通过tail,cat,vi/vim 进行编辑,或者重定向(包括 grep,| 等)
*****lastb 命令,读取并输出 /var/log/btmp 文件的内容,后者记录了未成功登录(登录失败)的用户的信息:
[root@centos6-5vm log]# lastb shayi tty7 :0 Tue Aug 12 08:56 - 08:56 (00:00) sync tty7 :0 Tue Aug 12 08:48 - 08:48 (00:00) sync tty7 :0 Tue Aug 12 08:48 - 08:48 (00:00) sync tty7 :0 Tue Aug 12 08:48 - 08:48 (00:00) shayi tty7 :0 Tue Aug 12 08:26 - 08:26 (00:00) root tty7 :0 Tue Aug 12 08:21 - 08:21 (00:00) root tty7 :0 Tue Aug 12 08:20 - 08:20 (00:00) shayi tty7 :0 Tue Aug 12 08:18 - 08:18 (00:00) shayi tty7 :0 Tue Aug 12 08:18 - 08:18 (00:00) btmp begins Mon Aug 11 10:21:28 2014
rsyslog配置
在centos6.5的最小桌面安装方案中,默认安装的不是syslog,而是rsyslog:
[root@centos6-5vm /]# rpm -qi rsyslog Name : rsyslog Relocations: (not relocatable) Version : 5.8.10 Vendor: CentOS Release : 8.el6 Build Date: 2013年11月22日 星期五 23时14分31秒 Install Date: 2014年06月25日 星期三 16时59分10秒 Build Host: c6b8.bsys.dev.centos.org Group : System Environment/Daemons Source RPM: rsyslog-5.8.10-8.el6.src.rpm Size : 2168638 License: (GPLv3+ and ASL 2.0) Signature : RSA/SHA1, 2013年11月25日 星期一 03时30分21秒, Key ID 0946fca2c105b9de Packager : CentOS BuildSystem <http://bugs.centos.org> URL : http://www.rsyslog.com/ Summary : Enhanced system logging and kernel message trapping daemons Description : Rsyslog is an enhanced, multi-threaded syslog daemon. It supports MySQL, syslog/TCP, RFC 3195, permitted sender lists, filtering on any message part, and fine grain output format control. It is compatible with stock sysklogd and can be used as a drop-in replacement. Rsyslog is simple to set up, with advanced features suitable for enterprise-class, encryption-protected syslog relay chains.
rsyslog是增强的多线程版syslog守护进程。它支持MYSQL数据库,syslog/TCP,RFC 3195标准,允许使用发送者列表,过滤部分信息,并且可控制输出格式的粒度(详细程度)。
它与旧的sysklogd兼容,并且以插入替换的方式来使用。Rsyslog易于建立,带有适用于企业级的高级特性,加密保护syslog的中继链。
查找rsyslog的配置文件存放路径:
[root@centos6-5vm /]# rpm -qc rsyslog /etc/logrotate.d/syslog /etc/rsyslog.conf /etc/sysconfig/rsyslog [root@centos6-5vm /]# vim /etc/rsyslog.conf
下面来解释配置文件中以#### RULES ####字段开始的记录规则:
# Log all kernel messages to the console. # Logging much else clutters up the screen. #kern.* /dev/console
kern 设备是内核产生信息,将它发送至 /dev/console。
这条规则默认是禁用的。但是后面我们会看到,iptables 防火墙属于内核模块之一,因此启用 iptables 后产生的任何信息也算是 kern 设备指代的内核信息,必须新添加一条规则将 iptables 的信息输出到一个独立的文件中,便于分析防火墙日志。注意,保持该条规则的注释状态,然后添加一条规则:
kern.warning /var/log/iptables.log
其中,warning是警告级别的信息,它会自动包含日志级别(优先级)比它低的其它几个级别的信息,syslog定义的所有信息的优先级别从低到高排列,依序为:
emerg(0),alert(1),crit(2),err(3),warning(4),notice(5),info(6),debug(7),none
下面引用 syslog 的 man 手册页相关内容来验证:
The conventional meaning of the loglevel is defined in <linux/kernel.h> as follows: #define KERN_EMERG "<0>" /* system is unusable */ #define KERN_ALERT "<1>" /* action must be taken immediately */ #define KERN_CRIT "<2>" /* critical conditions */ #define KERN_ERR "<3>" /* error conditions */ #define KERN_WARNING "<4>" /* warning conditions */ #define KERN_NOTICE "<5>" /* normal but significant condition */ #define KERN_INFO "<6>" /* informational */ #define KERN_DEBUG "<7>" /* debug-level messages */
上面系统预留的这些符号常量,与相应的 syslog 级别匹配,例如
KERN_NOTICE 就是 notice,日志级别(优先级)为 5;
KERN_WARNING 就是 warning,优先级为 4;
优先级越高,输出的信息量越多,该级别的日志文件占用的磁盘空间的增长速度也越快。 none例外,它表示不记录任何信息。
这样就避免了 iptables 的信息混杂在 /var/log/messages 中,影响网络访问流量的分析工作。
有一点要补充说明:上面我们只是告诉了 rsyslog,将 iptables 产生的日志,记录到 /var/log/iptables.log 文件中,但是我们还没有具体设置规则,告诉 iptables,那个或那些主机的入站或出站数据包流量,需要被记录到 rsyslog。
我们可以通过编写一条 iptables 防火墙规则策略,来实现上述目的,假设本机即运行 iptables 防火墙的内网 IP 为 192.168.1.20,要记录本机所有出站方向的流量(注意,这里“所有”表示任何网络层以及传输层协议,任何端口),并且允许放行:
[root@centos6-5 ~]# iptables -A OUTPUT -s 192.168.1.20/32 -j LOG [root@centos6-5 ~]# iptables -A OUTPUT -s 192.168.1.20/32 -j ACCEPT
注意编写的顺序:先记录,再允许放行,如果你仅仅编写了第一条,漏掉了第二条,由于 iptables 从上往下按顺序查找规则,一旦有一条匹配,就应用该规则,其后的规则全部被忽略;因此它只会“记录”,而不会“放行”(ACCEPT,接受)。
如果我们怀疑本地有恶意后门,木马程序,或 rootkit 尝试对外网不明主机发起网络连接,通信的时候,上面两条规则就可以发挥巨大作用:任何出站方向的任何程序产生的流量,其源地址,端口,目标地址,端口,均会被详细记录,我们只要分析 /var/log/iptables.log 文件中,那些我们陌生的目标地址以及端口,就可以验证是否有恶意程序,前提是你要记忆或维护或一张你经常访问,以及正常站点的域名到 IP 地址映射列表,任何不在该表中的 IP,出现在防火墙的日志里面,很有可能就是服务器被入侵植入后门的征兆。
当然,有些比较“流氓”一点的正常程序,或许也会向你不熟悉的外网 IP 发起连接,例如搜集用户数据来改善产品的用户体验程度等等,具体情况要具体分析,诀窍是用 WHOIS 数据库,以及一些基于 web 的 IP地址-域名-注册人-AS号码 查询工具来检验该 IP 的合法性,安全性等等。
还有一点要注意,必须确认 iptables 以及 rsyslog 这两个服务都启动,才能正常记录日志,这可以通过 service 命令来完成。
相反,如果你在分析日志时不想被实时动态产生的数据干扰,可以用 service 命令暂时关闭 rsyslog (不是关掉 iptables )来停止记录。
(延伸阅读:iptables,dmesg,klogd,/var/log/message 与 /var/log/kernlog)
linux 内核在引导的时候会探测系统硬件设备并且把结果输出到一个内部缓冲区,系统启动完成后,用户级别的命令 dmesg 可以读取并且输出这个缓冲区的内容;
klogd是“内核日志”守护进程,它负责把内核缓冲里关于检测到的硬件信息转储到一个日志文件,默认情况下,这个日志文件就是 /var/log/message,
为了达到日志文件各司其职,分类存放的目的,应该把这个信息保存在一个单独的日志文件中:
kern.*;kern.!=warning /var/log/kernlog
这样,内核产生的所有级别的信息,包括探测硬件的结果,都保存在 /var/log/kernlog 文件里,注意,由于我们前面已经指定内核产生的 warning 级别的信息(即 iptables 防火墙)保存在 /var/log/iptables.log 文件,因此这里需要把 warning 级别排除在外,否则 /var/log/kernlog 文件又会重复记录 warning 级别的信息,浪费了磁盘空间。
表达式 kern.*;kern.!=warning 的功能就是不记录 warning 级别的信息。
或者使用表达式 kern.debug;kern.!=warning 也可以达到相同效果,因为详细程度高的级别会包含详细程度比它低的所有级别。
继续来看 rsyslog.conf 中的内容:
# Log anything (except mail) of level info or higher. # Don't log private authentication messages! *.info;mail.none;authpriv.none;cron.none /var/log/messages
将所有设备(以通配符 * 指代)产生的 info 级别的信息,输出到 /var/log/messages 文件,不包含 mail设备(与电子邮件服务器有关的信息),
authpriv 设备(与私人账户认证相关的信息),以及 cron 设备(与 cron 和 at 等计划任务进程相关的信息)
# The authpriv file has restricted access. authpriv.* /var/log/secure
将 authpriv 设备产生的所有级别的信息,输出到 /var/log/secure 文件。
官方注释建议限制对记录 authpriv 设备输出信息的文件的访问,这就是为什么上面我们将 /var/log 目录的权限递归改为 600 的原因:禁止普通用户有意或无意变更其内容。
什么是 authpriv 设备?最直观的解释,就是记录远程用户访问本地的 FTP,TELNET,SSH 等服务器的验证状态与授权信息的设备。
一些 HTTP(web)服务器,例如 Apache,Nginx,Squid,以及 MYSQL 数据库程序,虽然实现了自己的日志记录机制(即它们的任何级别输出信息不交给 syslogd 来维护),但是它们用以存储信息的日志文件,默认还是在 /var/log 目录下的相应子目录中,例如,
apache 的日志文件,默认为 /var/log/httpd/access_log;
squid 的日志文件,默认为 /var/log/squid/access.log;
samba 的日志文件,默认为 /var/log/log.smbd
我们知道,用于记录本地用户登录的验证与授权状态的文件是 /var/log/wtmp, /var/run/utmp, /var/log/lastlog 等文件,那么,用于记录远程用户访问本地应用层网络服务的文件,默认情况下,syslog 将其定义为 /var/log/secure
# Log all the mail messages in one place. mail.* -/var/log/maillog
上面在定义所有设备的 info 级别信息时,禁止记录 mail 设备,那么在这里,就将 mail 设备的所有级别的输出信息,单独保存在 /var/log/maillog 文件中。在 mail 设备指代的程序中,最常见的为 sendmail 服务器。
注意:这里的日志文件绝对路径前面有个连接符号“-”
简单的讲,使用 - ,表示异步写该文件,
对于负载较高的 mail 服务器而言,服务器进程每执行一个需要记录在日志中的操作时,如果操作系统真的向磁盘执行写操作,那么磁盘的负荷会变得很大,而且影响整个服务器的性能(运行速度),因为 CPU 时间片全浪费在等待磁盘写操作上面了。
因此,使用连接符号“-”,来自 mail 服务器进程的写请求临时放在内核的缓冲区中,等待有空闲的时候再写入磁盘,这就是异步写。
对于那些不是由高并发,高负载服务器进程维护的日志文件,例如 message,secure 等等,不要添加连接符号“-”,这样每次记录信息时,都会执行系统调用 sync 来实际写入文件系统。
# Log cron stuff cron.* /var/log/cron
将 cron 设备产生的所有级别的输出信息,单独保存在 /var/log/cron 文件
cron 设备指代 crontab,crond等计划任务程序。由于 crond 执行任务失败会向用户发送邮件,所以也需要检查 /var/log/maillog 文件,尽可能多的获取任何有助于排除错误的信息。
上面的设置,都是将相关的信息记录到本地的日志文件中,为了避免被入侵者删除,可以设置为将输出信息发送到远程的一台专用于记录登录授权状态的日志服务器(下称 logserver)。注意这里“专用”,意味着 logserver 上面除了运行和开放用于接收日志信息的服务和端口外,不应该有其它服务和端口。这符合“最小权限原则”和“要做一件事就专注于它并且做好它”原则。
《使用 chkrootkit 检查内核级rootkit与后门》
chkrootkit源码的下载,编译,安装,执行很简单,这里不再详述,有兴趣的可以参考官网。使用下面命令运行chkrootkit来检查系统:
cd /usr/src/chkrootkit-0.50 ./chkrootkit | grep -v no
上面命令将过滤掉正常的chkrootkit输出,仅显示可疑的文件信息;也可以采用下面的“安静”模式:
./chkrootkit -q
另外 ,还可以使用nohup命令让chkrootkit在后台运行,nohup命令也适用于其它在shell或终端上运行时会向屏幕输出信息的命令,可以将其转移至后台运行,这样就不会阻塞当前的bash进程,并且返回一个用以查询在后台运行命令的pid,可以通过 ps命令找到。
下面演示 nohup 结合 chkrootkit以及ps命令的用法:
[root@centos6-5 chkrootkit-0.50]# nohup ./chkrootkit > /dev/null 2>&1 & [1] 15173 [root@centos6-5 chkrootkit-0.50]# ps -ef | grep "15173" root 15173 3634 1 22:08 pts/0 00:00:00 /bin/sh ./chkrootkit root 15743 15173 0 22:08 pts/0 00:00:00 /usr/bin/find /dev -type f -exec /bin/egrep -l ^[0-5] {} ; root 15840 3634 0 22:08 pts/0 00:00:00 grep 15173
上面将 chkrootkit 命令的标准输出(1)和错误输出(2),(即 “ 2> &1”)都重定向到 /dev/null 设备,即丢弃2种输出信息;
可以看到,pid 为15173的chkrootkit父进程创建一个pid为15743的子进程,即使用find命令查找/dev 路径下的文件。
假设系统上运行了 ntpd,rpcbind,rpc.statd等几个重要的服务进程,想要快速过滤出可疑的TCP连接,则可以使用下面命令的组合:
netstat -antupelo | grep "tcp" | grep -v "ntpd" | grep -v "rpcbind" | grep -v "rpc.statd"
通过 top命令搜索进程对应文件名和类型的实例:
[root@centos6-5 chkrootkit-0.50]# top top - 23:42:47 up 2:19, 3 users, load average: 0.16, 0.12, 0.09 Tasks: 219 total, 1 running, 218 sleeping, 0 stopped, 0 zombie Cpu(s): 1.6%us, 1.8%sy, 0.0%ni, 96.2%id, 0.3%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 15401760k total, 2109632k used, 13292128k free, 185016k buffers Swap: 8191992k total, 0k used, 8191992k free, 1173528k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 26577 root 20 0 827m 253m 30m S 10.3 1.7 5:17.18 plugin-container [root@centos6-5 chkrootkit-0.50]# ps -ef | grep "26577" root 26577 3701 14 23:06 ? 00:05:00 /usr/lib/firefox/plugin-container /usr/lib/flash-plugin/libflashplayer.so -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 3701 true plugin [root@centos6-5 chkrootkit-0.50]# find / -name "plugin-container" /usr/lib/firefox/plugin-container /usr/lib/xulrunner/plugin-container [root@centos6-5 chkrootkit-0.50]# file /usr/lib/firefox/plugin-container /usr/lib/firefox/plugin-container: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
上面例子中的 plugin-container 就是 FireFox 浏览器的插件容器(本质是32位的 ELF动态连接库文件),可用于提供像 shockwave flash 这样的插件运行环境。
查看 shockwave flash 自身的文件类型:
[root@centos6-5 桌面]# file /usr/lib/flash-plugin/libflashplayer.so /usr/lib/flash-plugin/libflashplayer.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped
由于播放网页视频通常需要借助该插件(支持HTML5 video 元素的浏览器例外),因此在top命令中看到插件容器的CPU使用时间片较高就是这个原因。
Linux服务器下检查木马后门的重点位置:
[root@centos6-5 ~]# cd /root [root@centos6-5 ~]# pwd /root [root@centos6-5 ~]# cat ./.bashrc # .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi
上面是 root 用户的bashrc文件的正常情况;恶意程序,木马以及后门可能会修改其内容,以及 /home/普通用户名/.bashrc 文件,在 .bashrc 文件中写入的命令会在相应用户登录进系统会话时自动执行。
[root@centos6-5 ~]# cat /etc/rc.local #!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff.
rc.local 文件中的命令将在所有类型的系统初始化脚本完成后执行,需要关注这里是否有可疑的命令随着开机而启动。
[root@centos6-5 ~]# crontab -l no crontab for root
注册计划任务也可以实现定时运行木马
[root@centos6-5 ~]# cat /etc/profile
profile 文件也是重点关注对象。对于正常内容太多的文件如 profile,可以采取在新系统上线还是干净的时候,将这些重要配置文件备份到外围存储设备,然后定时通过 diff 命令与本地磁盘上的原始文件进行比较,即可知道被更改的部分:
[root@centos6-5 ~]# diff /etc/profile /media/usb_disk/profile
在上面的命令中,diff 将本地硬盘的 profile 文件与U盘上的备份的正常文件进行比较,注意要使用U盘的挂载路径。
下面的方法演示了将当前系统上运行的进程列表输出到一个文件中,然后与存储在移动硬盘上的正常进程列表文件进行对比的操作:
[root@centos6-5 桌面]# ps -ef | awk '{print $NF}' > /tmp/currently_process_list [root@centos6-5 桌面]# diff /tmp/currently_process_list /media/My\ Book_/normal_process_list 217d216 < [flush-8:32]
上面示例中,当前系统多出一个flush-8:32的线程,属于正常状态。
使用 who -a 命令可以查看当前登录系统的所有本地和远程用户,系统引导时间,运行级别等信息:
[root@centos6-5 桌面]# who -a 系统引导 2015-09-07 06:04 运行级别 5 2015-09-07 06:04 登录 tty4 2015-09-07 06:04 2978 id=4 登录 tty3 2015-09-07 06:04 2976 id=3 登录 tty2 2015-09-07 06:04 2973 id=2 登录 tty6 2015-09-07 06:04 2982 id=6 登录 tty5 2015-09-07 06:04 2980 id=5 root + tty1 2015-09-07 06:04 旧的 3154 (:0) root + pts/0 2015-09-07 06:05 00:09 3649 (:0.0) root + pts/1 2015-09-07 06:36 . 3649 (:0.0)