OpenGFW

It's time to give power to the people and democratize censorship.

2025-10-18
linuxfirewall

توی این پست با یک ابزار فایروال اشنا میشیم. با استفاده از این ابزار میتونید یه تشکیلات فنی سانسورشیپ حرفه ای توی شبکه خودتون راه بندازید. منظور من از فایروال چیزی مثل iptables هست. اما تفاوت عمده این فایروال این هست که قابلیت بررسی عمیق الگو ها و بسته های شبکه رو در لایه های مختلف رو دراختیار شما قرار میده. شبیه به تشکیلاتی که در زیرساخت فنی کشور هایی مثل ایران، ترکیه، چین و روسیه وجود داره. بسیاری از ابزارهای سانسور قبلاً فقط برای افراد خاص سازمان‌ها در دسترس بود. سازنده‌های این فایروال دوست دارن که هر کسی بتونه به این ابزار دسترسی داشته باشه.

OpenGFW

پروژه به منظور دموکراتیزه کردن سانسورشیپ برای افراد عادی ساخته شده. چندمورد از کاربرد های دیگه ای که این نرم افزار میتونه داشته باشه اینها هست:

  • مراقبت والدین از فرزندان
  • مسدود سازی تبلیغات‌ و بدافزار
  • جلوگیری از هرگونه سواستفاده در شبکه خصوصی
  • کمک به ارضای انگیزه های دیکتاتوری شما

ذاتِ این پروژه ممکنه برای برخی از افراد عجیب به نظر بیاد. اما به هر حال، اگر به مسائلی مثل «حق دسترسی به اینترنت» و «اینترنت ازاد برای همه» باور دارید، وجود همچین چیزی خیلی نمیتونه علیه این موضوع باشه. چه بسا که بتونید با درک این مسائل کمک بزرگی به این داستان بکنید. این هم ذکر کنم که سازندگان این فایروال، همزمان سازنده پروتکل VPN قدرتمند Hysteria2 هم هستند!

و برعکس، اگر باور دارید که مصلحت نیست افراد به برخی از منابع اینترنتی دسترسی داشته باشند، میتونید سانسور رو حتی از اینی هم که هست بالاتر بکشید 🚀

چطور کار میکنه؟

فایروال ها رو معمولا روی کامپیوتر های شخصی بالا نمیارن. اما برای تست و اشنایی با نحوه راه اندازی اون، میتونید اون رو توی کامپیوتر خودتون هم تست کنید. با این کار، درحالت عادی فقط جریان شبکه کامپیوتر خودتون تحت تاثیر قرار میگیره. فعلا با این رویه جلو میریم…

نصب

فایروال نرم افزار با زبان Golang نوشته شده. برای نصب کردن اون دو راه دارید.

۱. پروژه رو clone کنید و خودتون با گولنگ Build کنید:

export CGO_ENABLED=0
go build

۲. فایل باینری نرم افزار رو مستقیم از گیت هاب پروژه دانلود کنید.

راه اندازی و اجرا

قبل از اجرا نرم افزار نیاز هست که یک سری ماژول های کرنل لینوکس رو در سیستم عامل خودتون نصب داشته باشید که در اینجا لیست میکنم:

  • kmod-nft-queue
  • kmod-nf-conntrack-netlink

خبر خوب این هست که اگر از توزیع های متعارف مثل 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 نرم افزار میشه. توضیحات مختصری درمورد این فیلد ها در مستندات پروژه وجود داره که میتونید مطالعه کنید. اما اگر اشنا نیست میتونید از همین حالت های پیش فرض استفاده کنید.

در اینده دوست دارم که بتونم درمورد نحوه کار این نرم افزار از لحاظ فنی هم بنویسم. اما فعلا بیایید نرم افزار رو راه بندازیم!

میرسیم به بخش جذاب: ایجاد فایل قوانین 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 فایروال کردیم. به علت عدم رمزنگاری، پروتکل 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 (توی خود روتر) چک کنید. با عملکرد صحیح فایروال میتونید نتیجه بگیرید که دستگاه هایی که به این روتر متصل میشن هم از فیلتر مورد نظر شما رد میشن.

ادامه این داستان با شماست.