Hướng Dẫn Tạo User SFTP-Only Trên VPS Ubuntu Bằng Chroot

Hướng dẫn tạo user SFTP-only trên VPS Ubuntu: giới hạn trong thư mục chroot, không cho shell SSH, dùng internal-sftp, phân quyền đúng và xử lý lỗi Permission denied.

Khi cần cho khách hàng, nhân viên hoặc ứng dụng upload/download file trên VPS Ubuntu, việc cấp nguyên tài khoản SSH có shell thường là quá rộng. OpenSSH cho phép tạo user chỉ được dùng SFTP, bị giới hạn trong một thư mục chroot và không có quyền mở shell, TCP forwarding hay X11 forwarding. Mô hình này phù hợp cho upload website, trao đổi file hoặc cung cấp vùng dữ liệu riêng cho từng người. Tuy nhiên, `ChrootDirectory` có yêu cầu quyền rất chặt: đường dẫn chroot phải thuộc root và không được user/group khác ghi vào, vì vậy cần tạo một thư mục con riêng để user upload. Bài viết này hướng dẫn từng bước tạo group SFTP, user không shell, cấu trúc thư mục, Match block trong sshd_config, test cấu hình và xử lý các lỗi phổ biến.

Điểm quan trọng Hãy lựa chọn dịch vụ dựa trên nhu cầu sử dụng thực tế và theo dõi tài nguyên thường xuyên để có hiệu quả tốt nhất.

Nếu bạn chỉ muốn một người upload hoặc download file trên VPS Ubuntu, việc đưa cho họ tài khoản SSH đầy đủ là không cần thiết. OpenSSH hỗ trợ SFTP trực tiếp và có thể giới hạn user bằng ChrootDirectory + ForceCommand internal-sftp.

Kết quả mong muốn:

  • user đăng nhập được bằng SFTP;
  • không có shell SSH tương tác;
  • không đi ra ngoài thư mục được cấp;
  • không dùng TCP forwarding/X11;
  • thư mục upload có quyền riêng;
  • dễ thu hồi account khi không còn nhu cầu.

Nếu bạn mới làm quen Linux, nên đọc bài Các lệnh Linux cơ bản trên VPS Ubuntu. Nếu cần bảo vệ SSH public, xem thêm Cài Fail2Ban trên VPS Ubuntu.

1. SFTP khác FTP thế nào?

SFTP là SSH File Transfer Protocol, chạy trên kết nối SSH và sử dụng cơ chế xác thực của OpenSSH.

Nó không phải FTP “bọc SSL”. Vì sử dụng SSH, bạn thường không cần mở thêm dải port passive như FTP truyền thống.

Nếu SSH đang ở port 22, SFTP cũng đi qua port đó. Nếu SSH chạy port custom, client SFTP phải dùng đúng port.

2. Vì sao nên tạo SFTP-only user?

Một tài khoản SSH thông thường có thể:

  • mở shell;
  • chạy lệnh;
  • đọc các file mà quyền Unix cho phép;
  • tạo tunnel/forwarding nếu cấu hình cho phép.

Trong khi đó, người chỉ cần upload file không cần tất cả quyền trên.

SFTP-only giúp áp dụng nguyên tắc least privilege.

3. ChrootDirectory hoạt động thế nào?

ChrootDirectory thay đổi filesystem root nhìn thấy bởi session sau khi xác thực.

Ví dụ nếu chroot là:

/srv/sftp/customer01

thì từ phía user, thư mục đó trở thành /.

OpenSSH kiểm tra rất nghiêm quyền chroot: các thành phần đường dẫn phải do root sở hữu và không được user/group khác ghi vào. Đây là lý do bạn không thể cho user sở hữu trực tiếp thư mục chroot.

Cách đúng là:

/srv/sftp/customer01       root:root, không writable bởi user
└── upload                 customer01:sftpusers, user được ghi

4. Backup cấu hình SSH trước khi sửa

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

Kiểm tra service:

sudo systemctl status ssh

Giữ phiên SSH hiện tại mở trong suốt quá trình cấu hình để có đường sửa lỗi nếu session mới không vào được.

5. Tạo group SFTP

sudo groupadd sftpusers

Nếu group đã tồn tại, hệ thống sẽ báo tương ứng.

Kiểm tra:

getent group sftpusers

6. Tạo user SFTP không có shell

Ví dụ user customer01:

sudo useradd -M -g sftpusers -d /upload -s /usr/sbin/nologin customer01

Ý nghĩa:

  • -M: không tự tạo home theo cách thông thường;
  • -g sftpusers: group chính;
  • -d /upload: thư mục làm việc bên trong chroot;
  • -s /usr/sbin/nologin: không cấp shell thông thường.

Đặt password:

sudo passwd customer01

Với production, bạn có thể dùng SSH key thay password nếu quy trình phù hợp.

7. Tạo cấu trúc chroot

sudo mkdir -p /srv/sftp/customer01/upload

Đặt owner cho thư mục chroot:

sudo chown root:root /srv/sftp/customer01
sudo chmod 755 /srv/sftp/customer01

Đặt owner cho thư mục upload:

sudo chown customer01:sftpusers /srv/sftp/customer01/upload
sudo chmod 750 /srv/sftp/customer01/upload

Kiểm tra:

namei -l /srv/sftp/customer01/upload

8. Cấu hình OpenSSH Match Group

Mở:

sudo nano /etc/ssh/sshd_config

Thêm cuối file:

Match Group sftpusers
    ChrootDirectory /srv/sftp/%u
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
    PermitTunnel no

%u sẽ được thay bằng username.

Với customer01, chroot trở thành:

/srv/sftp/customer01

9. Vì sao dùng internal-sftp?

OpenSSH cung cấp internal-sftp là SFTP server chạy trong process sshd. Tài liệu OpenSSH ghi rằng cách này đơn giản hóa cấu hình với ChrootDirectory vì không cần copy binary và library vào chroot.

Đây là lựa chọn phù hợp cho SFTP-only.

10. Kiểm tra Subsystem SFTP hiện tại

grep -n '^Subsystem' /etc/ssh/sshd_config

Bạn có thể thấy dạng:

Subsystem sftp /usr/lib/openssh/sftp-server

Hoặc internal-sftp.

Vì Match block dùng ForceCommand internal-sftp, SFTP-only user vẫn bị ép vào internal subsystem.

Không chỉnh dòng Subsystem nếu không có lý do rõ ràng.

11. Test cấu hình SSH trước khi reload

Không bỏ qua bước này.

sudo sshd -t

Nếu không có output, cú pháp thường hợp lệ.

Nếu báo lỗi, sửa trước khi reload service.

12. Reload SSH thay vì restart thô

sudo systemctl reload ssh

Kiểm tra:

sudo systemctl status ssh

Giữ terminal quản trị cũ mở cho tới khi test account mới thành công.

13. Test bằng SFTP command line

Từ máy khác:

sftp customer01@IP_VPS

Nếu SSH port custom:

sftp -P 2222 customer01@IP_VPS

Sau khi login:

pwd
ls
cd upload
put test.txt

User chỉ nên thấy filesystem trong chroot.

14. Test rằng shell SSH bị chặn

Thử:

ssh customer01@IP_VPS

Vì ForceCommand internal-sftp, session không nên cho shell tương tác thông thường.

Đây là điểm quan trọng của mô hình SFTP-only.

15. Dùng WinSCP hoặc FileZilla được không?

Có, miễn client hỗ trợ SFTP.

Thông tin kết nối:

Protocol: SFTP
Host: IP VPS hoặc domain
Port: SSH port
Username: customer01
Password/SSH key: theo cấu hình

Không chọn FTP nếu bạn đang cấu hình OpenSSH SFTP.

16. Vì sao user không upload được vào /?

Đây là hành vi đúng.

Thư mục chroot /srv/sftp/customer01 phải thuộc root và không writable bởi user.

User chỉ nên upload vào:

/upload

Nếu bạn chown customer01 cho thư mục chroot để user ghi trực tiếp vào /, sshd có thể từ chối session vì vi phạm yêu cầu an toàn của ChrootDirectory.

17. Lỗi bad ownership or modes for chroot directory

Kiểm tra:

ls -ld /srv /srv/sftp /srv/sftp/customer01

Các thành phần liên quan chroot phải có ownership/mode phù hợp.

Sửa ví dụ:

sudo chown root:root /srv/sftp/customer01
sudo chmod 755 /srv/sftp/customer01

Sau đó:

sudo sshd -t
sudo systemctl reload ssh

18. Lỗi Permission denied khi upload

Kiểm tra thư mục con:

ls -ld /srv/sftp/customer01/upload

Đảm bảo user sở hữu hoặc có quyền ghi:

sudo chown customer01:sftpusers /srv/sftp/customer01/upload
sudo chmod 750 /srv/sftp/customer01/upload

Nếu nhiều user dùng chung thư mục, cần thiết kế group permission/ACL rõ ràng thay vì chmod 777.

19. Dùng SSH key cho SFTP-only

Có thể.

Tuy nhiên, do chroot ownership rất chặt, vị trí authorized_keys cần được thiết kế cẩn thận.

Một cách quản trị tập trung là dùng AuthorizedKeysFile ở đường dẫn root-controlled, nhưng thay đổi này ảnh hưởng SSH toàn hệ thống.

Nếu bạn chỉ có một vài user, password mạnh + Fail2Ban có thể đơn giản hơn; nếu dùng key, hãy test với một account trước khi rollout.

20. Chặn password cho riêng SFTP user được không?

OpenSSH Match block cho phép áp dụng nhiều tùy chọn theo user/group.

Bạn có thể thiết kế chỉ dùng public key cho group SFTP, nhưng hãy kiểm tra syntax/compatibility với phiên bản OpenSSH đang dùng.

Không tắt password global trước khi xác nhận tất cả account quản trị đã có key hoạt động.

21. Tạo thêm user thứ hai

Ví dụ:

sudo useradd -M -g sftpusers -d /upload -s /usr/sbin/nologin customer02
sudo passwd customer02
sudo mkdir -p /srv/sftp/customer02/upload
sudo chown root:root /srv/sftp/customer02
sudo chmod 755 /srv/sftp/customer02
sudo chown customer02:sftpusers /srv/sftp/customer02/upload
sudo chmod 750 /srv/sftp/customer02/upload

Không cần thêm Match block mới vì %u tự thay username.

22. Tạo thư mục chung cho nhiều user

Nếu nhiều user cần dùng chung dữ liệu, có thể dùng group, ACL hoặc bind mount bên trong mỗi chroot.

Tuy nhiên, shared directory phức tạp hơn về permission. Hãy xác định:

  • ai được read;
  • ai được write;
  • ai được delete;
  • file mới mang group gì;
  • có cần setgid/ACL không.

Không nên dùng 777 như giải pháp mặc định.

23. Bind mount dữ liệu website vào chroot

Giả sử file website nằm tại:

/var/www/example.com/uploads

Bạn có thể bind mount vào:

/srv/sftp/customer01/upload

Ví dụ:

sudo mount --bind /var/www/example.com/uploads /srv/sftp/customer01/upload

Nếu muốn persistent, cần khai báo fstab cẩn thận.

Trước khi làm, hãy hiểu permission và tác động xóa file từ SFTP tới dữ liệu website thật.

24. SFTP-only có bảo vệ khỏi xóa file không?

Không nếu user có quyền write/delete trong thư mục được cấp.

Chroot chỉ giới hạn phạm vi filesystem, không biến user thành read-only.

Nếu user chỉ cần download, hãy cấp quyền read-only.

25. Tạo SFTP read-only

Một cách đơn giản là owner file thuộc root/app user và SFTP user chỉ có read/execute.

Ví dụ:

sudo chmod -R o-rwx /path

Nhưng quyền cụ thể phụ thuộc user/group đang dùng. Hãy thiết kế ACL theo nhu cầu thay vì copy một lệnh chung.

26. Log phiên SFTP

OpenSSH có thể ghi log xác thực qua journal/syslog.

Xem:

sudo journalctl -u ssh

Theo dõi:

sudo journalctl -u ssh -f

Với internal-sftp, logging chi tiết thao tác file có thể cần option riêng cho ForceCommand.

Ví dụ OpenSSH hỗ trợ các argument tương tự sftp-server; hãy tham khảo manpage phiên bản của bạn trước khi bật verbose logging vì log có thể tăng nhanh.

27. Giới hạn dung lượng SFTP user

Chroot không tự giới hạn quota.

Nếu cần quota theo user, bạn có thể dùng filesystem quota hoặc tách filesystem/storage.

Đây là lớp riêng với SFTP.

28. Fail2Ban có dùng được cho SFTP không?

SFTP xác thực qua sshd, nên các lần login sai thường được ghi vào SSH authentication log và có thể được jail sshd của Fail2Ban xử lý.

Bạn không cần một port SFTP riêng nếu dùng OpenSSH.

29. UFW cho SFTP

Nếu SSH dùng 22:

sudo ufw allow 22/tcp

Nếu dùng custom port, allow đúng port.

SFTP không cần mở port 21.

30. Tình huống thực tế: cấp account upload file cho khách hàng

Quy trình hợp lý:

  1. tạo customer01;
  2. không shell;
  3. chroot riêng;
  4. tạo /upload writable;
  5. test WinSCP/SFTP;
  6. giới hạn quyền file;
  7. bật Fail2Ban;
  8. ghi ngày hết hạn account;
  9. disable/xóa khi dự án kết thúc.

31. Disable SFTP user

Khóa password:

sudo passwd -l customer01

Hoặc lock account:

sudo usermod -L customer01

Cách phù hợp phụ thuộc phương thức xác thực. Nếu dùng SSH key, chỉ lock password có thể chưa chặn key auth.

Muốn vô hiệu hoàn toàn, hãy xem trạng thái account, key và cấu hình Match.

32. Xóa user SFTP

sudo userdel customer01

Không tự động xóa dữ liệu chroot nếu bạn không yêu cầu.

Kiểm tra dữ liệu trước khi xóa:

sudo du -sh /srv/sftp/customer01

Backup nếu cần.

33. Bảo mật SFTP bổ sung

  • dùng password mạnh hoặc SSH key;
  • bật Fail2Ban;
  • không chia sẻ account;
  • khóa account không dùng;
  • giới hạn firewall nguồn IP nếu có IP cố định;
  • backup dữ liệu;
  • cập nhật OpenSSH;
  • không cấp shell/admin cho user file transfer.

34. Checklist SFTP-only

  • Tạo group sftpusers.
  • User có shell nologin.
  • Chroot root-owned.
  • Thư mục con writable thuộc user.
  • Match Group cấu hình đúng.
  • ForceCommand internal-sftp.
  • Forwarding bị tắt.
  • sshd -t thành công.
  • Reload SSH.
  • Test SFTP.
  • Test shell bị chặn.
  • Có log/backup.

35. FAQ về SFTP-only trên Ubuntu

SFTP có dùng port 21 không?

Không. OpenSSH SFTP dùng kết nối SSH, mặc định thường là port 22.

User SFTP có SSH shell được không?

Nếu dùng ForceCommand internal-sftp trong Match block, user bị ép vào SFTP subsystem thay vì shell.

Vì sao thư mục chroot phải thuộc root?

Đây là yêu cầu an toàn của OpenSSH đối với ChrootDirectory.

Có thể cho user upload vào thư mục chroot / không?

Không nên. Hãy tạo thư mục con writable như /upload.

Có dùng WinSCP được không?

Có, chọn protocol SFTP.

Có thể dùng SSH key không?

Có, nhưng cần cấu hình authorized keys phù hợp và test kỹ với chroot.

SFTP-only có thay thế backup không?

Không. User vẫn có thể xóa dữ liệu nếu được cấp write/delete.

Kết luận

SFTP-only + ChrootDirectory là cách phù hợp để cấp quyền truyền file trên VPS Ubuntu mà không đưa cho người dùng shell SSH đầy đủ. Điểm quan trọng nhất là ownership của chroot: thư mục gốc phải do root quản lý, còn user chỉ được ghi trong thư mục con.

Trước khi reload SSH, luôn chạy sshd -t và giữ phiên quản trị hiện tại mở. Với VPS production, kết hợp SFTP-only với Fail2Ban, UFW, password/key mạnh và backup sẽ tạo mô hình quản trị file rõ ràng hơn.

Nếu bạn cần VPS Ubuntu tại HUONG CLOUD để chạy website hoặc cung cấp vùng upload riêng cho khách hàng, hãy xây quyền truy cập tối thiểu ngay từ đầu thay vì dùng chung tài khoản root/SSH quản trị.

Nguồn tham khảo

Kết luận

Nếu chưa chắc cấu hình hoặc loại dịch vụ nào phù hợp, hãy gửi nhu cầu thực tế để đội ngũ hỗ trợ tư vấn trước khi mua.

Chưa biết nên chọn gói nào?

Xem bảng giá VPS hoặc liên hệ đội ngũ hỗ trợ để chọn cấu hình phù hợp.

Xem bảng giá VPS →