本文综合分析了Linux系统下,如何使用runuser命令、su命令和sudo命令以其他用户身份来运行程序,以及这三个命令的运行效率比较。
一、su 命令临时切换用户身份
SU:( Switch user切换用户),可让一个普通用户切换为超级用户或其他用户,并可临时拥有所切换用户的权限,切换时需输入欲切换用户的密码;也可以让超级用户切换为普通用户,临时以低权限身份处理事务,切换时无需输入欲切换用户的密码。
zai Linux 系统中,有时候普通用户有些事情是不能做的,除非是 root 用户才能做到。这时就需要用 su 命令临时切换到 root 身份来做事了。
1、su 的语法
su [OPTION选项参数] [用户]
-, -l, –login
切换用户时,使环境变量(home,shell,user,logname,path等)和欲切换的用户相同、不使用则取得用户的临时权限,不加载环境变量。用su命令切换用户后,可以用 exit 命令或快捷键[Ctrl+D]可返回原登录用户;
-c, –command=COMMAND
使用 -c 传递单个命令到 shell 中,执行命令后,就恢复原来的用户身份,退出所切换到的用户环境;
–session-command=COMMAND
使用 -c 传递单个命令到 shell 中,并且不创建新的会话;
-f, –fast
通过 -f 参数到 shell (针对 csh 或 tcsh);
-m, –preserve-environment
不重置环境变量;
-s, –shell=SHELL
指定执行命令的shell;
–help
显示帮助信息;
–version
显示版本信息;
2、su 的范例:
1
2
3
4
5
|
su -
su - root
su - root -c "ls -l /root"
su - oracle -c "ulimit -aHS"
su -s /bin/sh -c "/usr/local/nginx/sbin/nginx"
|
3、su 的优缺点
su 的确为管理带来方便,通过切换到 root 下,能完成所有系统管理工具,只要把 root 的密码交给任何一个普通用户,他都能切换到 root 来完成所有的系统管理工作。但通过 su 切换到 root 后,也有不安全因素;比如系统有10个用户,而且都参与管理。如果这10个用户都涉及到超级权限的运用,做为管理员如果想让其它用户通过 su 来切换到超级权限的 root,必须把 root 权限密码都告诉这10个用户。如果这10个用户都有 root 权限,通过 root 权限可、以做任何事,这在一定程度上就对系统的安全造成了威协,想想 Windows 吧,简直就是恶梦。
“没有不安全的系统,只有不安全的人”,我们绝对不能保证这10个用户都能按正常操作流程来管理系统,其中任何一人对系统操作的重大失误,都可能导致系统崩溃或数据损失,所以 su 工具在多人参与的系统管理中,并不是最好的选择,su 只适用于一两个人参与管理的系统,毕竟 su 并不能让普通用户受限的使用;超级用户 root 密码应该掌握在少数用户手中,这绝对是真理!所以集权而治的存在还是有一定道理的。
二、sudo 命令
1、sudo 的适用条件
由于su 对切换到超级权限用户 root 后,权限的无限制性,所以 su 并不能担任多个管理员所管理的系统。如果用 su 来切换到超级用户来管理系统,也不能明确哪些工作是由哪个管理员进行的操作。特别是对于服务器的管理有多人参与管理时,最好是针对每个管理员的技术特长和管理范围,并且有针对性的下放给权限,并且约定其使用哪些工具来完成与其相关的工作,这时我们就有必要用到 sudo。通过 sudo,我们能把某些超级权限有针对性的下放,并且不需要普通用户知道 root 密码,所以 sudo 相对于权限无限制性的 su 来说,还是比较安全的,所以 sudo 也能被称为受限制的 su。另外 sudo 是需要授权许可的,所以也被称为授权许可的 su。
sudo 执行命令的流程是当前用户切换到root(或其它指定切换到的用户),然后以root(或其它指定的切换到的用户)身份执行命令,执行完成后,直接退回到当前用户,而这些的前提是要通过sudo的配置文件/etc/sudoers来进行授权。默认只有 root 用户能使用 sudo 命令,普通用户想要使用 sudo,是需要 root 预先设定的,默认 root 能够 sudo 是因为这个文件中有一行”root ALL=(ALL) ALL”。
2、sudo 配置文件
我们可以用他的专用编辑工具 visodu ,此工具的好处是在添加规则不太准确时,保存退出时会提示给我们错误信息;配置好后,可以用切换到您授权的用户下,通过sudo -l 来查看哪些命令是可以执行或禁止的。
/etc/sudoers 文件中每行算一个规则,前面带有 # 号可以当作是说明的内容,并不执行;如果规则很长,一行列不下时,可以用 \ 号来续行,这样看来一个规则也可以拥有多个行。
/etc/sudoers 的规则可分为两类:一类是别名定义,另一类是授权规则;别名定义并不是必须的,但授权规则是必须的。
sudo授权规则(sudoers配置):
1
|
授权用户 主机=命令动作 |
这三个要素缺一不可,但在动作之前也可以指定切换到特定用户下,在这里指定切换的用户要用( )号括起来,如果不需要密码直接运行命令的,应该加 NOPASSWD: 参数,但这些可以省略。举例说明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
## The COMMANDS section may have other options added to it. ## ## 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 |
执行visudo之后,可以看见缺省只有一条配置:
root ALL=(ALL) ALL
那么你就在下边再加一条配置:
admin ALL=(ALL) ALL
这样,普通用户 admin 就能够执行 root 权限的所有命令。
让普通用户support只能在某几台服务器上,执行root能执行的某些命令,首先需要配置一些Alias,这样在下面配置权限时,会方便一些,不用写大段大段的配置。Alias主要分成4种:
Host_Alias
Cmnd_Alias
User_Alias
Runas_Alias
配置Host_Alias:就是主机的列表
Host_Alias HOST_FLAG = hostname1, hostname2, hostname3
配置Cmnd_Alias:就是允许执行的命令的列表,命令前加上 ! 表示不能执行此命令。命令一定要使用绝对路径,避免其他目录的同名命令被执行,造成安全隐患 ,因此使用的时候也是使用绝对路径!
Cmnd_Alias COMMAND_FLAG = command1, command2, command3 ,!command4
配置User_Alias:就是具有sudo权限的用户的列表
User_Alias USER_FLAG = user1, user2, user3
配置Runas_Alias:就是用户以什么身份执行(例如root,或者oracle)的列表
Runas_Alias RUNAS_FLAG = operator1, operator2, operator3
配置权限的格式如下:
USER_FLAG HOST_FLAG=(RUNAS_FLAG) COMMAND_FLAG
如果不需要密码验证的话,则按照这样的格式来配置
USER_FLAG HOST_FLAG=(RUNAS_FLAG) NOPASSWD: COMMAND_FLAG
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
## Host Aliases ## Groups of machines. You may prefer to use hostnames (perhaps using ## wildcards for entire domains) or IP addresses instead. Host_Alias EPG = 192.168.1.1, 192.168.1.2 ## User Aliases ## These aren't often necessary, as you can use regular groups ## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname ## rather than USERALIAS # User_Alias ADMINS = jsmith, mikem ## Command Aliases ## These are groups of related commands... Cmnd_Alias SQUID = /opt/vtbin/squid_refresh , ! /sbin/service , /bin/rm Cmnd_Alias ADMPW = /usr/bin/passwd [A-Za-z]*, ! /usr/bin/passwd , ! /usr/bin/passwd root
## Allow root to run any commands anywhere root ALL=(ALL) ALL admin EPG=(ALL) NOPASSWD: SQUID admin EPG=(ALL) NOPASSWD: ADMPW ## 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 |
当然新用户的配置也可以放到,/etc/sudoers.d/ 下的文件里,也会生效,修改也方便。
3、sudo 语法
sudo [ -Vhl LvkKsHPSb ] │ [ -p prompt ] [ -c class│- ] [ -a auth_type ] [-u username│#uid ] command
1
2
3
4
5
6
7
8
9
10
11
|
-V 显示版本编号 -h 会显示版本编号及指令的使用方式说明 -l 显示出自己(执行 sudo 的使用者)的权限 -v 因为 sudo 在第一次执行时或是在 N 分钟内没有执行(N 预设为五)会问密码,这个参数是重新做一次确认,如果超过 N 分钟,也会问密码 -k 将会强迫使用者在下一次执行 sudo 时问密码(不论有没有超过 N 分钟) -b 将要执行的指令放在背景执行 -p prompt 可以更改问密码的提示语,其中 %u 会代换为使用者的帐号名称, %h 会显示主机名称 -u username/#uid 不加此参数,代表要以 root 的身份执行指令,而加了此参数,可以以 username 的身份执行指令(#uid 为该 username 的使用者号码) -s 执行环境变数中的 SHELL 所指定的 shell ,或是 /etc/passwd 里所指定的 shell -H 将环境变数中的 HOME (家目录)指定为要变更身份的使用者家目录(如不加 -u 参数就是系统管理者 root ) command 要以系统管理者身份(或以 -u 更改为其他人)执行的指令 |
三、runuser 命令
runuser命令使用一个替代的用户或者组ID运行一个Shell。这个命令仅在root用户时有用。
仅以会话PAM钩子运行,并且没有密码提示。如果用一个非root用户,并且该用户没有权限设置user ID,这个命令将会因为程序没有setuid而失败。因runuser不会运行认证和账户PAM钩子,它比su更底层。
1、runuser 语法
语法与 su 命令基本一样:
-, -l, –login
让shell成为登录shell,用 runuser -l PAM 文件替代默认的;
-g –group=group
指定主要的组;
-G –supp-group=group
指定追加组
-c, –command=COMMAND
使用 -c 传递单个命令到 shell 中,执行命令后,就退出到 root;
–session-command=COMMAND
通过一个单一的命令用 -c 参数到 shell ,不创建一个新的会话;
-f, –fast
通过 -f 参数到 shell (针对 csh 或 tcsh);
-m, –preserve-environment
不重置环境变量;
-p same as -m
-s, –shell=SHELL
指定执行命令的shell;
2、runuser 样例
1
2
3
|
runuser -l userNameHere -c '/path/to/command arg1 arg2'
runuser -l oracle -c 'ulimit -SHa'
runuser -s /bin/sh -c "/usr/local/nginx/sbin/nginx"
|
有时,root用户由于权限(安全)问题不能浏览NFS挂载的共享:
1
|
ls -l /nfs/wwwroot/http
|
或
1
|
cd /nfs/wwwroot/http
|
可能的输出:
1
|
- bash : cd : /nfs/wwwroot/http/ : Permission denied
|
尽管如此,apache用户被允许浏览或访问挂载在/nfs/wwwroot/http/下基于nfs的系统:
1
|
runuser -l apache -c 'ls -l /nfs/wwwroot/http/'
|
或
1
|
runuser -l apache -c 'cd /nfs/wwwroot/http/; vi index.php'
|
使用runuser命令,无需使用密码,并且,只能在root用户下使用。
四、总结:su VS su VS dorunuser
命令 | root 到 用户 |
用户 到 root |
任意用户 到 任意用户 |
认证方式 | 日志文件 | 备注 |
---|---|---|---|---|---|---|
runuser | Y | N | N | 无 | 无 | 因 runuser 不会运行认证和账户 PAM 钩子,它比 su 更底层。 |
su | Y | Y | Y | 目标用户的密码 |
/var/log/auth.log 或 /var/log/secure |
你必须与其它用户分享你的密码或 root 密码。 |
sudo | Y | Y | Y | 认证用户使用他们自己的密码,而不是目标用户。 |
/var/log/auth.log 或 /var/log/secure |
允许系统管理员委托授权给一个特定的用户(或用户组),让其在提供审计跟踪命令后可以以 root 或其它用户运行某些(或全部)命令。 |
su 与 runuser 都可以用来写系统自启动脚本,如 Tomcat 服务使用系统用户启动的自启动脚本。什么时候使用哪种命令,根据使用场景自己来决定吧。