ประวัติโปรโตคอลโอนไฟล์จาก Kermit สู่ rsync และ SFTP
ย้อนรอยวิวัฒนาการโปรโตคอลโอนไฟล์จากยุค Kermit บนสายโทรศัพท์สู่ rsync และ SFTP ในปัจจุบัน เรียนรู้ว่าทำไมข้อจำกัดของเครือข่ายในอดีตจึงกำหนดมาตรฐานการรับส่งข้อมูลที่เราใช้ในทุกวันนี้
เหตุใดโปรโตคอลการถ่ายโอนไฟล์จึงมีการเปลี่ยนแปลงอยู่ตลอด
โปรโตคอลการถ่ายโอนไฟล์แต่ละตัวถูกออกแบบมาเพื่อรับมือกับรูปแบบความล้มเหลวของทศวรรษที่มันถูกสร้างขึ้น Kermit ถูกออกแบบโดยสมมติว่าสายสัญญาณจะทำให้ข้อมูลไบต์ของคุณเสียหาย XMODEM และ ZMODEM ถูกออกแบบโดยสมมติว่าการเชื่อมต่อมีความเร็วต่ำและคุณต้องจ่ายค่าบริการเป็นรายนาที FTP (file transfer protocol) ถูกออกแบบโดยสมมติว่าเครือข่ายระหว่างทางมีความร่วมมือกัน ส่วน SSH ถูกออกแบบโดยสมมติว่าเครือข่ายนั้นเป็นศัตรู ซึ่งข้อสมมติสุดท้ายนี้คือสิ่งที่ได้รับชัยชนะ จึงเป็นเหตุผลว่าทำไม VPS ในปัจจุบันจึงให้คุณใช้งาน SFTP และ rsync ผ่าน SSH เป็นหลักและแทบไม่มีอย่างอื่นให้เลือกใช้
ปัจจุบันมีโอกาสที่น่าสนใจในการพิจารณาเรื่องนี้ C-Kermit 11.0.506 ได้รับการปล่อยออกมาเมื่อวันที่ 3 August 2026 ซึ่งถือเป็นรุ่น non-beta รุ่นแรกนับตั้งแต่ C-Kermit 9.0.302 เมื่อวันที่ 20 August 2011 โดยโปรโตคอลที่มันนำมาใช้งานนั้นถูกออกแบบขึ้นในเดือน May 1981 ระยะเวลา 45 ปีนั้นยาวนานเพียงพอที่จะได้เห็นหมวดหมู่เทคโนโลยีหนึ่งถูกคิดค้นขึ้น ได้รับการกำหนดมาตรฐาน ถูกทำลายโดยเครือข่ายที่มันทำงานอยู่ และในที่สุดก็ถูกผนวกรวมเข้าเป็นส่วนหนึ่งของ SSH
Kermit, 1981: ออกแบบมาเพื่อสายสื่อสารที่กัดกินไบต์ของคุณ
Kermit ถูกสร้างขึ้นในเดือนพฤษภาคม 1981 ที่ศูนย์คอมพิวเตอร์แห่งมหาวิทยาลัยโคลัมเบีย โดย Frank da Cruz และ Bill Catchings ชื่อนี้มาจาก Kermit the Frog โดย da Cruz เล่าว่าในขณะที่กลุ่มกำลังคิดชื่อโปรแกรม มีปฏิทิน Muppets แขวนอยู่บนผนัง และไม่มีใครคาดคิดว่าซอฟต์แวร์นี้จะแพร่หลายไปไกล
ปัญหาที่ Kermit แก้ไขไม่ใช่เรื่องความเร็ว เส้นทางระหว่างเทอร์มินัลกับเมนเฟรมในสมัยนั้นไม่ใช่ท่อส่งข้อมูลไบต์แบบอิสระ แต่เป็นอุปกรณ์สื่อสารแบบตัวอักษรที่มีข้อจำกัดเฉพาะตัว บางครั้งรองรับเพียง 7-bit บางครั้งเป็นแบบ half-duplex หรืออาจกลืนกินอักขระควบคุม (control characters) หรือตีความอักขระเหล่านั้นเป็นคำสั่ง ทำให้การส่งไฟล์ไบนารีผ่านช่องทางนี้โดยตรงไม่สามารถทำได้
การออกแบบจึงต้องคำนึงถึงข้อจำกัดเหล่านี้อย่างเคร่งครัด ประวัติของ Kermit Project ได้ระบุไว้ดังนี้:
- แพ็กเก็ตขนาดเล็ก เนื่องจากเมนเฟรมส่วนใหญ่ไม่สามารถรับข้อมูลปริมาณมากที่ส่งเข้ามาจากเทอร์มินัลได้
- การสื่อสารแบบ half-duplex ที่หยุดรอการตอบรับ (stop-and-wait) เนื่องจากเมนเฟรมของ IBM ไม่รองรับการสื่อสารแบบ full-duplex
- การเข้ารหัสอักขระควบคุมและอักขระ 8-bit ให้อยู่ในรูปแบบที่พิมพ์ได้ (printable encodings) เนื่องจากไดรเวอร์เทอร์มินัลของเมนเฟรมไม่สามารถส่งผ่านข้อมูลเหล่านี้ได้
- การตรวจสอบ checksum ในทุกแพ็กเก็ตโดยมีการตอบรับจากผู้รับ เพื่อให้เมื่อเกิดความเสียหายของข้อมูล จะเสียเวลาเพียงแค่การส่งซ้ำแพ็กเก็ตนั้น ไม่ใช่การส่งไฟล์ใหม่ทั้งหมด
ประเด็นที่สามเป็นสิ่งที่น่าสนใจที่สุด Kermit ส่งข้อมูลในรูปแบบที่ปลอดภัยสำหรับข้อความแทนที่จะส่งไฟล์ต้นฉบับ ไบต์ที่เป็นอักขระควบคุมจะถูกแปลงเป็นอักขระนำหน้าตามด้วยอักขระที่พิมพ์ได้ ส่วนไบต์ที่มีการตั้งค่า high bit ไว้ก็จะถูกเข้ารหัสในลักษณะเดียวกันเพื่อให้ผ่านลิงก์แบบ 7-bit ได้ อุปกรณ์ใดก็ตามที่อยู่ตรงกลางซึ่งเข้าใจเฉพาะข้อความที่พิมพ์ได้ก็จะมองเห็นเพียงข้อความปกติเท่านั้น สิ่งที่ต้องแลกคือขนาดไฟล์: ไฟล์ไบนารีจะมีขนาดใหญ่ขึ้นเมื่ออยู่บนสายส่ง แต่เมื่อเทียบกับการที่ front end ของเมนเฟรมจะทำลายข้อมูลจนเสียหายทั้งหมด นี่ถือเป็นการแลกเปลี่ยนที่คุ้มค่า
คุณสมบัติอีกประการที่โดดเด่นของ Kermit คือขอบเขตการใช้งาน XMODEM ออกแบบมาเพื่อย้ายไฟล์ระหว่างเครื่องสองเครื่องที่ตกลงกันไว้แล้วว่าไฟล์คืออะไร แต่ Kermit ถูกเขียนขึ้นเพื่อเป็นตัวกลางที่ต่ำที่สุดระหว่างระบบที่ไม่เข้าใจกัน ทั้งในแง่ของชุดอักขระ โครงสร้างบันทึกข้อมูล และแนวคิดเรื่องจุดสิ้นสุดของบรรทัดข้อความ นั่นคือโลกที่ถูกอธิบายไว้ใน การย้ายข้อมูลครั้งใหญ่จากเมนเฟรมสู่คลาวด์เซิร์ฟเวอร์ และ Kermit คือหน้าตาของการทำงานร่วมกันได้ (interoperability) ก่อนที่ network layer จะเข้ามาจัดการเรื่องนี้ให้คุณ
มหาวิทยาลัยโคลัมเบียยุติการสนับสนุนในปี 2011 และปล่อย C-Kermit ภายใต้สัญญาอนุญาต BSD 3-clause ฉบับปรับปรุง Frank da Cruz อยู่กับโครงการนี้มานานถึง 44 ปี ตั้งแต่การออกแบบในปี 1981 จนถึงปี 2025 สำหรับรุ่นปี 2026 นั้นได้รับการดูแลโดยโครงการ OpenKermit โดยมี John Goerzen เป็นผู้รับหน้าที่ปรับปรุง codebase ภาษา C ให้ทันสมัย ซึ่งมีอายุเก่าแก่กว่าผู้อ่านส่วนใหญ่ในปัจจุบันเสียอีก
XMODEM และ ZMODEM: เมื่อค่าโทรศัพท์กำหนดทิศทางการออกแบบ
Ward Christensen เขียนโปรแกรม MODEM.ASM ขึ้นในปี 1977 และโปรโตคอลที่เขาแนะนำคือ XMODEM ต่อมาในปี 1978 เขาและ Randy Suess ได้เปิดใช้งาน CBBS ซึ่งเป็นระบบกระดานข่าวสาธารณะแห่งแรก Christensen เสียชีวิตเมื่อวันที่ 11 ตุลาคม 2024
XMODEM เป็นโปรโตคอลที่มีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้ ข้อมูลจะถูกส่งเป็นบล็อกขนาด 128 ไบต์ แต่ละบล็อกจะมี checksum ขนาดหนึ่งไบต์ ซึ่งคำนวณจากผลรวมของข้อมูล 128 ไบต์แบบ modulo 256 ผู้รับจะส่งสัญญาณตอบรับ (acknowledge) ทุกครั้งที่ได้รับบล็อก หรือขอให้ส่งใหม่หากเกิดข้อผิดพลาด เหตุผลที่ออกแบบมาในลักษณะนี้คือเรื่องของต้นทุน ในยุคที่ใช้สายโทรศัพท์ (dial-up) คุณต้องจ่ายเงินตามเวลาที่ใช้งาน ดังนั้นหากเกิดข้อผิดพลาดบนสายส่ง ข้อมูลที่เสียหายควรมีขนาดเพียงหนึ่งบล็อก แทนที่จะต้องส่งใหม่ทั้งหมดตั้งแต่ต้น
จุดอ่อนของโปรโตคอลนี้ก็อยู่ในประโยคเดียวกัน XMODEM ต้องรอสัญญาณตอบรับหลังจากส่งข้อมูลทุกๆ 128 ไบต์ Chuck Forsberg ได้อธิบายไว้อย่างชัดเจนในข้อกำหนดของ ZMODEM ว่า "ขนาดบล็อกที่สั้นทำให้ประสิทธิภาพการรับส่งข้อมูลลดลงเมื่อใช้งานกับระบบ timesharing, เครือข่ายแบบ packet switched และวงจรสื่อสารผ่านดาวเทียม" ค่าความหน่วง (latency) คือสิ่งที่ทำลายระบบแบบ stop-and-wait ไม่ใช่แบนด์วิดท์ การรอสัญญาณตอบรับแต่ละครั้งคือช่วงเวลาที่สูญเปล่าบนสายส่งที่คุณต้องเสียค่าใช้จ่าย
ต่อมา YMODEM ได้ถูกพัฒนาขึ้น โดย Ward Christensen เป็นผู้ตั้งชื่อนี้ในปี 1985 สิ่งที่เพิ่มเข้ามาคือการส่งไฟล์แบบกลุ่ม (batch transfer) ผู้ส่งจะระบุชื่อไฟล์และขนาดก่อนเริ่มส่งข้อมูล ทำให้สามารถส่งหลายไฟล์ได้ในเซสชันเดียว และผู้รับจะทราบจุดสิ้นสุดของแต่ละไฟล์
ZMODEM คือคำตอบจาก Chuck Forsberg ซึ่งเขียนขึ้นที่ Omen Technology ข้อกำหนดฉบับวันที่ 14 ตุลาคม 1988 ระบุว่า "ZMODEM ถูกพัฒนาขึ้นสำหรับสาธารณสมบัติภายใต้สัญญาจ้างของ Telenet" ในขณะนั้น Telenet ดำเนินกิจการเครือข่ายข้อมูลแบบ packet-switched สาธารณะ ซึ่งอิทธิพลของสัญญานี้ปรากฏชัดในการออกแบบ ZMODEM มีการ escape อักขระควบคุมเครือข่าย เพื่อป้องกันไม่ให้เครือข่าย packet ที่อยู่ตรงกลางนำอักขระเหล่านั้นไปตีความ นอกจากนี้ยังทำเครื่องหมายจุดเริ่มต้นของทุกเฟรมด้วยลำดับอักขระเฉพาะ แทนที่จะคาดเดาขอบเขตเฟรมจากความเงียบ ทำให้ระบบสามารถกู้คืนจากการรบกวนได้โดยไม่ต้องรอให้หมดเวลา (timeout) อีกทั้งยังมีฟังก์ชันการส่งต่อ (resume) ที่ชัดเจน ทำให้การส่งไฟล์ที่ถูกขัดจังหวะสามารถเริ่มใหม่จากจุดเดิมได้
ที่สำคัญที่สุดคือ ZMODEM เลิกใช้วิธีการรอสัญญาณตอบรับ คำอธิบายในข้อกำหนดระบุว่า "ZMODEM ใช้ไฟล์ทั้งไฟล์เป็นหน้าต่าง (window) ในการส่งข้อมูล" ผู้ส่งจะสตรีมข้อมูลอย่างต่อเนื่องและหยุดก็ต่อเมื่อผู้รับแจ้งว่ามีปัญหา นี่คือแนวคิดเดียวกับที่ TCP ใช้ในระบบ window เพียงแต่เป็นการเข้าถึงจากมุมมองที่ต่างออกไป โดยเกิดจากการสังเกตเห็นโมเด็มที่ต้องนั่งรออย่างไร้ประโยชน์
เหตุใดการเชื่อมต่อสองทางของ FTP จึงล้าสมัยอย่างรวดเร็ว
FTP มีอายุเก่าแก่กว่าโปรโตคอลอื่นทั้งหมด RFC 114 เรื่อง "A File Transfer Protocol" ลงวันที่ 16 เมษายน 1971 เขียนโดย A. Bhushan
รายละเอียดที่ควรทราบคือ RFC 114 ได้พิจารณาการออกแบบที่ใช้การเชื่อมต่อสองทางแล้วแต่ปฏิเสธไป Bhushan ได้ชั่งน้ำหนักเรื่อง "การใช้ลิงก์ full-duplex สองชุด ชุดหนึ่งสำหรับข้อมูลควบคุม อีกชุดสำหรับข้อมูล" และสรุปว่า: "เราแนะนำให้ใช้การเชื่อมต่อ full-duplex เพียงชุดเดียวสำหรับการแลกเปลี่ยนทั้งข้อมูลและข้อมูลควบคุม" การแยกการเชื่อมต่อเกิดขึ้นในภายหลัง โดย RFC 354 ลงวันที่ 8 กรกฎาคม 1972 ระบุว่า "ข้อมูลและไฟล์จะถูกโอนย้ายผ่านการเชื่อมต่อข้อมูลเท่านั้น" โดยมีคำสั่งต่างๆ ส่งผ่านการเชื่อมต่อ Telnet แยกต่างหาก ส่วน RFC 959 เดือนตุลาคม 1985 โดย Postel และ Reynolds คือเวอร์ชันที่ทุกคนยังคงใช้งานอยู่ในปัจจุบัน
RFC 959 ยังได้กำหนดพอร์ตไว้ด้วย พอร์ตข้อมูลเริ่มต้นของเซิร์ฟเวอร์คือ "พอร์ตที่อยู่ติดกับพอร์ตการเชื่อมต่อควบคุม (เช่น L-1)" ซึ่งก็คือพอร์ต 20 ในขณะที่การเชื่อมต่อควบคุมใช้พอร์ต 21
นี่คือส่วนที่ไม่สามารถใช้งานได้ในปัจจุบัน ในโหมดดั้งเดิมของ FTP เซิร์ฟเวอร์จะเป็นฝ่ายเปิดการเชื่อมต่อข้อมูลกลับไปยังไคลเอนต์ ไคลเอนต์ที่อยู่หลัง NAT (network address translation) จะไม่มีที่อยู่ที่เซิร์ฟเวอร์สามารถเข้าถึงได้ และไคลเอนต์ที่อยู่หลังไฟร์วอลล์จะไม่ยอมรับการเชื่อมต่อขาเข้า ทำให้การเชื่อมต่อข้อมูลไม่เคยเกิดขึ้น และการโอนย้ายจะค้างทันทีที่มีการร้องขอรายการไฟล์หรือไฟล์ คำตอบของปัญหานี้คือ PASV ซึ่ง RFC 959 นิยามไว้ว่าเป็นการร้องขอให้เซิร์ฟเวอร์ "'ฟัง' บนพอร์ตข้อมูล (ซึ่งไม่ใช่พอร์ตข้อมูลเริ่มต้น) และรอการเชื่อมต่อแทนที่จะเป็นฝ่ายเริ่มเชื่อมต่อเองเมื่อได้รับคำสั่งโอนย้าย" เซิร์ฟเวอร์จะตอบกลับด้วยที่อยู่และพอร์ตที่จะให้เชื่อมต่อ:
PASV
227 Entering Passive Mode (203,0,113,10,195,80)การตอบกลับนั้นหมายถึงโฮสต์ 203.0.113.10 พอร์ต 195 คูณ 256 บวก 80 ซึ่งเท่ากับ 50000 เมื่อพิจารณาอีกครั้งจะเห็นปัญหาเชิงโครงสร้าง ปลายทางของการเชื่อมต่อที่สองถูกประกาศไว้ภายใน payload ของการเชื่อมต่อแรก อุปกรณ์ NAT หรือไฟร์วอลล์ไม่สามารถส่งผ่านการเชื่อมต่อดังกล่าวได้เว้นแต่จะวิเคราะห์ช่องทางควบคุมและเปิดพอร์ตที่เห็นในนั้น Linux มี connection tracking helper ที่ทำหน้าที่นี้โดยเฉพาะ แต่ helper จะทำงานได้ก็ต่อเมื่อการเชื่อมต่อควบคุมเป็นข้อความธรรมดา (cleartext) ดังนั้นการห่อหุ้ม FTP ด้วย TLS (transport layer security) จึงทำให้ middlebox ที่เคยช่วยให้ FTP ใช้งานได้นั้นมองไม่เห็นข้อมูล
นั่นคือบทเรียนของ FTP ในประโยคเดียว มันทำให้เครือข่ายกลายเป็นผู้มีส่วนร่วมในโปรโตคอล โปรโตคอลที่ต้องการให้เครือข่ายเข้าใจการทำงานของมันจะไม่สามารถอยู่รอดได้ในเครือข่ายที่เลิกเชื่อใจมันแล้ว
จุดจบของเรื่องนี้ถูกบันทึกไว้ชัดเจน Firefox ถอดการรองรับ FTP ออกในเวอร์ชัน 90 เมื่อเดือนกรกฎาคม 2021 ส่วน Chrome ถอดโค้ด FTP ออกใน Chrome 95 เมื่อเดือนตุลาคม 2021
rcp และคำสั่งตระกูล r: ความเชื่อถือผ่าน hostname
4.2BSD ซึ่งเปิดตัวในปี 1983 โดย Berkeley ด้วยเงินทุนจาก DARPA ได้นำเสนอ rcp, rsh และ rlogin เครื่องมือเหล่านี้ถูกสร้างขึ้นสำหรับกลุ่มเครื่อง Unix ในเครือข่ายเดียวกันภายในมหาวิทยาลัย ซึ่งรูปแบบการยืนยันตัวตนสะท้อนแนวคิดดังกล่าว โดยโฮสต์จะเป็นผู้ยืนยันว่าผู้ใช้คนใดกำลังเรียกใช้งาน หาก /etc/hosts.equiv หรือไฟล์ ~/.rhosts ของผู้ใช้ระบุว่าโฮสต์นั้นเชื่อถือได้ ระบบจะยอมรับการยืนยันนั้นโดยไม่ถามรหัสผ่าน
อธิบายกลไกนี้ให้ชัดเจน เพราะนี่คือเหตุผลที่คำสั่งเหล่านี้ถูกยกเลิกไป ความเชื่อถือขึ้นอยู่กับที่อยู่และการอ้างสิทธิ์ ข้อมูลทั้งสองส่วนเดินทางผ่านเครือข่ายในรูปแบบข้อความธรรมดา (cleartext) ดังนั้นใครก็ตามที่อยู่บนเส้นทางดังกล่าวสามารถอ่านและปลอมแปลงข้อมูลได้ รูปแบบนี้สมเหตุสมผลในสภาพแวดล้อมที่อธิบายไว้ใน เส้นทางจาก Unix สู่ Linux ซึ่งเครือข่ายจำกัดอยู่เพียงภายในอาคาร แต่แนวคิดนี้ไม่สมเหตุสมผลอีกต่อไปเมื่อเครือข่ายกลายเป็นอินเทอร์เน็ต
สิ่งที่ rcp ทำได้ดีคืออินเทอร์เฟซ ต้นทาง ปลายทาง เสร็จสิ้น ไม่ต้องเปิดเซสชัน ไม่ต้องตกลงโหมดการถ่ายโอน และไม่ต้องจัดเตรียมการเชื่อมต่อที่สอง มันทำงานเหมือนกับ cp โดยมีเครื่องหมายทวิภาค (colon) อยู่ใน path อินเทอร์เฟซดังกล่าวมีอายุยืนยาวกว่าโปรโตคอลของมันถึงสี่ทศวรรษ
SSH เข้ามาแทนที่ทุกอย่างในหมวดหมู่เดียวกัน
ในปี 1995 Tatu Ylonen ซึ่งขณะนั้นเป็นนักวิจัยที่ Helsinki University of Technology ได้เขียน SSH ขึ้นเพื่อตอบโต้การโจมตีแบบดักจับรหัสผ่านบนเครือข่ายของมหาวิทยาลัย เขาเผยแพร่ซอฟต์แวร์นี้ในรูปแบบฟรีซอฟต์แวร์พร้อมซอร์สโค้ดในเดือนกรกฎาคม 1995 เมื่อสิ้นปีนั้นมีการประเมินว่ามีผู้ใช้งานประมาณ 20,000 คนใน 50 ประเทศ และในเดือนธันวาคม 1995 เขาก่อตั้งบริษัท SSH Communications Security เพื่อพัฒนาซอฟต์แวร์นี้ต่อไป
ใบอนุญาตใช้งานมีความเข้มงวดมากขึ้นในเวอร์ชันถัดมา นักพัฒนา OpenBSD จึงทำการ fork เวอร์ชันสุดท้ายที่ยังเป็นใบอนุญาตแบบเสรี คือ ssh 1.2.12 การนำเข้าโค้ดครั้งแรกเกิดขึ้นเมื่อวันที่ 26 กันยายน 1999 และ OpenSSH 1.2.2 ได้ถูกปล่อยออกมาพร้อมกับ OpenBSD 2.6 ในวันที่ 1 ธันวาคม 1999 การ fork ครั้งนั้นเป็นกรณีศึกษาที่ชัดเจนว่า เหตุใดเงื่อนไขใบอนุญาตโอเพนซอร์สจึงมีความสำคัญในทางปฏิบัติ เพราะการใช้งาน SSH ที่เกือบทุกคนใช้ในปัจจุบันล้วนสืบทอดมาจากเวอร์ชันเดียวที่ใบอนุญาตยังคงอนุญาตให้ทำได้
เมื่อ SSH ถือกำเนิดขึ้น การโอนย้ายไฟล์ก็ไม่ใช่ปัญหาแยกต่างหากอีกต่อไป สตรีมข้อมูลที่ผ่านการตรวจสอบสิทธิ์และเข้ารหัสซึ่งรองรับหลายช่องทาง (multiple channels) ได้มอบสิ่งที่โปรโตคอลรุ่นเก่าต้องสร้างขึ้นเอง นั่นคือ ความสมบูรณ์ของข้อมูล (integrity), การเรียงลำดับ (ordering) และเส้นทางข้อมูลที่สองที่ไม่จำเป็นต้องใช้การเชื่อมต่อ TCP เพิ่มเติม หากกลไกเหล่านี้เป็นเรื่องใหม่สำหรับคุณ ให้เริ่มจากทำความเข้าใจว่า SSH คืออะไรจริงๆ ก่อนที่จะศึกษาต่อ
เครื่องมือสองอย่างเกิดขึ้นจากสิ่งนี้ scp คือโปรโตคอลการสื่อสารของ rcp ที่ทำงานภายในเซสชัน SSH ซึ่งเป็นเหตุผลว่าทำไมมันจึงสืบทอดรูปแบบคำสั่งของ rcp มาโดยตรง ส่วน SFTP เป็นการออกแบบที่แตกต่างออกไป คือเป็นโปรโตคอลสำหรับไฟล์โดยเฉพาะที่มีการแสดงรายการไดเรกทอรี, คุณสมบัติของไฟล์ และการเข้าถึงแบบสุ่ม (random access) โดยทำงานผ่านช่องทางของ SSH SFTP ไม่เคยกลายเป็นมาตรฐาน RFC โดยร่างของ IETF ที่ชื่อ draft-ietf-secsh-filexfer ได้รับการพัฒนาถึงเวอร์ชัน 13 เมื่อวันที่ 18 กรกฎาคม 2006 แล้วก็หมดอายุไป OpenSSH ได้นำเวอร์ชัน 3 ของร่างนั้นมาใช้งาน โปรโตคอลการโอนย้ายไฟล์ที่ปลอดภัยซึ่งมีการใช้งานแพร่หลายที่สุดในโลกจึงเป็นเพียงเวอร์ชันหนึ่งของร่างที่ถูกทิ้งไปแล้ว แต่มันก็ยังคงใช้งานได้ดี
โปรโตคอล scp รุ่นเก่าถูกยกเลิกการใช้งานแล้ว OpenSSH 8.8 ซึ่งปล่อยเมื่อวันที่ 26 กันยายน 2021 ได้แจ้งเตือนว่า "OpenSSH เวอร์ชันในอนาคตอันใกล้จะเปลี่ยน scp(1) จากการใช้โปรโตคอล scp/rcp รุ่นเก่าไปเป็นการใช้ SFTP เป็นค่าเริ่มต้น" ต่อมา OpenSSH 9.0 ซึ่งปล่อยเมื่อวันที่ 8 เมษายน 2022 ได้ดำเนินการดังกล่าวโดยระบุว่า "รุ่นนี้เปลี่ยน scp(1) จากการใช้โปรโตคอล scp/rcp รุ่นเก่าไปเป็นการใช้โปรโตคอล SFTP เป็นค่าเริ่มต้น"
เหตุผลนี้อธิบายความเชื่อที่สืบต่อกันมาได้ โปรโตคอล scp แบบเก่าจะขยาย wildcard ของชื่อไฟล์ระยะไกลโดยส่งต่อไปยังเชลล์ของเครื่องปลายทาง ซึ่งเป็นเหตุผลว่าทำไมผู้คนจึงเรียนรู้ที่จะใส่เครื่องหมายคำพูดครอบ metacharacter ทุกตัวใน path ของเครื่องปลายทาง บันทึกของเวอร์ชัน 8.8 ระบุว่า scp ที่ทำงานผ่าน SFTP "ไม่จำเป็นต้องใช้วิธีการใส่เครื่องหมายคำพูดที่ยุ่งยากและเปราะบางนี้อีกต่อไป" ดังนั้นบนเซิร์ฟเวอร์ปัจจุบัน scp จึงเป็นเพียงไคลเอนต์ SFTP ที่ใช้รูปแบบคำสั่งของ rcp อินเทอร์เฟซจากปี 1983 ยังคงอยู่ แต่โปรโตคอลการสื่อสารจากปี 1983 ได้ถูกแทนที่ไปแล้ว
rsync, 1996: ส่งเฉพาะส่วนต่าง ไม่ใช่ส่งทั้งไฟล์
Andrew Tridgell และ Paul Mackerras ประกาศเปิดตัว rsync เมื่อวันที่ 19 มิถุนายน 1996 ที่มหาวิทยาลัยแห่งชาติออสเตรเลีย พร้อมกับรายงานทางเทคนิค TR-CS-96-05 ในหัวข้อ "The rsync algorithm"
โปรโตคอลก่อนหน้านี้ทั้งหมดมุ่งเน้นที่วิธีการย้ายไฟล์โดยไม่ให้ข้อมูลเสียหาย แต่ rsync ตั้งคำถามว่าอีกฝั่งมีข้อมูลส่วนใดของไฟล์นี้อยู่แล้วบ้าง รายงานดังกล่าวระบุเป้าหมายไว้ว่าเป็น "การเชื่อมต่อสื่อสารแบบสองทางที่มีแบนด์วิดท์ต่ำและมีความหน่วงสูง" โดยมีจุดประสงค์เพื่อระบุ "ส่วนของไฟล์ต้นทางที่เหมือนกับส่วนใดส่วนหนึ่งของไฟล์ปลายทาง" เพื่อให้ส่งเฉพาะส่วนที่ไม่ตรงกันเท่านั้น
กลไกการทำงานนี้ควรค่าแก่การทำความเข้าใจ เพราะเป็นสิ่งที่อธิบายพฤติกรรมของ rsync ได้ ผู้รับจะแบ่งสำเนาไฟล์ที่มีอยู่เดิมออกเป็นบล็อกขนาดคงที่ และคำนวณ checksum สองชุดต่อหนึ่งบล็อก คือแบบอ่อนที่ประมวลผลได้เร็ว และแบบเข้มที่ประมวลผลได้ช้า จากนั้นผู้รับจะส่งรายการ checksum นี้ไปยังผู้ส่ง ผู้ส่งจะเลื่อนหน้าต่าง (window) ไปบนไฟล์ของตนทีละไบต์และอัปเดต checksum แบบอ่อนแบบเพิ่มทีละส่วน ซึ่งเป็นสิ่งที่ทำให้การสแกนทีละไบต์เป็นไปได้จริง เมื่อพบการจับคู่แบบอ่อน จะมีการยืนยันอีกครั้งด้วย checksum แบบเข้ม การจับคู่ที่ยืนยันแล้วจะกลายเป็นข้อมูลอ้างอิงบล็อก ส่วนข้อมูลที่เหลือจะถูกส่งไปเป็นไบต์ดิบ ผู้รับจะสร้างไฟล์ขึ้นใหม่จากข้อมูลอ้างอิงบล็อกที่มีอยู่เดิมรวมกับข้อมูลดิบที่เพิ่งได้รับ
หากแทรกหนึ่งไบต์ไว้ที่จุดเริ่มต้นของไฟล์ขนาดใหญ่ เครื่องมือเปรียบเทียบไฟล์ทั่วไปจะต้องส่งไฟล์ใหม่ทั้งหมดเพราะ offset ทุกจุดเปลี่ยนไป แต่หน้าต่างแบบเลื่อน (rolling window) ของ rsync จะพบบล็อกเดิมที่ offset ใหม่ ทำให้ rsync ส่งเพียงแค่หนึ่งไบต์บวกกับข้อมูลจัดการเล็กน้อย คุณสมบัตินี้คือเหตุผลที่ rsync ยังคงเป็นเครื่องมือที่เหมาะสมที่สุดสำหรับไดเรกทอรีที่คุณต้องคัดลอกมากกว่าหนึ่งครั้ง
มีพฤติกรรมสองอย่างที่มักทำให้ผู้ใช้ประหลาดใจ ซึ่งทั้งคู่ระบุไว้ในคู่มือการใช้งาน ประการแรก rsync ไม่ได้ใช้ checksum เพื่อตัดสินใจว่าจะตรวจสอบไฟล์หรือไม่ แต่จะ "ค้นหาไฟล์ที่จำเป็นต้องถ่ายโอนโดยใช้ 'quick check' algorithm (ค่าเริ่มต้น) ซึ่งจะดูไฟล์ที่มีการเปลี่ยนแปลงขนาดหรือเวลาที่แก้ไขล่าสุด" ดังนั้นไฟล์ที่เนื้อหาเปลี่ยนไปแต่ขนาดและ timestamp ยังคงเดิมจะถูกข้ามไป --checksum จะเปลี่ยนพฤติกรรมนี้และทำให้ทั้งสองฝั่งอ่านไฟล์ทุกไฟล์ที่เข้าข่ายจนครบถ้วน ประการที่สอง อัลกอริทึม delta จะถูกปิดใช้งานโดยค่าเริ่มต้นเมื่อทั้งสอง path อยู่ในเครื่องเดียวกัน เพราะการอ่านและคำนวณ checksum ของไฟล์สองชุดในเครื่องเดียวมีต้นทุนสูงกว่าการคัดลอกไบต์ข้อมูลโดยตรง การประหยัดทรัพยากรจะเกิดขึ้นก็ต่อเมื่อการเชื่อมต่อเครือข่ายเป็นคอขวดที่ช้าที่สุดเท่านั้น
เครื่องมือที่ควรเลือกใช้บน VPS และเหตุผล
สรุปสั้นๆ คือ ใช้ SFTP สำหรับไฟล์จำนวนน้อย และใช้ rsync ผ่าน SSH สำหรับไดเรกทอรีที่ต้องคัดลอกซ้ำ
ทั้งสองวิธีทำงานผ่าน SSH จึงได้รับประโยชน์จากการตรวจสอบ host key และการเข้ารหัสโดยไม่ต้องตั้งค่าเพิ่มเติม นี่คือผลลัพธ์จากการพัฒนามานานกว่า 50 ปีที่ถูกรวมไว้เป็นค่าเริ่มต้น ผู้ออกแบบโปรโตคอล Kermit ต้องตั้งสมมติฐานว่าสายสัญญาณจะทำให้ข้อมูลเสียหาย จึงสร้างระบบ checksum และการส่งข้อมูลซ้ำไว้ในโปรโตคอล ซึ่งปัจจุบัน TCP ทำหน้าที่นี้แทนแล้ว ส่วน Christensen และ Forsberg ต้องตั้งสมมติฐานว่าทุกไบต์มีต้นทุน จึงสร้างระบบ resume และ streaming ขึ้นมา ซึ่งปัจจุบันอัลกอริทึม delta ของ rsync ทำหน้าที่นี้ได้ดีกว่า ผู้สร้าง FTP ตั้งสมมติฐานว่าเครือข่ายประกอบด้วยโฮสต์ที่ให้ความร่วมมือกัน ซึ่งเป็นสมมติฐานเดียวที่กลายเป็นความเข้าใจผิดในรูปแบบที่ไม่มีการปรับปรุงโปรโตคอลใดจะแก้ไขได้
สิ่งที่ checksum ยังคงมีประโยชน์
คำว่า "checksum" ทำหน้าที่ 3 อย่างที่แตกต่างกันตลอดประวัติศาสตร์ที่ผ่านมา และไม่สามารถใช้แทนกันได้
checksum รายแพ็กเก็ตของ Kermit และ XMODEM ใช้ตรวจจับความเสียหายของข้อมูลระหว่างการส่งผ่านสายสัญญาณ ปัจจุบัน TCP checksum และการแก้ไขข้อผิดพลาดในระดับ link layer ได้เข้ามาทำหน้าที่นี้แทนแล้ว จึงเป็นเหตุผลว่าทำไมเครื่องมือถ่ายโอนข้อมูลสมัยใหม่จึงไม่จำเป็นต้องให้ผู้ใช้กังวลเรื่องนี้อีกต่อไป
block checksum ของ rsync ไม่ได้ตอบคำถามว่า "ข้อมูลนี้ถูกต้องหรือไม่" แต่ตอบว่า "คุณมี block ข้อมูลนี้อยู่แล้วหรือไม่" ดังนั้น checksum ที่แข็งแกร่งในบริบทนี้จึงเป็นเพียงคีย์สำหรับค้นหา ไม่ใช่การยืนยันที่มาของไฟล์
หน้าที่ที่สามคือสิ่งที่ยังคงเป็นภาระของคุณ การเผยแพร่ checksum ของไฟล์ที่ปล่อยออกมา (release file) ช่วยตอบคำถามที่ TLS ทำไม่ได้ TLS พิสูจน์ได้เพียงว่าคุณกำลังสื่อสารกับเซิร์ฟเวอร์ที่ถูกต้อง แต่มันไม่ได้พิสูจน์ว่าไฟล์ที่อยู่บนเซิร์ฟเวอร์นั้นเป็นไฟล์ที่ถูกต้อง และมันไม่มีผลใดๆ กับไฟล์ที่คุณดึงมาจาก mirror นั่นคือเหตุผลว่าทำไมการตรวจสอบ checksum และลายเซ็นของไฟล์ที่ปล่อยออกมาจึงยังคุ้มค่าที่จะเสียเวลาทำสัก 30 วินาที และเป็นนิสัยที่สร้างได้ง่าย: ตรวจสอบ checksum ของทุกไฟล์ที่คุณดาวน์โหลดมาติดตั้ง
หน้าที่อื่นทั้งหมดในเรื่องนี้ได้รับการแก้ไขโดยเลเยอร์ที่อยู่ด้านล่างไปหมดแล้ว ยกเว้นหน้าที่นี้ที่ยังคงอยู่ เพราะมันไม่เคยเป็นปัญหาของเครือข่ายตั้งแต่แรก
FAQ
FTP ยังปลอดภัยที่จะใช้บน VPS หรือไม่?
ไม่ปลอดภัย FTP แบบปกติจะส่งข้อมูลรับรองและเนื้อหาไฟล์เป็นข้อความธรรมดา (cleartext) ทำให้ทุกคนที่อยู่บนเส้นทางเครือข่ายสามารถอ่านข้อมูลได้ทั้งหมด นอกจากนี้ยังต้องพึ่งพาไฟร์วอลล์ที่สามารถวิเคราะห์ช่องทางควบคุม (control channel) ได้ ซึ่งจะทำไม่ได้ทันทีที่คุณเข้ารหัสช่องทางควบคุมด้วย TLS ปัจจุบันเบราว์เซอร์ต่างๆ ได้ยกเลิกการรองรับไปแล้ว โดย Firefox ถอดการรองรับ FTP ออกในเวอร์ชัน 90 เมื่อเดือนกรกฎาคม 2021 และ Chrome ถอดโค้ดออกในเวอร์ชัน 95 เมื่อเดือนตุลาคม 2021 ควรใช้ SFTP ผ่าน SSH แทน ซึ่งใช้เพียงพอร์ตเดียวและไม่จำเป็นต้องมีอุปกรณ์ตัวกลางที่ต้องเข้าใจโปรโตคอล
ทำไม FTP ถึงยังต้องมีโหมด passive?
เพราะในโหมดดั้งเดิมของ FTP เซิร์ฟเวอร์จะเป็นฝ่ายเปิดการเชื่อมต่อข้อมูลกลับไปยังไคลเอนต์ ตามมาตรฐาน RFC 959 พอร์ตข้อมูลเริ่มต้นของเซิร์ฟเวอร์คือ "พอร์ตที่อยู่ติดกับพอร์ตควบคุม (เช่น L-1)" ซึ่งก็คือพอร์ต 20 เมื่อพอร์ตควบคุมคือ 21 ไคลเอนต์ที่อยู่หลัง NAT (network address translation) จะไม่มีที่อยู่ที่เซิร์ฟเวอร์สามารถเข้าถึงได้ ทำให้การเชื่อมต่อไม่สำเร็จและค้างอยู่ที่การถ่ายโอนข้อมูล โหมด PASV จะสลับทิศทางโดยให้เซิร์ฟเวอร์เป็นฝ่ายรอรับการเชื่อมต่อแทน และตอบกลับด้วยที่อยู่และพอร์ตภายในข้อความตอบกลับ 227 Entering Passive Mode เพื่อให้ไคลเอนต์เชื่อมต่อเข้ามา
ปัจจุบัน scp ยังใช้โปรโตคอลของตัวเองอยู่หรือไม่?
ไม่แล้ว นับตั้งแต่ OpenSSH 9.0 ที่ปล่อยออกมาเมื่อ 8 เมษายน 2022 ซึ่ง "เปลี่ยนการทำงานของ scp(1) จากการใช้โปรโตคอล scp/rcp แบบเดิม มาเป็นการใช้โปรโตคอล SFTP เป็นค่าเริ่มต้น" โดย OpenSSH 8.8 ได้ประกาศการเปลี่ยนแปลงนี้ไว้ตั้งแต่เดือนกันยายน 2021 ความแตกต่างที่เห็นได้ชัดคือเรื่องการใส่เครื่องหมายคำพูด (quoting) โปรโตคอลแบบเก่าจะขยาย wildcards บนรีโมทโดยส่งผ่านไปยังเชลล์ของรีโมท แต่โปรโตคอลที่ใช้ SFTP จะไม่ทำเช่นนั้น ดังนั้น path ที่เคยพึ่งพาการขยายตัวของเชลล์แบบเดิมจึงมีพฤติกรรมที่เปลี่ยนไป
เมื่อใดที่ rsync ถึงจะดีกว่า scp สำหรับการใช้งานบน VPS?
เมื่อคุณต้องการคัดลอกโครงสร้างไฟล์เดิมซ้ำมากกว่าหนึ่งครั้ง rsync จะส่งเฉพาะส่วนของไฟล์ที่ปลายทางยังไม่มี ดังนั้นการคัดลอกครั้งที่สองจึงใช้ทรัพยากรน้อยกว่าครั้งแรกมาก สำหรับไฟล์เดียวที่ปลายทางไม่เคยมีมาก่อน scp และ rsync จะส่งข้อมูลในปริมาณที่ใกล้เคียงกันและ scp จะใช้งานได้ง่ายกว่า โปรดจำไว้ว่าโดยค่าเริ่มต้น rsync จะตัดสินใจว่าจะตรวจสอบไฟล์ใดโดยดูจากขนาดและเวลาที่แก้ไข (modification time) ดังนั้นไฟล์ที่เนื้อหาเปลี่ยนไปแต่ขนาดและเวลาที่แก้ไขยังคงเดิม จำเป็นต้องใช้ --checksum เพื่อให้ rsync ตรวจพบการเปลี่ยนแปลงนั้น
ทำไม Kermit ถึงต้องเข้ารหัสไฟล์เป็นข้อความที่พิมพ์ได้แทนที่จะส่งเป็นไบต์ดิบ?
เพราะการเชื่อมต่อที่ Kermit ออกแบบมาเพื่อใช้งานคือสายสัญญาณเทอร์มินัลที่เชื่อมเข้ากับเมนเฟรม ไม่ใช่ท่อส่งข้อมูลไบต์ทั่วไป ลิงก์เหล่านั้นอาจเป็นแบบ 7-bit และไดรเวอร์เทอร์มินัลของเมนเฟรมจะตอบสนองต่ออักขระควบคุม (control characters) แทนที่จะส่งผ่านไปเฉยๆ Kermit จึงเข้ารหัสไบต์ควบคุมและไบต์ที่มีบิตสูงให้เป็นอักขระที่พิมพ์ได้ เพื่อป้องกันไม่ให้อุปกรณ์ตัวกลางตอบสนองต่ออักขระเหล่านั้น การเข้ารหัสนี้ทำให้ไฟล์ไบนารีมีขนาดใหญ่ขึ้นเมื่อส่งผ่านเครือข่าย ซึ่งเป็นการแลกเปลี่ยนที่คุ้มค่าเมื่อเทียบกับการถ่ายโอนข้อมูลที่อาจเสียหายหากไม่ใช้วิธีนี้