Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

چندین یوزر روی یک پورت #35

Open
vahidxo opened this issue Jan 15, 2023 · 18 comments
Open

چندین یوزر روی یک پورت #35

vahidxo opened this issue Jan 15, 2023 · 18 comments

Comments

@vahidxo
Copy link

vahidxo commented Jan 15, 2023

سلام دوستان وقتتون بخیر
یه راهنمایی میخواستم برای راه اندازی این سرویس
میشه روی یک پورت چندین یوزر تعریف کرد؟ یا در کل پروتکلی و روشی هست به غیر از x-ui که بشه چندین یوزر روی یک پورت گذاشت؟

@hossein-mohseni
Copy link

بله با این پنل x-ui میشه

https://github.com/HexaSoftwareTech/x-ui

@OnceUponATimeInAmerica
Copy link

OnceUponATimeInAmerica commented Feb 4, 2023

بله. با همون x-ui معمولی هم میشه. روشش استفاده از مکانیسم fallback هست که در خود پرتکل v2ray تعبیه و تعریف شده.
هر چند تا یوزر (با یوزر و پسوردهای متفاوت و حتی پرتکلهای متفاوت) که بخواهید رو میشه با یک پورت عمومی سرویس داد.

روشش اینه:

  1. با x-ui یه پروکسی اصلی با پرتکل tcp (ترجیحا VLESS-XTLS-RPRX-VISION) روی همون پورت عمومی (ترجیحا 443) که با جهان خارج ارتباط خواهد داشت ایجاد میکنیم (توجه بشه این پورت در firewall مثلا ufw هم باید حتما باز باشه).
    در ساختن این پروکسی "اصلی یا عمومی" نکات زیر باید رعایت بشه:
  • فیلد listening ip باید خالی بمونه
  • پورت ترجیحا 443 باشه. به این پورت در این نوشته میگیم پورت public shared port.
  • TLS رو برای این پراکسی باید کامل و درست کانفیگ کنید (field های cert , key). تریجیحا sni نام یه سایت ایرانی دلخواه و معروف باشه.
  • یوزنیم و پسوردی که اینجا ست میکنید زیاد مهم نیست و به یوزر نهایی داده نمیشه.
  1. حالا برای هر یوزر یه پراکسی مخصوص با پورت جداگانه باید درست کنیم که برای راحتی از همون Trojan+TCP استفاده میکنیم (میشه با تنظیمات پیشرفته تر از انوع دیگه مثل gRPC یا WebSocket هم استفاده کرد که من اینجا فعلا توضیح نمیدم).
    در ساختن این پروکسی "فرعی یا خصوصی" نکات زیر باید رعایت بشه:
  • فیلد listening ip باید 127.0.0.1 باشه
  • پورت باید یه پورت اختصاصی و دلخواهی غیر از 443 باشه. به این پورت در این نوشته میگیم پورت private/local dispatch port.
  • TLS روی این پراکسی فرعی باید غیر فعال باشه.
  • گزینه acceptProxyProtocol باید فعال باشه.
  • یوزنیم و پسوردی که اینجا قرار میدید مهمه و میتونه اختصاصی باشه و تبدیل میشه به همون یوزنیم و پسوردی که در لینک تولید شده به یوزر نهایی داده میشه.
  1. حالا دوباره به پروکسی اصلی برمیگردیم و یک fallback متناظر بهش اضافه میکنیم:
  • دکمهfallback رو انتخاب میکنیم.
  • عدد xver رو میگذاریم 1.
  • dest باید دقیقا همون private/local dispatch port باشه که در مرحله 2 به پراکسی خصوصی اختصاص دادیم.
  • سیو میکنیم.
  1. حالا باید لینک نهایی هر یوزر رو تولید کنیم. برای اینکار روی هر پراکسی خصوصی/فرعی گزینه ckeck-> copy link رو انتخاب میکنیم. کار هنوز تموم نشده و باید در این لینک تولید شده حداقل 3 چیز رو تغییر بدیم:
  • یکی آدرس 127.0.0.1 باید به آدرس عمومی یا دامین سرور شما تغییر کنه.
  • عدد پورت private/local dispatch port که در لینک اومده باید به عدد پورت عمومی public shared port مثلا همون 443 تغییر کنه.
  • ضمنا!!! (این مرحله رو در نگارش اول از قلم انداخته بودم 😬) عبارت security=none در لینک تولید شده به security=tls&alpn=http%2F1.1 تغییر کنه. وقتی لینک نهایی در برنامه کلاینت پیست بشه، باید گزینه tls رو فعال نشون بده، در حالیکه روی خود پروکسی (فرعی-خصوصی) ما tls رو فعال نکرده بودیم. دلیلش اینه که اطلاعات tls رو xray از همون کانفیگ پراکسی اصلی (پورت 443 که فالبکها اونجا تعریف شدن) میگیره و لذا خود این پراکسی فرعی (که بهش ریدایرکت میکنیم) هم +tls (در مجموع trojan+tcp+tls) محسوب میشه.
  • در ضمن فیلد sni رو هم میتونید به لینک تولید شده اضافه کنید. مثلا با security=tls&alpn=http%2F1.1&sni=divar.ir به جای عبارت بالا.

کار تموته و پراکسی و لینک مربوطه یوزر آماده هست.

لازم به ذکر هست که فقط باید پورت عمومی یعنی همون 443 در فایروال باز باشه و میتونید همه پورت های دیگه (غیر از پورت خود پنل و احیانا ssh) رو ببندید. پورت های خصوصی فقط برای ارتباط محلی پروسسهای مختلف در خود حافظه سرور استفاده میشه و لازم نیست از خارج باز و قابل دسترسی باشه.

نکته آخر هم اینکه از همین مکانیسم fallback میشه برای ایجاد وب پیج استتارکننده برای سرور به همراه nginx استفاده کرد (البته اونهم کمی کانفیگ داره).

@OnceUponATimeInAmerica
Copy link

@iranxray این توضیحات رو میتونید به صفحه های مربوط به ایجاد پراکسی تون اضافه بکنید.
فکر کنم برای عموم مفید باشه.

@radio-azad-iran
Copy link

radio-azad-iran commented Feb 5, 2023

من تست کردم و جواب نگرفتم
اول از همه یه vless با tcp و tls vision روی ۴۴۳ ساختم، بعد یه trojan بدون tls روی tcp که داره به 127.0.0.1 گوش می‌ده روی ۲۰۵۳ ساختم و accept proxy protocol رو روش زدم
روی connection اولم fallback زدم با xver مقدار ۱ و dest مقدار 2053
آدرس رو از روی connection دوم برداشتم و جای ۱۲۷.۰.۰.۱ و ۲۰۵۳ رو با آدرس اصلی سرور و ۴۴۳ جایگزین کردم
این که ج نداد، یه کار دیگه کردم، connection دوم رو پاک کردم و روی ۲۰۵۳ در حال گوش دادن به ۱۲۷.۰.۰.۱ یه دونه vless ساختم و tls vision دادم و مجدد آدرس رو از روی connection برداشتم و جای ۱۲۷.۰.۰.۱ و ۲۰۵۳ رو با آدرس اصلی سرور و ۴۴۳ جایگزین کردم
این هم جواب نداد، به نحوی که اگه UUID معتبر تو کانکشن اصلی یعنی ۴۴۳ رو بگذارم داخل آدرسش درست می‌شه (طبیعتا)، ولی با UUID اون کانکشن ۲۰۵۳ هیچ کاری نمی‌کنه و خطای The underlying connection was closed‌ می‌ده

image
آیا نباید باقی فیلدها مقدار بگیره؟

به علاوه من یه مشکل مفهومی هم دارم، اگه کانکشن فرعی trojan بدون tls باشه برای مثال، و ما هم آدرس همون رو کپی کنیم و نهایتا 127.0.0.1 و 2053 رو با آدرس سرور و 443 جایگزین کنیم، که عملا کلاینت با trojan بدون tls وصل می‌شه که جالب نیست، یا این روش ج نمی‌ده که بازم جالب نیست

@hossein-mohseni
Copy link

من تست کردم و جواب نگرفتم
اول از همه یه vless با tcp و tls vision روی ۴۴۳ ساختم، بعد یه trojan بدون tls روی tcp که داره به 127.0.0.1 گوش می‌ده روی ۲۰۵۳ ساختم و accept proxy protocol رو روش زدم
روی connection اولم fallback زدم با xver مقدار ۱ و dest مقدار 2053
آدرس رو از روی connection دوم برداشتم و جای ۱۲۷.۰.۰.۱ و ۲۰۵۳ رو با آدرس اصلی سرور و ۴۴۳ جایگزین کردم
این که ج نداد، یه کار دیگه کردم، connection دوم رو پاک کردم و روی ۲۰۵۳ در حال گوش دادن به ۱۲۷.۰.۰.۱ یه دونه vless ساختم و tls vision دادم و مجدد آدرس رو از روی connection برداشتم و جای ۱۲۷.۰.۰.۱ و ۲۰۵۳ رو با آدرس اصلی سرور و ۴۴۳ جایگزین کردم
این هم جواب نداد، به نحوی که اگه UUID معتبر تو کانکشن اصلی یعنی ۴۴۳ رو بگذارم داخل آدرسش درست می‌شه (طبیعتا)، ولی با UUID اون کانکشن ۲۰۵۳ هیچ کاری نمی‌کنه و خطای The underlying connection was closed‌ می‌ده

image
آیا نباید باقی فیلدها مقدار بگیره؟

به علاوه من یه مشکل مفهومی هم دارم، اگه کانکشن فرعی trojan بدون tls باشه برای مثال، و ما هم آدرس همون رو کپی کنیم و نهایتا 127.0.0.1 و 2053 رو با آدرس سرور و 443 جایگزین کنیم، که عملا کلاینت با trojan بدون tls وصل می‌شه که جالب نیست، یا این روش ج نمی‌ده که بازم جالب نیست

اگر path ست کنیم برا کانفیگ trojan که قراره به اون ریدایرکت بشه به نظرت جواب میده؟ و این که خب وقتی کانفیگ پابلیک که روی پورت ۴۴۳ ست شده وقتی tls رو validate میکنه چرا همین رو ریدایرکت نکنه و به نطرم منطقی نیست مثلا کانفیگ پابلیک vless باشه و بخوایم به ساختار دیگه ای مثل تروجان ریدایرکت کنیم.

@OnceUponATimeInAmerica
Copy link

OnceUponATimeInAmerica commented Feb 5, 2023

@radio-azad-iran, @hossein-mohseni و @Bardiafa

من یه قسمت کوچولو رو فراموش کرده بودم و حالا اضافه کردم (ذیل بند 5 و همراه با ایموجی). دوباره ببینید.
چون من مدتها قبل این روش رو درآورده بودم همه مراحل رو حضور ذهن ممکنه نداشته باشم. اگه کار کرد بگید بدونم نوشته بالا ناقصی نداره. ممنون.

ضمنا نه باقی فیلدهای داخل fallback مقدار دهی نیاز ندارن (حداقل برای این کانفیگ خاص). اگه پراکسی خصوصی از نوع WebSocket یا gRPC (استفاده از فیلد path) باشه یا سایت استتارکننده با nginx هم بخوایم داشته باشیم (alpn=h2) اونوقت از فیلدهای دیگه هم استفاده میکنیم

@OnceUponATimeInAmerica
Copy link

OnceUponATimeInAmerica commented Feb 6, 2023

محض راهنمایی بیشتر این قسمت فالبک های پراکسی اصلی من روی پورت 443 (از نوع VLESS-RPRX-VISION) هست.

اولی (پورت محلی 31296) مربوط به یه پراکسی خصوصی/فرعی trojan+tcp . (در طرف کلاینت بصورت trojan+tcp+tls روی پورت 443 دیده میشه)

دومی برای فالبک به nginx (برای هم سایت استتار و هم ریدایرکت به پراکسی فرعی trojan+gRPC) nginx کانفیگ شده که روی پورت 31302 محلی گوش میده..
سومی به یه پراکسی فرعی دیگه trojan+websocket مربوط هست. اگه تعداد یوزر بیشتر از یکی باشه بهتره از همین پراکسی فرعی نوع websocket به همراه path منحصربفرد برای هر یوزر استفاده بشه (پراکسی tcp خالی پارامتر path نداره). برای پراکسی فرعی نوع websocket باید علاوه بر پورت فرعی، path ها هم در خود پراکسی و هم در فالبک متناظرش ذیل پراکسی اصلی یکسان باشه.

هر کدوم از اینها یا میتونن مربوط به یه یوزر جدا (با پسورد جدا) باشن. یا اینکه برای تنوع پرتکلی خودتون روی تک پورت 443 استفاده بشن.
توجه کنید تنها پورت باز سیستم در فایروال فقط 443 هست.

image

@hdd064
Copy link

hdd064 commented Feb 6, 2023

نکته آخر هم اینکه از همین مکانیسم fallback میشه برای ایجاد وب پیج استتارکننده برای سرور به همراه nginx استفاده کرد (البته اونهم کمی کانفیگ داره).

نکته آخر رو اگه میشه توضیح بدید استفاده کنیم :)

@radio-azad-iran
Copy link

توضیح داده دیگه، تو کامنت آخرش، fallback 2 رو ببین، داره می‌گه اگه request مبتنی بر http اومد روی پورت 443، بفرستش روی ۳۱۳۰۲ که nginx داره بهش گوش می‌ده @hdd064
درست متوجه شدم؟ @OnceUponATimeInAmerica بعد این h2 به request های http 1.1 هم جواب می‌ده؟

@OnceUponATimeInAmerica
Copy link

OnceUponATimeInAmerica commented Feb 6, 2023

بعد این h2 به request های http 1.1 هم جواب می‌ده؟

ریدایرک کردن هم بر اساس alpn و هم بر اساس path انجام میشه. پروکسی های trojan , ws هر دو http 1.1 ارایه میکنن و در نتیجه درخواستهای با منشا اونها اصلا به nginx نمیره (در اولین پستم امده).

نمونه کانفیگ (الحاقی) nginx میتونه اینطوری باشه. میبینید که فقط http2 رو سرویس میکنه و ضمنا میتونه به یه پراکسی فرعی دیگه gRPC (که پارامتر grpcpath خودش رو داره و در inbound ها تعریف شده) هم ریدایرکت کنه. فایلهای وب پیج استتاری تون هم در اون مسیری که در خط حدود 9-10 اومده قرار میگیره.

در کل با پراکسی نوع gRPC درخواست کلاینت خارجی اول به xray روی پورت 443 میرسه و بعد به nginx رو پورت محلی 31302 میره و اونهم (بر اساس path مشخص شده) دوباره درخواست رو به xray ولی اینبار به پورت 31301 که پراکسی gRPC روش تعریف شده برمیگردونه.

البته این کانفیگ پیشرفته و پیچیده ای هست ولی بسیار انعطاف پذیر و سریعه.


server {
	listen 80;
	server_name YOUR_SERVER_NAME.com;
	return 302 https://YOUR_SERVER_NAME.com;
}

server {
	listen 127.0.0.1:31302 http2 so_keepalive=on;
	server_name YOUR_SERVER_NAME.com ;
	root /usr/share/nginx/html;

	client_header_timeout 1071906480m;
    keepalive_timeout 1071906480m;

    location /grpcpath1 {
    	if ($content_type !~ "application/grpc") {
    		return 404;
    	}
 		client_max_body_size 0;
		grpc_set_header X-Real-IP $proxy_add_x_forwarded_for;
		client_body_timeout 1071906480m;
		grpc_read_timeout 1071906480m;
		grpc_pass grpc://127.0.0.1:31301;
	}

	location / {
        	add_header Strict-Transport-Security "max-age=15552000; preload" always;
    }
}

@radio-azad-iran
Copy link

چندین بار و با دقت مراحل رو رفتم و توفیقی حاصل نشد

@OnceUponATimeInAmerica
Copy link

باشه. سعی میکنم از کانفیگ موجودم استخراجش کنم.

@OnceUponATimeInAmerica
Copy link

OnceUponATimeInAmerica commented Feb 23, 2023

خب همونطور که قبلا گفتم، من قسمت آرایه inbounds در کانفیگ سرورم رو اینجام میگذارم.

  1. میتونید برای هر یوزر اضافی یه پراکسی فرعی به این آرایه اضافه کنید. یا میتونید متناظر با اطلاعات json پراکسی رو در پنل x-ui بسازید.

  2. ضمنا لینک های متناظر با پراکسی اصلی (اولی) و همچنین پراکسی فرعی رو هم قرار دادم تا نحوه تغییراتی که درش باید انجام بشه واضحتر بشه.

  3. باید قسمتهایی که با فارسی (هم در کانفیگ و هم در لینکها) داخل [] مشخص شده طبق نیازهای خودتون جایگزین بشه. این کانفیگ شامل یه پراکسی اصلی روی پورت 443 به همراه یه پراکسی فرعی (مخصوص هر یوز) روی پورت محلی و فرعی هست. هر دوشون (و هر چندتای دیگه که پراکسی فرعی نوع ws اضافه کردید) از طرف کلاینت همه روی همون پورت 443 دسترسی خواهند (که باید در فایروال باز باشه).

  4. نوع پراکسی ها رو میتونید بینtrojan , vless تغییر بدید. بقیه پاراکترها نباید تغییر کن.

  5. توجه کنید که باید path و پورت محلی/فرعی اختصاصی برای هر پراکسی جدید در نظر بگیرید که باید در لینک متناظر هم منعکس بشه.


لینکها

vless://[یوزر آی دی]@[آدرس سرور]:443?encryption=none&flow=xtls-rprx-vision&security=tls&sni=[SNI_شما]&alpn=h2%2Chttp%2F1.1&fp=chrome&type=tcp&headerType=none#%F0%9F%87%B3%F0%9F%87%B1%E2%9D%B7%E2%91%A0VLESS-XTLS-RPRX-VISION
trojan://[یوزر آی دی]@[آدرس سرور]:443?security=tls&sni=[SNI_شما]&alpn=http%2F1.1&fp=chrome&type=ws&path=%2F[path اختصاصی]#%F0%9F%87%B3%F0%9F%87%B1%E2%9D%B7%E2%91%A4Trojan-TLS-WS




کانفیگ
  
  "inbounds": [    
    {
      "listen": null,
      "port": 443,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "[یوزر آی دی]",
            "email": "[ایمیل]",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none",
        "fallbacks": [          
          {
            "name": "",
            "alpn": "",
            "path": "/[path اختصاصی]",
            "dest": "31297",
            "xver": 1
          }          
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "[SNI_شما]",
          "minVersion": "1.2",
          "maxVersion": "1.3",
          "cipherSuites": "",
          "certificates": [
            {
              "certificateFile": "[مسیر فایل cert]",
              "keyFile": "[مسیر فایل private key]"
            }
          ],
          "alpn": [
            "h2",
            "http/1.1"
          ]
        },
        "tcpSettings": {
          "header": {
            "type": "none"
          },
          "acceptProxyProtocol": false
        }
      },
      "tag": "inbound-443",
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      }
    },    
    {
      "listen": "127.0.0.1",
      "port": 31297,
      "protocol": "trojan",
      "settings": {
        "clients": [
          {
            "password": "[یوزر آی دی]",
            "email": "[ایمیل]",
            "flow": ""
          }
        ],
        "fallbacks": []
      },
      "streamSettings": {
        "network": "ws",
        "security": "none",
        "wsSettings": {
          "path": "/[path اختصاصی]",
          "headers": {},
          "acceptProxyProtocol": true
        }
      },
      "tag": "inbound-31297",
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      }
    }    
  ]



@Phoenix-999
Copy link

@OnceUponATimeInAmerica
@radio-azad-iran
راهی هست من بتونم به شما یک پیام خصوصی بدم ?!

@mokhtarabdi
Copy link

mokhtarabdi commented Jul 25, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants
@hdd064 @hossein-mohseni @OnceUponATimeInAmerica @radio-azad-iran @vahidxo @mokhtarabdi @Phoenix-999 and others