跳到主要内容

用户和组 -- 系统的“身份证”体系

三类用户

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 登录

# 在本地电脑生成密钥对
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/docker
    sudo 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
# 开始干活...