盒子
盒子
文章目录
  1. 限制基于密码的登录来保护账户
    1. 限制root只能在系统控制台登录
    2. 限制su到root账户
    3. 配置sudo改善对root访问的审计
    4. 禁止非root系统账户登录和使用shell
    5. 确认密码被适当存储和哈希
      1. 确保没有账户有空密码
      2. 确保所有账户密码哈希都被shadow
    6. 确认没有非root用户的UID为0
    7. 设置密码过期参数
      1. 从libuser.conf移除密码参数
    8. 移除密码文件中遗留的+条目
  2. 通过Unix组来加强安全
    1. 为每个账户创建一个唯一默认组
    2. 创建和维护包含所有人类账户的组
  3. 通过配置PAM保护帐号
    1. 设定密码质量要求
      1. 如果使用pam_cracklib,设置密码质量需求
      2. 如果使用pam_passwdqc,设置密码质量需求
    2. 设置失败密码尝试锁定
    3. 使用pam_deny.so快速禁止访问服务
    4. 仅控制台用户执行userhelper
    5. 升级密码哈希算法到SHA-512
    6. 限制密码重用
    7. 尽可能移除pam_crreds包
  4. 对登录用户使用安全会话配置文件
    1. 确保Root PATH不存在危险目录
      1. 确保Root PATH不包含相对路径或者空目录
      2. 确保ROOT路径不包含全局可写或组可写的目录
    2. 确保用户家目录不是组可写或者全局可读的
    3. 确保用户dot文件不是全局可写
    4. 确保用户有合理的umask值
    5. 确保用户没有.netrc文件
  5. 保护物理控制台访问
    1. 设置BIOS密码
    2. 设置Boot Loader密码
    3. 要求单用户模式登录认证
    4. 禁用交互式启动
    5. 对登录shell实现不活动超时
    6. 配置锁屏

Account and Access Control

传统的Unix中,一旦攻击者获得对应帐号的shell,他就能执行该账户所能行使的任何行为,存取该账户能存取的任何文件。因此,让未授权的人获得指定帐号shell更加困难(特别是对权限账户),是系统安全重要的部分。本文介绍如何引入限制账户登录的机制。

限制基于密码的登录来保护账户

传统Unix账户通过提供用户名和密码登录,这些用户名和密码会和储存在/etc/passwd/etc/shadow中的内容对比。密码登录可能被被猜测,被嗅探,被中间人截取,无论是从网络还是不安全的控制台中。因此,限制账户密码登录的机制很重要。

限制root只能在系统控制台登录

编辑/etc/securetty,确保只有以下行:

  • 基本的系统控制台设备:

    console
    
  • 虚拟控制台设备

    tty1
    tty2
    tty3
    tty4
    ...
    
  • 如果需要,保留这些废弃的控制台接口来保留向后兼容。

    vc/1
    vc/2
    ...
    
  • 如果需要,添加串口控制台:

    ttyS0
    ttyS1
    

仅在紧急情况下才允许root直接登录。通常,管理员可以通过唯一的非权限用户使用su或者sudo来执行权限命令。不鼓励管理员直接使用root用户有助于对多管理员系统的审计工作。减少root能直接连接的通道减少了root密码被猜解的几率。

login程序使用/etc/securetty确定哪些接口允许root登录。虚拟设备/dev/console/dev/tty*代表系统控制台(通过Ctrl-Alt-F1等打开)。默认的securetty文件也包含/dev/vc/*,来保留历史兼容性。

root用户也应该禁止通过网络协议登录。本文暂不讨论。

限制su到root账户

确保组wheel存在,所有持有root权限的管理员用户名作为其中的组员。

grep ^wheel /etc/group

编辑文件/etc/pam.d/su,添加、注释或者更改该行:

auth    required    pam_wheel.so    use_uid

su命令允许用户从其它用户通过输入密码获得权限。因此限制已知管理员使用root是必要的。一般wheel用户组包含允许运行权限命令的全部用户。PAM模块pam_wheel.so被用来限制一组用户的接入。

配置sudo改善对root访问的审计

确保wheel存在,所有持有root权限的管理员用户名作为其中的组员。

grep ^wheel /etc/group

编辑/etc/sudoers,添加、取消注释或者更改如下行:

%wheel  ALL=(ALL)   ALL

sudo能很好的控制哪个用户能用其它账户执行命令。这为每个权限用户执行的命令提供了审计可能。也许恶意管理员会绕过这个限制,但这个机制保证审计更容易。

手工编辑/etc/sudoer很危险,配置错误也许会禁用远程root访问。推荐的方式是用visudo命令编辑这个文件,该命令会在保存前检查文件语法。

权衡sudo带来的审计好处和安全风险。永远不要使用NOPASSWD指令,这会允许任何获取管理员账户的人在不知管理员密码的情况下以root身份执行命令。

更多定制参见sudoers man页面

禁止非root系统账户登录和使用shell

!!!!!!!!注意:不要对root执行以下配置

使用一下命令查看/etc/passwd

awk -F: '{print $1 ":" $3 ":" $7}' /etc/passwd

找到那些UID低于500(系统账户),不是root的账户:

对每个系统账户SYSACCT,锁定:

usermod -L SYSACCT

禁用它们的shell:

usermod -s /sbin/nologin SYSACCT

确认密码被适当存储和哈希

确保没有账户有空密码

使用以下命令查看:

awk -F: '($2 == "") {print}' /etc/shadow

如果有输出,检查这些账户并设置密码。

确保所有账户密码哈希都被shadow

确保没有在/etc/passwd中保存密码哈希:

awk -F: '($2 != "x") {print}' /etc/passwd

这个命令应该没有输出,所有密码哈希应该保存在/etc/shadow而不是所有用户都能读的/etc/passwd

确认没有非root用户的UID为0

列出所有UID为0的用户:

awk -F: '($3 == "0") {print}' /etc/passwd

通常,最好的审计实践是所有root账户的使用都限制到使用su或这sudo。有些站点使用多个管理员拥有UID 0,这种做法可能有意料外的副作用,并不推荐。

设置密码过期参数

编辑/etc/login.defs指定某个新账户的密码过期时间。添加或修改如下行:

PASS_MAX_DAYS 60
PASS_MIN_DAYS 7
PASS_MIN_LEN 14
PASS_WARN_AGE 7

对已经存在的人类用户USER,更改当前过期设置如下:

chage -M 60 -m 7 -W 7 USER

更改密码要在稳定性和安全性之间权衡,90到360天比较推荐。

从libuser.conf移除密码参数

确保/etc/libuser.conf[import]节包含:

login_defs = /etc/login.defs

同时确保在[userdefaults]下没有以下单词开头的行,这些设定会覆盖/etc/log in.defs的设定:

LU_SHADOWMAX
LU_SHADOWMIN
LU_SHADOWWARNING

/etc/libuser.conf文件包含libuser库的配置选项,这个库提供了一套操作和管理用户和组帐号的标准接口。默认情况下从/etc/login.defs读取密码设置,但是/etc/libuser.conf能覆盖这些参数。查看libuser.conf的man页面获取更多信息。

移除密码文件中遗留的+条目

用一下命令找到这些行:

grep "^+:" /etc/passwd /etc/shadow /etc/group

确保没有输出。

+被用来将来自NIS的数据映射到已知文件。一个/etc/passwd中NIS包含错误,但NIS没有运行会导致任意用户以+用户名免密码访问。

告诉本地系统使用网络数据库,比如LDAP或NIS,来获取用户信息的正确的方式是确保在/etc/nsswitch.conf中适当的配置。

通过Unix组来加强安全

通过标准Unix权限的访问控制很弱,但也可以利用。

为每个账户创建一个唯一默认组

当使用useradd命令时,不要使用-g参数覆盖默认组。

RedHat默认为每个用户创建相同名称的唯一所属组。推荐这样,保护组写权限的文件。

创建和维护包含所有人类账户的组

找到系统上所有人类用户,比如UID大于500的,一旦确认,创建一个usergroup组,并且把每个人类账户加进去:

groupadd usergroup
usermod -G usergroup human1
usermod -G usergroup human2
usermod -G usergroup human3
usermod -G usergroup human4

当用useradd添加新用户时,用-G usergroup将人类账户添加到改组。

这样做便于管理人类用户,比如为/path/to/graphical/command授权用户:

chgrp usergroup /path/to/graphical/command
chmod 750 /path/to/graphical/command

同时,限制非人类系统账户执行命令也非常重要。

通过配置PAM保护帐号

PAM,可插拔认证模块是为linux程序提供认证的模块。PAM是一个框架,提供可配置的系统认证架构来最小化系统所面对的风险。

PAM被作为一套动态共享库实现,在任何应用程序想认证用户的时候被加载和调用。通常为了使用PAM应用程序需要以root运行,传统的权限网络监听比如sshd和SUID程序比如sudo已经满足了这个要求。一个叫做userhelper的SUID root应用被用来为没有SUID或权限的程序提供利用PAM的可能。

PAM在/etc/pam.d/下搜寻应用特异的配置信息。比如对login程序,PAM库会遵循/etc/pam.d/login中的指示。

一个非常重要的文件是/etc/pam.d/system-auth。这个文件被许多其它文件包含(奇怪的是从RHEL6开始sshd只包含/etc/pam.d/password-auth),作为默认的系统认证措施,更改这个文件能确保全面的更改。

更改PAM的配置要十分小心,语法很复杂,更改可能有意料外的结果。默认配置对大多数用户足够了。

注意!!!!!!!!!!:运行authconfig或者system-config-authentication将覆盖PAM配置文件,摧毁任何手动的更改,将其覆盖成系统默认。

设定密码质量要求

默认的PAM模块pam_cracklib提供了加强的密码检查。它可以执行一系列检查包含字典单词的相似,最小长度,不是之前的密码,不是之前密码的简单大小写修改等。也能要求密码包含特定类型的字符。

pam_passwdqc模块提供了更严格的密码强度强制要求。可通过RPM包下载。

如果使用pam_cracklib,设置密码质量需求

pam_cracklib配置密码至少包含一个大写、小写、数字和其它字符,定位/etc/pam.d/system-auth中的一下行:

password requisite pam_cracklib.so retry=3

更改为(呵呵,required意指即使失败仍然会继续后面required的模块验证,然后在返回错误,让用户不知道哪里出的问题)

password required pam_cracklib.so retry=3 minlen=14 \
                    dcredit=-1, ucredit=-1 ocredit=-1 lcredit=-1

如果必要,更改为符合你要求的配置。

如果使用pam_passwdqc,设置密码质量需求

如果需要比pam_cracklib保证的密码强度更强,使用pam_passwdqc模块。

更改/etc/pam.d/system-auth中的如下行:

password requisite pam_cracklib.so retry=3

为(呵呵,这个直接requisite,只要不符合要求PAM就直接返回错误了)
password requisite pam_passwdqc.so min=disabled,disabled,16,12,8

按自己需要配置。

设置失败密码尝试锁定

使用pam_tally2.so模块来实现一定数量错误登录尝试后锁定账户。在/etc/pam.d/system-auth中添加到第一个auth开头的行上头(呵呵,RHEL6后/etc/pam.d/sshd包含的是/etc/pam.d/password-auth而不是/etc/pam.d/system-auth,所以,对ssh登录尝试锁定应该是对password-auth这个文件更改。)

auth required pam_tally2.so deny=5 onerr=fail unlock_time=900

在account开头的行上头加上一行:

account required pam_tally2.so

root要单独设置root_unlock_time=900

要解锁用户使用pam_tally2命令

/sbin/pam_tally2 --user username --reset

锁定用户造成潜在的DOS攻击,但能阻止密码猜解。权衡利弊设置unlock_time

使用pam_deny.so快速禁止访问服务

通过PAM阻止服务SVCNAME的访问,编辑/etc/pam.d/SVCNAME文件,添加这一行:

auth    requisite   pam_deny.so

这不是啥值得推荐的方法,不过挺方便,呵呵。

仅控制台用户执行userhelper

如果你的环境定义了一个组usergroup包含所有系统上的人类用户,限制userhelper程序只能由这些用户执行。(4710中的4表示suid/guid)

chgrp usergroup /usr/sbin/userhelper
chmod 4710 /usr/sbin/userhelper

userhelper程序提供必须以root运行的图形服务认证,比如system-config-族图形配置程序。只有登录到系统控制台的人类用户可以运行这些。以上提供了一定对userhelper实现缺陷的保护,防止被侵入的系统账户进一步提权。

userhelper程序在/etc/securetty/console.app/下的文件配置。每个文件指定了程序以什么身份运行,成功认证后应该执行什么。

注意:这些配置和PAM的配置/etc/pam.d下的配置相配合才能起作用。首先userhelper决定服务应该以什么身份运行(比如root),然后userhelper使用PAM API来允许运行程序的用户尝试认证为想要借身份运行的用户。PAM的API交互被封装在GUI中,如果程序配置要求的话。

升级密码哈希算法到SHA-512

需要编辑3个文件:

首先/etc/pam.d/system-auth中确保sha512被pam_unix.so模块在password节使用。而不是使用其它算法:(可能得改password-auth)

password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok

其次,编辑文件/etc/login.defs添加或更改以下行(确认下就好):

ENCRYPT_METHOD SHA512

最后,编辑/etc/libuser.conf添加或更改以下行:

crypt_style=sha512

其实吧,这是RHEL6的默认配置,呵呵。

限制密码重用

pam_unix模块使用remember参数可以防止用户重用最近的密码。为了阻止用户使用最近5次的密码,向/etc/pam.d/system-auth文件中,使用pam_unix模块的password行添加remember=5参数。

旧的密码(禁止重用的)保存在/etc/security/opasswd中。

尽可能移除pam_crreds包

除非用到认证缓存功能,移除pam_ccreds包:

yum erase pam_ccreds

该包包含setuid文件/usr/sbin/ccreds_validate。如果系统被入侵,任何系统上缓存的认证信息都会被获取。

对登录用户使用安全会话配置文件

当一个用户登录进Unix账户时,系统通过读取大量文件配置用户会话。许多这些文件在家目录下。错误或者不当的配置都会造成弱权限。攻击者可以修改甚至读取特定类型的账户信息,对受影响的账户获得全面的访问权限。因此,额是和修正账户特别是权限账户的配置文件权限非常重要。

确保Root PATH不存在危险目录

登录一个root shell运行:

echo $PATH

将给出冒号分隔的文件夹路径。

防止root执行未知或者不受信任的程序很重要,这些程序可能带有恶意代码。因此,root不应该运行非权限用户安装的程序。root经常工作在不受信任的目录,比如.代表的当前目录总不该出现在root的PATH中,任何非权限用户或系统用户能写入的目录都是如此。

对系统管理员来说,总是打出命令的绝对路径是个好习惯。

确保Root PATH不包含相对路径或者空目录

对每个路径中的目录DIR,确保DIR不是一个单一的.,或者任何可能导致相对路径遍历的符号比如..,或者不是以/开头。同时,确保路径中没有空元素,如下:

PATH=:/bin
PATH=/bin:
PATH=/bin::/sbin

这些空元素和一个.有相同效果。

我觉得这样比较方便:

echo $PATH | awk -F: '{for(i=1;i<NF;i++) print $i}'

确保ROOT路径不包含全局可写或组可写的目录

对PATH中的每一个元素,执行:

ls -ld DIR

确保组和其它的写权限被禁用。

我觉得这样比较好:

ls -ld `echo $PATH | awk -F: '{for(i=1;i<NF;i++) print $i}'`

确保用户家目录不是组可写或者全局可读的

首先通知你的用户。

对每个人类账户USER,查看账户权限:

ls -ld /home/USER

确保目录不是组可写和全局可读的,必要时修正:

chmod g-w /home/USER
chmod o-rwx /home/USER

家目录包含许多影响账户行为的配置,其它用户不该有权限写入。组共享目录应该在子目录或者其它什么地方而不是家目录。通常,家目录也不该全局可读。如果有一小撮用户非得读取其它用户目录,通过组来提供权限。

确保用户dot文件不是全局可写

确保用户USER家目录下的dot文件不是全局可写:

ls -ld /home/USER /.[A-Za-z0-9]*

确保任何文件都不是组或全局可写的。通过以下方式修正某个FILE

chmod go-w /home/USER/FILE

能更改其它用户配置文件的用户可能以那个用户权限执行命令,窃取数据,摧毁文件或者发起进一步攻击。

确保用户有合理的umask值

编辑全局配置/etc/profile,/etc/bashrc/etc/csh.cshrc.添加或修改以下行:

umask 077

其实profile里看是不是uid大于200且有效组名等于用户名,则设为002(目录775,文件644).否则设为022(目录755,文件644).

编辑/etc/login.defs:

UMASK   077

查看/etc/csh.login/etc/profile.d/*中的其它文件,确保没有重定义umask。除非有什么好的理由重定义umask。

grep -r umask /etc/profile /etc/csh.* /etc/bashrc /etc/login.defs

编辑root shell的配置文件/root/.bashrc/root/.bash_profile,/root/.cshrc/root/.tcshrc。添加或修改以下行:

umask 077

这样做确保任何用户创建的文件不会被其它用户读写与执行。如果有特殊需要,则使用chmod命令修改它。单个用户可以通过将umask设为027让其所在组用户能读和执行其文件。用户名和默认组一致,完全可以直接设成007来与组成员共享文件。

另外,暂时更改root 的umask来安装能让其它用户读取的软件或文件,或者修改特定服务帐号的umask默认设定的行为,都是必要的。但严格的默认限制能更好的保护意外泄漏。

确保用户没有.netrc文件

对每个人类用户USER,确保没有用户有.netrc文件。

find /home -name .netrc

应该没有返回。如果有联系用户讨论删除事宜。

.netrc是用来通过ftp无人登录到其它系统的配置文件。这个文件通常包含攻击其它系统未加密的密码。

保护物理控制台访问

不大可能保护系统免于物理接触攻击。有些步骤能让攻击者更加难以快速和不被发现地从控制台更改系统。

设置BIOS密码

x86系统的BIOS是机器首先运行代码的地方,控制着许多非常重要的系统参数,包含系统从哪个设备以什么顺序启动的信息。

为BIOS配置设置密码防止修改。尽管物理接触的攻击者通常很容易清除密码。

设置Boot Loader密码

Boot Loader通常负责启动内核并把参数传递给它。boot loader允许选择多个分区或者介质上的不同内核,能传递给内核的参数包括单用户模式(提供无需认证的root访问),禁用SELinux。阻止本地用户更改启动参数。为防止本地用户更改启动参数危害安全,启动器配置需要用密码保护:

Grub这样保护:

运行grub-md5-crypt得到md5后的哈希password-hash

/etc/grub.conf注释头下第一行添加:

password --md5 password-hash

确保/etc/grub.conf的权限。(指向../boot/grub/grub.conf)

chown root:root /etc/grub.conf
chmod 600 /etc/grub.conf

其它boot loader有类似的密码保护特性。

要求单用户模式登录认证

单用户模式被设计用来回复系统,通过启动选项给单用户root权限。默认情况下不需要认证,这造成了安全隐患。

即使以单用户模式启动,也要求输入root密码。在/etc/sysconfig/init文件中更改:

sed -i 's/SINGLE=\/sbin\/sushell/SINGLE=\/sbin\/sulogin/' /etc/sysconfig/init

禁用交互式启动

编辑/etc/sysconfig/init。添加或更改设置:

sed -i 's/^PROMPT.*/PROMPT=no/g' /etc/sysconfig/init

交互式启动,用户也许能禁用审计、防火墙和其它服务弱化系统安全。

对登录shell实现不活动超时

如果系统不运行X windows,登录shell可以配置为一段时间不活动自动登出用户。以下指令对运行X Windows的系统不合适,因为这将自动(深有体会!!)关闭X环境下的终端。

针对/bin/bash,实现一个15分钟的空闲超时,在目录/etc/profile.d/下新建文件tmout.sh,写入如下行:

TMOUT=900
readonly TMOUT
export TMOUT

tcsh,在/etc/profile.d/下新建autologout.sh,添加如下行:

set -r autologout 15

其它登录shell应该类似。

仅仅在shell是前台进程时才会自动登录超时。比如,一个vi会话空闲着并不会自动超时登出。

当通过远程连接时,比如SSH,通过该服务设置超时更加有效。

配置锁屏

一个是图形界面的锁屏(比如kde的Lock Screen),一个是控制台(vlock)。