本文综合分析了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
-bashcd/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 服务使用系统用户启动的自启动脚本。什么时候使用哪种命令,根据使用场景自己来决定吧。

Linux 下以其他用户身份运行程序—— su、sudo、runuser的更多相关文章

  1. 以不同用户身份运行程序,/savecred只需要输入一次密码(GetTokenByName取得EXPLORER.EXE的令牌,然后调用CreateProcessAsUser,而且使用LoadUserProfile解决另存文件的问题)good

    http://blog.sina.com.cn/s/blog_65977dde0100s7tm.html ----------------------------------------------- ...

  2. 在SYSTEM权限下以当前用户权限运行程序

    http://download.csdn.net/download/lai444132348/9730266 using System; using System.Runtime.InteropSer ...

  3. linux下在root用户登陆状态下,以指定用户运行脚本程序实现方式

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAABKCAIAAACASdeXAAAEoUlEQVR4nO2dy7WlIBBFTYIoSIIkmD ...

  4. 【转】在嵌入式Linux和PC机Linux下使用popen函数时,程序运行结果有差异。

    下面程序演示了在嵌入式Linux和PC机Linux下使用popen函数时,程序的运行结果是有差异的. 两个程序 atest.c 和 btest.c,atest 检查是否有 btest 进程运行,如果没 ...

  5. Linux下使用Eclipse开发Hadoop应用程序

    在前面一篇文章中介绍了如果在完全分布式的环境下搭建Hadoop0.20.2,现在就再利用这个环境完成开发. 首先用hadoop这个用户登录linux系统(hadoop用户在前面一篇文章中创建的),然后 ...

  6. Linux下通过源码编译安装程序

    本文简单的记录了下,在linux下如何通过源码安装程序,以及相关的知识.(大神勿喷^_^) 一.程序的组成部分 Linux下程序大都是由以下几部分组成: 二进制文件:也就是可以运行的程序文件 库文件: ...

  7. Linux下非root用户如何安装软件

    Linux下非root用户如何安装软件 从windows转移到Linux的用户最开始总会有各种不适,因为这种不适最终放弃linux的不在少数.对于这类人只能说可惜,还没有领略到linux的美好就过早放 ...

  8. C# WinForm判断Win7下是否是管理员身份运行

    原文:C# WinForm判断Win7下是否是管理员身份运行 如果程序不是以管理员身份运行,操作本地文件会提示:System.UnauthorizedAccessException异常 Vista 和 ...

  9. [原创]Win7、Win8、Win10始终以管理员身份运行程序。

    在Win7.Win8.Win10系统中,以管理员身份运行程序很麻烦,一般有以下几种方式: 1.在可执行程序或快捷方式上右键,以管理员身份运行: 2.在可执行程序或快捷方式上右键->属性-> ...

随机推荐

  1. 常用的JavaScript模式

    模式是解决或者避免一些问题的方案. 在JavaScript中,会用到一些常用的编码模式.下面就列出了一些常用的JavaScript编码模式,有的模式是为了解决特定的问题,有的则是帮助我们避免一些Jav ...

  2. ajax使用serialize()序列化提交

    form 表单使用.serialize()序列化后会出现中文乱码的问题 原因: .serialize()自动调用了encodeURIComponent方法将数据编码了 解决方法: 调用decodeUR ...

  3. jquery图片时钟

    一.生成数字时钟 <script src="http://code.jquery.com/jquery-latest.js"></script> <s ...

  4. [转]Java 常用排序算法/程序员必须掌握的 8大排序算法

    本文转自:http://www.cnblogs.com/qqzy168/archive/2013/08/03/3219201.html 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插 ...

  5. laravel administrator 一款通用的后台插件(PHP框架扩展)

    前几天我看了一下zend framework 2的一些官方文档,也找了一些例子,可惜所有的资料少之甚少.于是我就开始去找这国外用的比较流行的PHP框架laravel,希望能够找到其合适的例子,而且我本 ...

  6. VIJOS1240 朴素的网络游戏[DP]

    描述 佳佳最近又迷上了某款类似于虚拟人生的网络游戏.在游戏中,佳佳是某旅行团的团长,他需要安排客户住进旅馆.旅馆给了佳佳的旅行团一个房间数的限制.每一个房间有不同的容纳人数和价钱(这个价格是房间的总价 ...

  7. ArrayList如何实现线程安全

    一:使用synchronized关键字,这个大家应该都很熟悉了,不解释了: 二:使用Collections.synchronizedList();使用方法如下: 假如你创建的代码如下:List< ...

  8. sql索引的填充因子多少最好,填充因子的作用?

    当创建一个新索引,或重建一个存在的索引时,你可以指定一个填充因子,它是在索引创建时索引里的数据页被填充的数量.填充因子设置为100意味着每个索引页100%填满,50%意味着每个索引页50%填满. 如果 ...

  9. PHP中文名文件下载实现

    php下载文件的流程: 其实就是给予一个链接:  <a href="指向处理文件的地址"></a> 这样,当前端点击链接的时候,指向处理文件,比如downl ...

  10. oracl函数

    一:大小写函数 1:lower()全部小写 select lower('HEHE') lowerwords from dual 2:upper()全部大写 3:initcap()首字母大写 4:con ...