EST. 2026 — บันทึกงานเซิร์ฟเวอร์จริง SYSADMIN · SECURITY · AI · DIRECTADMIN เล่มที่ 01
THE SYSADMIN ALMANAC
หน้าหลัก / Linux / แชร์โฟลเดอร์ torrent ด้วย Samba: force user และกับดัก bind interfaces
Linux

แชร์โฟลเดอร์ torrent ด้วย Samba: force user และกับดัก bind interfaces

โดย Ton-Or ·10 พ.ย. 2026·อ่าน 8 นาที
แชร์โฟลเดอร์ torrent ด้วย Samba: force user และกับดัก bind interfaces

แชร์โฟลเดอร์ข้าม Windows กับ Linux ง่ายตอนเปิดครั้งแรก แต่เจ็บตอนที่ไฟล์สองฝั่งมีเจ้าของคนละคนแล้วลบของกันไม่ได้ สูตรสั้น ๆ ที่แก้ได้คือบังคับให้ทุกการเขียนผ่าน Samba กลายเป็น user เดียวกับ daemon

สรุปใน 1 นาที

อาการ/ปัญหา
แชร์โฟลเดอร์ดาวน์โหลดข้าม Windows กับ Linux แล้วเจ้าของไฟล์คนละคน ลบของกันไม่ได้
ใครควรอ่าน
คนที่ตั้ง Samba บน Debian ให้เปิดโฟลเดอร์ของ Transmission จาก Windows
ทางแก้แบบสั้น
ใช้ force user, force group และ create mask ให้เขียนเป็น user เดียวกับ daemon และเช็กบรรทัด bind interfaces only ที่ถูกคอมเมนต์อยู่
ข้ามไปขั้นตอน

พอดีผมมีเซิร์ฟเวอร์ Debian ตัวหนึ่งรัน transmission-daemon ดาวน์โหลดลงดิสก์แยกที่ mount ไว้ แล้วอยากเปิดโฟลเดอร์นั้นให้ Windows ในบ้านเห็นเป็นไดรฟ์เครือข่าย เปิดดู แก้ชื่อ และลบไฟล์ได้ โดยที่ Transmission ยังจัดการไฟล์เดียวกันต่อได้ ถ้าตั้ง Samba แบบพื้นฐาน ไฟล์ที่ฝั่ง Windows สร้างกับไฟล์ที่ Transmission สร้างจะมีเจ้าของคนละคน แล้วต่างฝ่ายต่างลบหรือย้ายของอีกฝั่งไม่ได้ ผมเลยเขียนสูตรที่ใช้อยู่ไว้ตรงนี้ สั้นกว่าบทความอื่น ๆ เพราะเป็นสูตรปฏิบัติ

ชื่อโฟลเดอร์ ชื่อ share ชื่อ interface และ IP ในบทความเป็นตัวอย่างทั้งหมด (/srv/downloads, Downloads, br0, 192.168.10.52) ส่วนเรื่องตำแหน่งที่ติดตั้ง ถ้าเครื่องเป็นโฮสต์ของ VM ในงานจริงควรแยก Samba ไปไว้ใน VM หรือ LXC ไม่ควรติดตั้งบนตัว hypervisor นี่เป็นความเห็นทั่วไป ไม่ใช่สิ่งที่ผมทำในเคสนี้

ทำไมต้อง force user

ปัญหาคือ Samba ใช้ user ของคนที่ล็อกอินเป็นเจ้าของไฟล์ที่สร้าง สมมติผมล็อกอินด้วย user ชื่อ media ไฟล์ที่ Windows เขียนลงไปจะเป็น media:media ส่วนไฟล์ที่ Transmission ดาวน์โหลดเป็นของ debian-transmission พอ Transmission จะลบหรือย้ายไฟล์ของ media ที่ผมเพิ่งเปลี่ยนชื่อ มันทำไม่ได้ และทางกลับกัน Windows ก็แก้ไฟล์ของ daemon ไม่ได้เหมือนกัน

ทางแก้คือ force user กับ force group ที่ทำให้ทุกอย่างที่เข้ามาทาง share นี้ถูกมองเป็น debian-transmission ทั้งหมดในระดับระบบไฟล์ และใช้ create mask กับ directory mask กำหนดสิทธิ์ของไฟล์ใหม่ให้ทั้ง user และ group เขียนได้

1 ไม่มี force user: เจ้าของไฟล์คนละคนWindowsเขียนไฟล์smbdในนาม mediaไฟล์เจ้าของmedia:mediaTransmissionลบไม่ได้2 มี force user และ mask: เจ้าของเดียวกันWindowsเขียนไฟล์force user/groupdebian-transmissionเจ้าของเดียวกัน0664 / 0775Transmissionแก้ ลบได้เส้นแดงคือขั้นที่ไฟล์ชนกำแพงสิทธิ์ ส่วนข้างล่างลบกำแพงนั้นออก
ผลต่างอยู่ที่ใครเป็นเจ้าของไฟล์ในระบบไฟล์จริง ไม่ใช่ที่รหัสผ่านที่ Windows พิมพ์
ตู้เย็นรวมในห้องครัวส่วนกลางมีชั้นหนึ่งติดป้ายว่า Downloads มีสองมือคือมือของโน้ตบุ๊กกับมือของเซิร์ฟเวอร์วางและหยิบของได้อิสระ ภาชนะทุกใบมีป้ายชื่อเจ้าของเดียวกัน
ชั้นเดียวกัน ป้ายชื่อเจ้าของเดียวกันทุกกล่อง ทั้งสองฝั่งเลยหยิบวางได้

config ที่ใช้

เริ่มจากสำรองไฟล์เดิมก่อนแก้ทุกครั้ง เพราะ Samba เป็นของที่แก้ผิดแล้วต้องหาทางกลับ

sudo cp -a /etc/samba/smb.conf /etc/samba/smb.conf.orig-$(date +%Y%m%d)

# user สำหรับล็อกอิน share (ไม่มี shell ไม่มี home ใช้ได้แค่ผ่าน Samba)
sudo useradd -M -s /usr/sbin/nologin media
sudo smbpasswd -a media        # ตั้งรหัสของ Samba แยกจากรหัส Linux
[global]
   interfaces = lo br0
   bind interfaces only = yes
   server min protocol = SMB2
   map to guest = never
   # ...ค่า global อื่นที่มากับ Debian...

[Downloads]
   path = /srv/downloads
   valid users = media
   guest ok = no
   read only = no
   force user = debian-transmission
   force group = debian-transmission
   create mask = 0664
   directory mask = 0775

อธิบายทีละกลุ่ม interfaces กับ bind interfaces only ให้ Samba ฟังเฉพาะ loopback กับ NIC ของ LAN ผมวางสองบรรทัดนี้ทันทีหลังบรรทัด [global] ซึ่งเรื่องนี้มีกับดักอยู่ ขอเล่าในหัวข้อถัดไป ส่วน server min protocol = SMB2 ปิดโปรโตคอลเก่า map to guest = never กับ guest ok = no ไม่เปิด guest เลย ต้องล็อกอินด้วย media เท่านั้น

ใน share ผมให้ valid users = media คือมีคนเดียวที่ล็อกอินได้ แต่ทุกการเขียนไฟล์ถูกบังคับให้เป็น debian-transmission ผ่าน force user กับ force group ส่วน create mask = 0664 กับ directory mask = 0775 ทำให้ไฟล์ใหม่ที่ Windows สร้างมีสิทธิ์ที่ทั้ง user และ group เขียนได้ หลังแก้ไฟล์ ตรวจ syntax แล้วค่อย restart

testparm                       # ต้องไม่มี error และโชว์ Loaded services file OK
sudo systemctl restart smbd
umask ของ Transmission ผมไม่ได้ยืนยัน

ผมยังไม่ได้ตั้งหรือตรวจว่า transmission-daemon ใช้ umask แบบไหนตอนสร้างไฟล์ดาวน์โหลดเอง ถ้าอยากให้ไฟล์ที่ Transmission สร้างตรงกับ 0664 และ 0775 ทั้งหมด ต้องไปดูฝั่ง daemon ต่างหาก ในเคสนี้ผมพึ่งแค่ว่าเจ้าของไฟล์ทั้งสองฝั่งเป็น user เดียวกัน ซึ่ง force user ทำให้แล้ว

ฝั่ง Windows: map เป็นไดรฟ์ถาวร

ฝั่ง Windows เก็บ credential ด้วย cmdkey แล้ว map เป็นไดรฟ์ตัวอักษรเดียว ใส่ /persistent:yes ให้กลับมาหลังรีบูต ตัวอย่างนี้ใส่ <secret> แทนรหัสจริง

cmdkey /add:192.168.10.52 /user:media /pass:<secret>
net use Z: \\192.168.10.52\Downloads /persistent:yes
dir Z:\

ถ้าไฟล์ถูกสร้างจาก Windows แล้วไปดูบนเซิร์ฟเวอร์ ควรเห็นเจ้าของเป็น debian-transmission ตามที่ force user บังคับ ไม่ใช่ media

ls -l /srv/downloads | head
# -rw-rw-r-- 1 debian-transmission debian-transmission ... ไฟล์ที่สร้างจาก Windows

กับดักที่หนึ่ง: bind interfaces only ที่ถูกคอมเมนต์ไว้

เครื่องมี NIC หลายตัว ตัวหนึ่งต่อ LAN อีกตัวเป็นช่องจัดการ หรือช่องต่อโมเด็ม ผมไม่อยากให้ Samba ฟังที่ตัวอื่นนอกจาก LAN เลยตั้ง interfaces กับ bind interfaces only และมีเงื่อนไขว่าอย่าให้กลายเป็นช่องโหว่ ถ้าเครื่องมี IP สาธารณะหรือ NIC ที่ต่ออินเทอร์เน็ตตรง ๆ ควรปิดช่องทางนั้นด้วย firewall เพิ่มอีกชั้น ซึ่งเป็นหลักทั่วไป

กับดักที่ผมเจอจริงคือ ไฟล์ smb.conf ค่าเริ่มต้นของ Debian มีบรรทัดแบบนี้อยู่แล้ว

;   bind interfaces only = yes

บรรทัดนั้นถูกคอมเมนต์ด้วยเครื่องหมาย ; ผมมีสคริปต์ติดตั้งที่เช็กก่อนเพิ่มค่าว่ามีบรรทัดนี้อยู่แล้วหรือยัง ด้วย grep แบบไม่ยึดต้นบรรทัด เจอบรรทัดที่คอมเมนต์ก็นึกว่ามีแล้ว เลยข้ามการเพิ่ม ผลคือ Samba ไม่ได้ bind จริง และไม่มี error ใด ๆ บอก

smbd ฟังเฉพาะ NIC ที่ระบุWindows192.168.10.xloloopbackbr0192.168.10.0/24mgmt/modemไม่ใช่ LANsmbdinterfaces =lo br0bind only = yesไม่รับกับดัก: ค่าเริ่มต้นมีบรรทัดนี้อยู่แล้วแต่ถูกคอมเมนต์; bind interfaces only = yes
Windows ใน LAN เข้าทาง br0 ได้ ส่วนช่องที่ไม่อยู่ใน interfaces เส้นประจบแล้วไม่รับ กล่องแดงล่างคือบรรทัดที่ grep หลงเชื่อ

วิธีแก้มีสองส่วน ตรวจด้วย pattern ที่ยึดต้นบรรทัดและไม่นับบรรทัดคอมเมนต์ และตรวจผลจริงที่ Samba อ่านได้ ไม่ใช่ดูแค่ไฟล์

# ผิด: เจอบรรทัดที่ถูกคอมเมนต์ด้วย เลยนึกว่ามีแล้ว
grep -q 'bind interfaces only' /etc/samba/smb.conf && echo "มีแล้ว (หลอก)"

# ถูก: นับเฉพาะบรรทัดที่ไม่ใช่คอมเมนต์
grep -Eq '^[[:space:]]*bind interfaces only' /etc/samba/smb.conf && echo "มีจริง"

# พิสูจน์ด้วยค่าที่ Samba ใช้จริง (รันหลัง restart)
testparm -s 2>/dev/null | grep -iE 'bind interfaces|interfaces ='

# พิสูจน์ว่า smbd ฟังที่ไหนบ้าง
sudo ss -ltnp | grep smbd

บรรทัดสุดท้ายคือด่านที่ผมไว้ใจที่สุด เพราะมันดูสิ่งที่ระบบเปิดฟังอยู่จริง ถ้า smbd ฟังที่ 0.0.0.0:445 แสดงว่ายังไม่ได้ bind ถ้าเห็นเฉพาะ IP ของ LAN กับ loopback ถึงถือว่าถูกต้อง ขั้น ss นี้เป็นวิธีตรวจทั่วไปที่ผมแนะนำให้ทดสอบบนเครื่องตัวเองด้วย ส่วนการวางบรรทัดใหม่ทันทีหลัง [global] ผมทำเพื่อไม่ให้ไปปนกับบรรทัดคอมเมนต์เดิมที่อยู่ลึกลงไป

แปลนอาคารที่มีสามประตู เปิดเฉพาะประตู LAN หลัก อีกสองประตูถูกปิดผนึกด้วยตราแดง
สามประตู เปิดทางเดียว คือ NIC ของ LAN ส่วนอีกสองบานต้องปิดจริง ไม่ใช่แค่เขียนว่าปิด
เช็กว่ามีบรรทัดนี้ ต้องเช็กให้ถูกชนิดบรรทัด

ค่าตัวอย่างที่คอมเมนต์ไว้ในไฟล์ค่าเริ่มต้นหลอก grep ได้ทุกครั้งที่ pattern ไม่ยึดต้นบรรทัด ทุกครั้งที่สคริปต์ติดตั้งจะ "เพิ่มถ้ายังไม่มี" ให้ตรวจผลที่ testparm -s หรือ ss ควบคู่ ไม่ใช่เชื่อแค่ผลของ grep บนไฟล์

ตัวเลข mask อ่านยังไง และ force user ทำให้เสียอะไร

ตัวเลข 0664 กับ 0775 คือสิทธิ์ของ Linux สามชั้นเรียงตามเจ้าของ กลุ่ม และคนอื่น โดย 6 คืออ่านกับเขียน 7 คืออ่าน เขียน และรันหรือเข้าโฟลเดอร์ 4 คืออ่านอย่างเดียว ดังนั้นไฟล์ใหม่เป็น rw-rw-r-- ส่วนโฟลเดอร์ใหม่เป็น rwxrwxr-x เหตุที่โฟลเดอร์ต้องมี x เพราะไม่มี x ก็เข้าโฟลเดอร์ไม่ได้ จุดสำคัญคือทั้งเจ้าของและกลุ่มเขียนได้ ถึงแม้ใครจะเปลี่ยนมาเป็น user อื่นในกลุ่มเดียวกันทีหลังก็ยังแก้ไฟล์ได้ ส่วนคนอื่นนอกกลุ่มอ่านได้อย่างเดียว

ราคาที่ต้องจ่ายของ force user มีสองข้อที่ควรรู้ก่อนเลือกใช้ ข้อแรก ทุกการเขียนผ่าน share นี้ถูกมองเป็น debian-transmission ในระดับระบบไฟล์ ถ้าอยากรู้ว่าใครสร้างหรือลบไฟล์ ต้องดูจาก log ของ Samba เอง เพราะระบบไฟล์ไม่เก็บชื่อคนที่ล็อกอินไว้ ข้อสอง ใครก็ตามที่อยู่ใน valid users จะมีสิทธิ์เท่ากับ daemon เสมอ ตอนนี้ผมให้มี user เดียวคือ media เลยไม่เป็นปัญหา แต่ถ้าวันหนึ่งเพิ่มคนเข้าไปหลายคน และอยากแยกสิทธิ์ใครอ่านอย่างเดียว ก็ต้องทำ share แยกอีกตัวที่ตั้ง read only = yes ไม่ใช่เอาไปปนในตัวนี้

ทางเลือกอื่นที่ผมรู้คือใช้ POSIX ACL กำหนดสิทธิ์ราย user บนโฟลเดอร์ หรือไล่ chown ตามหลังเป็นระยะ ซึ่งผมไม่ได้เลือก เพราะ ACL ซับซ้อนขึ้นอีกชั้นสำหรับโฟลเดอร์ที่ใช้งานคนเดียว และ chown ตามหลังต้องมีใครสักคนจำว่าต้องรัน force user ตัดปัญหานี้ที่ต้นทางและตั้งครั้งเดียวจบ ส่วนใครที่เครื่องมีหลายคนและต้องการสิทธิ์ต่างกัน ควรไปดูทาง ACL แทน

ขั้นตรวจก่อนบอกว่าเสร็จ

  1. รัน testparm ต้องไม่มีคำเตือนเรื่องค่าที่ไม่รู้จัก และต้องเห็นชื่อ share ที่ตั้งไว้
  2. รัน testparm -s | grep -i bind ต้องเห็น bind interfaces only = Yes จากค่าที่ Samba ตีความจริง
  3. รัน ss -ltnp | grep smbd ต้องไม่เห็น 0.0.0.0:445
  4. จาก Windows map ไดรฟ์ แล้วสร้างไฟล์ทดสอบ กลับไปดู ls -l บนเซิร์ฟเวอร์ ต้องเป็นเจ้าของ debian-transmission
  5. ลองลบไฟล์เดียวกันจากฝั่ง Transmission หรือด้วย user ของ daemon ต้องลบได้ และลบไฟล์ที่ Transmission สร้างจาก Windows ต้องได้ด้วย
ไม่ตั้ง

Samba พื้นฐาน

  • เจ้าของไฟล์ตาม user ที่ล็อกอิน
  • สองฝั่งลบของกันไม่ได้
  • ฟังทุก NIC ที่เครื่องมี
  • ต้องไล่ chown ทีหลังเรื่อย ๆ
ตั้งตามสูตร

force user + bind

  • เจ้าของไฟล์เป็น user ของ daemon
  • สองฝั่งแก้และลบได้
  • ฟังเฉพาะ lo กับ LAN
  • ตรวจผลจริงได้ด้วย ss
2 บรรทัดforce user และ force group
0664create mask ของไฟล์
0775directory mask ของโฟลเดอร์
SMB2+ขั้นต่ำของโปรโตคอล
0 guestต้องล็อกอินทุกครั้ง

ก่อนปิดเรื่อง ขอเล่าพฤติกรรมฝั่ง Windows ที่ทำให้งงได้ตอนแก้ config ถ้าไดรฟ์ Z: ต่ออยู่ก่อนแล้วผมไปแก้ smb.conf เซสชันเดิมยังคงถือค่าเก่า การทดสอบหลังแก้ต้องตัดการเชื่อมต่อเดิมก่อน (net use Z: /delete) แล้ว map ใหม่ ไม่งั้นจะนึกว่าแก้ไม่ได้ผล ทั้งที่แค่ยังไม่ได้ต่อใหม่ อีกข้อคือเมื่อเปลี่ยนรหัสด้วย smbpasswd ต้องลบ credential ที่เก็บไว้ด้วย cmdkey /delete:192.168.10.52 แล้วเพิ่มใหม่ มิฉะนั้น Windows จะส่งรหัสเก่าซ้ำไปจนบัญชีล็อกหรือขึ้นข้อความปฏิเสธซ้ำ ๆ ทั้งสองข้อเป็นเรื่องทั่วไปของการใช้ไดรฟ์เครือข่าย ไม่ได้เจาะจงกับเคสนี้

สิ่งที่ผมไม่ได้ทดสอบ

ผมไม่ได้วัดประสิทธิภาพการส่งไฟล์ ไม่ได้ลองกับ macOS หรือ Linux เป็นฝั่ง client และไม่ได้ทดสอบกับ Windows 11 ที่ปิด SMB1 ด้วยตัวเอง ที่บันทึกไว้คือเครื่อง Windows ฝั่งผมต่อได้ด้วย SMB2 ขึ้นไปและไม่มี guest ใครจะเอาสูตรนี้ไปใช้กับ client อื่นก็ต้องลองเองเลยครับ ส่วนเรื่องสิทธิ์ไฟล์เชิงลึกกว่านี้ เช่น ใช้ POSIX ACL แทน force user ก็เป็นอีกทางที่ผมไม่ได้เลือกในเคสนี้ ตรงไหนผมอธิบายตกหล่นหรือพิมพ์ผิด เดี๋ยวกลับมาแก้เพิ่มให้ภายหลังครับ

อยากให้เราทำให้ไหม?

ให้เราช่วยติดตั้ง ตั้งค่า ย้ายระบบ หรือแก้ปัญหาเซิร์ฟเวอร์ เพื่อให้คุณมีเวลาไปทำงานที่สำคัญกว่า

คุยเรื่องงานกับเรา

เคยเจองานแบบนี้ไหม? ติดตรงไหน?

มาแลกวิธีกันต่อในบอร์ด LinuxThai

→ คุยต่อในบอร์ด

ความคิดเห็น 0

ยังไม่มีความคิดเห็น — เป็นคนแรกเลย