核心概念:主組 vs 附屬組
| 屬性 | 主組 (Primary Group) | 附屬組 (Supplementary Groups) |
| 數量 | 每用戶僅 1 個 | 可屬多個 (上限 65535) |
| 新建文件預設組 | 是 | 否 |
| /etc/passwd 欄位 | 第 4 欄 (GID) | 不在 passwd 中 |
| /etc/group 記錄 | 組記錄中包含用戶 | 組記錄中包含用戶 |
usermod 三大核心用法
1. 修改主組(-g):強制指定,舊主組自動移除
usermod -g newgroup username
# 例:將 user1 主組改為 developers
usermod -g developers user1
⚠️ 慎用:用戶原主組建立的文件組屬不會自動變更,需配合 chgrp -R 手動修正。
2. 替換所有附屬組(-G):覆蓋模式,舊附屬組全部清除
usermod -G group1,group2,group3 username
# 例:user1 僅屬於 docker, k8s 兩個附屬組
usermod -G docker,k8s user1
3. 追加附屬組(-a -G):非破壞性新增,保留原附屬組
usermod -a -G newgroup username
# 例:為 user1 新增監控權限
usermod -a -G monitoring user1
✅ 生產環境首選:避免誤刪除關鍵附屬組(如 wheel、docker、sudo)。
完整參數速查表
| 參數 | 功能 | 範例 |
-c | 修改備註 (GECOS) | usermod -c "Zhang San" zhangsan |
-d | 修改家目錄 | usermod -d /home/newdir -m user1 (-m 同步移動內容) |
-e | 設定帳號過期日期 (YYYY-MM-DD) | usermod -e 2025-12-31 user1 |
-f | 密碼過期後緩衝天數 (-1 永不鎖定) | usermod -f 30 user1 |
-l | 修改用戶名 | usermod -l newname oldname |
-s | 修改登入 Shell | usermod -s /bin/zsh user1 |
-u | 修改 UID | usermod -u 2000 user1 |
-L | 鎖定帳號 (在 /etc/shadow 密碼前加 !) | usermod -L user1 |
-U | 解鎖帳號 | usermod -U user1 |
驗證修改結果
id username
# 輸出:uid=1000(user1) gid=1001(developers) groups=1001(developers),998(docker),999(k8s),997(monitoring)
# gid 為主組,groups 列出所有附屬組
常見坑點與避雷指南
| 操作 | 風險 | 對策 |
usermod -G 忘加 -a | 清空所有附屬組,導致 Docker、sudo、VPN 等權限瞬失 | 肌肉記憶:永遠 -a -G 成對使用 |
| 修改主組後文件組屬不一致 | find /home/user1 -group oldgroup 執行 chgrp | 規劃階段確定主組,避免後續變更 |
| 修改 UID/GID | 文件擁有者顯示數字而非用戶名,服務啟動失敗 | 極少修改;必改時全盤 find / -uid old -exec chown new {} \; |
| 鎖定帳號 (-L) 但 SSH 金鑰仍可登入 | -L 僅鎖密碼,不影響公鑰認證 | 需同時 usermod -s /sbin/nologin 或鎖定 SSH 金鑰 |
批量管理腳本範例
#!/bin/bash
# 為所有開發人員統一新增 docker 權限
for user in $(getent group developers | cut -d: -f4 | tr ',' ' '); do
usermod -a -G docker "$user"
echo "Added docker to $user"
done
總結
- 主組變更:
usermod -g,謹慎,影響文件預設組屬
- 附屬組替換:
usermod -G,全量覆蓋,極易誤傷
- 附屬組新增:
usermod -a -G,**日常運維 99% 場景的正確姿勢**
- 驗證:
id username 一條命令看透一切