SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor

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

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

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

پروتکل‌های انتقال فایل، هر کدام برای مقابله با حالت‌های خرابی (failure mode) دههٔ خود طراحی شدند. Kermit فرض می‌کرد که خط ارتباطی بایت‌های شما را خراب می‌کند. XMODEM و ZMODEM فرض می‌کردند که اتصال کند است و شما برای هر دقیقه هزینه می‌پردازید. FTP (پروتکل انتقال فایل) فرض می‌کرد که شبکهٔ میانی همکاری می‌کند. SSH فرض می‌کرد که شبکه خصمانه است. آن فرض آخر، فرضی بود که پیروز شد؛ به همین دلیل است که امروزه یک VPS به شما SFTP و rsync روی SSH می‌دهد و چیز دیگری ارائه نمی‌کند.

اکنون فرصتی برای بررسی این موضوع وجود دارد. نسخه C-Kermit 11.0.506 در تاریخ 3 اوت 2026 منتشر شد. این اولین نسخه غیر-بتا پس از C-Kermit 9.0.302 در تاریخ 20 اوت 2011 است و پروتکلی که پیاده‌سازی می‌کند به سال 1981 بازمی‌گردد، زمانی که اولین انتقال آزمایشی در 29 آوریل انجام شد. نسخه‌های جزئی (Point releases) از آن زمان تا 11.0.514 در پایان سپتامبر 2026 دنبال شدند. چهل و پنج سال زمان کافی است تا شاهد باشیم که یک ردهٔ کامل از فناوری اختراع، استانداردسازی و توسط شبکه‌ای که روی آن اجرا می‌شد تخریب، و سپس در SSH جذب شود.

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

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

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

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

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

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

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

دانشگاه کلمبیا حمایت مالی خود را در سال 2011 پایان داد و C-Kermit را تحت لایسنس بازنگری‌شده 3-clause 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 بایت‌های کنترلی و بایت‌های با بیت بالا را به کاراکترهای قابل‌چاپ تبدیل می‌کرد تا هیچ واسطه‌ای در مسیر نسبت به آن‌ها واکنش نشان ندهد. این کدگذاری باعث می‌شود فایل‌های باینری در حین انتقال حجم بیشتری اشغال کنند، اما این یک مبادله منطقی در برابر انتقال فایلی بود که در غیر این صورت به‌صورت ناقص و خراب به مقصد می‌رسید.

آیا این مقاله مفید بود؟