Quản lý user và sudo trên Linux: mô hình quyền an toàn cho server

Mô hình quản lý user và sudo Linux an toàn: user cá nhân, group theo vai trò, SSH key, quyền tối thiểu, audit và offboarding.

NHT
· 10 phút đọc
Mô hình quyền Linux với user cá nhân group sudo SSH key và service account an toàn

Quản lý user và sudo trên Linux là phần cốt lõi của mô hình quyền an toàn cho server. Khi nhiều người dùng chung root, log không còn cho biết ai đã thay đổi firewall, xóa file hay restart database. Khi cấp sudo quá rộng, một tài khoản ứng dụng bị lộ cũng có thể trở thành toàn quyền hệ thống.

Bài viết này dùng Ubuntu Server làm ví dụ, nhưng nguyên tắc áp dụng cho nhiều bản Linux: mỗi người có account riêng, quyền được cấp theo vai trò, thao tác quản trị đi qua sudo, SSH dùng key, group membership được rà soát và không xóa tài khoản quản trị cuối cùng khi chưa có phiên dự phòng.

Mô hình thực dụng: user cá nhân đăng nhập bằng SSH key, dùng `sudo` cho lệnh cần quyền cao, service chạy bằng system user riêng, thư mục dữ liệu có group rõ ràng và quyền được kiểm tra sau mỗi lần thay đổi. Root là cơ chế khôi phục, không phải account làm việc hằng ngày.

1. Root, user thường và system user khác nhau thế nào?

Root có UID 0 và bỏ qua phần lớn kiểm tra quyền thông thường. User thường đại diện cho người vận hành, thường có UID từ 1000 trở lên. System user phục vụ daemon như web server, database hoặc agent; chúng không nên có shell đăng nhập tương tác nếu không cần. Phân biệt ba loại này giúp bạn tránh chạy ứng dụng bằng root.

Loại accountMục đíchNguyên tắc
rootKhôi phục và tác vụ hệ thống đặc biệtKhông dùng đăng nhập hằng ngày; bảo vệ console và password
User cá nhânSSH, deploy, vận hành và auditMột người một account, key riêng, sudo có kiểm soát
System userChạy daemon hoặc ứng dụngKhông cấp sudo; shell và home tối thiểu
Service accountTác vụ tự động theo vai tròToken/key giới hạn scope, rotate và revoke được

Ubuntu mặc định vô hiệu hóa password của root và khuyến khích dùng sudo cho tác vụ quản trị [1]. Việc này không có nghĩa root bị xóa; nó giảm khả năng đăng nhập trực tiếp bằng một username phổ biến. Nếu nhà cung cấp yêu cầu root qua console, hãy giới hạn kênh đó và không dùng root làm identity chung cho cả team.

2. Liệt kê user và group mà không hiểu nhầm dữ liệu NSS

File `/etc/passwd` và `/etc/group` chứa các local account cơ bản. Lệnh `getent passwd` có thể trả cả nguồn từ NSS như LDAP hoặc Active Directory, nên trên hệ thống doanh nghiệp kết quả có thể lớn hơn local users. Hãy xác định bạn đang audit local account hay toàn bộ identity provider trước khi kết luận.

# Local users và UID
cut -d: -f1,3 /etc/passwd

# User hiện tại và các group hiệu lực
whoami
id

# Liệt kê thành viên group sudo
getent group sudo

# Kiểm tra các user có shell tương tác
awk -F: '$7 ~ /(bash|zsh|fish)$/ {print $1, $3, $7}' /etc/passwd

Đừng xóa system user chỉ vì thấy nó trong `/etc/passwd`. Nhiều daemon cần account riêng để giới hạn tác động nếu service bị khai thác. Trước khi xóa một user, kiểm tra process, cron, file ownership, SSH key và dữ liệu còn lại thuộc account đó.

3. Tạo user cá nhân và cấp sudo đúng cách

Ubuntu khuyến khích dùng package `adduser` để quản lý local account. User mới nên có tên cá nhân hoặc role rõ ràng, home directory riêng, shell phù hợp và SSH key. Chỉ thêm vào group `sudo` sau khi xác định user đó thực sự cần quyền quản trị.

# Thực hiện bằng console hoặc một user admin hiện có
sudo adduser alice
sudo adduser alice sudo

# Mở một phiên SSH mới bằng alice rồi kiểm tra
id alice
sudo -l -U alice
sudo -u alice whoami

Sau khi tạo user mới, hãy test bằng một terminal khác trước khi đóng session admin hiện tại. Nếu cấp sudo thông qua group, quyền thường áp dụng khi user đăng nhập lại. Không sửa trực tiếp `/etc/sudoers` bằng editor thông thường; dùng `visudo` để kiểm tra cú pháp trước khi lưu.

sudo visudo

# Ví dụ group sudo mặc định trên Ubuntu, chỉ tham khảo:
# %sudo ALL=(ALL:ALL) ALL

# Kiểm tra cấu hình include
sudo visudo -c
sudo ls -la /etc/sudoers.d

4. Sudo hoạt động thế nào và vì sao cần audit?

Sudo cho phép user thực hiện một lệnh với identity khác, thường là root, sau khi policy xác nhận user, host, command và cách xác thực. Mọi thành viên group `sudo` thường có quyền rất rộng; đó là quyền quản trị toàn hệ thống chứ không phải một permission nhỏ. Vì vậy, thêm user vào group sudo phải được xem như cấp root có audit.

Cách cấp quyềnMức rủi roKhi dùng
Group sudo toàn quyềnCao nhưng dễ quản trịAdmin tin cậy, server nhỏ, cần break-glass có kiểm soát
Rule command cụ thểThấp hơn nếu thiết kế đúngDeploy service, restart một daemon, backup riêng
NOPASSWD cho mọi lệnhRất cao nếu key bị lộTránh dùng; chỉ cân nhắc cho command hẹp
System user không sudoThấp hơnWeb, queue, database và daemon cần quyền riêng

Không nên tạo rule `user ALL=(ALL) NOPASSWD: ALL` chỉ để pipeline chạy nhanh. Nếu bắt buộc pipeline restart service, giới hạn đúng executable, tham số và file cấu hình; sau đó kiểm tra bằng `sudo -l -U user` và log sudo. Quyền càng rộng, blast radius của private key hoặc token bị lộ càng lớn.

5. SSH key, authorized_keys và session an toàn

SSH key tách private key khỏi public key. Private key phải ở máy quản trị, có passphrase và permission chặt; public key mới được đặt trên server. Ubuntu khuyến nghị Ed25519 cho key mới. Khi thêm hoặc xóa key, phải biết key đó thuộc ai, dùng cho môi trường nào và cách revoke khi nhân sự thay đổi.

# Trên máy quản trị
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_alice
ssh-copy-id -i ~/.ssh/id_ed25519_alice.pub alice@SERVER_IP

# Trên server: kiểm tra quyền thư mục và file
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R alice:alice ~/.ssh

Sau khi thay đổi `/etc/ssh/sshd_config` hoặc snippet trong `/etc/ssh/sshd_config.d/`, chạy `sudo sshd -t` rồi mới reload/restart. Ubuntu cảnh báo rằng cấu hình sai có thể làm mất đường truy cập nếu SSH là phương thức duy nhất; hãy giữ console hoặc session dự phòng [2].

sudo sshd -t
sudo systemctl reload ssh.service
sudo journalctl -u ssh.service --since "10 minutes ago" --no-pager

# Kiểm tra user có thể đăng nhập trong terminal mới trước khi đóng terminal cũ
ssh -i ~/.ssh/id_ed25519_alice alice@SERVER_IP

6. Thiết kế group theo vai trò thay vì chmod tùy tiện

Group giúp nhiều user cùng làm việc trên một vùng dữ liệu mà không cần cấp root. Ví dụ, nhóm `webops` có thể sở hữu file deploy; nhóm `appdata` có quyền đọc/ghi vào thư mục upload. Hãy đặt owner/group rõ ràng, dùng setgid cho thư mục cộng tác khi cần và tránh `chmod -R 777`.

sudo groupadd --system webops
sudo usermod -aG webops alice
sudo install -d -o root -g webops -m 2770 /srv/app/shared

# Xác minh group sau khi user đăng nhập lại
id alice
namei -l /srv/app/shared
getfacl /srv/app/shared 2>/dev/null || true

Bit setgid trên thư mục khiến file/thư mục con kế thừa group của thư mục cha trong nhiều trường hợp. Tuy nhiên, permission cụ thể còn phụ thuộc umask và ứng dụng tạo file. Hãy thử bằng user thật trong staging, không suy luận chỉ từ mode string.

7. Quyền file, umask và service user

Web server không nên sở hữu toàn bộ source code nếu không cần ghi. Tách read-only code, writable storage, log và secret giúp giảm thiệt hại khi một process bị khai thác. Service user của PHP-FPM, Nginx, queue worker hoặc database cần quyền đúng thư mục và không nên nằm trong group sudo.

# Tìm file có owner root hoặc quyền ghi rộng trong application tree
sudo find /var/www/app -xdev -type f -perm /o+w -ls
sudo find /var/www/app -xdev -type d -perm /o+w -ls

# Kiểm tra process đang chạy dưới user nào
ps -eo user,pid,comm,args --sort=user | grep -E '(nginx|php-fpm|queue|mysql)' || true

Một số ứng dụng cần thư mục cache hoặc upload ghi được; hãy cấp quyền riêng cho các thư mục đó thay vì mở toàn bộ project. Secret như `.env`, SSH key và database credential cần owner phù hợp, mode chặt và không xuất hiện trong log hoặc artifact build.

8. Sudo tối thiểu cho deploy và vận hành

Nếu deploy cần restart một service, có thể thiết kế policy hẹp thay vì cấp toàn quyền. Đây chỉ là ví dụ khái niệm; tên đường dẫn và command phải khớp server thật. Đặc biệt, cần cân nhắc khả năng command đó cho phép truyền tham số nguy hiểm hoặc ghi đè file cấu hình.

# /etc/sudoers.d/deploy-app — kiểm tra bằng visudo -cf
Cmnd_Alias APP_SERVICE = /usr/bin/systemctl reload nginx.service
%webops ALL=(root) APP_SERVICE

Ngay cả rule hẹp cũng cần review định kỳ. Kiểm tra owner/mode của file executable, PATH, symlink và các service unit. Nếu một command gọi script writable bởi user thường, quyền “hẹp” trên sudoers có thể trở thành đường nâng quyền.

9. Lock, unlock, rotate và offboarding user

Khi nhân sự rời dự án hoặc key bị nghi lộ, khóa quyền truy cập trước rồi mới dọn dữ liệu. Xóa user ngay có thể làm mất log mapping hoặc khiến file orphan; trong nhiều trường hợp, lock password, revoke SSH key, remove khỏi group và archive home directory là quy trình an toàn hơn.

# Khóa password và xem trạng thái account
sudo passwd -l alice
sudo usermod -s /usr/sbin/nologin alice

# Gỡ khỏi group đặc quyền
sudo gpasswd -d alice sudo
sudo gpasswd -d alice webops

# Tìm process và file còn thuộc user trước khi xóa
pgrep -u alice -a || true
sudo find / -xdev -user alice -ls 2>/dev/null | head -100

Nếu cần xóa account, hãy xác minh không còn cron, systemd unit, deploy hook hoặc backup nào phụ thuộc. Luôn giữ một user admin khác và console recovery. Sau offboarding, rotate secret mà user đó từng có thể đọc; chỉ xóa account không làm credential trong `.env` tự vô hiệu.

10. Checklist audit user và sudo hàng tháng

  • Xuất danh sách user, UID, shell, last login và group đặc quyền.
  • Đối chiếu mỗi user với owner thực tế; khóa account không còn nhu cầu.
  • Kiểm tra thành viên group `sudo`, `adm`, `docker` và các group nhạy cảm khác.
  • Đọc `/etc/sudoers` và `/etc/sudoers.d/` bằng `visudo -c`, tìm rule NOPASSWD quá rộng.
  • Kiểm tra SSH authorized_keys, comment owner, ngày rotate và key đã revoke.
  • Tìm file world-writable, setuid bất thường và thư mục app writable bởi service không cần thiết.
  • Kiểm tra log sudo/SSH và cảnh báo login thất bại hoặc địa chỉ bất thường.
  • Test một phiên console/SSH dự phòng trước khi thay đổi chính sách truy cập.

Bạn có thể ghi checklist này vào runbook bàn giao cùng sơ đồ port và lịch backup. Khi thay đổi quyền, hãy ghi ticket hoặc commit cấu hình để người khác truy lại nguyên nhân. Đừng biến security thành một loạt lệnh copy-paste không có chủ sở hữu. Tham khảo thêm checklist bàn giao website production để nối phần quyền truy cập với quy trình vận hành.

11. Các lỗi phổ biến cần tránh

Dùng chung tài khoản root

Bạn mất audit trail và mọi private key đều có blast radius tối đa. Hãy tạo user cá nhân, dùng sudo và giữ root cho break-glass.

Thêm user vào group docker rồi xem như không nhạy cảm

Trên nhiều hệ thống, quyền truy cập Docker daemon có thể tương đương quyền root. Hãy xem group này là đặc quyền cao và audit như sudo.

Chạy chmod -R 777 để sửa lỗi permission

Lệnh này che giấu owner/group sai và mở ghi cho toàn bộ user. Hãy tìm process cần ghi, sửa owner/group và cấp mode hẹp cho đúng thư mục.

Đổi SSH rồi đóng session hiện tại ngay

Nếu rule sai, bạn có thể tự khóa mình. Luôn chạy `sshd -t`, mở terminal mới, test key, kiểm tra log rồi mới đóng session cũ.

12. Kết luận

Mô hình quyền an toàn trên Linux bắt đầu từ identity rõ ràng: user cá nhân cho người vận hành, system user cho daemon, group cho cộng tác và sudo cho tác vụ quản trị được audit. Kết hợp SSH key, least privilege, permission đúng, offboarding và kiểm tra định kỳ sẽ giảm đáng kể rủi ro từ credential bị lộ hoặc thao tác nhầm.

Đối với server mới, hãy hoàn thành bài 22 trước rồi dùng checklist bài này để rà user/sudo. Khi hệ thống lớn lên, chuyển policy thành code được review, giám sát log và thử khôi phục quyền bằng console dự phòng.

Nguồn tham khảo

[1] Ubuntu Server Documentation — User management; [2] Ubuntu Server Documentation — OpenSSH server.