
مدتها برای پروویژن خودکار (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ها (مخصوصاً سیسکو)
با این ویژگیها:
ویژگیهای کلیدی
شروع سریع (Quick Start) روی لینوکس – با باینری استاتیک
سناریو نمونه:
۱. دانلود و آمادهسازی باینری
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
لاگ کنار هر فایل
کنار هر فایل در 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 روی لینوکس:
-
لاگها:
-
Event / مانیتورینگ:
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 بهت میدهد 🙌
اگر خواستی ته پست، یه بخش «جمعبندی و تشویق به مشارکت» هم بگذار: