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 خوشحالم میکنه 😊
