مهدی مزرعه ملایی
مهدی مزرعه ملایی
خواندن ۳ دقیقه·۸ ماه پیش

بررسی نحوه عملکرد تحریم شکن

کم و بیش در زندگی روزمره ممکن است از تحریم شکن هایی مثل شکن و ... استفاده کرده باشین.

در این پست کوتاه قصد دارم نحوه عملکرد این نوع تحریم شکن هارو بررسی کنیم.

Forward Proxy

پراکسی فوروارد یا Forward Proxy سروری هست که بین گروهی از ماشینهای سرویس گیرنده و اینترنت قرار میگیرد. وقتی کلاینتها request هایشان را ارسال میکنند، Forward-Proxy بعنوان یک واسط عمل میکند و request ها را از کلاینت ها میگیرد و در سمت دیگر، به سمت وب سرورهای مقصدشان میفرستد و در نهایت پاسخ وب سرورها را گرفته و به کلاینتها بر میگرداند.

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

در جواب باید گفت که این نوع از پراکسی، از اطلاعات هویتی کلاینتها یا به اصطلاح خودمان، از identity کلاینتها حفاظت میکند. به این صورت که اگر از یک فوروارد پراکسی استفاده کنیم، در آن صورت فقط آدرس IP کلاینتها حفظ میشود و در request header که به سمت وب سرور در نهایت ارسال میشود، آدرس IP پراکسی قابل مشاهده است.

تنها کاری که نیاز هست انجام بشه اینه که تمام درخواست های DNS ما به آدرس سرور ForwardProxy تبدیل بشود.

import sys, socket, argparse from dnslib import DNSRecord, DNSHeader, RR, A, QTYPE, DNSError from os import environ from socketserver import ThreadingUDPServer, DatagramRequestHandler allow_all = False w_list = [] args = None class PacketHandler(DatagramRequestHandler): # DatagramRequestHandler def handle(self) -> None: data = self.rfile.read(512) # Maximum UDP Packet Size is 512 Byte if args.debug: # Show Client Address (if debug) print(&quotAccept Request from : &quot, self.client_address[0]) try: packet = DNSRecord.parse(data) # Parse DNS Packet for question in packet.questions: # Iterate over questions ( however most of DNS Servers even BIND support single question) requested_domain_name = question.get_qname() # Get the requested name reply_packet = packet.reply() # Generate Reply packet if (not allow_all) and (w_list != [] and ( not any(s[1:] in str(requested_domain_name) for s in w_list))): # Check the Whitelist try: realip = socket.gethostbyname(requested_domain_name.idna()) # Get Real IP Address except Exception as e: if args.debug: print(e) realip = args.ip
reply_packet.add_answer(
RR(requested_domain_name, rdata=A(realip), ttl=60)) # Append Address to replies
if args.debug:
print(&quotRequest: %s --> %s&quot % (requested_domain_name.idna(), realip))
else:
reply_packet.add_answer(RR(requested_domain_name, rdata=A(args.ip), ttl=60)) # Fake the address
if args.debug:
print(&quotRequest: %s --> %s&quot % (requested_domain_name.idna(), args.ip))
self.wfile.write(reply_packet.pack()) # send Packed UDP Response to the client
except DNSError as err:
if args.debug:
print(err)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Process input')
parser.add_argument(&quot--ip&quot, help=&quotset listen ip address, set to ENV to get it from PUB_IP Env Variable&quot,
action=&quotstore&quot, type=str, default=&quot0.0.0.0&quot)
parser.add_argument(&quot--whitelist&quot,
help=&quotWhitelisted Domain. use ALL or DNS_ALLOW_ALL=YES Env variable for access all domain&quot,
action=&quotstore&quot, type=str, default=&quotEmpty&quot)
parser.add_argument(&quot--port&quot, help=&quotset listen port&quot, action=&quotstore&quot, type=int, default=53)
parser.add_argument(&quot--debug&quot, help=&quotenable debug logging&quot, action=&quotstore_true&quot)
args = parser.parse_args()
if str(args.ip).upper() == &quotENV&quot:
args.ip = environ.get(&quotPUB_IP&quot)
if args.debug:
print('IP: %s Port: %s' % (args.ip, args.port))
if environ.get(&quotDNS_ALLOW_ALL&quot) == &quotYES&quot or args.whitelist == &quotALL&quot:
allow_all = True
else:
if args.whitelist != &quotEmpty&quot:
with open(args.whitelist) as f:
w_list.extend(f.read().splitlines())
try:
udp_sock = ThreadingUDPServer((&quot0.0.0.0&quot, args.port), PacketHandler)
udp_sock.serve_forever()
except KeyboardInterrupt:
if args.debug:
print(&quotdone.&quot)


python3 test.py --ip 185.x.x.x

تنظیم nginx به عنوان Forward proxy

nano /etc/nginx/nginx.conf user www-data; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; worker_rlimit_nofile 65535; events { worker_connections 4096; multi_accept on; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] &quot$request&quot ' '$status $body_bytes_sent &quot$http_referer&quot ' '&quot$http_user_agent&quot &quot$http_x_forwarded_for&quot'; add_header Strict-Transport-Security &quotmax-age=31536000; includeSubDomains&quot always; add_header Cache-Control &quotno-cache, no-store, must-revalidate&quot always; add_header Pragma &quotno-store&quot always; add_header X-Content-Type-Options &quotnosniff&quot always; add_header X-Xss-Protection &quot1; mode=block&quot always; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off; #ssl_protocols TLSv1.2 TLSv1.3; #ssl_prefer_server_ciphers on; #ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM SHA256:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK'; #ssl_ecdh_curve secp384r1; #ssl_session_cache shared:SSL:10m; #ssl_session_timeout 10m; add_header Strict-Transport-Security &quotmax-age=15552000; includeSubDomains&quot always; client_max_body_size 2G; #gzip on; include /etc/nginx/conf.d/*.conf; } stream { server { resolver 8.8.8.8 ipv6=off; listen 443; ssl_preread on; proxy_pass $ssl_preread_server_name:443; } }
nano /etc/nginx/conf.d/base.conf server { listen 80 default_server; listen [::]:80 default_server; server_name _; return 301 https://$host$request_uri; }


منابع:

https://www.baeldung.com/nginx-forward-proxy

https://github.com/mosajjal/byosh

https://virgool.io/@ptabari/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-forward-proxy-%D8%A8%D8%A7-reverse-proxy-vjmp3fkovfbv

نحوه عملکردnginxshecanشکننحوه عملکرد شکن
شاید از این پست‌ها خوشتان بیاید