مجله ایرانیکاسرورآموزش سرور، هاست، وردپرس و شبکه
آموزشی

بررسی تداخل UFW و Docker؛ چرا قوانین Firewall روی کانتینرها اعمال نمی‌شوند؟

اگر روی سرور Ubuntu هم UFW فعال است و هم Docker اجرا می‌شود، ممکن است با یک وضعیت عجیب روبه‌رو شوید: در UFW یک پورت را بسته‌اید، اما سرویس Docker همچنان از اینترنت قابل…

بررسی تداخل UFW و Docker؛ چرا قوانین Firewall روی کانتینرها اعمال نمی‌شوند؟
خلاصه سریع این آموزش

اگر روی سرور Ubuntu هم UFW فعال است و هم Docker اجرا می‌شود، ممکن است با یک وضعیت عجیب روبه‌رو شوید: در UFW یک پورت را بسته‌اید، اما سرویس Docker…

۱۳ دقیقه مطالعه ۰ دیدگاه ۱۲ مهر ۱۴۰۵ آخرین به‌روزرسانی
اگر روی سرور Ubuntu هم UFW فعال است و هم Docker اجرا می‌شود، ممکن است با یک وضعیت عجیب روبه‌رو شوید: در UFW یک پورت را بسته‌اید، اما سرویس Docker همچنان از اینترنت قابل دسترسی است؛ یا برعکس، بعد از تغییر قوانین فایروال، ارتباط بعضی کانتینرها با اینترنت قطع می‌شود.

پاسخ کوتاه: Docker برای Bridge Network، NAT و انتشار پورت‌ها قوانین Firewall خودش را ایجاد می‌کند. در حالت رایج مبتنی بر iptables، ترافیک پورت‌های Publish‌شده ممکن است قبل از رسیدن به قوانین معمول UFW تغییر مسیر پیدا کند. به همین دلیل اجرای دستورهایی مانند ufw deny 8080 لزوماً به معنی بسته‌شدن پورت Docker نیست.

در این آموزش ابتدا بدون ایجاد تغییر خطرناک بررسی می‌کنیم Docker و UFW دقیقاً چه قوانینی روی سرور ساخته‌اند، سپس روش‌های امن کنترل دسترسی به کانتینرها را بررسی می‌کنیم.

فهرست مطالب

چرا Docker و UFW با یکدیگر تداخل پیدا می‌کنند؟

UFW یک رابط ساده برای مدیریت Firewall لینوکس است. Docker نیز برای راه‌اندازی شبکه‌های Bridge، انجام NAT، Masquerading و Port Forwarding مجبور است قوانین Netfilter ایجاد کند.

مشکل اصلی زمانی دیده می‌شود که پورتی از کانتینر روی Host منتشر می‌کنید. برای مثال:

docker run -d -p 8080:80 nginx

در این مثال Docker پورت 8080 سرور را به پورت 80 کانتینر متصل می‌کند. Docker برای انجام این کار فقط منتظر UFW نمی‌ماند؛ خودش قوانین لازم برای NAT و Forwarding را ایجاد می‌کند.

به همین دلیل ممکن است دستور زیر را اجرا کنید:

sudo ufw deny 8080/tcp

اما پورت Publish‌شده Docker همچنان از بیرون قابل دسترسی باشد. این رفتار به این دلیل است که Docker ترافیک کانتینر را در مسیر NAT تغییر می‌دهد و ترافیک لزوماً مانند یک اتصال عادی به سرویس Host از زنجیره‌های UFW عبور نمی‌کند.

قبل از هر تغییری از Firewall نسخه پشتیبان بگیرید

⚠️ هشدار: اگر از راه دور و از طریق SSH به VPS متصل هستید، یک قانون اشتباه Firewall می‌تواند ارتباط شما را قطع کند. قبل از Flush کردن زنجیره‌ها، Reset کردن UFW یا تغییر Policyهای FORWARD مطمئن شوید SSH مجاز است و در صورت امکان دسترسی Console از پنل سرویس‌دهنده دارید.

برای ثبت وضعیت فعلی UFW اجرا کنید:

sudo ufw status verbose
sudo ufw status numbered

سپس قوانین iptables را ذخیره کنید:

sudo iptables-save > ~/iptables-backup.rules
sudo ip6tables-save > ~/ip6tables-backup.rules

این فایل‌ها شامل اطلاعات شبکه و قوانین امنیتی سرور هستند؛ آن‌ها را عمومی منتشر نکنید.

مرحله ۱: وضعیت UFW را بررسی کنید

sudo ufw status verbose

اگر UFW فعال باشد، عبارت Status: active را خواهید دید. همچنین Default Policyها را بررسی کنید.

برای مشاهده قوانین همراه شماره:

sudo ufw status numbered

نکته مهم این است که خروجی ufw status تمام قوانین Netfilter سرور را نشان نمی‌دهد. بنابراین مشاهده یک پورت بسته در این خروجی به‌تنهایی ثابت نمی‌کند که Docker نیز دسترسی به آن را مسدود کرده است.

مرحله ۲: پورت‌های Publish‌شده Docker را پیدا کنید

حالا باید مشخص شود Docker واقعاً چه پورت‌هایی را روی Host منتشر کرده است:

docker ps --format "table {{.Names}}\t{{.Ports}}"

اگر چیزی شبیه نمونه زیر مشاهده کردید:

0.0.0.0:8080->80/tcp

یعنی پورت 8080 روی تمام IPv4 Addressهای Host منتشر شده است. اگر IPv6 نیز فعال باشد، وضعیت IPv6 را هم جداگانه بررسی کنید.

برای سرویس‌هایی که فقط باید روی خود سرور قابل استفاده باشند، انتشار روی Loopback بسیار امن‌تر است:

docker run -d -p 127.0.0.1:8080:80 nginx

این روش برای سرویس‌هایی که قرار است پشت Nginx، Caddy یا Reverse Proxy دیگری باشند معمولاً انتخاب بهتری از Publish کردن مستقیم آن‌ها روی 0.0.0.0 است.

مرحله ۳: مشخص کنید Docker از چه Firewall Backend استفاده می‌کند

در نسخه‌های جدید Docker نباید از روی نسخه Ubuntu یا وجود دستور nft حدس بزنید Docker دقیقاً از چه backendی استفاده می‌کند.

ابتدا نسخه Docker را ببینید:

docker version
docker info

سپس پیکربندی Daemon را در صورت وجود بررسی کنید:

sudo cat /etc/docker/daemon.json

در Docker Engine 29 امکان انتخاب backend آزمایشی nftables با گزینه firewall-backend وجود دارد. اگر چنین تنظیمی ندارید، بدون دلیل آن را تغییر ندهید.

همچنین وضعیت iptables سیستم را بررسی کنید:

iptables --version
sudo update-alternatives --display iptables

وجود عبارت nf_tables در خروجی iptables به این معنی است که ابزار iptables از لایه سازگاری nftables استفاده می‌کند؛ این موضوع با فعال‌کردن backend بومی nftables در Docker Engine 29 یکسان نیست.

مرحله ۴: قوانین ساخته‌شده توسط Docker را ببینید

اگر Docker از مسیر iptables استفاده می‌کند، ابتدا زنجیره‌های Filter را بدون تغییر مشاهده کنید:

sudo iptables -L -n -v --line-numbers

برای مشاهده قوانین NAT:

sudo iptables -t nat -L -n -v --line-numbers

و برای بررسی زنجیره مهم DOCKER-USER:

sudo iptables -L DOCKER-USER -n -v --line-numbers

در backend مبتنی بر iptables، Docker زنجیره DOCKER-USER را برای قوانین سفارشی مدیر سرور در نظر گرفته است. ترافیک Docker پیش از ورود به بخش‌های بعدی قوانین Docker از این زنجیره عبور می‌کند.

مرحله ۵: آیا واقعاً UFW توسط Docker دور زده می‌شود؟

برای آزمایش، فرض کنیم کانتینری روی پورت 8080 منتشر شده است.

وضعیت Docker:

docker ps

وضعیت UFW:

sudo ufw status numbered

سپس از یک دستگاه دیگر خارج از VPS دسترسی به پورت را آزمایش کنید. تست از localhost برای بررسی دسترسی خارجی کافی نیست.

در Linux یا macOS می‌توانید اجرا کنید:

curl -I http://192.0.2.10:8080

آدرس 192.0.2.10 در این مقاله فقط نمونه است و باید با IP واقعی سرور خود جایگزین شود.

اگر UFW دسترسی را Deny نشان می‌دهد ولی سرویس از اینترنت باز است، احتمال زیادی وجود دارد که با مسیر Port Publishing خود Docker روبه‌رو باشید.

نیاز به یک VPS لینوکسی برای Docker دارید؟

برای اجرای Docker، کانتینرها، Reverse Proxy و سرویس‌های Self-hosted می‌توانید از سرور مجازی استفاده کنید. اگر محل میزبانی داخل کشور برای پروژه شما مناسب است، پلن‌های VPS ایران ایرانیکاسرور نیز قابل بررسی هستند.

روش امن اول: پورت غیرعمومی را روی 127.0.0.1 منتشر کنید

اگر سرویس Docker قرار نیست مستقیماً از اینترنت در دسترس باشد، ساده‌ترین راه این است که اصلاً آن را روی تمام Interfaceهای Host منتشر نکنید.

به‌جای:

docker run -d -p 8080:80 nginx

از این ساختار استفاده کنید:

docker run -d -p 127.0.0.1:8080:80 nginx

در Docker Compose نیز می‌توانید به‌جای:

ports:
  - "8080:80"

بنویسید:

ports:
  - "127.0.0.1:8080:80"

این روش سطح حمله را کاهش می‌دهد و برای سرویس‌های داخلی، Databaseها و Backendهایی که پشت Reverse Proxy هستند بسیار مفید است.

روش امن دوم: استفاده از DOCKER-USER در backend مبتنی بر iptables

اگر لازم است کانتینر روی IP عمومی Publish شود اما فقط IPهای مشخصی اجازه اتصال داشته باشند، در Docker مبتنی بر iptables می‌توان از DOCKER-USER استفاده کرد.

⚠️ قبل از اجرا: این مثال را کورکورانه روی سرور Production اجرا نکنید. نام Interface، IP مجاز و نوع ترافیک باید متناسب با سرور شما تعیین شود. ابتدا با دستور ip route یا ip addr Interface خارجی را پیدا کنید.

برای مثال:

ip route

اگر Interface اینترنت سرور eth0 باشد و فقط IP نمونه 192.0.2.25 باید اجازه دسترسی به ترافیک Docker را داشته باشد، منطق کلی می‌تواند ابتدا اجازه Connectionهای برقرارشده و سپس محدودسازی منبع باشد.

sudo iptables -I DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -I DOCKER-USER -i eth0 ! -s 192.0.2.25 -j DROP

این فقط یک الگوی آموزشی است و در سروری که چند سرویس، چند Interface یا چند شبکه Docker دارد باید Rule دقیق‌تری طراحی شود.

نکته مهم‌تر اینکه هنگام ورود Packet به DOCKER-USER عملیات DNAT ممکن است قبلاً انجام شده باشد. بنابراین اگر قصد Match کردن IP یا Port مقصد اصلی قبل از DNAT را دارید، ممکن است به قابلیت‌های conntrack نیاز داشته باشید.

آیا باید iptables=false را در Docker فعال کنیم؟

معمولاً خیر.

گاهی برای حل تداخل UFW و Docker پیشنهاد می‌شود این تنظیم در /etc/docker/daemon.json قرار بگیرد:

{
  "iptables": false
}

این راه‌حل عمومی و مناسبی نیست. Docker برای Bridge Networking، NAT و Masquerading به قوانین Firewall نیاز دارد. جلوگیری از ساخت این قوانین بدون جایگزین‌کردن کامل آن‌ها می‌تواند ارتباط شبکه کانتینرها را خراب کند.

بنابراین iptables=false را صرفاً برای اینکه UFW «کنترل کامل» پیدا کند فعال نکنید، مگر اینکه دقیقاً بدانید قرار است قوانین شبکه Docker را چگونه جایگزین کنید.

تفاوت iptables-nft با backend بومی nftables در Docker 29

این قسمت یکی از مواردی است که در عیب‌یابی‌های جدید Docker اهمیت زیادی دارد.

ممکن است دستور زیر:

iptables --version

خروجی حاوی nf_tables بدهد. این موضوع لزوماً به معنی استفاده Docker از backend جدید nftables نیست.

iptables-nft رابط سازگاری iptables روی زیرساخت nftables است؛ در مقابل Docker Engine 29 یک backend بومی nftables نیز دارد که با گزینه‌ای مانند زیر انتخاب می‌شود:

{
  "firewall-backend": "nftables"
}

طبق مستندات Docker، پشتیبانی بومی nftables که از Docker Engine 29 معرفی شده هنوز Experimental است. همچنین مدل قوانین سفارشی آن با مسیر کلاسیک DOCKER-USER یکسان نیست. بنابراین آموزش‌های قدیمی مبتنی بر DOCKER-USER را نباید بدون بررسی روی backend بومی nftables اجرا کرد.

UFW و nftables را هم‌زمان و مستقل مدیریت نکنید

یک مشکل دیگر زمانی ایجاد می‌شود که مدیر سرور UFW را فعال کرده، Docker نیز قوانین خودش را دارد و هم‌زمان فایل /etc/nftables.conf با مجموعه قوانین مستقل دیگری در حال Load شدن است.

ابتدا وضعیت سرویس nftables را ببینید:

sudo systemctl status nftables

سپس Ruleset را فقط برای بررسی مشاهده کنید:

sudo nft list ruleset

اگر UFW، Docker و یک Ruleset دستی nftables هم‌زمان در حال مدیریت Netfilter هستند، قبل از هر اصلاح باید مشخص کنید مالک هر بخش از قوانین کدام سرویس است. پاک‌کردن کورکورانه Ruleset می‌تواند هم امنیت Host و هم شبکه Docker را مختل کند.

بررسی IP Forwarding

شبکه Bridge در Docker به Forwarding وابسته است. وضعیت IPv4 را با دستور زیر ببینید:

sysctl net.ipv4.ip_forward

مقدار 1 یعنی IPv4 Forwarding فعال است.

Policy زنجیره FORWARD را نیز بررسی کنید:

sudo iptables -L FORWARD -n -v

وجود Policy برابر DROP به‌تنهایی نشان‌دهنده خرابی Docker نیست. Docker می‌تواند زنجیره‌ها و Ruleهای مشخصی برای اجازه ترافیک مورد نیاز شبکه خودش ایجاد کند.

چرا بعد از ufw reload شبکه Docker خراب می‌شود؟

اگر مشکل دقیقاً بعد از Reload یا Reset کردن Firewall ظاهر شده، ترتیب و وضعیت قوانین را دوباره بررسی کنید:

sudo ufw status verbose
sudo iptables -L FORWARD -n -v
sudo iptables -L DOCKER-USER -n -v
sudo iptables -t nat -L DOCKER -n -v
docker network ls

اگر Docker از backend بومی nftables استفاده می‌کند، بررسی iptables به‌تنهایی کافی نیست و باید Ruleset nftables و پیکربندی Docker را نیز بررسی کنید.

جدول عیب‌یابی سریع Docker و UFW

نشانه‌ها و بررسی‌های پیشنهادی
نشانه بررسی علت محتمل
UFW پورت را بسته ولی Docker باز است docker ps و قوانین NAT Port Publishing و DNAT Docker
کانتینر اینترنت ندارد FORWARD، NAT و IP Forwarding قوانین Forwarding یا Masquerading
مشکل بعد از ufw reload iptables و زنجیره‌های Docker تغییر یا بازآرایی قوانین Firewall
بعد از reboot مشکل برمی‌گردد سرویس‌های UFW، Docker و nftables Rulesetهای دائمی یا ترتیب Load شدن سرویس‌ها
DOCKER-USER وجود ندارد Docker backend و نسخه Engine استفاده از backend متفاوت یا وضعیت غیرعادی Daemon

چه کارهایی را برای رفع مشکل انجام ندهیم؟

🔹 برای رفع سریع مشکل، UFW را برای همیشه خاموش نکنید.

🔹 بدون داشتن Console یا مسیر بازیابی، زنجیره‌های Firewall را Flush نکنید.

🔹 گزینه iptables=false را بدون طراحی قوانین جایگزین فعال نکنید.

🔹 فایل /etc/nftables.conf را فقط به دلیل مشاهده nftables پاک نکنید.

🔹 تصور نکنید ufw status تمام قوانین Firewall ساخته‌شده توسط Docker را نمایش می‌دهد.

🔹 وجود عبارت nf_tables در خروجی iptables را با backend بومی nftables در Docker 29 یکی ندانید.

🔹 Database، Redis، PostgreSQL و پنل‌های مدیریتی را بدون نیاز روی 0.0.0.0 Publish نکنید.

چک‌لیست نهایی بررسی تداخل UFW و Docker

برای عیب‌یابی اولیه معمولاً همین مجموعه دستورها اطلاعات زیادی در اختیار شما قرار می‌دهد:

sudo ufw status verbose
docker version
docker info
docker ps --format "table {{.Names}}\t{{.Ports}}"
iptables --version
sudo iptables -L -n -v
sudo iptables -L FORWARD -n -v
sudo iptables -L DOCKER-USER -n -v
sudo iptables -t nat -L -n -v
sysctl net.ipv4.ip_forward
sudo systemctl status nftables
sudo nft list ruleset

اگر یکی از دستورهای مربوط به DOCKER-USER یا nftables خطا داد، همان خطا خودش بخشی از اطلاعات تشخیصی است؛ فوراً زنجیره یا Ruleset جدید نسازید تا backend واقعی Docker مشخص شود.

سؤالات متداول

آیا Docker واقعاً UFW را دور می‌زند؟

در Port Publishing معمول Docker، بله؛ ترافیک کانتینر می‌تواند به دلیل NAT و مسیری که Docker در Netfilter ایجاد می‌کند قبل از اعمال قواعد معمول Host Firewall تغییر مسیر پیدا کند. به همین دلیل یک ufw deny ساده الزاماً پورت Publish‌شده Docker را مسدود نمی‌کند.

آیا باید UFW را هنگام استفاده از Docker خاموش کنیم؟

خیر. UFW همچنان می‌تواند از سرویس‌های خود Host مانند SSH محافظت کند. مسئله این است که برای ترافیک کانتینرهای Publish‌شده نباید فرض کنید تمام سیاست‌های UFW دقیقاً مانند سرویس‌های Host اعمال می‌شوند.

DOCKER-USER چیست؟

در backend مبتنی بر iptables، DOCKER-USER زنجیره‌ای برای قرار دادن قوانین سفارشی مدیر سیستم پیش از بخش مهمی از پردازش قوانین Forwarding خود Docker است. این زنجیره برای محدودکردن ترافیک Docker کاربرد دارد.

چرا ufw deny پورت Docker را نمی‌بندد؟

چون پورت منتشرشده Docker مانند یک سرویس عادی که مستقیماً روی Host گوش می‌دهد پردازش نمی‌شود. Docker برای Port Mapping از NAT و Forwarding استفاده می‌کند و همین موضوع مسیر Packet را تغییر می‌دهد.

آیا iptables-nft همان nftables backend جدید Docker است؟

خیر. iptables-nft رابط سازگاری iptables روی زیرساخت nftables است، در حالی که Docker Engine 29 امکان استفاده از backend بومی nftables را نیز اضافه کرده است. روش مدیریت قوانین سفارشی این دو حالت یکسان نیست.

برای سرویس Docker داخلی بهترین روش چیست؟

اگر سرویس نباید مستقیماً از اینترنت دیده شود، تا جای ممکن آن را روی 127.0.0.1 Publish کنید یا فقط داخل Docker Network نگه دارید و دسترسی خارجی را از طریق Reverse Proxy کنترل کنید.

آیا خاموش‌کردن ساخت قوانین iptables توسط Docker امن است؟

برای بیشتر سرورها خیر. مستندات Docker هشدار می‌دهند که جلوگیری از ایجاد قوانین Firewall توسط Docker می‌تواند Networking کانتینرها را مختل کند. این کار فقط زمانی منطقی است که مدیر سیستم قوانین جایگزین را کامل طراحی و مدیریت کند.

منابع رسمی

مبنای فنی این آموزش مستندات رسمی Docker درباره Packet Filtering، زنجیره‌های iptables و محدودیت UFW و همچنین مستندات Firewall اوبونتو است.

Docker Docs — Packet filtering and firewalls

Docker Docs — Docker with iptables

Docker Docs — Docker with nftables

Ubuntu Server — Firewall documentation

جمع‌بندی

UFW و Docker هر دو با Netfilter کار می‌کنند، اما Port Publishing در Docker باعث می‌شود ترافیک کانتینر دقیقاً مانند یک سرویس معمولی Host از قوانین UFW عبور نکند. قبل از تغییر Firewall ابتدا پورت‌های Publish‌شده، backend واقعی Docker، زنجیره‌های DOCKER-USER و FORWARD، قوانین NAT و وضعیت IP Forwarding را بررسی کنید. برای سرویس‌های غیرعمومی نیز محدودکردن Bind به 127.0.0.1 معمولاً از بازکردن پورت روی تمام Interfaceها امن‌تر و ساده‌تر است.

برای بررسی تنظیمات Docker و Firewall کمک می‌خواهید؟اگر تغییر قوانین UFW، iptables یا nftables ممکن است باعث قطع دسترسی سرور شود، قبل از آزمون‌های پرخطر می‌توانید درخواست بررسی و کانفیگ ثبت کنید.

تماس با پشتیبانی ایرانیکاسرور: 021-91302467

اشتراک‌گذاری مقاله
گفت‌وگو درباره آموزش

دیدگاه‌ها (۰)

هنوز دیدگاهی ثبت نشده است.

دیدگاه یا سؤال خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *