了解 Linux root 帐户及使用 sudo
查看【Linux】专题可浏览更多内容
root 帐户是全能的管理用户,也称为超级用户帐户(superuser account)。
root 帐户的决定性特效是 UID 为 0。有些人会突发奇想一些操作,比如修改该帐户的用户名或者创建其他 UID 为 0 的帐户,这些操作是能做到但是可能会造成安全隐患,另外在于多人使用系统时也会造成他人的困惑,是不推荐的行为。
传统 UNIX 允许超级用户对所有文件和进程执行任何「正当」的操作,如:
- 创建设备文件;
- 设置系统时钟;
- 提高资源使用限额以及进程优先级;
- 设置系统主机名;
- 配置网络接口;
- 打开特权网络端口(编号小于 1024 的端口);
- 关闭系统
正确管理 root 帐户至关重要,因为不仅在系统管理时需要,同时也是系统安全的关键所在。
root 帐户登陆
大多数系统允许直接以 root 帐户登陆,但这其实是糟糕。首先,使用 root 登陆不会留下任何操作记录,所以当使用 root 操作后如果回想不起来做了什么就够呛了。其次使用 root 登陆当另一个问题是无法记录执行操作当主题是谁,也就是说如果不止一个人以 root 登陆,压根就分不清是谁这什么时候登陆当。
su:替换用户身份
目前访问 root 帐户一种较好的方式是使用 su
命令,如果不带任何参数来调用 su
命令后,会提示用户输入 root 密码然后启动一个 root shell:
su
在使用完毕后使用 exit
命令退出。
su
并不会记录 root 执行过的命令,但回创建一条日志记录是谁在什么时候替换成 root。
su
即「switch user」所以也可以用于替换其他用户身份,在命令后接上用户名即可:
su <用户名>
-l
选项可以进一步简写成连字符 -
,使用该选项会加载用户环境并将工作目录更改为该用户的主目录。
# 切换到 root
su -
# 或指定用户
su - <用户名>
也可以使用 su
命令执行单个命令,而不用启动一个全新的交互式Shell:
su -c 'apt upgrade'
采用这种形式,该命令行被传入新 Shell 执行,且注意需要执行的命令需要用英文引号包裹着。
在诊断用户所碰到的问题时,通过启动登陆 shell 有助于重现发生问题的环境。登陆 shell 具体以 shell 的种类而异,如 bash 作为登陆 shell 为例会读取 ~/.bash_profile
,而非登陆 shell 则会读取 ~/.bashrc
。
⚠️ 注意:在某些系统中会明确要求先使用
su
替换到 root 才能再使用su
切换到其他用户。
在 su
替换成 root 后切换到其他用户不需要提供密码,所以妥善管理 root 密码是很重要的。
另外在使用 su
时最好养成输入命令完整路径的习惯(如 /bin/su
或 /usr/bin/su
),不要依赖 shell 的帮助查找命令,(特别在有风险的系统上)以防那些打着 su 的旗号偷偷安插到 shell 搜索路径企图窃取密码的恶意程序。
sudo:受限版的 su
sudo 意为「super user do」,当非特权用户使用的命令提示权限问题时,在命令前加上 sudo
,很容易记住对不对?
目前推荐使用 sudo
作为访问 root 帐户的主要方式,而使用 su
命令切换到超级用户是在 sudo
出现损坏或错误配置时,作为替代解决方案。
可能有的发行版或者云计算服务商提供的系统默认并不带有 sudo
,这时候需要自行安装一下,以 Debian 为例:
apt install sudo
sudo
采用命令行作为参数然后以 root(或其他受限用户)身份执行。sudo
会读取配置文件 /etc/sudoers
,该文件中列出了被授权使用 sudo
的用户以及被允许在每台主机上运行的命令。如果执行给出的命令,sudo
会提示输入相应用户(而不是 root 帐户)的密码以执行该命令。
第一次执行 sudo 时会看到一份提示:
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
翻译过来就是:
我们相信你已经接受了当地系统管理员的例行讲座。通常归结为这三点。
1)尊重他人的隐私。
2)输入前三思而后行。
3)权力越大,责任越大。
在第一次成功执行 sudo
命令后的 5 分钟内的 sudo
命令不需要再次输入密码执行。这是一种避免造成安全隐患的超时机制,可自定义配置延长时间。
sudo
保留了一份日志,其中记录了运行过的命令、运行命令的主机、请求执行命令的用户、运行时所在的目录及什么时候运行的。这些信息会由 syslog 记录或写入指定的文件中。
sudo 的优劣
sudo
的优点:
- 拥有命令日志,因此显著提高了安全审计能力;
- 用户无需使用不受限制的 root 权限就可以执行特定任务;
- 可以极少数人甚至没人知道 root 密码;
- 使用
sudo
要比运行su
或以 root 身份登陆进入系统要快; - 不需要更改 root 密码即可收回特权;
- 可维护一个所有具有 root 权限用户的规范列表;
- 降低了把 root shell 暴露给别人的机会。
- 只用单个文件就可以控制整个网络的访问控制。
sudo
的缺点:
sudo
用户的个人帐户所存在的安全隐患等同于 root 帐户的安全隐患,突破了sudo
用户就相当于突破了 root 帐户的安全防线。sudo
的命令日志机制很容易被一些小花招搞定,例如在许可的程序中使用 shell 转义字符,或执行sudo sh
、sudo su
。
配置 sudo
配置 sudo
需使用 visudo
命令进,因为它可以验证文件语法以免配置错误,并且还能让单个版本的文件同时用在不同主机上。
visudo
下面是配置内容:
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
先从最简单的开始
# User privilege specification
root ALL=(ALL:ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
井号开头的行为注释内容不起实际作用,所以就上述两行内容而言,主要构成信息如下:
用户/用户组 主机=[(切换到哪些用户或组)] [是否需要输入密码验证] 命令1,命令2,...
进一步说明:
- 名为 root 的用户和名为 sudo 的用户组(在组名前加百分号表示用户组)
- ALL=(ALL:ALL) 的第一个 ALL 也就是等号前的「ALL」表示主机,可配置成当仅允许本地登录时使用的
localhost
当包括远程登录时使用的All
,或是指定主机名。 - 然后是等号后的括号「(ALL:ALL)」,表示的是切换到的用户或用户组,如果省略, 相当于(root:root),表示可以通过 sudo 替换成到 root 身份执行; 如果为 (ALL) 或者 (ALL:ALL), 表示能够替换到 (任意用户:任意用户组)。
- 最后的「ALL」表示为是否需要密码及指定的程序,不需要密码则在该段开头使用
NOPASSWD:
,允许所有程序为ALL
。否则填程序的绝对路径,多个程序以逗号隔开,排除的程序在路径开头使用感叹号。
也就是说,现在名为 root 的帐户和名为 sudo 用户组的用户可以在任意主机上执行任意受限命令,且需要密码。
2 个小例子
1.配置名为 tom 的用户可以使用目录 /usr/sbin/
下和目录 /sbin/
下的程序,除了程序 /usr/sbin/visudo
tom ALL=/usr/sbin/*,/sbin/*,!/usr/sbin/visudo
2.用户名为 jerry 的用户仅在本地主机登录时使用 sudo
命令且不需要输入密码
jerry localhost=(ALL) NOPASSWD: ALL
别名(alias)
# Host alias specification
Host_Alis SHIELD=hub, sandbox, fridge, slingshot, triskelion, academy
# User alias specification
User_Alis ADMINS=tom, jerry
# Cmnd alias specification
Cmnd_Alis DUMP=/usr/sbin/tcpdump
ADMINS ALL=(ALL:ALL) ALL
tom SHIELD=(ALL) ALL, !/usr/sbin/visudo
jerry ALL=NOPASSWD:DUMP
上述示例使用了别名规范,主要是 3 个作用:
- 用户别名中的 ADMINS 含有 tom 和 jerry 两个用户名,在下面
ALL=(ALL:ALL) ALL
应用到了别名用户组 ADMINS 上等同于应用到了 tom 和 jerry 两个用户。 - 用户 tom 可以在 SHIELD 主机别名中的主机使用除了
/usr/sbin/visudo
以外的命令。 - 用户 jerry 可以任意主机上不需要密码执行程序
/usr/sbin/tcpdump
💡 最后,一个很酷的小技巧,在运行命令后才发现需要
sudo
时怎么办呢?再运行一条命令:sudo !!
让非特权用户得以使用 sudo
看完了上面此时让你配置一个名为 tom 的用户,使得它可以使用 sudo 你会怎么做呢?除了在 root ALL=(ALL:ALL) ALL
下增加一条 tom ALL=(ALL:ALL) ALL
还有一个方法是把 tom 用户加入到名为 sudo 的用户组中。
⚠️ 需要注意的是,不是每个发行版的默认配置中赋予权限的用户组都叫 sudo,比如在 CentOS 中就叫做 wheel。
在 CentOS 安装时的创建用户步骤,会提供选项「将此用户作为管理员」,在勾选时就会将用户将入到 wheel 组中。
新建名为 tom 的用户:
adduser tom
Debian 将普通用户 tom 加入到 sudo 用户组:
usermod -aG sudo tom
CentOS 将普通用户 tom 加入到 wheel 用户组:
usermod -aG wheel tom
使用 sudo 切换到 root
sudo -i