1. sudo简介
在sudo于1980年前后被写出之前,一般用户利用 su 切换用户,管理系统时通常使用此命令切换为超级用户。但是使用su的缺点之一在于必须要先告知目标用户的密码。
sudo使一般用户不需要知道目标用户的密码即可获得权限。首先由超级用户将普通用户的名字、可以执行的特定命令、按照哪种用户或用户组的身份执行等信息,登记在特殊的文件中(通常是/etc/sudoers),即完成对该用户的授权(此时该用户称为sudoer);在一般用户需要获取特定权限时,其可在命令前加上sudo,此时sudo将会询问该用户自己的密码(以确认终端前的是该用户本人),回答后系统即会将该命令的进程以目标用户的权限执行。如果没有指定目标用户,就默认以超级用户的权限执行。之后的一段时间内(默认为5分钟,可在/etc/sudoers自定义),使用sudo不需要再次输入密码。
当给用户授权sudo权限时,进行哪些限制会更加安全?本文以给 voidking
用户授权为例,学习一下授权sudo的方法。
参考文档:
- 维基百科 - sudo
- How To Edit the Sudoers File
- 8 Best practices with sudo on Linux – Do’s and Dont’s of sudo
- 关于linux的sudo的权限分离最佳实践
2. 给用户授权sudo
2.1. 方法一:直接授权给用户
1、编辑 sudoers 文件
1 | # vim /etc/sudoers |
添加授权内容:
1 | voidking ALL=(ALL:ALL) ALL |
2、测试
1 | su voidking |
2.2. 方法二:添加用户到sudo组(推荐)
2.2.1. 授权给sudo组
授权给sudo组,仅操作一次即可。
1、添加sudo用户组
1 | groupadd sudo |
2、编辑 sudoers 文件
1 | visudo |
添加内容:
1 | %sudo ALL=(ALL:ALL) ALL |
2.2.2. 添加用户到sudo组
1 | usermod -G sudo -a voidking |
3. 授权文件解释
已知一条sudoers授权规则为:
1 | voidking ALL=(ALL:ALL) ALL |
这个配置的含义为:
voidking
,表示这个规则是对用户 voidking 生效的- 第一个
ALL
,表示这个规则是对所有主机生效的 - 第二个
ALL
,表示voidking可以以所有用户身份运行命令 - 第三个
ALL
,表示voidking可以以所有用户组身份运行命令 - 第四个
ALL
,表示voidking用户可以运行所有命令
如果授权规则改为:
1 | voidking ALL=(ALL:ALL) NOPASSWD:ALL |
那么表示voidking用户在运行所有命令时都不需要密码。
4. 最佳实践
4.1. 开启sudo日志
将所有sudo命令操作记录到系统的日志文件中,以便日后审计。
sudoers文件中,添加日志配置
1 | Defaults logfile=/var/log/sudo.log |
4.2. 特定命令的执行权限
限制用户只能执行特定的命令,可以提高系统安全性。
sudoers文件中,配置改为只能执行指定命令
1 | voidking ALL=(ALL) /path/to/command |
4.3. 锁定sudo命令路径
锁定sudo可以执行的命令的路径。
1 | Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
4.4. 切换其他用户需要密码
默认情况下,用户可以使用sudo命令切换到任何其他用户的身份,我们可以限制用户切换到其他用户时需要密码。
sudoers文件中,添加切换用户需要密码的配置
1 | Defaults targetpw |
4.5. 禁止用户切换到root(不可行)
sudoers文件中,禁止用户使用sudo su
切换到root
1 | voidking ALL=(ALL) ALL,!/bin/su |
但是,这个方法并不能阻止用户切换到root,比如用户还可以使用sudo -i
或者sudo bash
切换到root。
更好的办法是配置用户只能执行特定的命令。
4.6. 特定sudo配置使用单独配置文件
对特定用户和用户组的一组配置,独立作为一个文件,结构会更加清晰。
默认 /etc/sudoers.d 目录中的文件会被include
1 | #includedir /etc/sudoers.d |
编辑独立配置文件:
1 | visudo -f /etc/sudoers.d/ops |
4.7. 不给docker命令sudo权限
如果给用户授权了sudo docker
权限,那么用户就可以挂载一些没有权限文件到容器中,此时就有权限进行操作了。
因此最好不要给用户授权docker的sudo权限,而是应该配置普通用户也可以直接执行docker命令。
5. 权限分配
5.1. sudoers默认权限分组
CentOS7 sudoers中的默认权限分组,可以参考。
1 | ## Command Aliases |
5.2. 权限配置示例
5.2.1. 运维组
1、权限规划
- 初级:查看文件列表和文件内容、查看系统信息、查看网络状态
- 高级:初级所有权限、修改网络配置、进程管理、存储管理、软件包管理
- 经理:超级用户所有权限
2、创建配置文件
1 | visudo -f /etc/sudoers.d/op |
注意:配置文件名不能含有.
,否则不会生效,详情参考文档File in /etc/sudoers.d file not being read by sudo
3、配置内容
1 | Cmnd_Alias JUNIOR_OP_CMD = /usr/bin/ls,/usr/bin/cat,/usr/bin/grep,/usr/bin/tail,/usr/bin/df,/usr/bin/free,/usr/bin/top,/usr/bin/hostname,/usr/bin/ping,/usr/sbin/ifconfig,/usr/bin/netstat,/usr/bin/systemctl status *,/usr/bin/journalctl |
如果是ubuntu/debian系统,软件包管理命令需要改成 /usr/bin/apt,/usr/bin/apt-get
另外不同的系统中,命令的路径也是不同的,需要针对不同系统进行修改。
5.2.2. 开发组
1、权限规划
- 初级:查看文件列表和文件内容权限,对应服务查看日志的权限
- 高级:初级所有权限,重启对应服务
- 经理:项目所在服务器的ALL权限,不能修改root密码,不能修改visudo
2、创建配置文件
1 | visudo -f /etc/sudoers.d/dev |
3、配置内容
1 | Cmnd_Alias JUNIOR_DEV_CMD = /usr/bin/ls,/usr/bin/cat,/usr/bin/grep /data/apps/logs,/usr/bin/tail /data/apps/logs |
5.2.3. 网络组
1、权限规划
- 初级:普通用户的权限,不加入sudo列表
- 高级:所在服务器的网络管理权限
2、创建配置文件
1 | visudo -f /etc/sudoers.d/net |
3、配置内容
1 | Cmnd_Alias SENIOR_NET_CMD = /usr/sbin/route,/usr/sbin/ifconfig,/usr/bin/ping,/usr/sbin/dhclient,/usr/include/net,/usr/sbin/iptables,/usr/sbin/mii-tool,/usr/bin/cat /var/log/* |
5.2.4. DBA组
1、权限规划
- 初级:普通权限,不加入sudo列表
- 高级:数据库服务器的ALL权限,不能修改root密码,不能修改visudo
2、创建配置文件
1 | visudo -f /etc/sudoers.d/dba |
3、配置内容
1 | Cmnd_Alias SENIOR_DBA_CMD = ALL,/usr/bin/passwd [A-Za-z]*,!/usr/bin/passwd root,!/usr/sbin/visudo |