คำตอบสั้น ๆ: ให้สิทธิ์ลูกค้าหรือผู้รับเหมาอัปโหลดไฟล์ได้ โดยเข้า Shell ไม่ได้และมองไม่เห็นไฟล์ส่วนอื่นของเครื่อง ด้วย ChrootDirectory ของ OpenSSH
คู่มือนี้อธิบาย SFTP ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
เมื่อต้องให้คนภายนอกอัปโหลดไฟล์ขึ้นเซิร์ฟเวอร์ การสร้างผู้ใช้ Linux ธรรมดาให้เขาถือว่าเสี่ยงเกินไป เพราะผู้ใช้นั้นจะ SSH เข้ามารันคำสั่งได้ และเดินดูไฟล์ทั่วทั้งเครื่องได้ แม้จะแก้ไขไม่ได้ก็ตาม
OpenSSH มีความสามารถที่แก้เรื่องนี้ในตัวอยู่แล้วโดยไม่ต้องติดตั้ง FTP Server เพิ่ม คือการจำกัดผู้ใช้ไว้ในโฟลเดอร์เดียว (chroot) และอนุญาตเฉพาะ SFTP เท่านั้น คู่มือนี้ตั้งค่าทั้งชุดพร้อมอธิบายกฎเรื่องสิทธิ์ที่ทำให้หลายคนติดปัญหา
สิ่งที่ต้องเตรียม
- Linux Server ที่ใช้ OpenSSH และสิทธิ์
sudo - ชื่อผู้ใช้ที่จะสร้าง และโฟลเดอร์ปลายทางที่ต้องการให้เข้าถึง
ขั้นตอนที่ 1: สร้างกลุ่มสำหรับผู้ใช้ SFTP
ใช้กลุ่มเป็นตัวกำหนดนโยบาย ทำให้เพิ่มผู้ใช้ใหม่ในอนาคตไม่ต้องแก้คอนฟิกอีก
sudo groupadd sftponly
ขั้นตอนที่ 2: สร้างผู้ใช้
sudo useradd -m -d /var/sftp/customer1 -s /usr/sbin/nologin -G sftponly customer1
sudo passwd customer1
ตั้ง Shell เป็น /usr/sbin/nologin ตั้งแต่ต้น ผู้ใช้นี้จะเข้า SSH แบบรันคำสั่งไม่ได้เลย บน AlmaLinux และ Rocky Linux ใช้ /sbin/nologin แทน
หากต้องการใช้ SSH Key แทนรหัสผ่าน สร้างไฟล์ authorized_keys ให้ผู้ใช้
sudo mkdir -p /var/sftp/customer1/.ssh
sudo nano /var/sftp/customer1/.ssh/authorized_keys
sudo chown -R customer1:customer1 /var/sftp/customer1/.ssh
sudo chmod 700 /var/sftp/customer1/.ssh
sudo chmod 600 /var/sftp/customer1/.ssh/authorized_keys
ขั้นตอนที่ 3: ตั้งสิทธิ์โฟลเดอร์ให้ถูกกฎของ chroot
นี่คือจุดที่คนติดปัญหามากที่สุด OpenSSH บังคับกฎสองข้อกับโฟลเดอร์ที่ใช้เป็น chroot
- โฟลเดอร์นั้นและทุกโฟลเดอร์แม่เหนือขึ้นไป ต้องเป็นของ root
- โฟลเดอร์นั้นและทุกโฟลเดอร์แม่ ต้องไม่ให้กลุ่มหรือคนอื่นเขียนได้ คือสิทธิ์ต้องเป็น 755 หรือแคบกว่า
ผลคือผู้ใช้จะเขียนลงโฟลเดอร์บนสุดของตัวเองไม่ได้ ต้องสร้างโฟลเดอร์ย่อยไว้ให้เขียน
sudo chown root:root /var/sftp /var/sftp/customer1
sudo chmod 755 /var/sftp /var/sftp/customer1
sudo mkdir -p /var/sftp/customer1/upload
sudo chown customer1:customer1 /var/sftp/customer1/upload
sudo chmod 755 /var/sftp/customer1/upload
ตรวจสิทธิ์ทุกชั้นในบรรทัดเดียว
namei -l /var/sftp/customer1/upload
ขั้นตอนที่ 4: ตั้งค่า sshd
sudo nano /etc/ssh/sshd_config
ตรวจว่ามีบรรทัด Subsystem แบบนี้ หากเป็น /usr/lib/openssh/sftp-server ให้เปลี่ยนเป็น internal-sftp เพราะ chroot ต้องใช้แบบภายในจึงไม่ต้องคัดลอกไฟล์ระบบเข้าไปในกรง
Subsystem sftp internal-sftp
เพิ่มบล็อกนี้ ไว้ท้ายไฟล์เสมอ เพราะบล็อก Match มีผลกับทุกบรรทัดที่อยู่ถัดลงไปจนจบไฟล์
Match Group sftponly
ChrootDirectory %h
ForceCommand internal-sftp -u 0002
AllowTcpForwarding no
X11Forwarding no
PermitTunnel no
AllowAgentForwarding no
PasswordAuthentication yes
%h คือโฮมไดเรกทอรีของผู้ใช้ ทำให้ใช้บล็อกเดียวกับผู้ใช้ทุกคนในกลุ่มได้ ส่วน -u 0002 คือ umask ที่ทำให้ไฟล์ที่อัปโหลดมีสิทธิ์ให้กลุ่มอ่านได้ ซึ่งสะดวกเมื่อเว็บเซิร์ฟเวอร์ต้องอ่านไฟล์นั้นต่อ
sudo sshd -t
sudo systemctl reload ssh
สั่ง sshd -t ก่อนเสมอ หากคอนฟิกผิดแล้วรีสตาร์ต คุณอาจเข้าเครื่องไม่ได้อีก