用户和组 -- 系统的“身份证”体系
三类用户
Linux 把用户分为三种角色:
| 类型 | 说明 | 例子 |
|---|---|---|
| 超级用户 | 系统的上帝,什么都能干 | UID=0 |
| 普通用户 | 日常使用的账户,受限 | UID ≧ 1000 (通常) |
| 系统用户 | 给程序/服务用的,不能登录 | UID 通常在 1 - 999 |
UID (User ID) 是系统识别用户的唯一编号。用户名只是给人看的”昵称“,系统内部只用数字 UID。
组(Group) --- "俱乐部"的盖面
每一个用户可以属于多个组,就像一个人可以参加多个俱乐部。
- 主组(Primary Group) :用户创建文件时,文件默认属于这个组
- 附加组((Supplementary Groups) :用户额外加入的组,获得这些组的权限
关键配置文件
系统通过两个纯文本来管理用户和组:
/etc/passwd --- 用户列表(任何人可读):
root:x:0:0:root:/root:/bin/bash
alice:x:1000:1000:Alice:/home/alice:/bin/bash
nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin
格式: 用户名:密码占位符:UID:GID:描述:home 目录:Shell
密码不在 /etc/passwd 里,真正的密码哈希在 /etc/shadow
/etc/group --- 组列表:
root:x:0:
docker:x:993:alice,bob
wheel:x:10:alice
格式:组名:密码占位符:GID:成员列表
登录方式
本地终端登录(TTY)
服务器通常是没有图像界面的,开机后会看到登录提示:
login:
输入用户名 ➙ 回车 ➙ 输入密码(输入时不显示任何字符) ➙ 回车 ➙ 登录成功
登录成功后,系统会:
- 读取 home 目录(如
/home/alice) - 加载 shell(通常是
/bin/bash) - 执行 启动脚本 (
~/.bashrc、~/.profile等 )
SSH 远程登录( 最常用 )
通过 SSH 协议从另一台电脑连接到服务器:
ssh username@ServerIP
密码登录 (更安全,推荐):
# 本地生成密钥对
ssh-keygen -t ed25519 -C "Mr.MudBean@outlook.com"
# 将公钥传到服务器
ssh-copy-id username@ServerIP
## 传特定名称的密钥
ssh-copy-id -i ~/.ssh/[密钥名称].pub username@ServerIP
之后就可以免密登录了。
图形界面登录
如果是带桌面的 Linux(如 Ubuntu Desktop ),就是普通的图像化登录界面,输入用户名和密码即可。
切换用户
su --- Switch User(切换用户)
su # 切换到 root(需要输入 root 密码)
su - # 切换到 root,并加载 root 的环境(推荐)
su - alice # 切换到 alice 用户,并加载 alice 的环境
su alice # 切换到 alice 用户,但保留当前环境变量
两种方式的区别:
| 命令 | 效果 | 通俗理解 |
|---|---|---|
su alice | 仅切换身份,不加载 alice 的环境 | 换个马甲接着干 |
su - alice | 切换身份,同时加载 alice 的 home 目录和环境变量 | 完全变成 alice 这个人 |
# 当前是 alice,环境变量 HOME=/home/alice
$ echo $HOME
/home/alice
$ su bob
Password: [输入 bob 的密码]
$ echo $HOME
/home/alice # ❌ HOME 还是 alice 的!因为没用 -
$ exit
$ su - bob
Password: [输入 bob 的密码]
$ echo $HOME
/home/bob # ✅ 现在才是 bob 的环境
sudo --- SuperUser DO (以其他用户身份执行命令)
sudo 不是“切换用户”,而是“借用某个用户的权限来执行特定的命令”。
sudo command # 以 root 身份执行 command
sudo -u postgres psql # 以 postgres 用户身份执行 psql
sudo -u nginx ls /var/log/nginx # 以 nginx 用户身份列出日志
为什么现代系统推荐 sudo 而不是 su :
- 不需要分享 root 密码 :管理员只需要把自己的账户加入 sudo 组即可,不用把 root 密码告诉所有人
- 操作可追溯 :日志里清清楚楚写着 “xxx 在什么时候执行了什么命令”
- 权限最小化 :可以通过配置权限某个用户只能执行特定的命令
配置哪些用户能用 sudo :
编辑 /etc/sudoers(必须使用 visudo 命令,有语法检查):
# 允许 wheel 组的所有成员使用 sudo
%wheel ALL=(ALL) ALL
# 允许 alice 以 root 身份执行所有命令
alice ALL=(ALL) ALL
# 允许 bob 只能重启 Nginx,不能干别的
bob ALL=(root) /usr/bin/systemctl restart nginx
查看和修改超时时间:
# 查看当前时间戳
sudo -v # 刷新时间戳(不需要重新输入密码,只是延长有效期)
# 强制清除缓存(下次 sudo 需要重新输入密码)
sudo -k
# 查看配置中的超时时间
sudo cat /etc/sudoers.d/* 2>/dev/null || grep timestamp_timeout /etc/sudoers
login 命令(较少用)
login # 重新登录
login alice # 以 alice 身份重新登录
这会启动一个新的登录会话,效果类似于注销当前用户再重新登录。
退出当前会话
exit # 退出当前 shell(如果是最外层,则断开连接)
logout # 等同 exit(仅适用于 login shell)
Ctrl+D # 等同 exit 的快捷键
查看当前身份信息
whoami # 我是谁?→ 输出当前用户名
id # 详细信息:UID、GID、所属组
groups # 我属于哪些组?
添加账户
# 方法一:useradd(底层命令,需要手动配置)
useradd -m -s /bin/bash MudBean
# -m:自动创建家目录 /home/MudBean
# -s /bin/bash:指定登录 shell
# 设置密码
passwd MudBean
# 然后输入两次密码
# 方法二:adduser(交互式,更友好,Ubuntu/Debian 推荐)
adduser MudBean
# 会一步步引导你输入密码、全名等信息,自动创建家目录
创建后验证:
id MudBean # 查看用户信息
ls /home/MudBean # 确认家目录存在
给用户赋予 sudo 权限
# Ubuntu / Debian 系列(将用户加入 sudo 组)
usermod -aG sudo MudBean
# CentOS / RHEL 系列(将用户加入 wheel 组)
usermod -aG wheel MudBean
查看 sudo 权限
## 查看当前用户的权限
sudo -l
## 查看指定用户的权限
sudo -l -U [用户名]
## 查看用户所属的组
groups [用户名]
## 全面检查
id [用户名]
## 使用 getent
getent group sudo
### 或者 CentOS/RHEL 系统
getent group wheel
删除用户
# 删除用户,但保留家目录
userdel MudBean
# 删除用户及其家目录(彻底清除)
userdel -r MudBean
# 强制删除(即使用户正在登录)
userdel -f MudBean
如果要删除用户的同时移除其 sudo 权限(虽然用户都没了):
# 从 sudo 组中移除(如果手动配置过)
gpasswd -d MudBean sudo
禁止 root 远程登录(强烈建议)
创建好普通账户并测试能正常 sudo 之后,可以禁用 root 远程登录 SSH ,提高安全性:
# 编辑 SSH 配置文件
vim /etc/ssh/sshd_config
# 找到并确保以下行存在且设置为 no
PermitRootLogin no
# 重启 SSH 服务使配置生效
systemctl restart sshd
遵循原则
步骤1:创建普通用户
步骤2:设置密码
步骤3:赋予 sudo 权限
步骤4:测试该用户能正常 SSH 登录 + 能正常使用 sudo
步骤5:【确认无误后】才禁止 root 远程登录
具体操作:
# === 步骤1-3:在 root 会话中执行 ===
adduser alice
passwd alice
usermod -aG sudo alice
# === 步骤4:另开一个 SSH 窗口测试(千万别关当前的 root 会话!)===
# 在新窗口中:
ssh alice@服务器IP
# 登录成功后:
sudo whoami
# 应该输出 root
# === 只有测试通过后,才执行步骤5 ===
vim /etc/ssh/sshd_config
# 设置 PermitRootLogin no
systemctl restart sshd
# 此时原 root SSH 会话还在!万一出问题可以回滚
永远保持当前的 root SSH 会话开着,直到测试完毕
补救措施
通过云服务商的控制台(最常见)
如果你用的是云服务器(阿里云、腾讯云、AWS、DigitalOcean 等):
- 登录云服务商的管理控制台
- 找到这台服务器 → VNC 控制台 或 救援模式
- 通过 VNC 直接进入服务器的本地终端(绕过 SSH)
- 以 root 身份登录
- 创建普通用户并赋予 sudo 权限
- 或者直接改回
PermitRootLogin yes,然后systemctl restart sshd
单用户模式(适用于有控制台权限的情况)
- 重启服务器
- GRUB 菜单时按 e编辑启动项
- 在 linux行末尾加上
init=/bin/bash - 启动后以 root shell 直接进入(无需密码)
- 重新挂载文件系统为可写:
mount -o remount,rw / - 创建用户或修改 SSH 配置
查看当前用户
# 查看当前有哪些用户登录着
who
# 输出示例:
# alice pts/0 2025-05-22 10:00 (192.168.1.100)
# alice pts/1 2025-05-22 11:30 (192.168.1.100) ← 同一个人,第二个会话
# bob pts/2 2025-05-22 12:00 (192.168.1.200)
# 更详细的信息
w
# 可以看到每个用户正在执行什么命令
# 查看当前所有进程及其所属用户
ps aux | head -20
查看当前账户数
查看 /etc/passwd :
# 统计系统中总共有多少个用户(包括系统用户和普通用户)
wc -l /etc/passwd
# 输出:42 /etc/passwd ← 表示有 42 个账户
# 查看所有账户列表
cat /etc/passwd
# 只看用户名那一列
cut -d: -f1 /etc/passwd
# 统计有多少个普通用户(UID ≥ 1000)
awk -F: '$3 >= 1000 {print $1}' /etc/passwd
# 统计有多少个系统用户(UID < 1000)
awk -F: '$3 < 1000 {print $1}' /etc/passwd | wc -l
使用 getent 命令:
# 列出所有用户
getent passwd
# 统计总数
getent passwd | wc -l
查看哪些用户有登录权限
# 查看可以登录的系统用户(shell 不是 /sbin/nologin 或 /bin/false)
grep -v '/sbin/nologin\|/bin/false' /etc/passwd
# 或者更直接地查看 /etc/passwd 中有哪些用户的 shell 是正常的
awk -F: '$7 != "/sbin/nologin" && $7 != "/bin/false" {print $1, $7}' /etc/passwd
查看当前活跃会话
# 当前有哪些用户登录着(可能有多个会话)
who | cut -d' ' -f1 | sort -u
查看日志
查看登录日志
# 查看当前登录的用户
who
# 输出示例:
# alice pts/0 2025-05-22 10:00 (192.168.1.100)
# bob pts/1 2025-05-22 11:30 (192.168.1.200)
# 更详细的当前登录信息(包括正在执行的命令)
w
# 查看所有用户的登录历史(包括失败的)
last
# 输出:用户名、终端、来源IP、时间
# 查看失败的登录尝试(暴力破解的可疑记录)
lastb
# 需要 root 权限(查看最多的 ip )
sudo lastb | awk '{print $3}' | sort | uniq -c | sort -nr | head -10
# 查看上次登录信息(每次登录后会显示)
lastlog
查看 sudo 操作日志
# Ubuntu/Debian 系统
sudo cat /var/log/auth.log | grep sudo
# CentOS/RHEL 系统
sudo cat /var/log/secure | grep sudo
# 只看最近的 sudo 操作
sudo tail -50 /var/log/auth.log | grep sudo
## CentOS/RHEL 系统
sudo tail -50 /var/log/secure | grep sudo
查看系统日志
# 使用 journalctl(systemd 系统的统一日志工具)
# 查看所有日志(实时滚动)
sudo journalctl -f
# 查看最近的 100 条日志
sudo journalctl -n 100
# 查看指定服务的日志
sudo journalctl -u nginx
sudo journalctl -u mysql
sudo journalctl -u docker
sudo journalctl -u sshd -n 30 --no-pager
# 查看今天的日志
sudo journalctl --since today
# 查看指定时间段的日志
sudo journalctl --since "2025-05-22 09:00:00" --until "2025-05-22 12:00:00"
# 只看错误日志
sudo journalctl -p err
查看命令历史记录
# 查看当前用户的命令历史
history
# 查看 alice 的命令历史(需要 alice 的权限或 root)
sudo cat /home/alice/.bash_history
# 或者切换到 alice 查看
sudo su - alice
history
安全防护
禁止 root SSH 登录
详细见禁用 root
sudo vim /etc/ssh/sshd_config
# 找到并确保:
PermitRootLogin no
# 重启 SSH
sudo systemctl restart sshd
改用密钥登录,禁止密码登录
# 在本地电脑生成密钥对
ssh-keygen -t ed25519 -C "alice@server"
# 把公钥传到服务器
ssh-copy-id alice@服务器IP
ssh-copy-id -i ~/.ssh/[自定义密钥名称].pub alice@服务器IP
# 验证密钥登录是否正常
ssh alice@服务器IP
# 应该不需要输入密码就直接登录了
# 确认没问题后,禁用密码登录
sudo vim /etc/ssh/sshd_config
# 设置:
PasswordAuthentication no
# 重启
sudo systemctl restart sshd
自动封禁恶意 IP
# 1. 卸载 fail2ban(保留配置选 no,或者干脆删掉)
sudo yum remove fail2ban -y
sudo yum remove fail2ban* -y
# 2. 手动清理残留配置(确保干净)
sudo rm -rf /etc/fail2ban
sudo yum install epel-release -y
sudo yum install fail2ban -y
# 创建本地配置
sudo vim /etc/fail2ban/jail.local
### 以下为配置
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
bantime = 3600
findtime = 600
maxretry = 3
backend = auto
[sshd]
enabled = true
filter = sshd
port = ssh # 如果更改了 port ,这里需要更改
logpath = /var/log/secure
maxretry = 3
####
# 编辑配置,确保 SSH 防护开启
sudo vim /etc/fail2ban/jail.local
# 找到 [sshd] 部分,确保:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
# 启动
sudo systemctl start fail2ban
# 设置开机器自启
sudo systemctl enable fail2ban
# 重启 fail2ban
sudo systemctl restart fail2ban
# 查看状态
sudo systemctl status fail2ban
# 查看启用了什么防护监狱
sudo fail2ban-client status
# 查看被封禁的 IP
sudo fail2ban-client status sshd
# 手动解封某个被误封的 IP
sudo fail2ban-client set sshd unbanip [需要解封的IP地址]
## 查看配置的正则表达式能否抓取日志中的攻击记录
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
修改 SSH 端口
sudo vim /etc/ssh/sshd_config
# 找到 Port 22,改成其他端口(如 2222)
Port 2222
sudo systemctl restart sshd
配置防火墙,只允许特定 IP 访问 SSH
# 只允许你的办公网络/家庭网络访问 SSH
sudo ufw allow from 你的公网IP to any port 22
# 或者只允许特定端口范围
sudo ufw allow 2222/tcp
验证状态
# 看看还有没有新的失败尝试
sudo tail -f /var/log/auth.log | grep "Failed password"
# 查看 fail2ban 是否在工作
sudo fail2ban-client status
# 查看被封禁的 IP
sudo fail2ban-client status sshd
示例
安装
安装 Docker 是系统级操作,因为:
- 需要安装系统包(
apt install docker.io或添加 Docker 官方源) - 需要在
/etc/systemd/下创建服务配置 - 需要启动
dockerd守护进程 - 会创建
/var/run/docker.sock
安装这一步,必须用 root 或 sudo,绕不过去。
# 安装 Docker(需要 sudo)
sudo apt update
sudo apt install docker.io
# 或者安装 Docker CE(官方版)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
开启权限
只要你的普通用户在 docker组里,就能直接和 Docker daemon 通信,不需要 sudo!
# 假设 alice 是你的普通用户
# 1. 把 alice 加入 docker 组
sudo usermod -aG docker alice
# 2. alice 需要重新登录(或执行 newgrp docker)让组生效
# 注销当前 SSH 会话,重新登录
# 3. 验证
docker ps # 不需要 sudo 了!
docker compose up -d # 也不需要 sudo!
加入 docker组后,alice 就能读写 /var/run/docker.sock,从而直接和 Docker daemon 对话。daemon 本身以 root 运行,所以执行 docker ps时,虽然是 alice 发起的命令,但实际是在 root 权限的 daemon 中执行的。
文件操作
/srv/docker/ 目录如果是 root 创建的,默认权限是 755(rwxr-xr-x) ,这意味着:
| 操作 | alice 能不能做 |
|---|---|
cd /srv/docker | ✅ 能(有 x 权限) |
ls /srv/docker | ✅ 能(有 r 权限) |
vim docker-compose.yml (写入文件) | ❌ 不能(没有 w 权限) |
mkdir newProject (创建目录) | ❌ 不能 |
可以:
- 把目录的 owner 改成 alice:
sudo chown -R alice:alice /srv/docker# 之后 alice 对这个目录就有完全控制权了
- 把目录的组改成 docker,并给组写权限
sudo chown -R root:docker /srv/dockersudo chmod -R g+w /srv/docker# alice 因为在 docker 组里,自然就有写权限了
- 给 Others 加写权限(不推荐,太宽松)
sudo chmod -R 757 /srv/docker# 任何人都能写,不安全
完整流程
【一次性操作,用 root/sudo】
1. 安装 Docker
2. 创建普通用户 alice
3. 把 alice 加入 sudo 组(方便应急)
4. 把 alice 加入 docker 组(免 sudo 使用 Docker)
5. 创建项目目录并设置归属
sudo mkdir -p /srv/docker/myproject/{nginx,gin,mysql,static}
sudo chown -R alice:alice /srv/docker
【日常操作,alice 登录】
6. cd /srv/docker/myproject
7. 上传/编辑 docker-compose.yml 和配置文件
8. docker compose up -d ← 不需要 sudo!
9. docker compose logs -f ← 也不需要 sudo!
10. docker ps ← 也不需要 sudo!
# === 在服务器上(root 或有 sudo 权限执行)===
# 1. 创建 alice 的目录结构
sudo mkdir -p /srv/alice/docker
# 2. 设置 owner
sudo chown -R alice:alice /srv/alice
# 3. 设置权限(推荐 750 或 700)
sudo chmod 750 /srv/alice
# 或者更严格的:
sudo chmod 700 /srv/alice
# 4. 验证
ls -ld /srv/alice
# 应该看到:drwxr-x--- alice alice /srv/alice
# 或者: drwx------ alice alice /srv/alice
# === 然后 alice 可以自己操作了 ===
# (alice 登录后)
mkdir -p /srv/alice/docker/myproject/{nginx,gin,mysql,static}
cd /srv/alice/docker/myproject
# 开始干活...