یه نویسنده

مقاله، کتاب، برنامه و ...

مقاله، کتاب، برنامه و ...

یه نویسنده

وبلاگی برای فعالیتهای پژوهشی و برنامه نویسی کامپیوتر، که شاید دفتر یادداشتی از دانسته‌های روزانه‌ی من باشد(شاید به‌کار شما هم بیاید). مطالبی که از دنیای کدباز جمع‌آوری میکنم و برای علاقه‌مندان این شاخه از فناوری انتشار میدهم. بیشتر نوشته‌های وبلاگ را برنامه‌نویسی‌php و سیستم‌عامل لینوکس تشکیل می‌دهند.

طبقه بندی موضوعی

۱ مطلب با کلمه‌ی کلیدی «opentftp» ثبت شده است

ctftp – یک TFTP Server سبک، چندریسمانی و قابل مانیتورینگ برای پروویژن خودکار

 

مدت‌ها برای پروویژن خودکار (Auto Provisioning) گوشی‌های سیسکو و سایر IP Phoneها، همه‌چیز به TFTP وابسته است؛
اما واقعیت اینه که اکثر TFTP سرورهای موجود یا:

  • روی لینوکس راحت کامپایل و اجرا نمی‌شن (مثل OpenTFTP که با کلی وابستگی و هدر ویندوزی و … درگیر می‌شی)،

  • یا اصلاً لاگ و ابزار دیباگ درست‌وحسابی ندارن،

  • یا آن‌قدر گنده و پیچیده‌ان که برای یک سناریوی سادهٔ provisioning زیادی‌ان.

برای همین من رفتم سراغ نوشتن یک سرور TFTP اختصاصی به نام ctftp؛
چیزی که دقیقاً برای همین use-case طراحی شده:

  • سبک و چندریسمانی (multi-threaded)،

  • مخصوص تحویل فایل کانفیگ و firmware،

  • با لاگ‌گیری عالی و خروجی event برای مانیتورینگ.

🔗 صفحه پروژه (ctftp):
https://seifzadeh.github.io/ctftp/

🔗 سورس پروژه در گیت‌هاب:
https://github.com/seifzadeh/ctftp

🔗 دانلود مستقیم باینری لینوکس (static):
https://github.com/seifzadeh/ctftp/releases/download/0.0.1/ctftp-static-linux

چون باینری استاتیک هست، واقعاً استفاده ازش در لینوکس می‌شه:

«دانلود کن، اجرا کن، تمام.» 😎


مشکل از کجا شروع شد؟ (داستان OpenTFTP روی لینوکس)

اگر با OpenTFTP و نمونه‌های مشابه سر و کله زده باشی، احتمالاً این‌ها برات آشناست:

  • سورس‌ها برای ویندوز نوشته شده، پر از ws2tcpip.h و چیزهای خاص ویندوز.

  • روی لینوکس ۳۲/۶۴ بیت باید کلی پچ و دستکاری کنی تا اصلاً کامپایل بشه.

  • خبری از لاگ‌های درست‌وحسابی برای هر درخواست نیست.

  • ابزار مانیتورینگ، event، خروجی JSON، هیچی.

برای سناریویی مثل auto provisioning گوشی‌های سیسکو که باید دقیقاً بدونی:

  • کدوم IP چه فایلی را کی گرفته،

  • آیا کامل و سالم منتقل شده یا نه،

  • چقدر ترافیک رد و بدل شده،

این محدودیت‌ها واقعاً اذیت‌کننده‌ست.

ctftp دقیقاً برای حل همین درد ساخته شده.


ctftp دقیقاً چی هست و چه‌کار می‌کند؟

به‌صورت خلاصه:

  • یک TFTP Server چندریسمانی نوشته‌شده با C

  • مخصوص Read-Only (فقط RRQ / دریافت فایل از سرور)

  • مناسب Auto-Provisioning IP Phone‌ها (مخصوصاً سیسکو)

  • با این ویژگی‌ها:

ویژگی‌های کلیدی

  • 🚀 Multi-threaded

    • برای هر IP:port یک Listener Thread

    • برای هر درخواست TFTP (هر RRQ) یک Session Thread جدا

  • 📁 Read-only و امن‌تر

    • فقط RRQ (خواندن فایل) را اجرا می‌کند؛ هیچ WRQ (آپلود) ندارد.

    • مناسب سناریوهای تحویل کانفیگ و firmware، بدون ریسک نوشتن سمت سرور.

  • 🧾 لاگ‌گیری قوی

    • یک لاگ مرکزی (مثلاً /var/log/ctftp/ctftp.log) برای همه‌ی رویدادها.

    • برای هر فایلی که درخواست می‌شود، کنار همان فایل در root_dir یک فایل .log ساخته می‌شود:

      • شامل زمان شروع/پایان، IP و Port کلاینت، حجم ارسال‌شده، و وضعیت نهایی.

  • 📡 ارسال Event

    • ارسال Event به صورت JSON روی UDP به یک آدرس/پورت مشخص

    • ارسال Event به صورت JSON روی HTTP POST به یک URL مشخص

    • مناسب مانیتورینگ real-time، داشبورد، SIEM و…

  • ⚙️ تنظیمات ساده و فایل‌محور

    • همه چیز از یک فایل config ساده key=value خوانده می‌شود:

      • root_dir, log_dir

      • لیست listeners (IP:Port)

      • timeout، retry، log_level

      • مقصد UDP و HTTP برای رویدادها

  • 🛡️ سخت‌گیر روی مسیر فایل

    • مسیرهای مطلق و .. بلاک می‌شوند (جلوگیری از directory traversal).

    • خیلی راحت می‌توانی با کاربر غیر privileged اجراش کنی.


شروع سریع (Quick Start) روی لینوکس – با باینری استاتیک

سناریو نمونه:

  • سرور لینوکس (systemd دار، مثلاً Ubuntu/Debian)

  • روت TFTP در /srv/tftp

  • لاگ‌ها در /var/log/ctftp

  • فایل config و باینری در /opt/ctftp

۱. دانلود و آماده‌سازی باینری
 

cd /opt
sudo mkdir -p /opt/ctftp
cd /opt/ctftp

# دانلود باینری استاتیک ctftp
sudo curl -L -o ctftp-static-linux \
  https://github.com/seifzadeh/ctftp/releases/download/0.0.1/ctftp-static-linux

# اجراپذیر کردن
sudo chmod +x ctftp-static-linux



۲. ساخت پوشه‌ها و کاربر سرویس
 

# روت TFTP
sudo mkdir -p /srv/tftp

# دایرکتوری لاگ
sudo mkdir -p /var/log/ctftp

# کاربر سیستمی بدون شل (اختیاری ولی توصیه می‌شود)
sudo useradd -r -s /usr/sbin/nologin ctftp || true

# مالکیت پوشه‌ها
sudo chown -R ctftp:ctftp /srv/tftp /var/log/ctftp /opt/ctftp



 

۳. ساخت کانفیگ پایه

فایل /opt/ctftp/ctftp.conf را بساز:
 

# Root directory for TFTP files
root_dir=/srv/tftp

# Log directory (central log file)
log_dir=/var/log/ctftp

# لیسنرها (IP:Port) – اینجا روی همه اینترفیس‌ها و پورت ۶۹
listeners=0.0.0.0:69

# ارسال event روی UDP – خالی یعنی غیرفعال
event_udp=

# ارسال event روی HTTP – خالی یعنی غیرفعال
event_http_url=

# Timeout و Retries
timeout_sec=3
max_retries=5

# سطح لاگ: error, info, debug
log_level=info



برای تست یک فایل ساده بگذاریم:
echo "hello from ctftp" | sudo tee /srv/tftp/test.txt
sudo chown ctftp:ctftp /srv/tftp/test.txt


۴. اجرای دستی برای تست
cd /opt/ctftp
sudo -u ctftp ./ctftp-static-linux ./ctftp.conf


حالا از یک سیستم دیگر (یا حتی همان سرور) با یک tftp client تست کن:
tftp <SERVER-IP> 69
tftp> get test.txt


اگر همه‌چیز درست باشد باید فایل را از /srv/tftp/test.txt دریافت کنی.
 

اجرای ctftp به صورت سرویس systemd

برای این‌که بعد از ریبوت سیستم خودش بالا بیاید، یک سرویس systemd تعریف می‌کنیم.

۱. ساخت فایل سرویس

فایل /etc/systemd/system/ctftp.service:
 

[Unit]
Description=ctftp - Multi-threaded TFTP server
After=network.target

[Service]
Type=simple
User=ctftp
Group=ctftp
WorkingDirectory=/opt/ctftp
ExecStart=/opt/ctftp/ctftp-static-linux /opt/ctftp/ctftp.conf
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target



اگر مسیر باینری یا کانفیگ را تغییر داده‌ای، در همین فایل اصلاح‌شان کن.
۲. فعال‌سازی سرویس
sudo systemctl daemon-reload
sudo systemctl enable ctftp
sudo systemctl start ctftp
sudo systemctl status ctftp

 

از این به بعد با هر ریبوت سیستم، ctftp هم خودکار بالا می‌آید.


مانیتورینگ و لاگ‌گیری

لاگ مرکزی

ctftp یک لاگ مرکزی مثل این می‌نویسد:
sudo tail -f /var/log/ctftp/ctftp.log

نمونه لاگ:
[2025-12-02T10:15:42] [INFO] ctftp starting with config: /opt/ctftp/ctftp.conf
[2025-12-02T10:15:42] [INFO] Starting listener on 0.0.0.0:69
[2025-12-02T10:16:01] [INFO] RRQ from 192.168.10.50:40000 file="test.txt" mode="octet"
[2025-12-02T10:16:02] [INFO] EVENT type=0 client=192.168.10.50:40000 file="test.txt" bytes=16 status=ok msg=transfer_complete


 

  • می‌بینی از چه IP چه فایلی درخواست شده

  • چقدر دیتا ارسال شده

  • وضعیت نهایی OK بوده یا نه

لاگ کنار هر فایل

کنار هر فایل در root_dir، یک .log ساخته می‌شود. مثلاً:
/srv/tftp/test.txt
/srv/tftp/test.txt.log

محتوا شبیه این است:
2025-12-02T10:16:01;2025-12-02T10:16:02;192.168.10.50;40000;16;ok;transfer_complete

 

ساختار هر خط:

start_ts;end_ts;client_ip;client_port;bytes;status;message

این خیلی برای سناریوهایی مثل «کدوم گوشی‌ها کانفیگ رو گرفتن، کی گرفتن، چند بار گرفتن» عالیه.
 

مقایسه با OpenTFTP و ابزارهای قدیمی

چیزی که من شخصاً باهاش درگیر بودم:

  • OpenTFTP روی لینوکس:

    • به‌خاطر هدرهای خاص ویندوز (ws2tcpip.h و…) روی GCC لینوکسی به‌راحتی کامپایل نمی‌شود.

    • باید نصف سورس را دستکاری کنی که اصلاً بیلد شود.

  • لاگ‌ها:

    • در ساده‌ترین حالت، چند خط کلی می‌نویسند؛ خبری از per-file log و per-request log نیست.

  • Event / مانیتورینگ:

    • هیچ خروجی استانداردی برای وصل کردن به سیستم‌های مانیتورینگ (مثل UDP JSON / HTTP POST) وجود ندارد.

ctftp دقیقاً اینجا خودش را نشان می‌دهد:

  • باینری آماده (static) برای لینوکس → بدون درگیری با کامپایل.

  • لاگ مرکزی + لاگ جدا برای هر فایل → برای دیباگ و گزارش‌گیری.

  • Event JSON روی UDP و HTTP → مستقیم قابل مصرف توسط داشبوردها، ELK، SIEM، یا حتی یک اسکریپت ساده Python.


لینک‌ها

🔗 صفحه پروژه (ctftp):
https://seifzadeh.github.io/ctftp/

🔗 سورس پروژه (ctftp):
https://github.com/seifzadeh/ctftp

⬇️ دانلود باینری استاتیک لینوکس:
https://github.com/seifzadeh/ctftp/releases/download/0.0.1/ctftp-static-linux

اگر در پروژه‌هات از TFTP برای پروویژن گوشی‌ها، تجهیزات VoIP یا هر سناریوی مشابه استفاده می‌کنی،
به‌نظرم یک بار ctftp را تست کن؛ راه‌اندازی‌اش چند دقیقه بیشتر طول نمی‌کشد،
ولی دید خیلی خوبی از رفتار کلاینت‌ها و وضعیت provisioning بهت می‌دهد 🙌

اگر خواستی ته پست، یه بخش «جمع‌بندی و تشویق به مشارکت» هم بگذار:

  • اگر استفاده کردید و به‌دردتون خورد، لطفاً توی GitHub یک ⭐ بدید.

  • اگر ایده یا باگ دیدید، Issue یا Pull Request خوشحال‌م می‌کنه 😊