AIDE、sudo、TCP_Wrappers、PAM
1. AIDE入侵检测
当一个入侵者进入了你的系统并且种植了木马,通常会想办法来隐蔽这个木马(除了木马自身的一些隐蔽特性外,他会尽量给你检查系统的过程设置障碍),通常入侵者会修改一些文件,比如管理员通常用ps -aux来查看系统进程,那么入侵者很可能用自己经过修改的ps程序来替换掉你系统上的ps程序,以使用ps命令查不到正在运行的木马程序。如果入侵者发现管理员正在运行crontab作业,也有可能替换掉crontab程序等等。所以由此可以看出对于系统文件或是关键文件的检查是很必要的。目前就系统完整性检查的工具用的比较多的有两款:Tripwire和AIDE,前者是一款商业软件,后者是一款免费的但功能也很强大的工具
1.1 AIDE概述
AIDE(Advanced Intrusion Detection Environment)
- 高级入侵检测环境,是一个入侵检测工具,主要用途是检查文件的完整性,审计计算机上的那些文件被更改过了。
- AIDE能够构造一个指定文件的数据库,它使用aide.conf作为其配置文件。AIDE数据库能够保存文件的各种属性,包括:权限(permission)、索引节点序号(inode number)、所属用户(user)、所属用户组(group)、文件大小、最后修改时间(mtime)、创建时间(ctime)、最后访问时间(atime)、增加的大小以及连接数。AIDE还能够使用下列算法:sha1、md5、rmd160、tiger,以密文形式建立每个文件的校验码或散列号.
- 这个数据库不应该保存那些经常变动的文件信息,例如:日志文件、邮件、/proc文件系统、用户起始目录以及临时目录.
1.2 AIDE
- 安装
yum install aide - 数据库,保存文件的状态和属性,为以后比较提供依据
var/lib/aide - 配置文件
/etc/aide.conf - 修改配置文件
1. [root@hai7-7 ~]$vim /etc/aide.conf
# The location of the database to be read. 要读取的数据库位置
database=file:@@{DBDIR}/aide.db.gz
# The location of the database to be written. 要写入的数据库位置
database_out=file:@@{DBDIR}/aide.db.new.gz
`也就是说生成的数据文件时aide.db.new.gz,如果想要数据库读取文件取监控变化,就需要将生成的数据文件改名为aide.db.gz`
!/etc/mtab
`表示忽略这个文件的检查`
R=p+i+n+u+g+s+m+c+md5
`R=权限+索引节点+链接数+用户+组+大小+最后一次修改时间+创建时间+md5校验值
定义需要监控的属性`
示例1:在/data下创建3个文件分别为f1、f2、f3,只想监控f1、f2的md5、大小、所属者、权限、修改时间
`先定义监控属性`
TEST=s+md5+u+p+m
`在目录执行监控内容`
/data TEST
`排除f3文件`
!/data/f3
- 初始化默认的AIDE的库
根据你定义的规则将要监控的属性存到数据库里,承上例
`初始化数据库`
[root@hai7-7~]$/usr/local/bin/aide --init
`查看数据库目录`
[root@hai7-7~]$ls /var/lib/aide
aide.db.new.gz <==生成文件
生成检查数据库(建议初始数据库存放到安全的地方),并另存为读取格式后缀
`进入数据库目录`
[root@hai7-7~]$cd /var/lib/aide
`将上例生成的文件另存为.db.gz后缀`
[root@hai7-7~]$mv aide.db.new.gz aide.db.gz
- 检测
比对文件现在状态与数据库状态差别
/usr/local/bin/aide --check
更新数据库:如果想保存更改后的状态,需要更新数据库
aide --update
2. sudo(superuser do)
2.1 概述
-
来源与帮助
来自sudo包,man 5 sudoers -
功能
- sudo能够授权指定用户在指定主机上运行某些命令。如果未授权用户尝试使用 sudo,会提示联系管理员
- sudo可以提供日志,记录每个用户使用sudo操作
- sudo为系统管理员提供配置文件,允许系统管理员集中地管理用户的使用权限和使用的主机
- sudo使用时间戳文件来完成类似“检票”的系统,默认存活期为5分钟的“入场券”
-
主要文件
- 授权配置文件
- 主配置文件/etc/sudoers,其中比较特殊的两项
- root ALL=(ALL) ALL
配置文件中存在此项,意思是root永久为管理员 - %wheel ALL=(ALL) ALL
%代表组,wheel组的成员可以在所有客户端执行所有操作
- root ALL=(ALL) ALL
- 授权子配置文件/etc/sudoers.d/
允许用户按需求建立子配置文件,放在此目录下
- 主配置文件/etc/sudoers,其中比较特殊的两项
- 时间戳文件:/var/db/sudo
授权用户使用sudo时,需要验证身份,输入自己的登录密码通过验证。登录用户如果长时间不操作(默认等待5分钟),系统就会从新验证身份。此文件就是相关的时间记录 - 日志文件:/var/log/secure
- 授权配置文件
-
配置文件支持使用通配符glob:
符号 | 含义 |
---|---|
? | 任意单一字符 |
: | 匹配任意长度字符 |
[wxc] | 匹配其中一个字符 |
[!wxc] | 除了这三个字符的其它字符 |
\x | 转义 |
[[alpha]] | 字母 |
- 通过visudo命令编辑配置文件,具有语法检查功能
示例1:visudo –c 检查语法,故意将配置文件修改错,执行命令
[root@hai7-7 ~]$visudo -c
>>> /etc/sudoers: syntax error near line 80 <<<
parse error in /etc/sudoers near line 80
提示第80行解析误差
示例2:使用visudo编辑配置文件功能,如果修改存在错误,保存时会出现报错提示
[root@hai7-7 ~]$visudo
>>> /etc/sudoers: syntax error near line 67 <<<
What now?
Options are:
(e)dit sudoers file again <=='e再次修改'
e(x)it without saving changes to sudoers file <=='x取消修改'
(Q)uit and save changes to sudoers file (DANGER!) <=='Q保存修改'
What now?
缺点是没有颜色,可以通过定义EDITOR来增加颜色
[root@hai7-7 ~]$echo 'export EDITOR=vim' > /etc/profile.d/vim.sh
示例3:编辑子配置文件,格式如下,需要加-f选项,然后指定配置文件
[root@hai7-7 ~]$visudo -f /etc/sudoers.d/test
2.2 配置文件规则有两类
- 别名定义:不是必须的
- 授权规则:必须的
2.2.1 授权规则
-
授权规则格式:
user hosr=(runas) command- 格式说明:
- user: 运行命令者的身份
- host: 通过哪些主机
- (runas):以哪个用户的身份
- command: 运行哪些命令
- 示例:
示例1:常规格式示例
'1. 授权给用户v9,在所有主机,代表root,执行挂载光盘到mnt下的命令'
v9 ALL=(root) /bin/mount/ /dev/sr0/mnt
'2. 授权用户v9所有权限,而且不需要验证密码'
v9 ALL=(root) NOPASSWD: ALL
示例2:承上例,授权moli用户,代表v9,执行所有命令
'1. 授权'
moli ALL=(v9) ALL
'2. 以传统格式执行如下命令'
[moli@hai7-7 ~]$sudo -u v9 /bin/cat /etc/shadow <==没有权限
[sudo] password for moli: <== 输入的数moli自己密码
'3. 间接执行'
[moli@hai7-7 ~]$sudo -u v9 sudo cat /etc/shadow <==可以执行
[sudo] password for v9: <== 输入v9的密码
'说明,可以被授权的权限,必须为直接执行权限,被授予的权限是不能被继承的'
示例3:省略(runas),与代表root效果相同,root为默认值
'授权格式如下'
v9 ALL= /bin/mount/ /dev/sr0/mnt
示例4:授权的严格性
'授权格式如下'
v9 ALL=(root) /bin/mount/ /dev/sr0/mnt
'以v9用户来执行,会报错,因为此授权很严格,授权命令不可增减内容,如下例mnt多出来的/'
[v9@hai7-7 ~]$sudo -u root /bin/mount/ /dev/sr0/mnt/
'正确输入,-u 为指定代表的用户,默认为root可以不加此项。'
[v9@hai7-7 ~]$sudo -u root /bin/mount/ /dev/sr0/mnt
'想要授权多个命令权限用[,]隔开,如下所示/bin/umount,可以取消挂载所有设备'
v9 ALL=(root) /bin/mount/ /dev/sr0/mnt,/bin/umount
2.2.2 别名
- Users和runas:
字符 | 含义 | 示例 |
---|---|---|
username | 用户全名 | moli |
#uid | 用户的uid,前面加#号 | #1000 |
%group_name | 组名,前面要加%号 | %wheel |
%#gid | 支持gid,前面加#号 | %#1000 |
User_Alias, Runas_Alias | 自定义别名 | NETADMIN= v9,moli |
- host
字符 | 含义 | 示例 |
---|---|---|
ip或hostname | ip地址或主机名 | 172.20.192.20=root |
network(/netmask) | ip/子网掩码 | 172.20.192.20/16 |
Host_Alias | 自定义别名 | SERS=172.16.0.0/24 |
- command:
字符 | 含义 | 示例 |
---|---|---|
command name | 命令名 | /usr/bin/ls |
directory | 支持目录,目录下的所有程序都可以执行 | /usr/bin/ |
sudoedit | 授权用户,可以更改配置文件 | |
Cmnd_Alias | 自定义别名 | SYDCMD=/bin/chown,/bin/chmod |
示例:为v9用户授权更改配置文件
`授权sudoedit格式`
v9 ALL= sudoedit
`编辑配置文件,执行的命令为sudoedit`
[v9@hai7-7 ~]$sudoedit /etc/sudoers
2.2.3 别名类型和示例
-
别名有四种类型
- User_Alias
- Runas_Alias
- Host_Alias
- Cmnd_Alias
-
别名格式
开头必须为大写字母,后续为大写字母或数字加下划线组合
[A-Z]([A-Z][0-9]_)* -
别名定义:
Alias_Type NAME1 = item1, item2, item3 : NAME2 = item4, item5
先定义别名类型,如User_Alias。后续将别名的内容一个一个加入一逗号隔开
可以一次定义多个别名,中间冒号隔开 -
示例
示例1:定义的别名可以包含n个内容,以逗号分隔
'定义运行命令用户别名为NETADMIN'
User_Alias NETADMIN= v9,moli
'定义授权操作别名为NETCMD'
Cmnd_Alias NETCMD = /usr/sbin/ip,/usr/sbin/ifconfig
'授权配置如下,允许用户v9,moli在所有主机上以root省份执行ip,ifconfig命令'
NETADMIN ALL=(root) NETCMD
示例2:同类型别名可以叠加使用,中间以逗号分隔
'定义运行命令用户别名为SYSADER,包含wang,mage,%admins被授权者'
User_Alias SYSADER=wang,mage,%admins
'定义运行命令用户tom别名为DISKADER'
User_Alias DISKADER=tom
'定义主机别名为SERS,内容如下'
Host_Alias SERS=www.magedu.com,172.16.0.0/24
'定义匹配用户别名为OP'
Runas_Alias OP=root
'定义2个授权操作别名,分别为SYDCMD和DSKCMD'
Cmnd_Alias SYDCMD=/bin/chown,/bin/chmod
Cmnd_Alias DSKCMD=/sbin/parted,/sbin/fdisk
'授权配置如下:
用户SYSADER匹配root身份,在SERS主机上,授权操作 SYDCMD,DSKCMD'
SYSADER SERS= SYDCMD,DSKCMD
'用户DISKADER,在所有主机上匹配OP,授权DSKCMD'
DISKADER ALL=(OP) DSKCMD
示例3:一次定义同一类型多个别名,中间以冒号分隔
User_Alias SYSADER=wang,mage,%admins : DISKADER=tom
示例4:支持通配符写法
'定义运行着别名'
User_Alias ADMINUSER = adminuser1,adminuser2
'定义授权操作别名,其中 /usr/bin/passwd [a-zA-Z]*表示,可更改密码用户,!/usr/bin/passwd root表示root除外'
Cmnd_Alias ADMINCMD = /usr/sbin/useradd,/usr/sbin/usermod, /usr/bin/passwd [a-zA-Z]*, !/usr/bin/passwd root
'配置授权,执行ADMINCMD不需要密码,但执行userdel需要密码'
ADMINUSER ALL=(root) NOPASSWD:ADMINCMD,PASSWD:/usr/sbin/userdel
示例5:默认用户配置
'默认用户配置格式,表示默认运行用户wang,匹配的用户为tom'
Defaults:wang runas_default=tom
'设置默认配置后,如下配置表示匹配用户tom'
wang ALL= ALL
示例6:授权wang用户在所有主机代表所有人,执行cat ,查看messages*文件
这样授予权限存在巨大隐患,因为*统配符表示所有字符包括空格及特殊字符
wang ALL=(ALL) /bin/cat /var/log/messages*
'授权的cat命令是不能查看其它文件的,如下所示'
[root@hai7-7 ~]$sudo cat /etc/shadow
Sorry, user wang is not allowed to execute ' /bin/cat /etc/shadow' as root on centos7_27
'但是可以按如下格式查看'
[root@hai7-7 ~]$sudu cat /var/log/messages* /etc/shadow
避免这种授权漏洞,排除掉带空格的文件
wang ALL=(ALL) /bin/cat /var/log/messages* ,!/bin/cat /var/log/messages* *
2.3 sudo命令
- 格式
sudo [-u user] COMMAND - 常用选项
-V:显示版本信息等配置信息
-u user:默认为root,例如-u v9
-l,ll:列出用户在主机上可用的和被禁止的命令
-v:再延长密码有效期限5分钟,更新时间戳,也就是下次验证时间
-k:清除时间戳(1970-01-01),下次需要重新输密码
-K:与-k类似,还要删除时间戳文件
-b:在后台执行指令,例如执行sleep时
-p:改变询问密码的提示符号,系统默认格式为[sudo] password for %p : - 示例
示例1:修改询问密码的提示符号,%p代表用户名,%h代表主机名
[v9@hai7-7 ~]$sudo -p ”password on %h for user %p:” sleep 100
示例2:也可以切换,需要授权才可以,不如直接su
[v9@hai7-7 ~]$sudo –i –u wang
3. TCP_Wrappers介绍
解决TCP协议的安全控制,例如ssh服务,想要控制那些主机可以访问,那些不可访问,就可以通过 TCP_Wrappers实现,前提条件时此服务支持调用TCP_Wrappers的库libwrap
3.1 概述
- 作用
对有状态连接的特定服务进行安全检测并实现访问控制 - 判断服务程序是否能够由tcp_wrapper进行访问控制的方法,示例如下
ldd /PATH/TO/PROGRAM|grep libwrap.so
'查看服务路径'
[v9@hai7-7 ~]$which sshd
/sbin/sshd
'列出动态库依赖关系,查看是否支持'
[v9@hai7-7 ~]$ldd /sbin/sshd|grep libwrap.so
libwrap.so.0 => /lib64/libwrap.so.0 (0x00007fde219a3000)
- 配置文件,修改后立即生效
- 允许访问规则/etc/hosts.allow
- 拒绝访问规则/etc/hosts.deny
- 帮助参考
man 5 hosts_access,man 5 hosts_options - 检查顺序:
hosts.allow ==> hosts.deny(默认允许)
注意:一旦前面规则匹配,直接生效,将不再继续
3.2 TCP_Wrappers使用
-
基本语法:
daemon_list@host: client_list [ :options :option… ]- daemond_list
-
单个应用程序的二进制文件名,而非服务名,例如in.telnetd
telnet服务,需要取得进程名。管理telnet服务daemond_list为in.telnetd [root@hai7 ~]# ps aux|grep telnet roo 65772 0.4 0.0 12836 872 ? Ss 13:46 0:00 /usr/sbin/in.telnetd
-
以逗号或空格分隔多个应用程序,如:sshd,vsftpd
-
- @hostIP
指定需要监测服务在那个ip地址上运行,不加为监测所有本地主机ip
例如:sshd@192.168.0.254 ALL - client_list
允许或拒绝的客户端列表 - option
1.deny 2.allow 3.spawn 4.twist 5.except
- daemond_list
-
客户端Client_list格式
- 以逗号或空格分隔的客户端列表
- 基于IP地址:192.168.10.1 或172.168.0省略写法
- 基于主机名:www.magedu.com .magedu.com 较少用
- 基于网络/掩码:192.168.0.0/255.255.255.0
- 基于net/prefixlen: 192.168.1.0/24(CentOS6不支持)
- 基于网络组(NIS 域):@mynetwork
- 内置ACL:
- ALL
所有用户 - LOCAL
不带域后缀的主机名,也就是不带[ . ]的主机名,例如centos6.localhost就不符合要求 - KNOWN
可以解析的主机名,也可以反向解析成ip的主机名 - UNKNOWN
主机名不能解析为ip地址的主机名 - PARANOID
主机名可以解析为ip,但ip反向解析不是原主机名,正向反向解析不对应
- ALL
-
[:options]选项:
- deny 主要用在/etc/hosts.allow定义“拒绝”规则
如:拒绝匹配到的所有网段vsftpd: 172.16. :deny
- allow 主要用在/etc/hosts.deny定义“允许”规则
如:此文件中加此项vsftpd:172.16. :allow
与不定义效果相同,没意义 - spawn
启动一个外部程序完成执行的操作,并没有对允许或拒绝列表有影响,只是激活一个命令 - twist
实际动作是拒绝访问,使用指定的操作替换当前服务,标准I/O和ERROR发送到客户端,默认至/dev/null - except
会匹配第一个列表中所有项,除非匹配第二个列表。
- deny 主要用在/etc/hosts.allow定义“拒绝”规则
示例1:在A主机上设置sshd允许所有用户访问,加上spawn选项,后面跟echo命令,并导入文件/data/sshd.log
sshd: ALL :spawn echo on "$(date +%%F) login attempt from %c to %s,%d" >>/data/sshd.log
#使用另一台主机通过ssh连接A,不管连接成功与否,都会激活echo命令,在/data/下生成文件
%c 客户端信息
%s 服务器端信息
%d 服务名
%p 守护进程的PID
%% 表示%
[root@hai7-7 ~]$ssh 172.20.50.201
示例2:在A的允许列表配置in.telnetd允许所有用户访问,加twist选项,跟echo命令
in.telnetd: ALL : twist echo "forbidden telnet login "
'使用另外一个客服端取连接A'
[root@hai7 .ssh]$telnet 172.20.129.251
Trying 172.20.129.251...
Connected to 172.20.129.251.
Escape character is '^]'.
forbidden telnet login <==拒绝访问,但是替换执行了echo命令
Connection closed by foreign host.
示例3:管理telnet服务,允许访问网段为172.20.0.0/16,排除其中的172.20.112.0/24网段,允许172.20.112.224访问
'此时使用172.20.112.100访问,仍然可以访问,因为不在允许范围,会去看禁止列表,禁止列表没有设置,所以可以访问'
in.telnetd: 172.20. EXCEPT 172.20.112. EXCEPT 172.20.112.224
'在禁止列表添加如下行,表示除允许范围外,都禁止'
in.telnetd:ALL
示例4:承上,也可以一次控制多个服务,以逗号隔开
'/etc/hosts.allow'
sshd,in.telnetd: 172.20. EXCEPT 172.20.112. EXCEPT 172.20.112.224
'/etc/host.deny'
sshd,in.telnetd: ALL
3.3 测试工具
- 格式
tcpdmatch [-d] daemon[@host] client - 选项
-d:测试当前目录下的hosts.allow和hosts.deny - 示例
'配置规则'
in.telnetd: ALL :spawn echo on "`date +%%F` telnet login from %c to %s,%d" >> /data/telnet.log
'测试'
[root@hai6 /data]$tcpdmatch -d in.telnetd 172.20.50.201
client: address 172.20.50.201
server: process in.telnetd
access: delegated <==测试结果为委托,激活命令
4. PAM 可插拔认证模块
PAM(Pluggable Authentication Modules )是由Sun提出的一种认证机制,可以理解为是一个平台
- 面向应用程序开发者
使用PAM API实现安全认证方法的调用,在开发应用程序时,涉及到安全方面相关的功能,只需要调用安全模块就可以了,不需要重复开发 - 面向安全模块开发者
利用PAM SPI来编写认证模块,将不同的认证机制加入到系统中 - 将两者关联
PAM核心库(libpam)读取配置文件,将服务程序和相应的认证方法联系起来,提供了对所有服务进行认证的中央机制,适用于login,远程登录(telnet,rlogin,fsh,ftp,点对点协议(PPP)),su等应用程序中 - 系统管理员
根据需要给不同的服务配置不同的认证方式而无需更改服务程序 - pam文档说明
- /user/share/doc/pam-*
- rpm -qd pam
- man –k pam_
- man 模块名 如man rootok
- 《The Linux-PAM System Administrators’ Guide》
PAM架构
4.1 PAM认证机制
- PAM相关文件
- 模块文件目录:/lib64/security/*.so
- 环境相关的设置:/etc/security/ 个别过于复杂的模块,有专业的配置文件
- 主配置文件:/etc/pam.conf,默认不存在,不需要创建,用于定义所有模块
- 针对每个服务单独建立的子配置文件:/etc/pam.d/APP_NAME,应用程序开发者,定义如何调用这些模块而写的配置文件
注意:如/etc/pam.d存在,/etc/pam.conf将失效
- pam认证原理
- PAM认证一般遵循这样的顺序:Service(服务)→PAM(配置文件)→pam_*.so
- PAM认证首先要确定那一项服务,然后加载相应的PAM的配置文件(位于/etc/pam.d下),最后调用认证文件(位于/lib/security下)进行安全认证
- PAM认证过程:
- 使用者执行/usr/bin/passwd 程序,并输入密码
- passwd开始调用PAM模块,PAM模块会搜寻passwd程序的PAM相关设置文件,这个设置文件一般是在/etc/pam.d/里边的与程序同名的文件,即PAM会搜寻/etc/pam.d/passwd此设置文件
- 经由/etc/pam.d/passwd设定文件的数据,取用PAM所提供的相关模块来进行验证
- 将验证结果回传给passwd这个程序,而passwd这个程序会根据PAM回传的结果决定下一个动作(重新输入密码或者通过验证)
4.2 配置文件格式
- 通用配置文件/etc/pam.conf格式
|application | type | control | module-path | arguments | - 专用配置文件/etc/pam.d/* 格式
|type | control | module-path | arguments |
[root@hai7 pam.d]$cat /etc/pam.d/passwd
#%PAM-1.0
auth include system-auth
-password optional pam_gnome_keyring.so use_authtok
| type | control | module-path | arguments |
| 类型 | 控制 | 模块 | 模块参数 |
- 配置文件说明:
- 服务名(application)
telnet、login、ftp等,服务名字“OTHER”代表所有没有在该文件中明确配置的其它服务 - 模块类型(module-type)
- 控制(control)
PAM库该如何处理与该服务相关的PAM模块的成功或失败情况 - 模块(module-path)
用来指明本模块对应的程序文件的路径名 - 参数(Arguments)
用来传递给该模块的参数
- 服务名(application)
4.2.1 模块类型(module-type)
- Auth
主要是接受用户名和密码,进而对该用户的密码进行认证,并负责设置用户的一些秘密信息 - Account
账号管理相关的非认证类的功能,主要是检查帐户是否被允许登录系统,帐号是否已经过期,帐号的登录是否有时间段的限制等等。
例如:用来限制/允许用户对某个服务的访问时间,当前有效的系统资源(最多可以有多少个用户),限制用户的位置(例如:root用户只能从控制台登录) - Password
用户修改密码时密码复杂度检查机制等功能 - Session
用户获取到服务之前或使用服务完成之后需要进行一些附加的操作,如:记录打开/关闭数据的信息,监视目录等 - -type 表示因为缺失而不能加载的模块将不记录到系统日志,对于那些不总是安装在系统上的模块有用
4.2.2 控制(Control)
PAM库如何处理与该服务相关的PAM模块成功或失败情况,以简单和复杂两种方式实现
-
简单方式实现:一个关健词实现
- required:一票否决
表示本模块必须返回成功才能通过认证,但是如果该模块返回失败,失败结果也不会立即通知用户,而是要等到同一type中的所有模块全部执行完毕再将失败结果返回给应用程序,即为必要条件 - requisite :一票否决
该模块必须返回成功才能通过认证,但是一旦该模块返回失败,将不再执行同一type内的任何模块,而是直接将控制权返回给应用程序,是一个必要条件 - sufficient :一票通过
表明本模块返回成功则通过身份认证的要求,不必再执行同一type内的其它模块,但如果本模块返回失败可忽略,即为充分条件 - optional :参考值
表明本模块是可选的,它的成功与否不会对身份认证起关键作用,其返回值一般被忽略 - include:
调用其他的配置文件中定义的配置信息
- required:一票否决
-
复杂详细实现:使用一个或多个“status=action”
- 格式
[status1=action1 status2=action …] - Status
检查各个模块执行结果的返回状态,可以为success、open_err、jgnore、user_unknown、default等,比较特殊的是default,表示没有明确定义返回值的其他行为 - Action
采取行为 ok,done,die,bad,ignore,reset,一个正整数N
action 含义 ok 模块通过,继续检查 done 模块通过,返回最后结果给应用 bad 结果失败,继续检查 die 结果失败,返回失败结果给应用 ignore 结果忽略,不影响最后结果 reset 忽略已经得到的结果 N 与跳过下一个N个模块的副作用是一样的在堆栈。注意,N=0是不允许的 - 示例:简单模式用复杂模式表示
required:[success=ok new_authtok_reqd=ok ignore=ignore default=bad]
requisite:[success=ok new_authtok_reqd=ok ignore=ignore default=die]
sufficient:[success=done new_authtok_reqd=done default=ignore]
optional:[success=ok new_authtok_reqd=ok default=ignore]
- 格式
4.2.3 模块路径(module-path):
- 相对路径:
/lib64/security目录下的模块可使用相对路径
如:pam_shells.so、pam_limits.so - 绝对路径:
模块通过读取配置文件完成用户对系统资源的使用控制
/etc/security/*.conf - 注意:修改PAM配置文件将马上生效
- 建议:编辑pam规则时,保持至少打开一个root会话,以防止root身份验证错误
4.3 PAM模块示例
- 模块:pam_shells
- 功能:检查有效登录shell,定义在目录/etc/shells下的shell是有效shell
- 查询:man pam_shells
- 配置示例:| auth | required | pam_shells.so |
示例:不允许使用/bin/csh的用户本地登录
'1:将v9用户的默认shell修改为/bin/csh '
[root@hai7 ~]$usermod -s /bin/bash v9 或chsh -s /bin/csh v9
'2:注释掉 /bin/csh'
[root@hai7 ~]vim /etc/shells
'3:配置shells模块'
[root@hai7 ~]$vim /etc/pam.d/login
#%PAM-1.0
auth required pam_shells.so <==增加此行
auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth substack system-auth
auth include postlogin
'4:使用账号v9登录,不允许登录,但是可以通过su切换至用户v9'
[root@hai7 ~]$su - v9
Last login: Sat Sep 22 19:50:06 CST 2018 on tty3
Last failed login: Sat Sep 22 19:54:14 CST 2018 on tty3
There was 1 failed login attempt since the last successful login. <==登录成功
'5. 如果继续将su模块也修改了,那么su切换也将失效'
[root@hai7 pam.d]# vim /etc/pam.d/su
#%PAM-1.0
auth required pam_shells.so <==同样增加此行
auth sufficient pam_rootok.so
[root@hai7 pam.d]# su - v9
Password: <==修改后要求输入密码,仍然无法登录
su: Authentication failure
'6. 日志文件记录'
tail /var/log/secure
Sep 22 19:54:14 hai7 login: FAILED LOGIN 1 FROM tty3 FOR v9, Authentication failure
- 模块:pam_securetty.so
- 功能:只允许root用户在/etc/securetty列出的安全终端上登陆
- 示例:| auth | required | pam_securetty.so |
示例1:查看那些程序调用了此模块
'1. 进入专用配置文件'
[root@hai7 etc]$cd /etc/pam.d/
'2. 搜索模块'
[root@hai7 pam.d]$grep pam_securetty.so *
login:auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so <==本地登录
remote: auth required pam_securetty.so <==远程登录例如ssh、telnet等
示例2:允许root在telnet登陆
默认telnet远程连接是不运行root登录的,原因在于telnet登录用的终端号为/dev/pts/2,不在/etc/securetty中
方法1
[root@hai7~]$vim /etc/pam.d/remote
#auth required pam_securetty.so 将这一行加上注释掉
方法2
编辑/etc/securetty文件
加入pts/0,pts/1…pts/n,因为telnet调用的端口可能为3、2、1等
- 模块:pam_nologin.so
- 功能:如果/etc/nologin文件存在,将导致非root用户不能登陆,适用于维护时
- 示例:| account | required | pam_nologin.so |
- 编辑拒绝登录提示语,将需要显示内容放在/etc/nologin中
echo nologin >/etc/nologin
示例:将su加入nologin安全检测,使其在/etc/nologin文件存在时,不能切换用户
[root@hai7 pam.d]$ vim su
account required pam_nologin.so <==在account类型中加入此行
- 模块:pam_limits.so
- 功能:在用户级别实现对其可使用的资源的限制,例如:可打开的文件数量,可运行的进程数量,可用内存空间
- 修改限制的实现方式:
-
ulimit命令,立即生效,但无法保存,选项及示例在结尾
-
配置文件:/etc/security/limits.conf, /etc/security/limits.d/*.conf
<domain> <type> <item> <value>
-
<domain> 应用于哪些对象
Username
:单个用户
@group
:组内所有用户
*
: 所有用户
%
:限制了组成员所有用户的登录总数,例如%group -
<type> 限制的类型
Soft
:软限制,普通用户自己可以修改
Hard
:硬限制,由root用户设定,且通过kernel强制生效
-
:soft和Hard值相同 -
<item> 限制的资源
nofile
:所能够同时打开的最大文件数量,默认为1024
nproc
:所能够同时运行的进程的最大数量,默认为1024 -
<value> 指定具体值
-
-
示例1:限制用户最多打开的文件数和运行进程数
[root@hai7 pam.d]$vim /etc/pam.d/system-auth
session required pam_limits.so <==在服务中调用此模块
'配置专用配置文件,也可用写在子文件中'
[root@hai7 pam.d]$vim /etc/security/limits.conf
apache – nofile 1024 <==用户apache可打开10240个文件
student hard nproc 20 <==用户student不能运行超过20个进程
示例2:使用ulimit命令,临时改变某些限制
1. 列出当前系统当前限制值
[root@hai6 pam.d]$ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 5790
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024 <==打开文件个数
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 5790
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
2. 验证此设定值,访问web服务,利用ab命令,同时并发打开多个连接,每个连接打开一个socket,而一个socket就会占用一个文件
[root@hai7~]$ ab -c 1030 -n 2000 http://172.20.129.251/
socket: Too many open files (24) <==超出范围
修改对应参数
[root@hai7~]$ulimit -n 2000 临时修改参数
[root@hai7 pam.d]$ulimit -a
open files (-n) 2000
保存修改,需要更改配置文件
[root@hai7 ~]$vim /etc/security/limits.conf
v9 - nofile 2000 增加此行
- ulimit选项及示例
选项 | 含义 | 示例 |
---|---|---|
-H | 设置硬资源限制,一旦设置不能增加 | ulimit -Hs 64 ;限制硬资源,线程栈大小为64 |
-S | 设置软资源限制,设置可增减,但不能超过硬资源设置 | ulimit -Sn 32 ;限制软资源,32个文件描述符 |
-a | 显示当前所有的limit信息 | ulimit -a |
-c | 醉倒的core文件的大小,以blocks为单位 | ulimit -c unlimited ;对生成的core文件大小不进行限制 |
-d | 进程最大的数据段大小,以Kbytes为单位 | ulimit -d unlimited ;对进程的数据段大小不进行限制 |
-f | 进程可以创建文件的最大值,以blocks为单位 | ulimit -f 2048 ;限制进程可以创建的最大文件大小为2048blocks |
-l | 最大可加锁内存大小,以Kbytes为单位 | ulimit -l 32 ;限制最大可加锁内存大小为32Kbyes |
-m | 最大内存大小,以Kbytes为单位 | ulimit -m unlimited ;对最大内存不进行加锁 |
-n | 可以打开最大文件描述符数量 | ulimit -n 128 ;限制最大可以使用128个文件描述符 |
-p | 管道缓冲区的大小,以Kbytes为单位 | ulimit -p 512 ;限制管道缓冲区的大小为512Kbytes |
-s | 线程栈大小,以Kbytes为单位 | ulimit -s 512 ;限制线程栈的大小为Kbytes |
-t | 最大的cpu占用时间,以秒为单位 | ulimit -t unlimited ;对最大的cpu占用时间不进行限制 |
-u | 用户最大可用的进程数 | ulimit -u 64 ;限制用户最多可以使用64个进程 |
-v | 进程最大可用的虚拟内存,以Kbytes为单位 | ulimit -v 200000 ;限制最大可用的虚拟内存为200000Kbytes |