TcpListener
📖 معرفی کلی
گره TcpListener یکی از بنیادیترین و حیاتیترین اجزای WaterWall است که مسئولیت پذیرش و مدیریت اتصالات TCP ورودی را بر عهده دارد. این نود به عنوان نقطه ورودی اصلی برای ترافیک شبکه عمل میکند.
🔧 مشخصات فنی اساسی
ویژگی | مقدار | توضیح |
---|---|---|
نوع نود | Adapter (تکجهته) | جهت کانکشن ها از چپ شروع و به راست پیش روی میکنند |
لایه شبکه | لایه ۴ (Transport Layer) | کار با کانکشنها، نه پکتهای خام |
جهت پشتیبانی | چپ به راست (Left to Right) | دوجهته نیست مثل بعضی نودهای لایه ۳ |
موقعیت در زنجیر | ابتدای زنجیر (Entry Point) | جایگاه دیگری نمیتواند داشته باشد |
وابستگی | نیاز به حداقل یک نود در بخش next | برای انتقال دادهها ضروری است |
- جایگاه ثابت: این نود حتماً باید در ابتدای یک زنجیر قرار گیرد و نمیتواند در میانه یا انتهای زنجیر استفاده شود
- وابستگی اجباری: برای عملکرد صحیح، حتماً نیاز به معرفی حداقل یک نود در بخش
next
دارد تا دادهها به آن منتقل کند - عدم دوجهته بودن: برخلاف برخی نودهای لایه ۳، این نود فقط از جهت چپ به راست داده منتقل میکند
- نود Adapter: این نود یک Adapter است
🎯 قابلیتها و عملکردها
گره TcpListener وظایف زیر را انجام میدهد که در ادامه دقیقتر توضیح داده میشوند:
🌐 مدیریت اتصالات TCP
- سرور TCP: گوش دادن به اتصالات TCP ورودی روی آدرس و پورت مشخص شده
- مدیریت چرخه حیات: کنترل کامل سوکتها از ایجاد تا بسته شدن و انتقال دادهها به گره بعدی
- انتقال داده: هدایت مطمئن دادهها به گره بعدی در زنجیر
🔒 کنترل دسترسی پیشرفته
- Whitelist: پیادهسازی فیلترینگ whitelist برای آدرسهای IP کلاینت
- Blacklist: پیادهسازی فیلترینگ blacklist برای آدرسهای IP کلاینت
- فیلترینگ CIDR: پشتیبانی از فرمتهای مختلف شبکه مانند
/24
,/32
⚖️ سیستم تعادل بار (Load Balancing)
- توزیع هوشمند: پشتیبانی از توزیع اتصالات ورودی بین چندین listener
- سیستم گروهبندی: مدیریت listener ها در گروههای تعادل
- کنترل زمانی: تنظیم فواصل زمانی برای تخصیص مجدد
🚪 پشتیبانی چند پورت
- پورت منفرد: قابلیت گوش دادن به پورتهای مجزا
- محدوده پورت: قابلیت گوش دادن به محدودهای از پورتها
- بهینهسازی منابع: استفاده از iptables برای مدیریت بهینه پورتهای متعدد
🏆 سیستم اولویتبندی
- همپوشانی هوشمند: قابلیت وجود چند گوشدهنده به یک پورت و تصمیمگیری بر اساس اولویت
- محاسبه اولویت: تعیین listener مناسب بر اساس تنظیمات
- تصمیمگیری پویا: انتخاب بهترین listener بر اساس شرایط
⚙️ راهنمای پیکربندی
📋 ساختار کلی
{
"name": "listener_name",
"type": "TcpListener",
"settings": {
// تنظیمات پایه
"address": "0.0.0.0",
"port": 8443,
"nodelay": true,
// تنظیمات اختیاری
"whitelist": [],
"blacklist": [],
"balance-group": "",
"balance-interval": 60000,
"interface": "",
"multiport-backend": "iptables"
},
"next": "next_node_name"
}
🔧 پارامترهای ضروری
1. Address (آدرس گوش دادن)
"address": "0.0.0.0"
مقادیر معتبر:
"0.0.0.0"
: گوش دادن به تمام interface ها (IPv4)"127.0.0.1"
: فقط localhost (IPv4)"::"
: گوش دادن به تمام interface ها (IPv6)- IP خاص: مانند
"192.168.1.100"
2. Port (پورت)
پورت منفرد:
"port": 8443
محدوده پورت:
"port": [8000, 9000]
⚠️ نکته مهم: در حالت محدوده پورت، تمام پورتهای داخل بازه (8000 تا 9000) گوش داده خواهند شد.
3. Nodelay (بهینهسازی TCP)
"nodelay": true
📚 دلیل اهمیت این پارامتر: به نظر من صرفنظر از سناریویی که میخواهید پیاده کنید، همیشه Nodelay را فعال کنید.
توضیح ساده: سیستم عامل برای ارسالهایی که سایز زیادی ندارند تأخیر میگذارد و یا اصلاً نمیفرستد به خاطر کاهش مصرف CPU یا اینکه پهنای باند کمتر مصرف شود که این اصلاً برای استفادههای ما خوب نیست.
توضیح تکمیلی: این پارامتر الگوریتم Nagle را غیرفعال میکند. الگوریتم Nagle در حالت عادی پکتهای کوچک را با تأخیر ارسال میکند تا بتواند آنها را با پکتهای بعدی ترکیب کند. این رفتار برای اپلیکیشنهای زمانحساس مناسب نیست.
چرا همیشه true؟
- کاهش latency
- بهبود پاسخدهی real-time
- جلوگیری از تأخیرهای غیرضروری
📚 مطالعه بیشتر: اگر خواستید بیشتر درمورد این موضوع بخوانید میتوانید سرچ کنید: tcp nagle Algorithm
🚪 مدیریت چند پورت
اگر به یک بازهی پورت گوش میدهید (حالت مالتی پورت)، میتوانید این پارامتر هم تنظیم کنید برای کنترل بیشتر
🔧 تنظیمات Backend
"multiport-backend": "iptables"
گزینههای موجود:
"iptables"
(پیشفرض): استفاده از iptables برای مدیریت"socket"
: ایجاد سوکت مجزا برای هر پورت
📊 مقایسه روشها
روش | مزایا | معایب | کاربرد توصیه شده |
---|---|---|---|
iptables | مصرف کم CPU/RAM، مقیاسپذیری بالا | وابستگی به iptables | بازههای بزرگ پورت |
socket | کنترل دقیقتر، مستقل از iptables | مصرف بیشتر منابع | اگر iptables نصب نباشد یا نمیخواهید rule هایش دست بخورد توسط واتروال یا دلایل تستی و غیره دارید |
استفاده از iptables معمولاً بهتر است.
دلیل: مخصوصاً وقتی بازه پورت بزرگ باشد، ساختن سوکت برای هر پورت به سیستم فشار میآورد و مصرف CPU و RAM زیاد میشود، ولی روش iptables بدون فشار اضافی امکان این را میدهد که ما هر چند تا پورت را گوش کنیم.
🏆 سیستم اولویتبندی و همپوشانی
نودهای گوشدهنده در واتروال قابلیت همپوشانی دارند که یعنی مثلاً:
- ۲ تا TcpListener به یک پورت گوش بدهند
- یک TcpListener به یک بازه و یک TcpListener به یک پورت که داخل بازه نود اول بود گوش بدهد
در این حالات، اولویتها مشخصکننده هستند که سوکت به کدام TcpListener تعلق دارد.
🧮 محاسبه اولویت
اولویت پایه TcpListener: ۰
افزایش اولویت: اگر توی تنظیماتش مقادیری از جمله موارد زیر باشد، به ازای هر کدام یک اولویت بیشتر میشود:
- وجود
whitelist
: +۱ - وجود
blacklist
: +۱
📝 مثال عملی
// Listener با اولویت بالا (اولویت = 1)
{
"name": "high_priority_listener",
"type": "TcpListener",
"settings": {
"port": 443,
"whitelist": ["1.1.1.1/32"]
},
"next": "next_node_name_1"
}
// Listener با اولویت پایین (اولویت = 0)
{
"name": "default_listener",
"type": "TcpListener",
"settings": {
"port": 443
},
"next": "next_node_name_2"
}
نحوه عملکرد: وقتی این تنظیمات داده میشود، مثلاً فرض کنیم ۲ تا TcpListener به پورت ۴۴۳ گوش میدهند:
- کلاینت با IP
1.1.1.1
→ بهhigh_priority_listener
که whitelist داشت میرود - کلاینت با IP دیگر → اگر IP اش
1.1.1.1
نباشد میرود بهdefault_listener
نکته مهم: blacklist هم همینطوری عمل میکند و اگر IP توی blacklist باشد رد میشود.
🔒 کنترل دسترسی IP
✅ Whitelist (لیست سفید)
"whitelist": [
"192.168.1.0/24", // کل شبکه محلی
"10.0.0.100/32", // IP خاص
"203.0.113.0/24" // شبکه شرکت
]
❌ Blacklist (لیست سیاه)
"blacklist": [
"192.168.1.100/32", // IP مشکلساز
"10.0.0.0/8", // کل رنج خصوصی
"172.16.0.0/12" // شبکه مشکوک
]
این تنظیمات whitelist و blacklist فقط برای همپوشانی نیستند؛ حتی اگر یک tcp listener هم داشته باشید میتوانید استفاده کنید و محدودش کنید.
🎯 کاربرد در تونل معکوس TLS
این کار بخصوص توی زدن تونل معکوس TLS کاربرد دارد؛ وقتی که سرور خارج شما و کاربران شما همه میخواهند به پورت ۴۴۳ وصل شوند و رفتار تونل باید در برابر IP سرور خارج متفاوت باشد.
سناریو: سرور خارج و کاربران به پورت 443 متصل میشوند، اما رفتار برای هر کدام متفاوت است.
// برای سرور خارج
{
"name": "foreign_server_listener",
"type": "TcpListener",
"settings": {
"port": 443,
"whitelist": ["FOREIGN_SERVER_IP/32"]
},
"next": "reverse_tunnel_handler"
}
// برای کاربران عادی
{
"name": "users_listener",
"type": "TcpListener",
"settings": {
"port": 443
},
"next": "normal_handler"
}
⚖️ سیستم تعادل بار (Load Balancing)
🎯 مفهوم کلی
این نود یک قابلیت load balancing سادهای دارد که شاید بدردتان بخورد، ولی load balancing پیشرفتهتر در نود router پیاده میشود.
شما مثلاً ۲ تا نود TcpListener دارید که پورتهاشان همپوشانی دارند و میخواهید کاری کنید کاربران بین اینها پخش شوند.
نکته مهم: کاربران وقتی پخش میشوند باید تا مدتی هم اگر کانکشن جدید زدند روی همان TcpListener قبلی وصل شوند.
تعادل بار در TcpListener امکان توزیع کلاینتها بین چندین listener را فراهم میکند. این قابلیت برای سناریوهای چند سرور یا پخش بار بسیار مفید است.
⚙️ پارامترهای تعادل بار
{
"balance-group": "server_group",
"balance-interval": 60000
}
balance-group
- نوع: String
- توضیح: نام گروه تعادل برای مشخص کردن listener هایی که باید در توزیع شرکت کنند
- مثال:
"iran_servers"
,"europe_group"
balance-interval
- نوع: Integer (میلیثانیه)
- پیشفرض: 60000 (60 ثانیه)
- توضیح: مدت زمانی که کلاینت به یک listener خاص متصل میماند قبل از امکان تخصیص مجدد
🔄 منطق عملکرد
- اتصال اول: کلاینت به یکی از listener ها تخصیص مییابد
- قفل زمانی: کلاینت برای مدت
balance-interval
به همان listener متصل میماند - تخصیص مجدد: پس از گذشت زمان، کلاینت میتواند به listener دیگری منتقل شود
- تمدید زمان: هر اتصال جدید، تایمر را از ابتدا شروع میکند
💡 مثال عملی: دو سرور خارج
یک مثال بخواهم بزنم: فرض کنیم ما یک سرور ایران داریم و دو تا خارج؛ یکی هلند و یکی آلمان و ما میخواهیم کاربرانمان را نصفشان را به هلند وصل کنیم و نصفشان به آلمان.
برای اینکار ۲ تا نود TcpListener تعریف میکنیم هردو روی پورت ۴۴۳ و سپس برای هرکدام هم یک TcpConnector یا حالا به هر روشی که خواستید وصل شوند به سرور خارجشان.
سپس در تنظیمات این ۲ تا نود TcpListener این مقادیر را اضافه میکنیم:
سناریو: یک سرور ایران، دو سرور خارج (هلند و آلمان)
// Listener برای سرور هلند
{
"name": "netherlands_listener",
"type": "TcpListener",
"settings": {
"port": 443,
"balance-group": "europe_servers",
"balance-interval": 300000 // 5 دقیقه
},
"next": "netherlands_connector"
}
// Listener برای سرور آلمان
{
"name": "germany_listener",
"type": "TcpListener",
"settings": {
"port": 443,
"balance-group": "europe_servers",
"balance-interval": 300000 // 5 دقیقه
},
"next": "germany_connector"
}
⏱️ اهمیت balance-interval
balance-interval
تعیین میکند که مثلاً:
اگر کاربر آمد و بار اول قرار شد به آلمان وصل شود؛ اگر برود ۶۰ ثانیه دیگر بیاید دوباره تصمیمگیری شود که به آلمان وصل شود یا هلند.
اگر زودتر از 60 ثانیه از کانفیگش استفاده کند همینطور به آلمان وصل میشود و ۶۰ ثانیه از اول شروع میشود.
و این خیلی مهم است: اگر IP کاربر مثلاً بدون وقفه زمانی عوض شود آنوقت سایتها براش درست باز نمیشوند یا مشکل کپچا و غیره میخورد.
مشکلات interval کوتاه:
- تغییر مکرر سرور
- مشکلات کپچا و احراز هویت
- عدم ثبات جلسات کاربری
مشکلات interval طولانی:
- عدم توزیع مناسب بار
- چسبیدگی کلاینتها به سرور واحد
توصیه: برای کاربرد عمومی، 5-10 دقیقه مناسب است.
🌐 تنظیمات Interface
"interface": "eth0"
📋 کاربرد
این بدرد وقتی میخورد که چند کارت شبکه دارید و میخواهید این TcpListener روی یکی از آنها سوار شود.
مثالهای معمول:
"eth0"
: کارت شبکه اصلی"eth1"
: کارت شبکه ثانویه"tun0"
: Interface تونل"br0"
: Bridge interface
⚠️ نکته: در غیر این صورت کاربردی ندارد. در اکثر موارد نیازی به تنظیم این پارامتر نیست.
🎯 مثالهای کاربردی
🔹 1. Listener ساده
{
"name": "simple_web_listener",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": 8443,
"nodelay": true
},
"next": "web_handler"
}
کاربرد: گوش دادن ساده به یک پورت برای وب سرویس
🔹 2. Listener چند پورت با بهینهسازی
{
"name": "gaming_multi_port_listener",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": [7000, 7100],
"nodelay": true,
"multiport-backend": "iptables"
},
"next": "game_server_handler"
}
کاربرد: سرور بازی با پورتهای متعدد و بهینهسازی منابع
🔹 3. Load Balancer پیشرفته
// Listener اول
{
"name": "load_balanced_listener_1",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": 443,
"nodelay": true,
"balance-group": "web_servers",
"balance-interval": 600000 // 10 دقیقه
},
"next": "server_cluster_1"
}
// Listener دوم
{
"name": "load_balanced_listener_2",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": 443,
"nodelay": true,
"balance-group": "web_servers",
"balance-interval": 600000 // 10 دقیقه
},
"next": "server_cluster_2"
}
کاربرد: توزیع بار بین دو کلاستر سرور با ثبات جلسه
🔹 4. کنترل دسترسی پیشرفته
{
"name": "secure_admin_listener",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": 22,
"nodelay": true,
"whitelist": [
"192.168.1.0/24", // شبکه داخلی
"203.0.113.50/32" // IP مدیریت خارجی
],
"blacklist": [
"10.0.0.100/32" // IP مسدود شده
]
},
"next": "admin_ssh_handler"
}
کاربرد: دسترسی امن SSH با کنترل دقیق IP
🔹 5. تونل معکوس TLS
// برای سرور خارج
{
"name": "foreign_server_tls_listener",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": 443,
"nodelay": true,
"whitelist": ["FOREIGN_SERVER_IP/32"]
},
"next": "reverse_tls_tunnel"
}
// برای کاربران
{
"name": "users_tls_listener",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": 443,
"nodelay": true
},
"next": "user_tls_handler"
}
کاربرد: مدیریت جداگانه ترافیک سرور خارج و کاربران روی یک پورت
⚠️ نکات مهم و بهترین روشها
🎯 بهینهسازی عملکرد
- همیشه nodelay فعال: برای کاهش latency
- استفاده از iptables: برای بازههای بزرگ پورت
- تنظیم مناسب balance-interval: متناسب با نوع کاربرد
🔒 امنیت
- محدود کردن address: در صورت امکان از
0.0.0.0
اجتناب کنید - استفاده از whitelist: برای محیطهای حساس
- مانیتورینگ blacklist: برای شناسایی حملات
🏗️ معماری
- موقعیت در زنجیر: همیشه در ابتدا
- تعریف next node: اجباری برای عملکرد
- تفکیک وظایف: از listener های جداگانه برای منطقهای مختلف
📊 مانیتورینگ
- پایش اتصالات: تعداد و کیفیت
- بررسی load balancing: توزیع مناسب
- کنترل منابع: CPU و RAM در حالت چند پورت