DevOps

Quản lý user, sudo, permission và SSH keys theo nhóm 2026

Cập nhật 18/04/2026
quản lý user sudo permission và ssh keys theo nhóm

“Quản lý user, sudo, permission và SSH keys theo nhóm” là nội dung trong plan series VPS Ubuntu LTS. Ở vị trí này, bài này làm nhiệm vụ chuẩn hóa cách cấp quyền trên server sau khi đã vào máy an toàn ở bài “Kết nối SSH lần đầu: key-based login, known_hosts và anti-lockout 2026” và đã dọn lớp nền hệ điều hành ở bài “Cấu hình ban đầu Ubuntu LTS chuẩn production tối thiểu 2026“, trước khi bật firewall, cài web stack hay đi sâu vào hardening nâng cao ở các bài sau.

Một VPS có thể chạy ổn khi chỉ một người quản lý, nhưng rất nhanh trở nên lộn xộn khi bắt đầu có thêm cộng tác viên, dev, hoặc chính bạn quay lại sau vài tháng mà không còn nhớ user nào có quyền gì, thư mục nào thuộc về ai, và vì sao sudo lúc được lúc không. Ubuntu Server docs hiện vẫn nhấn mạnh dùng sudo thay cho việc làm việc bằng root thường xuyên, còn OpenSSH và sudoers đều có sẵn cơ chế để tách quyền rõ ràng nếu bạn làm đúng từ đầu.

Mục tiêu của bài này không phải là thêm thật nhiều user cho “có vẻ chuyên nghiệp”, mà là thiết lập một mô hình đơn giản nhưng bền: mỗi người có tài khoản hoặc ít nhất có SSH key riêng, quyền quản trị đi qua sudo, SSH chỉ mở cho đúng nhóm cần vào máy, và quyền file được thiết kế theo vai trò thực tế thay vì sửa lỗi bằng chmod 777. Ubuntu docs cũng ghi rõ home directory của user mới trên các bản Ubuntu hiện đại được tạo với quyền riêng tư 0750 theo mặc định, cho thấy Canonical đang đi theo hướng an toàn hơn ngay từ tầng user management.

1. Mục tiêu sau bài học

Sau khi làm xong bài A6, người đọc nên hiểu được bốn lớp thường bị trộn lẫn vào nhau khi quản trị server: user và group dùng để nhận diện người hoặc tiến trình, sudo dùng để cấp quyền nâng cao theo chính sách, ownership dùng để xác định ai sở hữu file, còn permission bits dùng để xác định ai được đọc, ghi hoặc thực thi. Các lớp này liên quan chặt chẽ với nhau nhưng không thay thế cho nhau. chown đổi chủ sở hữu và group của file, còn chmod đổi mode bits; bản thân hai lệnh này giải quyết hai bài toán khác nhau.

2. Vì sao “Quản lý user, sudo, permission và SSH keys theo nhóm” nên tách riêng khỏi A4 và A7

“A4 – Kết nối SSH lần đầu: key-based login, known_hosts và anti-lockout 2026” tập trung vào việc vào máy an toàn bằng SSH key và tránh tự khóa mình, còn “A7 – Firewall và cập nhật tự động: UFW + unattended-upgrades” mới là nơi hợp lý để nói trọn vẹn về UFW và automatic updates. Bài này nằm giữa vì quản lý user và quyền là lớp nền của mọi bước phía sau: nếu user admin, group, SSH key và ownership chưa sạch, thì đến lúc cài Nginx, PHP-FPM, backup hay monitoring bạn sẽ gặp lỗi permission chồng chéo rất khó debug.

3. Mô hình thực tế phù hợp cho đa số VPS nhỏ và vừa

Với phần lớn VPS chạy website, API, blog hoặc môi trường staging, một mô hình rất dễ bảo trì là thế này: có một hoặc vài user quản trị dùng sudo, mỗi người có SSH key riêng, root không dùng như tài khoản làm việc hằng ngày, SSH chỉ cho những user hoặc group cần thiết đăng nhập, còn code hoặc webroot được sở hữu theo vai trò rõ ràng giữa người deploy và tiến trình web.

Ubuntu docs ghi rõ user đầu tiên được tạo khi cài Ubuntu mặc định nằm trong group sudo, và muốn cấp full root access qua sudo cho user khác thì chỉ cần thêm họ vào group này. Đồng thời, Ubuntu cũng hướng dẫn có thể giới hạn SSH bằng AllowGroups, ví dụ tạo group sshlogin rồi chỉ những ai thuộc group đó mới được phép SSH vào máy.

Điểm cần tránh là dùng một tài khoản chung cho cả đội. Về kỹ thuật thì vẫn chạy được, nhưng bạn sẽ mất gần như toàn bộ khả năng audit ai đã làm gì. sudoers được thiết kế theo hướng chính sách theo user và theo command; chính tài liệu sudoers(5) cũng mô tả sudo là cơ chế xác định ai được chạy gì dựa trên policy trong /etc/sudoers và các file include liên quan. Khi mọi người dùng chung một tài khoản, lợi ích audit này gần như biến mất.

4. Phân biệt rõ user, group, sudo và permission

4.1. User và group là lớp nhận diện

Ubuntu khuyến nghị dùng adduser để quản lý account cục bộ trên các hệ Debian/Ubuntu. Tạo user bằng sudo adduser username, tạo group bằng sudo addgroup groupname, và thêm user vào group bằng sudo adduser username groupname. Đây là cách quản lý dễ đọc, ít gây nhầm hơn so với việc nhớ quá nhiều cờ lệnh thấp hơn.

Group đặc biệt hữu ích khi bạn cần biểu diễn “vai trò” thay vì “một người”. Ví dụ, bạn có thể có group sshlogin cho người được SSH vào server, group deploy cho người được cập nhật mã nguồn, hoặc tận dụng group www-data của web server để cho tiến trình web đọc được code. Chính Ubuntu docs dùng ví dụ sshlogin để giới hạn SSH access, cho thấy group là công cụ rất tự nhiên cho các policy kiểu này.

4.2. sudo là lớp nâng quyền, không phải tài khoản riêng

sudoers(5) mô tả rất rõ: policy của sudo được điều khiển bởi /etc/sudoers hoặc các nguồn policy tương đương; mặc định hầu hết user phải xác thực trước khi dùng sudo, và khi sudo yêu cầu xác thực thì nó kiểm tra credential của user đang gọi lệnh, không phải mật khẩu root. Đây là khác biệt quan trọng so với tư duy “biết root password là xong”.

Điều này tạo ra hai lợi ích thực tế. Một là trách nhiệm thao tác gắn với từng user, không phải với một tài khoản root chung. Hai là bạn có thể cho một người được chạy một số lệnh quản trị nhất định mà không phải giao toàn bộ quyền root. sudoers còn hỗ trợ alias như Cmnd_Alias để gom nhóm lệnh và cấp quyền chính xác hơn thay vì dùng ALL quá sớm.

4.3. Ownership và mode bits là lớp bảo vệ file

Manpage của chown nói thẳng: chown đổi owner và/hoặc group ownership của file. Manpage của chmod thì nói chmod đổi file mode bits, tức các quyền kiểu read, write, execute theo user, group và others. Nói cách khác, chown trả lời câu hỏi “file này thuộc về ai”, còn chmod trả lời câu hỏi “những ai được làm gì với file này”. Bạn sẽ sửa sai rất nhiều ít hơn nếu luôn tách hai câu hỏi này ra khi xử lý permission.

5. Quy trình triển khai bài này theo hướng production tối thiểu

Bước 1: Tạo user quản trị riêng thay vì làm việc lâu dài bằng root

Nếu server hiện mới chỉ có một user bootstrap, hoặc vẫn đang đi vào bằng root key từ nhà cung cấp VPS, hãy tạo một user quản trị riêng trước. Ubuntu docs khuyến nghị dùng adduser cho việc này.

sudo adduser devops
sudo adduser devops sudo
id devops
getent group sudo

Sau bước này, devops đã là user người thật để bạn làm việc hằng ngày, còn quyền nâng cao đi qua sudo. Đây là mô hình sạch hơn rất nhiều so với việc SSH trực tiếp vào root rồi thao tác tất cả từ đó. Ubuntu docs cũng nhắc rõ rằng user đầu tiên của hệ thống được thêm vào group sudo theo mặc định; vì vậy việc thêm user quản trị mới vào group này là cách Ubuntu đang kỳ vọng bạn mở rộng quyền quản trị.

Bước 2: Chuyển SSH key sang user quản trị mới

OpenSSH server docs của Ubuntu hiện vẫn khuyến nghị dùng khóa ed25519 vì key ngắn hơn và chi phí tính toán thấp hơn; public key được thêm vào ~/.ssh/authorized_keys bằng ssh-copy-id, và file authorized_keys chỉ nên cho user đã xác thực có quyền ghi. Docs cũng khuyên xem journalctl -fu ssh.service nếu cần troubleshoot live.

Từ máy local của bạn:

ssh-copy-id devops@SERVER_IP
ssh devops@SERVER_IP

Trên server, kiểm tra lại quyền:

ls -ld /home/devops
ls -ld /home/devops/.ssh
ls -l /home/devops/.ssh/authorized_keys
chmod 700 /home/devops/.ssh
chmod 600 /home/devops/.ssh/authorized_keys

OpenSSH client manpage cũng nói rõ public key auth hoạt động bằng cách server biết public key trong ~/.ssh/authorized_keys, còn client chứng minh mình giữ private key tương ứng. Cùng manpage này còn nhắc rằng file authorized_keys nên chỉ cho user đọc/ghi và không cho người khác truy cập.

Bước 3: Siết quyền thư mục home cho đúng mức cần thiết

Ubuntu user management docs ghi rõ từ Ubuntu 21.10 trở đi, thư mục home của user mới được tạo với private permissions 0750 theo mặc định, tức chỉ user và group của họ được truy cập. Nếu bạn phát hiện máy cũ hoặc image cũ còn dùng 0755, Ubuntu khuyên chỉ cần chỉnh parent directory về 0750, không nên chmod -R bừa bãi toàn bộ home vì có thể tạo hiệu ứng phụ không mong muốn.

Kiểm tra:

ls -ld /home/devops

Nếu cần sửa:

sudo chmod 0750 /home/devops

OpenSSH có mặc định StrictModes yes, nghĩa là sshd sẽ kiểm tra owner và mode của file người dùng và home directory trước khi chấp nhận login. Vì vậy, home directory và .ssh quá “thoáng” không chỉ là vấn đề thẩm mỹ mà còn có thể làm public key auth thất bại.

Bước 4: Khóa password root, nhưng chỉ sau khi đã test đường vào mới

Ubuntu docs hướng dẫn khóa password của root bằng sudo passwd -l root. Đây là bước hợp lý sau khi bạn đã xác nhận user quản trị mới có thể SSH vào bằng key và có sudo hoạt động.

sudo passwd -l root

Lưu ý rằng khóa password root không có nghĩa là mọi thứ liên quan đến root biến mất. Nó chỉ ngăn việc xác thực bằng password của tài khoản root. Với nhiều VPS nhỏ và vừa, đây là trạng thái lành mạnh hơn rất nhiều so với việc giữ root password sống mãi trên một máy public-facing.

Bước 5: Quản lý SSH keys theo nhóm theo cách audit được

authorized_keys mặc định có một key trên mỗi dòng, các dòng comment hoặc rỗng được bỏ qua, và comment field ở cuối dòng không được dùng cho xác thực nhưng hữu ích để nhận diện key. OpenSSH sshd(8) nói thẳng như vậy. Đây là chi tiết rất đáng tận dụng cho môi trường nhóm: hãy để comment theo định dạng dễ đọc như an.nguyen@macbook-pro hoặc devops-laptop-2026, để khi review file bạn biết key nào thuộc về ai.

Một policy thực tế, dễ bảo trì là thế này. Mỗi người một key riêng. Mỗi thiết bị chính một key riêng nếu cần. Không dùng một private key chung cho cả đội. Khi một thành viên nghỉ hoặc đổi máy, bạn chỉ cần xóa đúng dòng key của người đó khỏi authorized_keys hoặc khỏi user tương ứng. Đây không phải là “quy định bắt buộc của phần mềm”, nhưng nó tận dụng đúng lợi thế mà authorized_keys và audit theo comment field mang lại.

Nếu bạn đã có key công khai trên Launchpad hoặc GitHub, Ubuntu docs cho biết có thể bootstrap bằng ssh-import-id, với prefix mặc định lp: cho Launchpad và gh: cho GitHub. Tuy nhiên, với production, vẫn nên review key sau khi import thay vì coi đó là “đã an toàn mặc định”.

ssh-import-id gh:username

Bước 6: Chỉ cho đúng nhóm được SSH vào server

Ubuntu user management docs đề xuất một cách rất gọn để giới hạn SSH: tạo group sshlogin, cấu hình AllowGroups sshlogin trong sshd_config, rồi chỉ thêm những ai thực sự cần SSH vào group đó. OpenSSH sshd_config(5) cũng xác nhận rằng nếu đặt AllowGroups, chỉ user có primary hoặc supplementary group khớp mới được phép login.

Ví dụ:

sudo addgroup sshlogin
sudo adduser devops sshlogin
sudo editor /etc/ssh/sshd_config.d/10-access.conf

Nội dung file:

AllowGroups sshlogin

Sau đó test và restart:

sudo sshd -t
sudo systemctl restart ssh.service

Ubuntu OpenSSH docs nhấn mạnh rất rõ: vì mất SSH có thể đồng nghĩa mất đường vào server, hãy luôn kiểm tra cấu hình bằng sshd -t trước khi restart. Trên Ubuntu, custom config trong /etc/ssh/sshd_config.d/ cũng được ưu tiên sạch hơn so với sửa chồng trực tiếp vào file chính.

Bước 7: Dùng sudo theo mức cần thiết, không mặc định NOPASSWD: ALL

Cách nhanh nhất để “mọi thứ chạy được” là thêm tất cả người liên quan vào group sudo. Nhưng đó không phải lúc nào cũng là mô hình tốt nhất. sudoers cho phép bạn định nghĩa alias theo lệnh, dùng tag PASSWDNOPASSWD, và đọc thêm rule từ /etc/sudoers.d theo thứ tự lexical thông qua @includedir /etc/sudoers.d. Tài liệu cũng nói rõ NOPASSWD thay đổi hành vi xác thực, còn mặc định authenticate là bật.

Với production nhỏ, bạn có thể dùng hai mức đơn giản:

Mức 1 là user quản trị thật sự, thuộc group sudo, dùng khi cần toàn quyền root và vẫn phải nhập password của chính họ.

Mức 2 là user deploy hoặc operator, chỉ được chạy một số lệnh đã chỉ định, ví dụ reload nginx, restart php-fpm, xem status service.

Ví dụ một rule riêng trong /etc/sudoers.d/20-deploy:

sudo visudo -f /etc/sudoers.d/20-deploy

Nội dung:

Cmnd_Alias WEB_MAINT = /usr/bin/systemctl status nginx, /usr/bin/systemctl reload nginx, /usr/bin/systemctl status php8.3-fpm, /usr/bin/systemctl restart php8.3-fpm
%deploy ALL=(root) WEB_MAINT

visudo tồn tại chính để sửa sudoers an toàn hơn; manpage của Ubuntu mô tả nó là công cụ “safely edit the sudoers file”, có thể check lỗi với -c và edit file cụ thể bằng -f. Đồng thời, sudoers cũng yêu cầu file policy không được world-writable; mode mặc định của /etc/sudoers0440.

Điểm đáng nhớ là NOPASSWD không sai tuyệt đối, nhưng chỉ nên dùng cho các lệnh rất hẹp, ít rủi ro và thật sự cần tự động hóa. sudoers(5) mô tả rõ PASSWDNOPASSWD là tag theo command, vì vậy hãy dùng nó như một dao mổ, không phải như búa tạ.

Bước 8: Thiết kế ownership và permission cho webroot theo vai trò

Lỗi phổ biến nhất ở VPS tự host là không phân biệt “ai deploy code” với “tiến trình nào đọc hoặc ghi code”. Một mô hình dễ bảo trì cho web app nhỏ là: user deploy sở hữu source code, web server hoặc PHP-FPM chỉ được đọc những gì cần đọc, còn thư mục cần ghi runtime thì tách riêng và cấp quyền riêng.

Ví dụ:

sudo mkdir -p /srv/www/example.com
sudo chown -R deploy:www-data /srv/www/example.com
sudo find /srv/www/example.com -type d -exec chmod 0750 {} \;
sudo find /srv/www/example.com -type f -exec chmod 0640 {} \;

Về mặt kỹ thuật, chown cho phép bạn đặt owner và group bằng cú pháp owner:group, còn chmod cho phép bạn set mode bits bằng octal hoặc symbolic mode. Đó là nền tảng của mọi mô hình permission trên Linux. Cách cấp 0750 cho directory và 0640 cho file ở ví dụ trên chỉ là một baseline an toàn để web server có thể đọc qua group www-data mà không mở quyền cho everyone. Nếu ứng dụng có thư mục upload, cache, sessions hoặc storage, hãy tách riêng và cấp quyền ghi đúng chỗ đó thay vì mở write toàn bộ webroot.

Điều nên tránh là sửa lỗi kiểu “Permission denied” bằng:

chmod -R 777 /var/www/example.com

Ubuntu docs đã cảnh báo trong phần home directory rằng dùng -R một cách bừa bãi có thể tạo ra hậu quả ngoài ý muốn. Dù ví dụ đó nói về /home, nguyên tắc vẫn giống hệt với webroot: recursive chmod/chown thiếu suy nghĩ thường chữa cháy nhanh nhưng để lại nợ kỹ thuật và rủi ro bảo mật.

Bước 9: Quy trình offboarding khi user rời nhóm

Ubuntu user management docs đưa sẵn các thao tác cơ bản để lock password, delete user, đổi owner thư mục cũ và archive home directory nếu cần giữ lại dữ liệu. Đây là phần nhiều team bỏ qua cho đến khi có người nghỉ việc.

Một quy trình ngắn gọn, đủ dùng là:

sudo passwd -l username
sudo deluser username sshlogin
sudo deluser username sudo
sudo chown -R root:root /home/username
sudo mkdir -p /home/archived_users
sudo mv /home/username /home/archived_users/

Nếu bạn dùng mô hình “mỗi người một key”, offboarding sẽ gọn hơn rất nhiều. Bạn chỉ cần khóa account, xóa khỏi group liên quan, và review lại authorized_keys hoặc user account tương ứng.

6. Command snippets quan trọng

sudo adduser devops
sudo adduser devops sudo
sudo addgroup sshlogin
sudo adduser devops sshlogin
id devops
getent group sudo
getent group sshlogin
ssh-copy-id devops@SERVER_IP
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
sudo passwd -l root
sudo editor /etc/ssh/sshd_config.d/10-access.conf
sudo sshd -t
sudo systemctl restart ssh.service
sudo visudo -f /etc/sudoers.d/20-deploy
sudo -l
sudo chown -R deploy:www-data /srv/www/example.com
sudo find /srv/www/example.com -type d -exec chmod 0750 {} \;
sudo find /srv/www/example.com -type f -exec chmod 0640 {} \;
sudo passwd -l username
sudo deluser username sshlogin

7. Kiểm tra sau khi cấu hình

Sau khi hoàn tất bài hướng dẫn này, đừng chỉ nhìn thấy “không báo lỗi” rồi xem như xong. Bạn nên kiểm tra ít nhất bốn việc.

  • User quản trị mới SSH vào được bằng key và sudo -l ra đúng quyền mong muốn.
  • Home directory và .ssh không quá rộng quyền.
  • SSH chỉ cho đúng group hoặc user được phép đăng nhập nếu bạn đã bật AllowGroups hoặc AllowUsers.
  • Webroot có owner/group hợp lý và không còn chỗ nào bị mở write bừa bãi cho everyone.

Nếu bạn có sửa SSH config, luôn chạy lại sudo sshd -t trước khi restart và mở thêm một phiên SSH mới để test. Ubuntu docs coi đây là bước bắt buộc trên server từ xa.

8. Lỗi thường gặp và cách tránh

  • Lỗi đầu tiên là dùng chung một account quản trị cho cả nhóm. Bạn có thể làm việc nhanh hơn trong 1 tuần đầu, nhưng đến lúc audit hoặc thu hồi quyền thì gần như không biết key nào là của ai.
  • Lỗi thứ hai là nhét tất cả mọi người vào group sudo vì “cho tiện”. Group sudo là quyền rất mạnh; Ubuntu docs nói rõ vào group này là có full root access qua sudo. Hãy chỉ dùng nó cho người thực sự cần, còn các vai trò hẹp thì cấp rule riêng trong /etc/sudoers.d.
  • Lỗi thứ ba là sửa trực tiếp /etc/sudoers bằng editor thường. visudo tồn tại để giúp bạn chỉnh file policy an toàn hơn và check lỗi cú pháp. Trên máy production, một lỗi sudoers có thể làm bạn mất luôn khả năng dùng sudo bình thường.
  • Lỗi thứ tư là nghĩ rằng permission chỉ là chuyện chmod. Thực tế, rất nhiều lỗi phát sinh vì ownership sai, không phải vì mode bits sai. Nếu owner/group đặt sai vai trò, bạn sẽ thấy những chuỗi “Permission denied” rất khó hiểu dù nhìn qua có vẻ file đã 644 hoặc 755.
  • Lỗi thứ năm là dùng NOPASSWD: ALL quá sớm. sudoers hỗ trợ NOPASSWD, nhưng nó nên là ngoại lệ có kiểm soát, không phải mặc định cho mọi lệnh của mọi user.

9. FAQ

9.1. Có nên dùng root để SSH hằng ngày cho nhanh không?

Không nên. Ubuntu docs đã thiết kế sẵn mô hình dùng sudo thay cho thao tác thường xuyên bằng root, và user đầu tiên cũng được đưa vào group sudo theo mặc định để phục vụ đúng mô hình này.

9.2. Có nên dùng một SSH key chung cho cả team không?

Không nên. authorized_keys cho phép bạn lưu nhiều key, mỗi key một dòng, và comment field giúp nhận diện từng key. Nếu dùng key riêng theo người hoặc theo thiết bị, việc audit và thu hồi quyền sẽ rõ ràng hơn rất nhiều.

9.3. Có nên để /home/username0755 không?

Trên Ubuntu 21.10 trở đi, home directory mới được tạo với quyền riêng tư 0750 theo mặc định. Nếu đây là server nhiều user, 0750 thường hợp lý hơn 0755 vì giảm khả năng các user khác duyệt nội dung dưới home của nhau.

9.4. Có nên dùng NOPASSWD cho deploy user không?

Chỉ khi bạn giới hạn rất hẹp command nào được chạy. sudoers hỗ trợ NOPASSWD, nhưng mặc định authenticate đang bật và đó là trạng thái an toàn hơn cho phần lớn thao tác quản trị.

9.5. Có nên dùng AllowUsers hay AllowGroups?

Với môi trường nhóm, AllowGroups thường dễ bảo trì hơn vì bạn chỉ cần thêm hoặc gỡ user khỏi group. OpenSSH hỗ trợ cả hai, nhưng Ubuntu docs dùng ví dụ AllowGroups sshlogin cho policy SSH access theo nhóm.

10. Gợi ý

Kết nối SSH lần đầu: key-based login, known_hosts và anti-lockout 2026

Đừng bỏ lỡ

Theo dõi bản tin mới nhất tại đây

Chào bạn 👋
Rất vui được làm quen.

Đăng ký để nhận nội dung hấp dẫn mỗi tháng qua email.

Bằng việc đăng ký, bạn đồng ý với Chính sách bảo mật của DevNook.

Tác giả

Tuấn Lê

Tại DevNook, mình chia sẻ kiến thức thực chiến, kinh nghiệm làm sản phẩm và những công cụ hữu ích giúp bạn làm việc hiệu quả hơn mỗi ngày.