SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor

تاریخچه پروتکل‌های انتقال فایل: از Kermit تا rsync

بررسی تکامل پروتکل‌های انتقال فایل از Kermit تا rsync و SFTP. چرا با وجود انتشار نسخه 11.0.506 در سال 2026، همچنان SSH برنده نهایی زیرساخت‌های شبکه باقی مانده است؟

چرا پروتکل‌های انتقال فایل مدام تغییر می‌کردند

هر یک از پروتکل‌های انتقال فایل برای مقابله با حالت‌های خرابی (failure mode) دههٔ خود طراحی شده بودند. پروتکل Kermit فرض را بر این می‌گذاشت که خط ارتباطی بایت‌های شما را تخریب می‌کند. پروتکل‌های XMODEM و ZMODEM فرض می‌کردند که اتصال کند است و شما برای هر دقیقه هزینه پرداخت می‌کنید. پروتکل FTP (پروتکل انتقال فایل) فرض می‌کرد که شبکهٔ میانی همکاری‌کننده است. پروتکل 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 طراحی شده بود. چهل و پنج سال زمان کافی است تا شاهد باشیم که یک رده کامل از فناوری ابداع، استانداردسازی، توسط شبکه‌ای که روی آن اجرا می‌شد تخریب، و سپس در SSH ادغام شود.

Kermit، محصول 1981: طراحی‌شده برای خطوطی که بایت‌های شما را می‌بلعند

پروتکل Kermit در مه 1981 در مرکز کامپیوتر دانشگاه کلمبیا توسط Frank da Cruz و Bill Catchings ایجاد شد. نام آن از Kermit the Frog گرفته شده است. طبق روایت Da Cruz، در حالی که گروه در حال فکر کردن برای انتخاب نام بودند، تقویمی از Muppets روی دیوار بود و هیچ‌کس انتظار نداشت که این پروتکل تا این حد گسترش یابد.

مشکلی که Kermit حل کرد، سرعت نبود. مسیر بین یک ترمینال و یک mainframe، لوله‌ای برای انتقال بایت‌های دلخواه نبود؛ بلکه یک دستگاه کاراکتری با محدودیت‌های خاص خود بود. این مسیر می‌توانست 7-بیتی باشد، نیمه‌دوطرفه (half-duplex) باشد، کاراکترهای کنترلی را ببلعد یا یکی از آن‌ها را به عنوان دستور تفسیر کند. ارسال یک فایل باینری از طریق آن بدون تغییر، کارساز نبود.

بنابراین، طراحی پروتکل این محدودیت‌ها را دقیقاً لحاظ کرد. تاریخچه خودِ پروژه Kermit آن‌ها را این‌گونه فهرست می‌کند:

  • بسته‌های کوچک، زیرا اکثر mainframeها نمی‌توانستند حجم زیادی از داده‌های ورودی از ترمینال را دریافت کنند.
  • مکانیزم توقف و انتظار (stop-and-wait) نیمه‌دوطرفه، زیرا mainframeهای IBM از ارتباط تمام‌دوطرفه (full-duplex) پشتیبانی نمی‌کردند.
  • کدگذاری‌های قابل‌چاپ برای کاراکترهای کنترلی و کاراکترهای 8-بیتی، زیرا هیچ‌کدام نمی‌توانستند از درایور ترمینال mainframe عبور کنند.
  • یک checksum روی هر بسته که توسط گیرنده تأیید می‌شد، تا یک بسته آسیب‌دیده تنها هزینه یک ارسال مجدد را داشته باشد و نه کل فایل را.

نکته سوم جالب است. Kermit به جای ارسال خودِ فایل، یک نسخه کدگذاری‌شده و امن از فایل را ارسال می‌کند که برای متن مناسب است. یک بایت کنترلی به یک کاراکتر پیشوند و به دنبال آن یک کاراکتر قابل‌چاپ تبدیل می‌شود و بایتی که بیت بالایی آن تنظیم شده است نیز می‌تواند به همین روش برای یک لینک 7-بیتی کدگذاری شود. هر واسطه‌ای در این میان که فقط متن قابل‌چاپ را می‌فهمد، تنها متن قابل‌چاپ را مشاهده می‌کند. هزینه این کار افزایش حجم است: یک فایل باینری روی شبکه بزرگ‌تر می‌شود. در برابر یک front-end در mainframe که در غیر این صورت انتقال را کاملاً مختل می‌کرد، این معامله درستی بود.

ویژگی غیرمعمول دیگر Kermit، دامنه کاربرد آن است. XMODEM فایل را بین دو ماشینی جابه‌جا می‌کرد که از قبل بر سر ماهیت فایل توافق داشتند. Kermit به عنوان کوچک‌ترین مخرج مشترک بین سیستم‌هایی نوشته شد که با هم توافق نداشتند؛ سیستم‌هایی با مجموعه‌کاراکترهای متفاوت، ساختارهای رکورد متفاوت و تعاریف متفاوت از پایان خط متن. این همان دنیایی است که در مهاجرت طولانی از mainframeها به سرورهای ابری توصیف شده است و Kermit نمادی از این است که قابلیت همکاری (interoperability) پیش از آنکه لایه شبکه این وظیفه را بر عهده بگیرد، چگونه بوده است.

دانشگاه کلمبیا حمایت خود را در سال 2011 پایان داد و C-Kermit را تحت مجوز اصلاح‌شده 3-بندی BSD منتشر کرد. Frank da Cruz به مدت 44 سال، از طراحی سال 1981 تا سال 2025، با این پروژه همراه بود. نسخه 2026 توسط پروژه OpenKermit نگهداری می‌شود و John Goerzen وظیفه مدرن‌سازی یک codebase به زبان C را بر عهده دارد که از سن اکثر خوانندگان این متن قدیمی‌تر است.

پروتکل‌های XMODEM و ZMODEM: زمانی که هزینه تلفن طراحی را شکل می‌داد

وارد کریستنسن (Ward Christensen) در سال 1977 برنامه MODEM.ASM را نوشت و پروتکلی که معرفی کرد XMODEM نام داشت. در سال 1978، او به همراه رندی سوس (Randy Suess) اولین سیستم تابلوی اعلانات عمومی یا همان CBBS را آنلاین کردند. کریستنسن در 11 اکتبر 2024 درگذشت.

XMODEM تا حد ممکن یک پروتکل کوچک و ساده است. داده‌ها در بلوک‌های 128 بایتی منتقل می‌شوند. هر بلوک شامل یک بایت checksum است که حاصل‌جمع 128 بایت داده به پیمانه 256 است. گیرنده هر بلوک را تأیید می‌کند یا درخواست ارسال مجدد آن را می‌دهد. دلیل این ساختار، مسائل اقتصادی بود. در خطوط تلفن dial-up، شما هزینه را بر اساس زمان پرداخت می‌کردید؛ بنابراین یک خطای خط باید فقط هزینه یک بلوک را به شما تحمیل می‌کرد، نه کل فایل در حال انتقال را.

نقطه ضعف پروتکل نیز در همان جمله نهفته است. XMODEM پس از هر 128 بایت منتظر تأییدیه می‌ماند. چاک فورسبرگ (Chuck Forsberg) در مشخصات ZMODEM این موضوع را به صراحت بیان کرده است: «طول کوتاه بلوک‌ها باعث می‌شود که هنگام استفاده از سیستم‌های اشتراک زمانی، شبکه‌های سوئیچینگ بسته (packet switched) و مدارهای ماهواره‌ای، نرخ انتقال داده (throughput) به‌شدت کاهش یابد.» آنچه پروتکل‌های stop-and-wait را از پا درمی‌آورد، تأخیر (latency) است، نه پهنای باند. هر رفت‌وبرگشت (round trip) به معنای زمان مرده‌ای است که شما بابت آن هزینه پرداخت می‌کنید.

سپس YMODEM آمد و وارد کریستنسن در سال 1985 این نام را برای آن انتخاب کرد. دستاورد آن، انتقال دسته‌ای (batch transfer) بود. فرستنده پیش از ارسال داده، نام فایل و اندازه آن را اعلام می‌کند تا چندین فایل بتوانند در یک نشست منتقل شوند و گیرنده بداند هر فایل کجا به پایان می‌رسد.

ZMODEM پاسخ چاک فورسبرگ بود که در شرکت Omen Technology نوشته شد. مشخصات آن مربوط به بازبینی 14 اکتبر 1988 است و در آن ذکر شده که «ZMODEM تحت قرارداد با Telenet برای دامنه عمومی توسعه یافته است». Telenet یک شبکه عمومی داده با سوئیچینگ بسته را اداره می‌کرد و این قرارداد در طراحی پروتکل مشهود است. ZMODEM کاراکترهای کنترلی شبکه را escape می‌کند تا شبکه بسته‌ای که در میانه مسیر قرار دارد، آن‌ها را به عنوان دستور تلقی نکند. این پروتکل شروع هر فریم را با یک توالی کاراکتری منحصربه‌فرد مشخص می‌کند، به‌جای اینکه مرز فریم‌ها را از روی سکوت تشخیص دهد؛ بنابراین در صورت بروز نویز، بدون نیاز به انتظار برای پایان timeout، بازیابی انجام می‌شود. همچنین قابلیت resume صریح دارد تا انتقال‌های قطع‌شده از همان‌جایی که متوقف شده‌اند، ادامه یابند.

مهم‌تر از همه، این پروتکل دیگر منتظر نمی‌ماند. در توصیف خودِ مشخصات آمده است که «ZMODEM در عمل از کل فایل به عنوان یک پنجره استفاده می‌کند». فرستنده جریان داده را ارسال می‌کند و تنها زمانی متوقف می‌شود که گیرنده مشکلی را گزارش کند. این همان بینشی است که TCP در پنجره (window) خود کدگذاری کرده است؛ با این تفاوت که از مسیر دیگری به آن رسیده است، توسط کسی که نظاره‌گر بیکار ماندن مودم بود.

چرا طراحی دو اتصالی FTP به مرور زمان ناکارآمد شد

پروتکل FTP از تمام این موارد قدیمی‌تر است. سند RFC 114 با عنوان "A File Transfer Protocol" در تاریخ 16 آوریل 1971 توسط A. Bhushan نوشته شده است.

نکته قابل‌توجه این است که RFC 114 طراحی دو اتصالی را بررسی و رد کرده بود. Bhushan استفاده از «دو لینک تمام‌دوطرفه، یکی برای اطلاعات کنترلی و دیگری برای داده» را سبک‌سنگین کرد و به این نتیجه رسید: «ما استفاده از یک اتصال تمام‌دوطرفه واحد برای تبادل داده و اطلاعات کنترلی را توصیه می‌کنیم.» این تفکیک بعداً رخ داد. سند RFC 354 که در تاریخ 8 ژوئیه 1972 منتشر شد، بیان می‌کند که «داده‌ها و فایل‌ها فقط از طریق اتصال داده منتقل می‌شوند» و دستورات از طریق یک اتصال Telnet جداگانه ارسال می‌گردند. سند RFC 959 که در اکتبر 1985 توسط Postel و Reynolds نوشته شد، همان نسخه‌ای است که هنوز توسط همه پیاده‌سازی می‌شود.

سند RFC 959 همچنین پورت‌ها را تعیین کرد. پورت پیش‌فرض داده در سمت سرور، «پورت مجاور پورت اتصال کنترلی (یعنی L-1)» است که در صورت استفاده از پورت 21 برای اتصال کنترلی، پورت 20 خواهد بود.

این بخشی است که دوام نیاورد. در حالت اصلی FTP، سرور اتصال داده را به سمت کلاینت برقرار می‌کند. کلاینتی که پشت NAT (ترجمه آدرس شبکه) قرار دارد، آدرسی ندارد که سرور بتواند به آن دسترسی پیدا کند و کلاینتی که پشت فایروال است، اتصالات ورودی را نمی‌پذیرد؛ بنابراین اتصال داده هرگز برقرار نمی‌شود و به محض درخواست لیست فایل‌ها یا خودِ فایل، عملیات انتقال متوقف می‌ماند. پاسخ این مشکل PASV بود که RFC 959 آن را به عنوان درخواستی تعریف می‌کند که از سرور می‌خواهد «روی یک پورت داده (که پورت پیش‌فرض داده نیست) گوش دهد و به جای برقراری اتصال پس از دریافت دستور انتقال، منتظر بماند». سرور با آدرس و پورتی که باید به آن متصل شد، پاسخ می‌دهد:

PASV
227 Entering Passive Mode (203,0,113,10,195,80)

این پاسخ به معنای هاست 203.0.113.10 و پورت 50000 (حاصل 195 ضربدر 256 به علاوه 80) است. با خواندن دوباره آن، مشکل ساختاری آشکار می‌شود. نقطه پایانی اتصال دوم در داخل محتوای (payload) اتصال اول اعلام می‌شود. یک دستگاه NAT یا فایروال نمی‌تواند آن اتصال را عبور دهد مگر اینکه کانال کنترلی را تحلیل کرده و پورتی را که در آنجا می‌بیند، باز کند. لینوکس یک ابزار کمکی برای رهگیری اتصال (connection tracking helper) دارد که دقیقاً همین کار را انجام می‌دهد. این ابزار کمکی فقط زمانی کار می‌کند که اتصال کنترلی به صورت متن ساده (cleartext) باشد، بنابراین رمزنگاری FTP با TLS (امنیت لایه انتقال)، میان‌افزاری را که باعث قابل‌استفاده بودن FTP می‌شد، کور می‌کند.

این درس FTP در یک جمله است: این پروتکل، شبکه را به یکی از شرکت‌کنندگان در پروتکل تبدیل کرد. پروتکلی که برای کارکردن نیاز دارد شبکه آن را درک کند، نمی‌تواند در شبکه‌ای که دیگر به آن اعتماد ندارد، دوام بیاورد.

پایان کار ثبت شده است. فایرفاکس پشتیبانی از FTP را در نسخه 90 در ژوئیه 2021 حذف کرد. کروم نیز کد FTP را در نسخه 95 در اکتبر 2021 حذف نمود.

دستور rcp و دستورات r: اعتماد بر اساس نام میزبان

نسخه 4.2BSD که در سال 1983 توسط برکلی و با بودجه DARPA منتشر شد، دستورات rcp، rsh و rlogin را معرفی کرد. این ابزارها برای محیط دانشگاهی متشکل از ماشین‌های Unix در یک شبکه واحد طراحی شده بودند و مدل احراز هویت آن‌ها نیز بازتاب‌دهنده همین موضوع است. در این مدل، میزبان اعلام می‌کرد که کدام کاربر در حال برقراری ارتباط است. اگر فایل /etc/hosts.equiv یا فایل ~/.rhosts کاربر تأیید می‌کرد که آن میزبان مورد اعتماد است، ادعای مطرح‌شده پذیرفته می‌شد و هیچ درخواستی برای رمز عبور ارسال نمی‌گشت.

مکانیسم این فرآیند را به‌صراحت بیان می‌کنیم، چرا که دلیل اصلی منسوخ شدن این دستورات همین است. اعتماد بر پایه یک آدرس و یک ادعا استوار بود. هر دوی این موارد به‌صورت متن ساده (cleartext) در شبکه منتقل می‌شدند؛ بنابراین هر کسی در مسیر شبکه می‌توانست آن‌ها را بخواند و هر کسی در مسیر می‌توانست آن‌ها را جعل کند. این مدل در محیطی که در مسیر از Unix به Linux توصیف شده است، یعنی زمانی که شبکه محدود به یک ساختمان بود، منطقی به نظر می‌رسید. اما به محض اینکه شبکه به اینترنت تبدیل شد، این مدل دیگر کارایی نداشت.

نکته‌ای که rcp به‌درستی پیاده‌سازی کرده بود، رابط کاربری آن بود. مبدأ، مقصد، تمام. نیازی به باز کردن نشست (session)، مذاکره برای حالت انتقال یا تنظیم اتصال دوم نبود. این دستور دقیقاً مانند cp عمل می‌کند، با این تفاوت که یک دونقطه (colon) در مسیر قرار می‌گیرد. این رابط کاربری چهار دهه بیشتر از پروتکل اصلی خود عمر کرد.

SSH کل این حوزه را در بر می‌گیرد

در سال 1995، Tatu Ylonen که در آن زمان پژوهشگر دانشگاه صنعتی هلسینکی بود، SSH را در واکنش به یک حملهٔ شنود رمز عبور در شبکهٔ دانشگاه نوشت. او آن را در ژوئیه 1995 به عنوان نرم‌افزار آزاد با سورس‌کد منتشر کرد. تا پایان همان سال، تخمین زده می‌شد که حدود 20,000 کاربر در 50 کشور از آن استفاده می‌کردند و در دسامبر 1995، او شرکت SSH Communications Security را برای ادامهٔ توسعهٔ آن تأسیس کرد.

مجوز این نرم‌افزار در نسخه‌های بعدی محدودتر شد، بنابراین توسعه‌دهندگان OpenBSD آخرین نسخه با مجوز آزاد، یعنی ssh 1.2.12 را فورک کردند. اولین import در 26 سپتامبر 1999 انجام شد و OpenSSH 1.2.2 همراه با OpenBSD 2.6 در 1 دسامبر 1999 عرضه شد. آن فورک یک مطالعهٔ موردی فشرده دربارهٔ اهمیت عملی شرایط مجوزهای متن‌باز است، زیرا پیاده‌سازی SSH که امروزه تقریباً همه از آن استفاده می‌کنند، از همان نسخه‌ای نشأت می‌گیرد که مجوزش هنوز اجازهٔ این کار را می‌داد.

هنگامی که SSH به وجود آمد، انتقال فایل دیگر یک مشکل جداگانه نبود. یک جریان رمزنگاری‌شده و احراز هویت‌شده که چندین کانال را حمل می‌کند، همان چیزی را فراهم می‌کند که پروتکل‌های قدیمی مجبور بودند خودشان برای آن تلاش کنند: یکپارچگی، ترتیب‌بندی و یک مسیر دادهٔ دوم که نیازی به اتصال TCP مجدد ندارد. اگر این مکانیسم‌ها برای شما جدید هستند، پیش از ادامه، با ماهیت واقعی SSH آشنا شوید.

دو ابزار از دل این موضوع بیرون آمدند. scp پروتکل انتقال rcp بود که درون یک نشست SSH اجرا می‌شد و به همین دلیل دقیقاً همان خط فرمان rcp را به ارث برد. SFTP طراحی متفاوتی دارد: یک پروتکل فایل واقعی با قابلیت لیست کردن دایرکتوری، ویژگی‌های فایل و دسترسی تصادفی که روی یک کانال SSH حمل می‌شود. SFTP هرگز به یک RFC تبدیل نشد. پیش‌نویس IETF با نام draft-ietf-secsh-filexfer در 18 ژوئیه 2006 به نسخه 13 رسید و سپس منقضی شد. 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، کاراکترهای عام (wildcards) نام فایل‌های راه دور را با سپردن آن‌ها به shell راه دور گسترش می‌داد؛ به همین دلیل بود که کاربران یاد گرفته بودند تمام فراکاراکترها (metacharacters) را در مسیرهای راه دور داخل کوتیشن قرار دهند. یادداشت‌های نسخه 8.8 می‌گویند که scp روی SFTP «دیگر نیازی به این کوتیشن‌گذاری‌های حساس و شکننده ندارد». بنابراین در یک سرور امروزی، scp یک کلاینت SFTP است که ظاهر خط فرمان rcp را حفظ کرده است. رابط کاربری سال 1983 باقی ماند، اما پروتکل انتقال دادهٔ آن سال دیگر استفاده نمی‌شود.

rsync، 1996: ارسال تفاوت، نه کل فایل

Andrew Tridgell و Paul Mackerras در 19 ژوئن 1996 در دانشگاه ملی استرالیا، rsync را به همراه گزارش فنی TR-CS-96-05 با عنوان "الگوریتم rsync" معرفی کردند.

تمام پروتکل‌های پیش از آن، بر چگونگی انتقال یک فایل بدون خرابی تمرکز داشتند. rsync پرسید که طرف مقابل چه مقدار از این فایل را از قبل در اختیار دارد. این گزارش، هدف را "یک لینک ارتباطی دوطرفه با پهنای باند کم و تأخیر بالا" تعریف می‌کند و هدف نهایی را شناسایی "بخش‌هایی از فایل مبدأ که با بخشی از فایل مقصد یکسان هستند" می‌داند تا فقط بخش‌های غیرمشابه ارسال شوند.

درک این مکانیزم اهمیت دارد، زیرا رفتار rsync را توضیح می‌دهد. گیرنده، نسخه موجود خود را به بلوک‌هایی با اندازه ثابت تقسیم کرده و برای هر بلوک دو checksum محاسبه می‌کند: یکی ضعیف و ارزان، و دیگری قوی و گران. گیرنده این لیست را برای فرستنده می‌فرستد. فرستنده یک پنجره را روی فایل خود، بایت به بایت می‌لغزاند و checksum ضعیف را به‌صورت افزایشی به‌روزرسانی می‌کند؛ این همان چیزی است که اسکن بایت‌به‌بایت را مقرون‌به‌صرفه می‌کند. سپس یک تطابق ضعیف با checksum قوی تأیید می‌شود. تطابق‌های تأییدشده به ارجاع‌های بلوکی تبدیل می‌شوند. هر چیز دیگری به‌عنوان بایت‌های تحت‌اللفظی ارسال می‌شود. گیرنده فایل را از ترکیب ارجاع‌های بلوک‌هایی که از قبل دارد و بایت‌های دریافتی جدید، بازسازی می‌کند.

اگر یک بایت به ابتدای یک فایل بزرگ اضافه کنید، ابزارهای سادهٔ تفاوت‌سنجی مجبورند کل فایل را ارسال کنند، زیرا تمام offsetها تغییر کرده‌اند. اما پنجره لغزان، همان بلوک‌ها را در offsetهای جدیدشان پیدا می‌کند، بنابراین rsync فقط یک بایت به اضافه مقداری داده‌های مدیریتی ارسال می‌کند. همین ویژگی باعث می‌شود rsync همچنان ابزار مناسبی برای دایرکتوری‌هایی باشد که بیش از یک‌بار کپی می‌شوند.

دو رفتار rsync معمولاً کاربران را غافلگیر می‌کند و هر دو در دفترچه راهنما ذکر شده‌اند. اول اینکه، rsync برای تصمیم‌گیری درباره بررسی فایل‌ها، از آن‌ها checksum نمی‌گیرد. این ابزار "فایل‌هایی که نیاز به انتقال دارند را با استفاده از یک الگوریتم 'بررسی سریع' (به‌صورت پیش‌فرض) پیدا می‌کند که به دنبال فایل‌هایی می‌گردد که اندازه یا زمان آخرین تغییر آن‌ها تغییر کرده است". فایلی که محتوایش تغییر کرده اما اندازه و timestamp آن ثابت مانده باشد، نادیده گرفته می‌شود. پرچم --checksum این رفتار را تغییر می‌دهد و باعث می‌شود هر دو طرف، تمام فایل‌های کاندید را به‌طور کامل بخوانند. دوم اینکه، الگوریتم delta به‌صورت پیش‌فرض زمانی که هر دو مسیر محلی هستند غیرفعال است، زیرا خواندن و محاسبه checksum دو نسخه روی یک ماشین، هزینه بیشتری نسبت به کپی کردن مستقیم بایت‌ها دارد. صرفه‌جویی در زمان، تنها زمانی رخ می‌دهد که لینک شبکه، گلوگاه (بخش کند) باشد.

آنچه در عمل روی یک VPS به آن نیاز دارید و دلیل آن

خلاصه مطلب: برای چند فایل محدود از SFTP استفاده کنید و برای دایرکتوری‌هایی که قرار است دوباره کپی شوند، rsync را از طریق SSH به کار ببرید.

هر دو ابزار از بستر SSH استفاده می‌کنند، بنابراین هر دو بدون نیاز به پیکربندی اضافی، از قابلیت تأیید کلید میزبان (host key verification) و رمزنگاری بهره‌مند می‌شوند. این یعنی پنجاه سال تلاش مهندسی که در یک تنظیم پیش‌فرض فشرده شده است. طراحان پروتکل Kermit مجبور بودند فرض کنند که خط ارتباطی داده‌ها را مخدوش می‌کند، بنابراین در پروتکل خود قابلیت چک‌سام (checksum) و ارسال مجدد را تعبیه کردند. امروزه پروتکل TCP این وظیفه را بر عهده دارد. Christensen و Forsberg باید فرض می‌کردند که هر بایت هزینه دارد، بنابراین قابلیت ادامه (resume) و استریمینگ را ساختند. امروزه الگوریتم دلتای rsync این کار را انجام می‌دهد و آن را به شکلی بهینه‌تر اجرا می‌کند. نویسندگان FTP فرض کرده بودند که شبکه متشکل از میزبان‌های همکاری‌کننده است؛ این تنها فرضی بود که مشخص شد به شکلی نادرست است که هیچ مقدار توسعه پروتکل نمی‌توانست آن را اصلاح کند.

کاربرد فعلی چک‌سام‌ها

واژه "checksum" در طول این تاریخ سه وظیفه متفاوت داشته است که با یکدیگر قابل جایگزینی نیستند.

چک‌سام‌های هر بسته (per-packet) در پروتکل‌های Kermit و XMODEM، خرابی داده‌ها در طول مسیر انتقال را شناسایی می‌کردند. امروزه چک‌سام TCP و قابلیت تصحیح خطا در لایه پیوند (link layer) این وظیفه را بر عهده دارند؛ به همین دلیل است که هیچ ابزار انتقال مدرنی از شما نمی‌خواهد نگران این موضوع باشید.

چک‌سام‌های بلوکی در rsync به این پرسش که "آیا این داده صحیح است" پاسخ نمی‌دهند. آن‌ها پاسخ می‌دهند که "آیا شما این بلوک را از قبل دارید یا خیر". در اینجا، یک چک‌سام قوی نقش یک کلید جستجو را ایفا می‌کند، نه گواهی بر اصالت فایل.

وظیفه سوم، تنها موردی است که هنوز بر عهده شما باقی مانده است. چک‌سام منتشر شده برای یک فایل release، به پرسشی پاسخ می‌دهد که TLS قادر به پاسخگویی آن نیست. TLS ثابت می‌کند که شما با سرور درستی ارتباط برقرار کرده‌اید، اما ثابت نمی‌کند که فایل درستی روی آن سرور قرار داشته است و در مورد فایلی که از یک mirror دریافت کرده‌اید نیز هیچ کمکی نمی‌کند. به همین دلیل است که چک‌سام‌ها و امضاهای فایل‌های release هنوز ارزش صرف 30 ثانیه زمان را دارند و ایجاد این عادت ساده است: چک‌سام هر فایلی که دانلود و نصب می‌کنید را بررسی کنید.

تمام موارد دیگر در این داستان توسط لایه‌های زیرین حل شده‌اند. اما این مورد حل نشده باقی مانده است، زیرا هرگز یک مشکل شبکه‌ای نبوده است.

FAQ

آیا استفاده از FTP روی VPS هنوز امن است؟

خیر. پروتکل FTP ساده، اعتبارنامه‌ها و محتوای فایل‌ها را به‌صورت متن آشکار (cleartext) ارسال می‌کند، بنابراین هر کسی در مسیر شبکه می‌تواند آن‌ها را بخواند. این پروتکل همچنین به فایروالی وابسته است که کانال کنترل آن را تحلیل کند؛ به محض اینکه کانال کنترل را با TLS رمزنگاری کنید، این تحلیل دیگر ممکن نخواهد بود. مرورگرها نیز پشتیبانی از آن را کنار گذاشته‌اند: فایرفاکس در نسخه 90 در ژوئیه 2021 و کروم در نسخه 95 در اکتبر 2021 پشتیبانی از FTP را حذف کردند. از SFTP روی SSH استفاده کنید که تنها به یک پورت نیاز دارد و به هیچ میان‌افزار (middlebox) آگاه به پروتکل وابسته نیست.

چرا FTP اصلاً به حالت passive نیاز دارد؟

زیرا در حالت اصلی FTP، سرور اتصال داده را به سمت کلاینت برقرار می‌کند. استاندارد RFC 959 پورت پیش‌فرض داده سرور را «پورت مجاور پورت اتصال کنترل (یعنی L-1)» تعیین کرده است؛ بنابراین وقتی پورت کنترل 21 باشد، پورت داده 20 است. کلاینتی که پشت NAT (ترجمه آدرس شبکه) قرار دارد، آدرسی ندارد که سرور بتواند به آن دسترسی پیدا کند، بنابراین آن اتصال هرگز برقرار نمی‌شود و انتقال فایل متوقف می‌ماند. حالت PASV جهت را معکوس می‌کند: سرور در این حالت گوش می‌دهد و با یک آدرس و پورت در پاسخ 227 Entering Passive Mode به کلاینت اطلاع می‌دهد تا کلاینت به آن متصل شود.

آیا scp هنوز از پروتکل اختصاصی خود استفاده می‌کند؟

خیر، از زمان انتشار OpenSSH 9.0 در تاریخ 8 آوریل 2022، این ابزار «به‌طور پیش‌فرض از پروتکل قدیمی scp/rcp به پروتکل SFTP تغییر یافته است». نسخه OpenSSH 8.8 این تغییر را در سپتامبر 2021 اعلام کرده بود. تفاوت مشهود در نحوه استفاده از کوتیشن‌ها است. پروتکل قدیمی، کاراکترهای wildcard از راه دور را با ارسال آن‌ها به شل (shell) مقصد گسترش می‌داد، اما پروتکل مبتنی بر SFTP این کار را انجام نمی‌دهد؛ بنابراین مسیرهایی که به آن گسترش شل وابسته بودند، اکنون رفتار متفاوتی دارند.

چه زمانی rsync برای VPS بهتر از scp است؟

زمانی که قصد دارید یک ساختار درختی از فایل‌ها را بیش از یک بار کپی کنید. ابزار rsync فقط بخش‌هایی از هر فایل را ارسال می‌کند که در مقصد وجود ندارد، بنابراین کپی دوم بسیار سریع‌تر و کم‌هزینه‌تر از کپی اول است. برای یک فایل تکی که مقصد قبلاً آن را ندیده است، scp و rsync تقریباً حجم یکسانی از داده را منتقل می‌کنند و استفاده از scp ساده‌تر است. به یاد داشته باشید که rsync به‌طور پیش‌فرض بر اساس اندازه و زمان تغییر (modification time) تصمیم می‌گیرد که چه چیزی را بررسی کند؛ بنابراین فایلی که محتوای آن تغییر کرده اما اندازه و زمان تغییرش ثابت مانده است، پیش از آنکه rsync متوجه تغییر شود، به --checksum نیاز دارد.

چرا Kermit فایل‌ها را به‌جای ارسال بایت‌های خام، به متن قابل‌چاپ تبدیل می‌کرد؟

زیرا اتصالی که Kermit برای آن طراحی شده بود، یک خط ترمینال متصل به یک مین‌فریم بود، نه یک لوله انتقال بایت (byte pipe). آن لینک‌ها ممکن بود 7-بیتی باشند و درایور ترمینال مین‌فریم به‌جای عبور دادن کاراکترهای کنترلی، نسبت به آن‌ها واکنش نشان می‌داد. Kermit بایت‌های کنترلی و بایت‌های با بیت بالا را به کاراکترهای قابل‌چاپ تبدیل می‌کرد تا هیچ واسطه‌ای در مسیر نسبت به آن‌ها واکنش نشان ندهد. این کدگذاری باعث می‌شود فایل‌های باینری در حین انتقال حجم بیشتری اشغال کنند، اما این یک مبادله منطقی در برابر انتقال فایلی بود که در غیر این صورت به‌صورت ناقص و خراب به مقصد می‌رسید.