Quản lý người dùng và nhóm trên Linux

Một máy chủ có người vào ra, có dịch vụ chạy nền, có script tự động. Cho tất cả dùng chung một tài khoản là cách nhanh nhất để không bao giờ biết ai đã làm gì. Người dùng và nhóm là lớp phân chia cơ bản nhất của Linux — và cũng là thứ dễ làm sai nhất chỉ vì thiếu một chữ cái trong câu lệnh.

Ba file giữ toàn bộ thông tin

/etc/passwd — đọc được bởi mọi người, bảy trường cách nhau bằng dấu hai chấm:

an:x:1001:1001:,,,:/home/an:/bin/bash
│  │  │    │    │   │        └─ shell dang nhap
│  │  │    │    │   └────────── thu muc nha
│  │  │    │    └────────────── mo ta (GECOS)
│  │  │    └─────────────────── GID cua nhom chinh
│  │  └──────────────────────── UID
│  └─────────────────────────── x = mat khau nam o /etc/shadow
└────────────────────────────── ten dang nhap

/etc/shadow — chỉ root đọc được, chứa mật khẩu đã băm và các mốc thời hạn:

ten:mat_khau_bam:lan_doi_cuoi:toi_thieu:toi_da:canh_bao:khong_dung:het_han:du_tru

/etc/group — tên nhóm, GID, và danh sách thành viên phụ:

docker:x:998:an,trien_khai

Đừng sửa tay ba file này bằng trình soạn thảo thường. Có công cụ khóa file và kiểm tra cú pháp trước khi lưu, đúng tinh thần của visudo:

sudo vipw          # sua /etc/passwd an toan
sudo vigr          # sua /etc/group
sudo pwck          # kiem tra tinh nhat quan

Tạo người dùng

sudo useradd -m -s /bin/bash -c "To ha tang" an
sudo passwd an
  • -m — tạo thư mục nhà và sao chép khung từ /etc/skel. Thiếu cờ này, người dùng đăng nhập vào một thư mục không tồn tại.
  • -s — shell đăng nhập.
  • -c — phần mô tả.
  • -u, -g, -G — chỉ định UID, nhóm chính, danh sách nhóm phụ.

Trên Debian và Ubuntu còn có adduser, một lớp bọc hỏi đáp từng bước; useradd thì giống nhau trên mọi bản phân phối nên hợp với script. Giá trị mặc định nằm ở /etc/login.defs/etc/default/useradd.

Xem một tài khoản đang có gì

id an                      # UID, GID chinh, toan bo nhom phu
groups an                  # chi ten nhom
getent passwd an           # doc qua NSS, thay ca tai khoan tu LDAP
getent group docker        # ai dang o trong nhom nay
sudo passwd -S an          # trang thai mat khau: P / L / NP

Dùng getent thay vì grep /etc/passwd: nếu máy có nối thư mục người dùng tập trung, chỉ getent mới thấy được.

Nhóm chính và nhóm phụ

Mỗi người dùng có đúng một nhóm chính — ghi ở trường GID trong /etc/passwd, và là nhóm được gán cho mọi file người đó tạo ra. Ngoài ra có thể thuộc bao nhiêu nhóm phụ tùy ý, liệt kê trong /etc/group.

Thêm nhóm phụ: nhớ chữ -a

sudo usermod -aG docker an      # THEM vao nhom docker
sudo usermod -G docker an       # THAY THE toan bo nhom phu bang mot nhom

Dòng thứ hai là tai nạn kinh điển. Thiếu -a, người dùng bị gỡ khỏi mọi nhóm phụ khác — kể cả nhóm cho phép dùng sudo. Nếu đó là tài khoản quản trị duy nhất và bạn đã tắt đăng nhập root, bạn vừa tự khóa mình ra khỏi máy chủ.

Cách an toàn hơn là dùng gpasswd, vốn chỉ có thao tác thêm và bớt, không có chế độ thay thế:

sudo gpasswd -a an docker       # them
sudo gpasswd -d an docker       # bo ra
sudo groupadd duan              # tao nhom moi
sudo groupdel duan

Thay đổi nhóm chỉ có hiệu lực ở phiên mới

Danh sách nhóm được gắn vào tiến trình lúc đăng nhập và không cập nhật về sau. Vừa thêm mình vào nhóm docker mà vẫn bị từ chối quyền là chuyện bình thường — shell đang mở vẫn mang danh sách nhóm cũ.

id                # danh sach nhom cua phien hien tai
newgrp docker     # mo shell moi voi nhom vua them

Cách chắc chắn nhất vẫn là đăng xuất rồi đăng nhập lại. Với dịch vụ chạy nền, phải khởi động lại dịch vụ thì tiến trình mới nhận nhóm mới.

Chia thư mục dùng chung theo nhóm

Đây là ứng dụng thực tế nhất của nhóm phụ. Muốn vài người cùng sửa được một thư mục dự án:

sudo groupadd duan
sudo gpasswd -a an duan
sudo gpasswd -a trien_khai duan

sudo chgrp -R duan /srv/duan
sudo chmod -R 2775 /srv/duan
ls -ld /srv/duan        # chu s o vi tri quyen thuc thi cua nhom

Số 2 đứng đầu là bit setgid trên thư mục, và nó mới là mấu chốt: mọi file và thư mục con tạo mới bên trong sẽ tự mang nhóm duan, thay vì mang nhóm chính của người tạo. Không có bit này, mỗi người tạo file lại gán một nhóm khác nhau và cả nhóm mất quyền ghi chéo sau vài ngày.

Tài khoản cho dịch vụ

Dịch vụ nền không cần đăng nhập, không cần thư mục nhà, và tuyệt đối không nên chạy dưới root nếu tránh được:

sudo useradd -r -M -d /var/lib/ungdung -s /usr/sbin/nologin ungdung
sudo install -d -o ungdung -g ungdung -m 750 /var/lib/ungdung

-r tạo tài khoản hệ thống với UID nằm dưới ngưỡng dành cho người dùng thật. -M không tạo thư mục nhà. Shell nologin nằm ở /usr/sbin/nologin trên Debian/Ubuntu và /sbin/nologin trên RHEL/Rocky — kiểm tra trước khi chép nguyên câu lệnh.

Khóa tài khoản cho đúng

sudo usermod -L an       # khoa mat khau
sudo passwd -l an        # tuong duong
sudo usermod -U an       # mo lai

Nhưng phải hiểu rõ giới hạn: các lệnh trên chỉ vô hiệu hóa mật khẩu. Nếu người đó đăng nhập bằng khóa SSH, họ vẫn vào được như không có gì xảy ra. Khóa một tài khoản thật sự cần làm đủ bốn việc:

sudo usermod -L an                          # 1. khoa mat khau
sudo chage -E 0 an                           # 2. cho tai khoan het han
sudo usermod -s /usr/sbin/nologin an         # 3. doi shell
sudo mv /home/an/.ssh/authorized_keys \
        /home/an/.ssh/authorized_keys.tat    # 4. vo hieu khoa SSH

sudo pkill -u an                             # dong cac phien dang mo

Và đừng quên phần quan trọng nhất: gỡ họ khỏi các nhóm đặc quyền. Bài sudo và nguyên tắc đặc quyền tối thiểu trên trang này đã nói kỹ về chuyện nhóm sudo trên Debian/Ubuntu và nhóm wheel trên RHEL/Rocky là tấm vé vào quyền root — người còn trong nhóm đó thì mọi thao tác khóa ở trên đều có thể bị vòng qua.

Hạn dùng mật khẩu

sudo chage -l an                  # xem toan bo moc thoi han
sudo chage -M 90 -W 14 an         # toi da 90 ngay, canh bao truoc 14 ngay
sudo chage -d 0 an                # buoc doi mat khau ngay lan dang nhap toi

chage -d 0 rất hợp khi bàn giao tài khoản mới: bạn đặt mật khẩu tạm, người nhận buộc phải đổi ngay lần đầu và bạn không còn biết mật khẩu của họ.

Xóa người dùng và dọn tàn dư

sudo userdel an           # giu lai thu muc nha
sudo userdel -r an        # xoa ca thu muc nha va hop thu

Xóa tài khoản không xóa những file người đó để lại ở nơi khác. Chúng trở thành file mồ côi mang một UID không còn ai sở hữu — và sẽ thuộc về người tiếp theo được cấp trùng UID đó.

sudo find / -xdev \( -nouser -o -nogroup \) -ls
sudo find /srv -xdev -uid 1001 -ls        # tim truoc khi xoa tai khoan

Hãy dành mười phút chạy getent passwd trên máy chủ của bạn và đối chiếu với danh sách người đang thực sự làm việc. Trên máy đã chạy vài năm, gần như luôn có vài tài khoản của người đã nghỉ — vẫn còn shell đăng nhập, vẫn còn khóa SSH, và vẫn còn trong nhóm quản trị.

Lên đầu trang