ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

สร้างผู้ใช้ SFTP ที่เข้าได้เฉพาะโฟลเดอร์ของตัวเอง
Home สร้างผู้ใช้ SFTP ที่เข้าได้เฉพาะโฟลเดอร์ของตัวเอง

สร้างผู้ใช้ 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 ก่อนเสมอ หากคอนฟิกผิดแล้วรีสตาร์ต คุณอาจเข้าเครื่องไม่ได้อีก

ขั้นตอนที่ 5: ทดสอบ

sftp [email protected]

เมื่อเข้าได้ ให้ลองคำสั่งเหล่านี้ในหน้าต่าง sftp

pwd
ls
cd upload
put testfile.txt
ls -l

ผู้ใช้จะเห็น / เป็นโฟลเดอร์บนสุด ซึ่งจริง ๆ คือ /var/sftp/customer1 และจะออกไปข้างนอกไม่ได้

ทดสอบว่า SSH ปกติเข้าไม่ได้จริง

ssh [email protected]

ควรถูกปฏิเสธหรือปิดการเชื่อมต่อทันที

ขั้นตอนที่ 6: ให้เข้าถึงโฟลเดอร์เว็บโดยไม่ย้ายไฟล์

กรณีที่พบบ่อยคืออยากให้ลูกค้าอัปโหลดไฟล์เข้าโฟลเดอร์เว็บที่อยู่คนละที่ ห้ามใช้ Symbolic Link เพราะลิงก์จะชี้ออกนอกกรงและใช้ไม่ได้ ให้ใช้ bind mount แทน

sudo mkdir -p /var/sftp/customer1/www
sudo mount --bind /var/www/example.com/public /var/sftp/customer1/www

ให้อยู่ถาวรหลังรีบูต

sudo nano /etc/fstab
/var/www/example.com/public  /var/sftp/customer1/www  none  bind  0 0
sudo mount -a
mount | grep customer1

ขั้นตอนที่ 7: เพิ่มผู้ใช้คนถัดไป

เมื่อวางโครงไว้แล้ว การเพิ่มคนใหม่เหลือเพียงสามคำสั่ง ไม่ต้องแตะคอนฟิก sshd อีก

sudo useradd -m -d /var/sftp/customer2 -s /usr/sbin/nologin -G sftponly customer2
sudo passwd customer2
sudo chown root:root /var/sftp/customer2 && sudo chmod 755 /var/sftp/customer2
sudo mkdir -p /var/sftp/customer2/upload
sudo chown customer2:customer2 /var/sftp/customer2/upload

ปัญหาที่พบบ่อย

เชื่อมต่อแล้วหลุดทันที ขึ้น Connection closed

สาเหตุอันดับหนึ่งคือสิทธิ์ของโฟลเดอร์ chroot ไม่เป็นไปตามกฎ ตรวจด้วย namei -l ทุกชั้นต้องเป็นเจ้าของ root และไม่เกิน 755 ดูสาเหตุที่แท้จริงได้จาก Log

sudo journalctl -u ssh -n 30 --no-pager | grep -i chroot

อัปโหลดไฟล์ไม่ได้ ขึ้น Permission denied

ผู้ใช้เขียนลงโฟลเดอร์บนสุดไม่ได้ตามกฎของ chroot ให้อัปโหลดเข้าโฟลเดอร์ย่อยที่เป็นเจ้าของโดยผู้ใช้นั้น เช่น upload

ไฟล์ที่อัปโหลดมาเว็บเซิร์ฟเวอร์อ่านไม่ได้

ตั้ง umask ด้วย -u 0002 ใน ForceCommand และให้ผู้ใช้เว็บอยู่ในกลุ่มเดียวกัน หรือใช้ ACL กำหนดสิทธิ์สืบทอดตามคู่มือเรื่อง ACL

Symbolic link ใช้ไม่ได้ในกรง

เป็นข้อจำกัดของ chroot โดยธรรมชาติ ลิงก์ที่ชี้ออกนอกกรงจะตามไม่ได้ ใช้ bind mount ตามขั้นตอนที่ 6 แทน

ต้องการให้ทีมงานช่วยวางสิทธิ์การเข้าถึงสำหรับผู้รับเหมาหรือลูกค้า ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security