
It's time to give power to the people and democratize censorship.
توی این پست با یک ابزار فایروال اشنا میشیم. با استفاده از این ابزار میتونید یه تشکیلات فنی سانسورشیپ حرفه ای توی شبکه خودتون راه بندازید. منظور من از فایروال چیزی مثل iptables هست. اما تفاوت عمده این فایروال این هست که قابلیت بررسی عمیق الگو ها و بسته های شبکه رو در لایه های مختلف رو دراختیار شما قرار میده. شبیه به تشکیلاتی که در زیرساخت فنی کشور هایی مثل ایران، ترکیه، چین و روسیه وجود داره. بسیاری از ابزارهای سانسور قبلاً فقط برای افراد خاص سازمانها در دسترس بود. سازندههای این فایروال دوست دارن که هر کسی بتونه به این ابزار دسترسی داشته باشه.
پروژه به منظور دموکراتیزه کردن سانسورشیپ برای افراد عادی ساخته شده. چندمورد از کاربرد های دیگه ای که این نرم افزار میتونه داشته باشه اینها هست:
ذاتِ این پروژه ممکنه برای برخی از افراد عجیب به نظر بیاد. اما به هر حال، اگر به مسائلی مثل «حق دسترسی به اینترنت» و «اینترنت ازاد برای همه» باور دارید، وجود همچین چیزی خیلی نمیتونه علیه این موضوع باشه. چه بسا که بتونید با درک این مسائل کمک بزرگی به این داستان بکنید. این هم ذکر کنم که سازندگان این فایروال، همزمان سازنده پروتکل VPN قدرتمند Hysteria2 هم هستند!
و برعکس، اگر باور دارید که مصلحت نیست افراد به برخی از منابع اینترنتی دسترسی داشته باشند، میتونید سانسور رو حتی از اینی هم که هست بالاتر بکشید 🚀
فایروال ها رو معمولا روی کامپیوتر های شخصی بالا نمیارن. اما برای تست و اشنایی با نحوه راه اندازی اون، میتونید اون رو توی کامپیوتر خودتون هم تست کنید. با این کار، درحالت عادی فقط جریان شبکه کامپیوتر خودتون تحت تاثیر قرار میگیره. فعلا با این رویه جلو میریم…
فایروال نرم افزار با زبان Golang نوشته شده. برای نصب کردن اون دو راه دارید.
۱. پروژه رو clone کنید و خودتون با گولنگ Build کنید:
export CGO_ENABLED=0
go build
۲. فایل باینری نرم افزار رو مستقیم از گیت هاب پروژه دانلود کنید.
قبل از اجرا نرم افزار نیاز هست که یک سری ماژول های کرنل لینوکس رو در سیستم عامل خودتون نصب داشته باشید که در اینجا لیست میکنم:
خبر خوب این هست که اگر از توزیع های متعارف مثل Fedora و Ubuntu استفاده میکنید، این ماژول ها به احتمال زیاد همراه با سیستم عامل شما نصب شدند. نصب دستی این ماژول ها بیشتر برای سیستم عامل های خاص مثل OpenWRT موضوعیت داره. ( به دلایل مختلف، که احتمالا محدود بودن سخت افزار روتر میتونه جزش باشه)
بعد از چک کردن این موضوع، فایل پیکربندی نرم افزار رو با نام config.yaml ایجاد میکنیم. نمونه کانفیگی که لازم دارید رو قرار میدم:
io:
queueSize: 1024
queueNum: 100
table: opengfw
connMarkAccept: 1001
connMarkDrop: 1002
rcvBuf: 4194304
sndBuf: 4194304
local: true
rst: false
workers:
count: 4
queueSize: 64
tcpMaxBufferedPagesTotal: 65536
tcpMaxBufferedPagesPerConn: 16
tcpTimeout: 10m
udpMaxStreams: 4096
این فایل پیکربندی یک سری از پارامتر های داخلی برنامه رو تنظیم میکنه. پاراگراف اول (بخش io)، پیکربندی های مرتبط با تعامل فایروال داخلی سیستم عامل شما (یعنی nftables یا iptables) رو مشخص میکنه و پاراگراف دوم (بخش workers) مربوط به cuncurrency نرم افزار میشه. توضیحات مختصری درمورد این فیلد ها در مستندات پروژه وجود داره که میتونید مطالعه کنید. اما اگر اشنا نیست میتونید از همین حالت های پیش فرض استفاده کنید.
با توجه به معماری سیستم عامل های لینوکسی، OpenGFW نرم افزاری هست که در بخش User space کامپیوتر شما فعالیت میکنه. برنامه هایی که در User space فعالیت میکنن نمیتونن فعالیت های اینچنینی رو بدون تعامل با کتابخانه های مرتبط با کرنل انجام بدن. پاراگراف io از فایل پیکربندی هم دقیقا مرتبط با همین موضوع هست.
در اینده دوست دارم که بتونم درمورد نحوه کار این نرم افزار از لحاظ فنی هم بنویسم. اما فعلا بیایید نرم افزار رو راه بندازیم!
میرسیم به بخش جذاب: ایجاد فایل قوانین rules.yaml برای تعیین سیاست نرم افزار در مواجهه با بسته های شبکه!
توی این فایل شما مجموعه ای از قوانین رو تعریف میکنید که در مواجه با کانکشن های مختلف چه عملی انجام بشه. فایل rules رو باید با سینتکس زبان expr بنویسید. این زبان به شما کمک میکنه که توی تعریف قوانین بتونید تا جای ممکن انعطاف پذیر عمل کنید. یه نمونه از تکنیک های ساده ی مسدودسازی، تکنیک DNS poison هست. بیاید برای شروع سایت علی بابا رو در نظر بگیریم و انجامش بدیم:
- name: I hate alibaba!
action: modify
modifier:
name: dns
args:
a: "0.0.0.0"
aaaa: "::"
expr: dns != nil && dns.qr && any(dns.questions, {.name endsWith "alibaba.ir"})
در فیلد name، نام قانون رو مشخص میکنید. فیلد action میتونه یکی از مقدار های allow, block, drop, modify رو دریافت کنه. در تکنیک dns poision معمولا در مواجهه با دیتاگرام dns غیرمجاز، اون بسته دستکاری میشه تا از دسترسی به پاسخ صحیح جلوگیری بشه. پس ما اینجا از عمل modify استفاده کردیم تا بسته دستکاری بشه.
در فیلد بعدی یعنی modifier، مشخص میکنیم که بسته dns مورد نظر به چه مقداری تغییر کنه. مقدار این فیلد ها میتونه هر چیز غیرمنطقی ای باشه. مثل ادرس یک ip محلی به جای ip public.
و در اخر، در فیلد expr، شرط مورد نظر رو برای مطابقت دادن با سایت مورد نظر خودمون مینویسیم. ما اینجا این محدودیت رو برای بسته های کوئری dns با نام ”alibaba.ir” اعمال کردیم. برای بررسی فیلد های موجود به مستندات OpenGFW مراجعه کنید.
حالا نرم افزار رو با ارگومان های config.yaml و rules.yaml اجرا میکنیم:
$ sudo ./OpenGFW-linux-amd64 -c config.yaml rules.yaml
2025-10-18T21:25:53+03:30 INFO engine started
اگر اروری مشاهده نکردید، میتونید کارایی نرم افزار رو بررسی کنید. من اینجا از ابزار dig برای پیدا کردن ایپی ادرس سایت alibaba.ir استفاده میکنم. نتیجه باید چیزی شبیه به زیر باشه:
$ dig alibaba.ir
; <<>> DiG 9.18.39 <<>> alibaba.ir
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21880
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;alibaba.ir. IN A
;; ANSWER SECTION:
alibaba.ir. 0 IN A 0.0.0.0
;; Query time: 674 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Sat Oct 18 21:38:21 +0330 2025
;; MSG SIZE rcvd: 65
به خاطر داشته باشید که روش dns poison دربرابر پروتکل DNS Over HTTPS کارایی نداره. در همچین شرایطی میتونید از فیلتر کردن بر اساس فیلد sni در بسته TLS استفاده کنید.
ما صرفا با انالیزور DNS فایروال کردیم. به علت عدم رمزنگاری، پروتکل DNS در حالت سنتی اش راهکاری عالی برای سانسور هست. کانکشنهای رمزنگاریشده مثل پروتکل های VPN چطور؟ خبر جذاب اینه که این فایروال از برخی از پروتکل های VPN رمزنگاری شده هم پشتیبانی میکنه! میتونید انالیزور های مختلف و نحوه کار اونها رو از مستندات پروژه مشاهده کنید.
تا الان فایروال رو در کامپیوتر شخصی تست کردیم. اما برای اینکه این سیستم کاربردی تر باشه، احتمالا دوست دارید که این رو توی router شبکه مورد نظرتون راه اندازی کنید. این فایروال نیاز به یک روتر با سیستم عامل مبتنی بر لینوکس داره که ازادی عمل خوبی هم به شما بده. گزینه معروف برای این کار، سیستم عامل OpenWRT هست. برخی از روتر های بازار این سیستم عامل رو برای نصب پشتیبانی میکنن. من دسترسی به روتر مناسب اینکار ندارم.
اما خوشبختانه سیستم عامل OpenWRT روی ابزار های مجازی ساز مثل qemu قابل اجرا هست. به عبارتِ دیگه، OpenWRT تقریبا روی هر کامپیوتری اعم از کامپیوتر های شخصی قابل نصب هست. در ادامه از پلتفرم QEMU برای شبیه سازی نصب این فایروال روی OpenWRT استفاده میکنیم…
در قدم اول باید مجموعه ابزار های مرتبط با QEMU رو در کامپیوتر خودتون نصب کنید:
sudo apt-get install qemu
بعد، image سیستم عامل OpenWRT رو از سایت مرجع دانلود کنید. پیشنهاد من ورژن 23.05 هست. در ورژن جدید تر یعنی 24.10، ماژول های کرنلِ لازم برای کار این نرم افزار وجود نداره. (یا حداقل، من پیدا نکردم)
بعد از انتخاب ورژن مورد نظر، از دایرکتوری Targets/x86/64 میتونید image های موجود رو مشاهده کنید. من از image نوع generic-ext4-combined استفاده میکنم. ایمیج رو دانلود کنید و با دستور gunzip اون رو از حالت فشرده خارج کنید.
حالا باید با کمک qemu، ایمیج رو اجرا کنید. چون اپشن ها و ارگومان های qemu کمی طولانیه، بهتره اون رو داخل یه شل اسکریپت قرار بدید:
#!/usr/bin/bash
qemu-system-x86_64 \
-M q35 \
-drive file=openwrt-23.05.6-x86-64-generic-ext4-combined.img,format=raw,if=virtio \
-m 512 \
-nographic -enable-kvm \
-device virtio-net,netdev=lan0 \
-netdev user,id=lan0 \
-device virtio-net,netdev=wan0 \
-netdev user,id=wan0,hostfwd=tcp::11122-:22,hostfwd=tcp::8085-:80
توی اسکریپت بالا، بعد از یک سری اپشن های کلی مثل تعیین نوع ماشین و مقدار مموری، کارت های شبکه مجازی ماشین رو مشخص میکنیم. استفاده از netdev user در پورت wan ماشین، امکان دسترسی به اینترنت رو به OpenWRT میده. (درواقع دسترسی به اینترنت از طریق کامپیوتر هاست تامین میشه)
حالا اسکریپت رو اجرا کنید و منتظر باشید تا سیستم عامل بوت بشه. بعد، دسترسی به اینترنت ماشین رو چک کنید:
BusyBox v1.36.1 (2025-08-14 18:27:40 UTC) built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 23.05.6, r24232-539228933c
-----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:/# ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 56 data bytes
64 bytes from 1.1.1.1: seq=0 ttl=255 time=77.994 ms
64 bytes from 1.1.1.1: seq=1 ttl=255 time=78.461 ms
64 bytes from 1.1.1.1: seq=2 ttl=255 time=78.280 ms
64 bytes from 1.1.1.1: seq=3 ttl=255 time=78.034 ms
(اگر دستگاه به اینترنت دسترسی نداشت، با دستور ip در OpenWRT، پیکربندی شبکه ماشین رو چک کنید. احتمالا gateway اولین چیزیه که میخواید چک کنید)
وقتی از اتصال اینترنت مطمعن شدید، پیش نیاز های مورد نیاز رو از پکیج منیجر مخصوص OpenWRT نصب کنید:
opkg install nftables kmod-nft-queue kmod-nf-conntrack-netlink
عالیه! حالا فایل باینری رو OpenGFW رو به نحوی به دستگاه منتقل کنید (با wget میتونید این کار رو انجام بدید که به طور پیشفرض در سیستم عامل موجوده) و بعد از اون، دقیقا مثل بخش های قبل، فایل rule.yaml و config.yaml رو اماده کنید و برنامه رو اجرا کنید:
root@OpenWrt:~/gfw# ll
drwxr-xr-x 2 root root 4096 Oct 10 11:55 ./
drwxr-xr-x 3 root root 4096 Oct 10 11:44 ../
-rw-r--r-- 1 root root 562 Oct 10 11:45 config.yaml
-rwx------ 1 root root 13627544 Oct 10 11:54 opengfw*
-rw-r--r-- 1 root root 198 Oct 10 13:48 rule.yaml
root@OpenWrt:~/gfw# ./opengfw -c config.yaml rule.yaml
2025-10-18T18:22:08Z INFO engine started
اگر با اروری مواجه نشدید، عملکرد فایروال رو میتونید با چیزی مثل curl یا dig (توی خود روتر) چک کنید. با عملکرد صحیح فایروال میتونید نتیجه بگیرید که دستگاه هایی که به این روتر متصل میشن هم از فیلتر مورد نظر شما رد میشن.
ادامه این داستان با شماست.