一 sudo配置文件/etc/sudoers介绍
① 什么是sudo
1) sudo 的'英文全称'是 super user do,即以超级用户'root 用户'的方式执行命令
2) /etc/sudoers 是一个文本文件,只有'root用户'有该命令的'执行'权限
1) 允许'普通用户'以'特权用户的权限'去执行某些'特权'命令,访问和使用本身'没有权限'文件的工具
2) sudo可以让'普通用户'在'不需要'知道特权用户的'口令'时,可获得'特权'用户的权限
备注: 不一定是'特权用户',可以变换为'另一个用户'
补充: su 从'低级'切换到'高级'用户需要密码
Real user ID, Effective userID , Set user ID 之间的关系
sudo su和su的区别
1)su的'缺点之一'在于必须要'先告知'超级用户的'密码'
2) sudo使一般用户'不需要知道超级用户'的密码即可获得权限
② 如何使用sudo
1) 超级用户可以将普通用户的'用户名'、可执行的特定'命令'、运行'身份(用户[组])信息'写入配置中
2) 在'/etc/sudoers'配置文件中完成对'普通用户'的授权,此时该用户称为"sudoer"
4) 在一般用户需要'取得'特殊权限时,就可以在'命令'前加上"sudo",以特权用户'执行'该命令
校验规则:
1) 此时sudo将会'询问该用户自己(需要密码场景)'的密码,以'确认'终端机前的是该用户本人
2) 回答后系统即会将该'命令的进程'以'超级用户的权限'运行
3) 之后的一段时间内(默认为5分钟,可在/etc/sudoers自定义),使用sudo'不需要'再次输入密码
由于不需要超级用户的密码,'部分Unix系统(Ubuntu)'利用sudo使一般用户取代超级用户作为管理帐号
+++++++++++++ "补充说明" +++++++++++++
1) 将需要执行'sudo命令'的'用户'、'用户组'、以及允许执行的'命令'、'脚本'写入到配置文件中
备注: 一般是'/etc/sudoers文件'或'/etc/sudoers.d/文件夹'
③ 编辑/etc/sudoers的细节
1) sudo命令对应的用户'权限授权配置文件'为'/etc/sudoers'
2) 推荐'使用专用工具visudo'来完成有关sudo的'授权'管理配置
说明1: 使用visudo工具的'好处'是在添加规则之后,保存退出时会'检查'授权配置的'语法'
说明2: 直接用'vi/vim'编辑/etc/sudoers,不会进行配置'语法'校验
现象: vi配置'发生错误',会造成所有普通用户都'无法'通过sudo执行命令以及切换到'超级'root上了
3) visudo编辑'出错'
[1]、键入"e"是重新编辑,键入"x"是不保存退出,键入"Q"是'退出并保存'
[2]、如果真选择Q,那么sudo将'不会再运行',直到错误'被纠正'
+++++++++++ "编辑配置文件的方式" +++++++++++
1) sudoedit /etc/sudoers
2) vim /etc/sudoers
3) visudo
[1]、visudo -c # 命令具有'语法检查'功能
[2]、visudo -cq # 返回1错误,0无错误,可以用'$?'来获取
4) 补充:还可以为每个用户建立'特定'sudo策略文件
[1]、在'/etc/sudoers.d/'目录下建立与'用户同名'的策略文件
visudo -f /etc/sudoers.d/kiosk,'写入':
kiosk ALL=/usr/bin/, !/usr/bin/passwd, /bin/, !/bin/kill #不可杀进程和修改密码
补充: /etc/sudo.conf解读
④ 为何要使用sudo
1) 运行'软件程序的帐号'要极尽可能的使用'低权限'的帐号,所以各软件一般都使用'独立的帐号'运行
目的: 防止'某个程序'本身出现'漏洞 leak'时,攻击者获得'管理员'权限
2) Linux系统的'安全加固'要求
⑤ sudo带来的问题
背景: sudo可以让指定的'普通用户'在'不需要'输入'超级用户'密码的情况下执行指定的'特权'命令
特性: sudo工具在带来'方便'的同时,也会产生一些'安全隐患'
问题:
1) sudo的配置文件'配置不当',导致普通用户可以'获取'超级用户权限
2)可能对系统进行'破坏'、'删除'或者'修改'系统的'重要'文件
要做:必须进行'安全测试时'需要对sudo应用的相关'命令'、'文件'进行检查
⑥ sudo的原则
1) 以'超级用户'权限执行的操作,操作对象必须是'安全的',否则将存在'低权限'用户提权到'超级'风险
2) 操作对象'包括':
① 命令'本身';
② 命令调用的'其他'命令;
③ 传递给'命令'的所有参数;
④ 环境'变量'
3) 操作对象'安全性':
① 操作对象本身的'属主'、'权限'属性
② 操作对象'所在的目录',及递归的'上级'目录的'属主、权限'属性
⑦ sudo的运行原理
1) 当涉及到 sudoers 文件时,'从上到下'读取该文件,以'最后'的设置为准
[1]、当用户执行sudo时,系统会'主动寻找/etc/sudoers'文件,判断该用户是否有执行sudo的权限
[2]、确认'用户'具有可执行sudo的权限后,让用户输入用户'自己的密码'确认
[3]、若密码输入成功,则判断'当前命令'是否授权,通过则执行'sudo后续'的命令
注意:你应该从'通用设置开始',并在'末尾放置例外'情况,否则通用设置会'覆盖例外'情况
2) sudo 会创建一个'子进程',调用 setuid() 来'切换'到目标用户
3) 接着,它会在'上述子进程中'执行参数给定的 shell 或命令
二 配置文件语法规则
man sudoers --> 查看'详细配置'语法,注意"EXAMPLES 章节"
① 配置语法注意事项
1) 命令别名下的成员必须是文件或目录的'绝对路径'
2) 别名名称'包含'大写字母、数字、下划线等,如果是字母则都要'大写'
3) 一个别名下包含多个成员,成员与成员之间,通过",(逗号)"号进行分隔,成员必须是有效且实际存在的
4) 别名成员受'别名类型'Host_Alias、User_Alias、Runas_Alias、Cmnd_Alias的制约
解读: 定义什么类型的别名,就要有'什么类型的成员'与之'相配'
5) 别名规则是每行算一个规则,如果一行容不下,则可以通过"(反斜杠 \)"来'续行'
6) 指定'切换的用户'要用"(括号)"括起来
[1] 如果'省略'括号,则默认为root用户
[2] 如果括号里是'ALL',则代表能够切换到'所有(任意)'用户
7) 如果希望'不需要密码'就直接运行命令,则应该加上"NOPASSWD:"参数
8) 若想'禁止'某类程序或命令执行,则要在命令动作前面加上"! 感叹"号,并且放在允许执行命令的后面
9) 用户'组'前面必须加"%"号
② sudo相关文件
1) 配置文件: /etc/sudoers '属性必须为0440', /etc/sudoers.d/
2) '时间戳'文件: /var/db/sudo
3) '日志'文件: /var/log/secure --> 记录'sudo'命令的操作信息
4) 配置文件支持使用'通配符glob':
? :任意'[0,1]'个字符
* :匹配'任意'长度字符
+ :至少'匹配一次'
[wxc]:匹配'其中一个'字符
[!wxc]:'除了'这三个字符的其它字符
\x : 转义
[[alpha]] :字母 示例: /bin/ls [[alpha]]*
sudo配置专属日志
++++++++++++ "日志的作用" ++++++++++++
1) 查看主机是否遭到'入侵'攻击
2) 查看某用户登录进来并使用'特殊权限'是否执行'错误'指令等
目标: 我们要'实时监控'此文件的动向
+++++++++++++++ "/etc/sduoers 中的#include讲解" +++++++++++++++
+++++++++++++++ "/etc/sduoers 中的#includedir讲解" +++++++++++++++
说明: /ect/dudoers.d/目录下的文件通过 'visudo -f 或 sudo -e' 进行编辑
补充: 目录下的文件'按照字母顺序'加载的
③ 别名规则
别名类型的定义:'不是必须'的,别名必须'全部而且只能'使用'大写'英文字母的组合
sudoers文件中的别名类型'Alias_Type'包括如下'四'种
(1)Host_Alias
1)Host_Alias,表示定义'主机别名',实际'配置语法'如下:
特点: 将主机分类,这些都是'随便分得',目的是为了更好地'管理'
2) 关于Host_Alias的说明'具体'如下:
[1] 在'生产'场景中,一般'不需要'设置主机别名,在定义'授权规则'时通过'ALL'来匹配所有的主机
说明: 有些规范虽然不是必需的,但最好能够按照系统的标准来进行配置,这样可以'避免意外'问题的发生
补充: 主机名就是一个'逻辑上'的主机组
1. 当多台服务器共享一个'/etc/sudoers'的时候就会用到这个'主机别名'
2. 不过在'实际'企业运维中,这个需求几乎是'不存在'的
[2] 在sudo实际'授权语法规则'配置时,第一个'ALL'的位置就是'主机别名'的'配置'位置
[3] 带'\'的场景,注意":"
Host_Alias SPARC = bigtime, eclipse, moet, anchor :\
SGI = grolsch, dandelion, black
"等效":
Host_Alias SPARC = bigtime, eclipse, moet, anchor
Host_Alias SGI = grolsch, dandelion, black
(2)User_Alias
1) 表示定义'用户别名','别名成员'可以是'用户'、'用户组(加%)',实际配置语法如下:
(3)Runas_Alias
1) '操作类型'分类,这个别名指定的是授权的"用户身份",即sudo允许'切换到'的用户身份
Runas_Alias OP = root, operator
Runas_Alias DB = oracle, mysql
2) Runas_Alias定义的是可以执行sudo '后面命令'的'用户身份'
备注:
[1]、实际工作中都是普通用户需要'转换'到root身份
[2]、普通用户之间权限相同,'极少'有授权其他普通用户身份的需求
(4) Cmnd_Alias
1) 定义'命令的'路径,命令一定要使用'绝对'路径
目的: 避免其他目录的'同名命令'被执行,造成安全'隐患'
用法: 一般将'不同类型'的命令'分组'
2) 案例讲解1
User_Alias ADMINS = ton,tom,%server
ADMINS ALL=(root) /bin/su -
解读:以'普通用户'可以su - 至root进行操作
3) 案例讲解2 --> "!"的应用
Cmnd_Alias COMAD = !/usr/bin/passwd root,/usr/bin/passwd [a-zA-Z]*
tom ALL=(root) COMAD
解读: 可以sudo,修改'除了root的'密码
(5)别名应用场景
问题: 企业运维中,什么情况下会使'用到别名'
1) 当工作中有很'多台'服务器,每台服务器又包含'多个'系统用户
2) 需要对用户权限进行'严格管理'(关键命令的使用)、'分层授权'管理用户的时候
别名的应用场景
(6)Defaults
说明: 这个'不是别名',下面的将以第一个 Defaults 作为基准来参考
Defaults parameter, parameter_list ## 对'任意主机登录'的所有用户起作用
Defaults@Host_List parameter, parameter_list ## 对指定主机登录的所有用户起作用
Defaults:User_List parameter, parameter_list ## 对'指定用户'起作用
Defaults!Cmnd_List parameter, parameter_list ## 对'指定命令'起作用
Defaults>Runas_List parameter, parameter_list ## 对以'指定目标用户'运行命令起作用
重点: parameter 参数可以是'标记 (flags)'、'整数值'或者是'列表 (list)'
1)标记 (flag) 是指'布尔类型值',可以使用 '!' 操作符来进行'取反'
2)列表 (list) 有两个'赋值运算符':'+=' (添加到列表) 和 '-= '(从列表中移除)。
'需求1': 修改默认密码提示超时时间,默认是'5min'
Defaults env_reset,timestamp_timeout=20 #改为20min
解读: 即两次sudo操作间隔在'20min内'则不用重新输入密码,否则需'重输(需要密码的场景)'
'需求2':安置一个'安全的 PATH 环境'变量
说明: 该 PATH 环境变量'应用于每个通过 sudo 执行'的命令
注意两点:
1) 当系统管理员'不信任 sudo 用户',便可以设置一个安全的 PATH 环境变量。
2) 该设置将root的PATH和用户的 PATH 分开,只有在 exempt_group 组的用户不受该设置的影响
应用:
可以添加以下内容来设置:
Defaults secure_path="/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
重点: Defaults需求参考
'需求3':允许 'tty 用户会话'使用 sudo
该设置允许在一个'真实的 tty 中'进行调用 sudo,
备注:但‘不允许‘通过 cron 或者cgi-bin 脚本等方法来调用
添加以下内容来设置:
Defaults requiretty
+++++++++++++ "分割线" +++++++++++++
'需求4':使用 'pty' 运行 sudo 命令
1) 少数情况下,攻击者可以通过 sudo 来运行一个‘恶意程序‘ (比如病毒或者恶意代码)
2) 这种恶意程序可能会'分叉'出一个'后台'运行的进程
--> 即使主程序完成执行,它仍能够运行在'用户的终端'设备上
3) 为了'防止'出现这样的情况,你可以通过 use_pty 参数来设置 sudo 使用'伪终端'来运行其他命令
-->而不必管 I/O 日志的开启状态,如下:
Defaults use_pty
'需求5': 创建 sudo '日志'文件
1) 默认: sudo 通过 syslog(3) 来记录到日志
2) 但是我们可以通过 'logfile 参数'来指定一个'自定义的日志文件'
3) 如下:Defaults logfile="/var/log/sudo.log"
4) 使用 log_host 和 log_year 参数可以对应记录日志'主机名'和4位数'年份'到自定义日志文件
如下:Defaults log_host, log_year, logfile="/var/log/sudo.log"
'需求6': 记录 sudo 命令的输入/输出
1) log_input 和 log_output 参数可以让 sudo 命令运行在'伪终端'
--> 并可以对应地'记录'所有的用户输入和输出到屏幕上
2) 默认的 I/O 日志目录为 /var/log/sudo-io
--> 如果存在会话序列号,它将被存储到该目录,你可以通过'iolog_dir 参数'来指定一个目录
Defaults log_input, log_output
备注: 这其中支持'转义'字符,像 %{seq} —— 以 36 为基数的'单调递增'序列
比如 000001,这里'每两个数字'都分别用来形成一个'新目'录--> 00/00/01
'需求7':为 sudo 用户'提示命令'用法
1) 如下,使用 lecture 参数可以在系统中为 sudo 用户提示命令的用法,参数属性值有三个选择:
always – '一直提示'
once – 用户首次运行 sudo 时提示 (未指定参数属性值时的默认值)
never – 从不提示
Defaults lecture="always"
2) 此外,你还可以使用lecture_file参数类自定义提示内容,在指定的文件中输入适当的提示内容即可
Defaults lecture_file="/path/to/file"
'需求8':、输入'错误'的 sudo 密码是显示'自定义'信息
1) 当某个用户输错密码时会有一个'对应的信息'显示在屏幕上
2) 默认是'sorry, try again',你可以通过 badpass_message 参数来'修改'该信息:
Defaults badpass_message="Password is wrong, please try again"
'需求9': 增加 sudo 密码尝试'限制'次数
passwd_tries 参数用于指定用户尝试输入密码的次数,默认为 '3'
Defaults passwd_tries=5
'需求10': 增加 sudo 密码尝试限制'超时'时间
使用 passwd_timeout 参数设置密码超时 (默认为 5 分钟),如下:
Defaults passwd_timeout=2
'需求11':在输错密码时让 sudo 羞辱用户
1)使用了 insults 参数之后,一旦你输出了密码,sudo 便会在命令窗口中显示羞辱你的信息
2)这个参数会'自动关闭 badpass_message' 参数
Defaults insults
④ 授权规则
1) 授权规则是'必须'的
user host=(runas) [tag:]command
[1] user: 运行'sudo'命令的身份 --> '授权用户'
[2] host: 通过'哪些'主机
场景: 一般在有'NIS服务或集中管理'的时候
其实就是'管理所有主机的管理策略'在'一台主机上'编辑sudoers这个文件,然后将它'推到'所有主机
[3] runas: 以'哪个用户(执行用户)'的身份执行'command'
1. 如果省略默认是'root'
2. (ALL,!root) --> '除了root'之外
[4] tag: NOPASSWD、PASSWD;使用sudo是否使用'对应切换用户(runas)'密码
注意:PASSWD、NOPASSWD等标签'只能在授权项中'使用,不能在'别名'中使用
[5] command: 运行'哪些'命令
解读: '谁'能够以'哪个用户的身份'通过'什么主机'执行什么'命令'
2) 常见的形式
'案例1': kiosk ALL=(ALL:ALL) ALL
[1]、ALL表示从'任何的主机(host)'都可以执行
[2]、(ALL:ALL) 是以谁的身份来执行,ALL:ALL就表示root可以以'任何人的身份'来执行命令
备注:第一个ALL是'用户',第二个ALL是'组'
[3]、ALL 表示任何命令
解读: 那么整条规则就是kiosk用户可以在'任何主机'以'任何人'的身份来执行'所有'的命令
'案例2': %wheel ALL=(ALL) ALL
解读: 允许wheel'组'中的所有人运行所有的命令,可以把用户加入到wheel组就可以使用sudo命令
'案例3': kisok 172.25.2.0/24=(root) /usr/sbin/useradd
解读: 只允许kiosk用户在'172.25.2.0/24网段上'连接主机并且以root权限执行useradd命令
'案例4': kiosk ALL=(ALL) NOPASSWD: ALL
补充: 设置 sudo 时'不需要'输入密码
sudoers配置可以在'命令部分'附加选项,比如设置执行sudo时'不需要'输入密码
setfacl限制root用户执行某些命令
三 sudo命令细讲
说明: 便于'巩固'之前'ansible.conf'关于'sudo'的知识
核心: man sudo --> 'EXAMPLES'
补充ansible关于sudo
① -l
功能: sudo -l,显示'允许当前用户(执行 sudo 的使用者)'使用的'命令'
1) 列出目前用户'可执行'与'无法执行'的指令
2) 也就是可以查看'自己'使用'哪个用户的身份'执行那些'特殊'权限
② -k
说明: 将会'强迫'使用者在'下一次执行 sudo' 时问输入'密码(如果需要密码)'
细节: 不论'有没有超过' N 分钟
K(大写) --> "了解"
③ -A
场景: 进行一个'自动化'脚本时,利用环境变量'SUDO_ASKPASS'来实现'免密码'执行
1) 创建一个'程序(jva、python、perl、shell等均可)'文件,产生'密码'
2) 在脚本中执行sudo 命令'之前'引入'环境变量'SUDO_ASKPASS
3) 执行命令
④ -i
1) 目的: 为了'频繁'的执行某些只有'超级用户'才能执行的权限,而'不用'每次输入密码
重点: 没有时间'限制'
2) 但是只有'指定的用户'才有执行'指定的命令(格式:/bin/bash -c )'的权限
⑤ -u
用法: -u 'username'| '#uid' -->指定'runas'
1) '不加'此参数,代表要以 'root' 的身份'执行'指令
2) 而'加了'此参数,可以'以 username 的身份'执行指令
⑥ -T
⑦ -V、-v、--、-s
1) -V, --version 显示'版本信息'并且退出
2) -v, --validate 更新用户的'时间戳'而'不运行'一个命令
3) -- 停止处理'命令行参数'
4) -s 执行环境变数中的 SHELL变量 所指定的 shell,或是 /etc/passwd 里所指定的 shell
⑧ -e
sudo -e 文件名: '不是'执行命令,而是'修改'文件;相当于命令'sudoedit'
说明: -E'大写'选项后
1) 用户可以在sudo执行时'保留当前用户'已存在的环境变量,不会被sudo'重置'
2) 另外,如果用户对于'指定的环境变量没有权限',则会'报错'
⑨ 其他
-b, --background 将要'执行的指令'放在'后台'运行
-C, --close-from=num 关闭所有'大于等于'num的'文件描述符'
-E, --preserve-env 运行命令时保存用户环境
-g, --group=group 以指定的组名或组ID运行一个命令
-H, --set-home 设置 HOME 变量以指向用户的 HOME 目录
-h, --host=host 在主机上运行命令(如果插件支持)
-n, – non-interactive 非交互方式,无提示被使用
-P, --preserve-groups 保存组向量而非设置指定的目标
-P, --prompt=prompt 使用指定的'密码提示'
-r, --role=role 用指定的角色创建SELinux安全上下文
-S, --stdin 从变准输入读取密码
-t, --type=type 使用指定的类型创建 SELinux 安全上下文
-U, --other-user=user 在列表模式中,显示用户特权
⑩ sudo 1.9.x 新版本安装
sudo新版本下载
新版本特性
sudo相关博客
四 滥用sudo提权案例讲解
涉及: vim、nmap、man、'less/more'、awk、nano、wget、apache命令
重点: sudo授权时passwd,su,sudo,sudoedit,visudo等具有'特殊意义'的命令时,务必要考虑全面
① vim错误提权
需求: 只能用'vim、vi、view'编辑'特定'文件,但是却'错误逃逸(通过 :!bash、:!sh)'
同理: 'less、more'命令'一样'的效果,之后按'!'按下并按'Enter'
② 使用awk命令
sudo awk 'BEGIN {system("/bin/sh")}'
③④⑤⑥⑦⑧⑨⑩