Admin Levelمدیریت سرور

نصب tc و مدیریت ترافیک سرور

چگونه پهنای باند را در سرور لینوکس مدیریت و کنترل کنیم؟

ابزار tc چیست؟

tc کوتاه شده‌ی Traffic Control هست.
ابزاری از پکیج iproute2 که توی لینوکس استفاده میشه برای مدیریت ترافیک شبکه.

به طور خلاصه:

✅ می‌تونی با tc سرعت ورودی یا خروجی رو محدود کنی.
✅ می‌تونی ترافیک رو صف‌بندی کنی (queue)، مثلا صف‌های مختلف با اولویت بسازی.
✅ می‌تونی تأخیر (delay)، از دست دادن بسته‌ها (loss)، یا تغییر ترتیب بسته‌ها (reorder) شبیه‌سازی کنی.
✅ در پروژه‌های واقعی و تستی یا سرورهای واقعی کاربرد زیادی داره.


🔹 چه کارهایی دقیقا میشه با tc کرد؟

 

کار توضیح
محدود کردن سرعت (Rate Limit) مثلا بگی نهایتا با سرعت ۵ مگابیت در ثانیه بشه دانلود کرد.
اولویت‌بندی ترافیک (QoS) مثلا بگی پورت‌های خاص یا IPهای خاص سرعت بیشتری داشته باشن.
شبیه‌سازی Delay مثلا بگی بسته‌ها ۱۰۰ میلی‌ثانیه تأخیر بخورن، مناسب تست.
simulate loss یا drop مثلا ۵٪ بسته‌ها عمداً گم بشن، برای تست رفتار نرم‌افزار.

🔹 اجزای اصلی در tc

tc روی ۳ سطح اصلی کار می‌کنه:

 

اجزا توضیح
qdisc (Queue Discipline) کنترل نحوه صف‌بندی و ارسال بسته‌ها (مهم‌ترین بخش)
class گروه‌بندی ترافیک تحت یک qdisc برای تنظیمات جزئی‌تر
filter فیلتر کردن ترافیک و مشخص کردن این که هر بسته به کدوم class بره

🔹 معروف‌ترین qdisc ها:

 

qdisc کاربرد
pfifo_fast صف پیش‌فرض، اولویت‌بندی ساده
tbf (Token Bucket Filter) محدود کردن پهنای باند با نرخ ثابت
htb (Hierarchical Token Bucket) تقسیم‌بندی دقیق‌تر پهنای باند بین کلاس‌های مختلف
netem شبیه‌سازی تاخیر، گم شدن بسته، خراب شدن بسته و …
ingress برای کنترل سرعت بسته‌های ورودی (upload به سرور)

🔹 یک مثال ساده:

مثلاً این دستور:

tc qdisc add dev eth0 root tbf rate 5mbit burst 10kb latency 70ms

میگه روی خروجی کارت شبکه eth0، ترافیک رو محدود کن به:

  • سرعت ۵ مگابیت بر ثانیه

  • تا ۱۰ کیلوبایت به صورت ناگهانی اجازه بده

  • حداکثر تاخیر ۷۰ میلی‌ثانیه باشه

نصب tc

 

نصب بسته iproute

sudo dnf install iproute

نصب ابزارهای لازم برای کامپایل

sudo dnf groupinstall "Development Tools"
sudo dnf install libmnl-devel
گاهی پس از نصب iproute دستور tc فعال نمی شود، برای این موضوع می توانید از طریق سورس نصب کنید.
git clone https://github.com/iproute2/iproute2.git
cd iproute2
make
make install
با tc می توانید روی ترافیک ورودی و خروجی قوانین اجرا کنید.

🔵 با tc به تنهایی نمی‌توان مستقیماً سرعت ورودی (ingress) را محدود کرد.
چون tc روی خروجی (egress) خیلی راحت کار می‌کند، ولی روی ورودی باید ترفند بزنی.


راه درست محدودسازی پهنای باند ورودی upload:

ما باید روی Ingress qdisc کار کنیم و بسته‌های ورودی را فیلتر کنیم و بعد با police محدود کنیم.

فرمول کلی:

tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: protocol all prio 50 u32 match u32 0 0 police rate 8mbit burst 10k drop flowid :1

توضیح این دستورات:

  1. tc qdisc add dev eth0 handle ffff: ingress

    • ایجاد صف‌بندی (qdisc) روی ورودی کارت شبکه (interface).

  2. tc filter add dev eth0 parent ffff: protocol all prio 50 u32 match u32 0 0 police rate 8mbit burst 10k drop flowid :1

    • هر بسته‌ای که میاد رو فیلتر کن، اگر بیشتر از ۸ مگابیت بر ثانیه بود → بندازش (drop کن).

    • burst 10k یعنی حداکثر ۱۰ کیلوبایت اجازه جهش لحظه‌ای.


نکته:

  • عدد 8mbit رو به دلخواه می‌تونی تغییر بدی به هر سرعتی که میخوای.

  • اگه بخوای خیلی حرفه‌ای‌ترش کنی، میشه reclassify یا continue بجای drop بزاری ولی این ساده‌ترین روش برای کاهش سرعت ورودی است.

خلاصه خیلی ساده:

 

نوع کنترل روش معمولی روش برای ورودی
خروجی (Download سمت کاربر) tc tbf راحت
ورودی (Upload به سرور) tc ingress + police با ترفند

اسکریپت پیشرفته محدودسازی پهنای باند

#!/bin/bash

# --------------------------
# محدودسازی حرفه‌ای سرعت آپلود و دانلود در لینوکس
# --------------------------

# --- رنگ‌ها ---
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

# --- ورودی از کاربر ---
read -p "➤ نام کارت شبکه را وارد کنید (مثلا eth0): " IFACE
read -p "➤ حداکثر سرعت دانلود (مثلا 10mbit): " DOWNLOAD_LIMIT
read -p "➤ حداکثر سرعت آپلود (مثلا 5mbit): " UPLOAD_LIMIT

# --- فایل لاگ ---
LOG_FILE="/tmp/bandwidth_limiter.log"

# --- پاکسازی قوانین قبلی ---
echo -e "${GREEN}[*] پاکسازی رول‌های قبلی...${NC}"
tc qdisc del dev $IFACE root 2>/dev/null
tc qdisc del dev $IFACE ingress 2>/dev/null

# --- اعمال محدودیت آپلود (ورودی سرور) ---
echo -e "${GREEN}[*] اعمال محدودیت آپلود...${NC}"
tc qdisc add dev $IFACE root handle 1: htb default 10
tc class add dev $IFACE parent 1: classid 1:10 htb rate $UPLOAD_LIMIT

# --- اعمال محدودیت دانلود (خروجی سرور) ---
echo -e "${GREEN}[*] اعمال محدودیت دانلود...${NC}"
tc qdisc add dev $IFACE handle ffff: ingress
tc filter add dev $IFACE parent ffff: protocol ip u32 match u32 0 0 police rate $DOWNLOAD_LIMIT burst 10k drop flowid :1

# --- نوشتن در لاگ ---
echo "$(date '+%Y-%m-%d %H:%M:%S') | Limited $IFACE | Download: $DOWNLOAD_LIMIT | Upload: $UPLOAD_LIMIT" >> $LOG_FILE

echo -e "${GREEN}[+] محدودیت‌ها اعمال شدند.${NC}"
echo -e "${GREEN}[!] حالت ایمن فعال شد؛ قوانین بعد از ۳۰ ثانیه پاک می‌شوند مگر اسکریپت قطع نشود.${NC}"

# --- FailSafe: پاک کردن رول ها بعد از 30 ثانیه در صورت نیاز --- میتوانید این قسمت را غیرفعال کنید
(sleep 30
echo -e "${RED}[!] پاکسازی خودکار رول‌ها بعد از ۳۰ ثانیه (safety mode)...${NC}"
tc qdisc del dev $IFACE root 2>/dev/null
tc qdisc del dev $IFACE ingress 2>/dev/null
echo "$(date '+%Y-%m-%d %H:%M:%S') | Rules auto-cleared after 30s timeout." >> $LOG_FILE
) &

exit 0

🛡 توضیح نکات پیشرفته:

 

ویژگی توضیح
FailSafe اگر SSH قطع شد یا مشکل پیش اومد، قوانین بعد ۳۰ ثانیه حذف میشن تا دسترسی کامل از بین نره
لاگ اطلاعات در /tmp/bandwidth_limiter.log ثبت میشه
رنگی پیام‌ها با رنگ‌های قرمز و سبز برای فهم بهتر
ورودی پویا دیگه لازم نیست دستی تو کد تغییر بدی

⚡️ روش استفاده:

  1. اسکریپت رو ذخیره کن مثلا به نام limit_bandwidth.sh

  2. دسترسی اجرایی بده:

chmod +x limit_bandwidth.sh
  1. اجراش کن:

./limit_bandwidth.sh

✅ ویژگی‌های نسخه پیشرفته اسکریپت:

🌟 گرفتن ورودی سرعت دانلود و آپلود (کاربر خودش وارد می‌کند)

🌟 انتخاب کارت شبکه به صورت پویا (اگر خواستی)

🌟 FailSafe تایمر: اگر اسکریپت قطع شد، بعد از ۳۰ ثانیه قوانین خودش پاک میشه. (‌بعد از اطمینان این قسمت را غیرفعال کنید تا قوانین حذف نشود.)

🌟 لاگ‌برداری (ثبت در یک فایل)

🌟 پیام‌های رنگی و واضح

🌟 پاکسازی قوانین قدیمی قبل از اجرای جدید

 

پاک کردن rule ها:

 

نوع رول دستور پاک کردن
رول روی خروجی (download سمت کلاینت) tc qdisc del dev eth0 root
رول روی ورودی (upload به سرور) tc qdisc del dev eth0 ingress

اگر بخوای همه‌ی رول‌ها رو با هم پاک کنی:

میتونی دوتا دستور رو پشت هم بزنی:

tc qdisc del dev eth0 root
tc qdisc del dev eth0 ingress

یا اگر حرفه‌ای‌تر بخوای:

for i in root ingress; do tc qdisc del dev eth0 $i 2>/dev/null; done

(اینطوری اگر وجود نداشت هم خطا نمیده.)

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا