لینوکس

نحوه فوروارد کردن پورت‌ها از طریق یک دروازه لینوکسی با Iptables

مقدمه

NAT یا ترجمه آدرس شبکه (Network Address Translation)، اصطلاح عمومی‌ای برای دستکاری بسته‌ها به منظور هدایت‌شان به آدرس جایگزین است. معمولاً از این برای اجازه عبور ترافیک از مرزهای شبکه استفاده می‌شود. میزبانی که NAT را پیاده می‌کند معمولاً به دو شبکه یا بیشتر دسترسی دارد و طوری پیکربندی شده که ترافیک را بین آن‌ها مسیریابی کند.

فوروارد کردن پورت (Port Forwarding)، فرایند فوروارد کردن درخواست‌های یک پورت خاص به میزبان، شبکه یا پورت دیگر است. چون این فرایند مقصد بستهِ در-مسیر را تغییر می‌دهد، نوعی عملیات NAT تلقی می‌شود. دو عملیات کلیدی این کار را ممکن می‌سازند: DNAT (NAT مقصد) که آدرس مقصد بسته‌های ورودی را بازنویسی می‌کند و SNAT (NAT مبدأ) که آدرس مبدأِ بسته‌های خروجی را بازنویسی می‌کند تا پاسخ‌ها درست به عقب مسیریابی شوند.

در این آموزش یاد می‌گیرید چگونه با iptables، پورت‌ها را از طریق یک دروازه لینوکسی با تکنیک‌های NAT—including قوانین DNAT و SNAT در زنجیرهای PREROUTING و POSTROUTING—فوروارد کنید. این مفید است اگر شبکه خصوصی پیکربندی کرده‌اید اما همچنان می‌خواهید ترافیک مشخصی را از طریق ماشین دروازه‌ای تعیین‌شده به داخل اجازه عبور بدهید. فوروارد کردن IP را در سطح کرنل راه می‌اندازید، قوانین فیلترینگ بسته فایروال را پیکربندی و ورودی‌های جدول NAT را می‌نویسید تا ترافیک پورت ۸۰ را به وب‌سرور داخلی مسیریابی کنید.

نکته: این آموزش در اصل برای اوبونتو 20.04 نوشته شده و روی اوبونتو 22.04 و 24.04 LTS اعتبارسنجی شده است. دستورات iptables، پارامترهای فوروارد کرنل و سرویس netfilter-persistent استفاده‌شده در این راهنما در همه نسخه‌های LTS فعلی اوبونتو یکسان کار می‌کنند. اگر نسخه متفاوتی از اوبونتو اجرا می‌کنید، تا وقتی پکیج‌های iptables و iptables-persistent نصب باشند، مراحل همچنان اعمال می‌شوند.

نکات کلیدی

  • فوروارد کردن پورت با iptables به سه جزء نیاز دارد: فوروارد IP سطح-کرنلِ فعال‌شده از طریق sysctl، قوانین زنجیر FORWARD در جدول filter و قوانین DNAT/SNAT در جدول nat.
  • DNAT (پیکربندی‌شده در زنجیر PREROUTING) آدرس مقصد بسته‌های ورودی را بازنویسی می‌کند تا به سرور داخلی درست برسند. SNAT (پیکربندی‌شده در زنجیر POSTROUTING) آدرس مبدأ را بازنویسی می‌کند تا پاسخ‌ها از طریق دروازه به عقب مسیریابی شوند.
  • ردیابی اتصال (conntrack) به iptables اجازه می‌دهد اتصالات جدید را شناسایی و ترافیک ESTABLISHED/RELATED را در هر دو جهت جریان بدهد؛ که زنجیر FORWARD را امن نگه می‌دارد در عین مجاز دانستن ترافیک بازگشتی قانونی.
  • همیشه باید قوانین iptables خود را با netfilter-persistent یا با ویرایش مستقیم /etc/iptables/rules.v4 ذخیره کنید تا مطمئن شوید قوانین بین ریبوت‌ها باقی می‌مانند.
  • در محیط‌های ابری، ترکیب قوانین NAT مربوط به iptables با فایروال ابری پارمین کلود را برای دفاع-در-عمق در نظر بگیرید.

پیش‌نیازها

برای دنبال کردن این راهنما، به این موارد نیاز دارید:

  • دو سرور اوبونتویی در همان دیتاسنتر با شبکه خصوصی فعال‌شده. روی هر کدام از این ماشین‌ها، باید حساب کاربر غیر root با دسترسی sudo راه‌اندازی کنید. می‌توانید نحوه انجام این کار را از راهنمای راه‌اندازی اولیه سرور اوبونتو در پارمین کلود یاد بگیرید. مطمئن شوید گام ۴ آن راهنما را رد می‌کنید؛ چون فایروال را در طول این آموزش راه‌اندازی و پیکربندی می‌کنید.
  • روی یکی از سرورهای‌تان، قالب فایروال را با iptables راه‌اندازی کنید تا بتواند به‌عنوان سرور فایروال عمل کند. این کار را با پیروی از راهنمای «پیاده‌سازی فایروال پایه با Iptables روی اوبونتو» در پارمین کلود می‌توانید انجام دهید. وقتی کامل شد، سرور فایروال‌تان باید این موارد را آماده برای استفاده داشته باشد:
    • iptables-persistent نصب‌شده
    • مجموعه قوانین پیش‌فرض در /etc/iptables/rules.v4 ذخیره‌شده
    • درکی از نحوه افزودن یا تنظیم قوانین با ویرایش فایل قانون یا با استفاده از دستور iptables

اگر با iptables تازه‌وارد هستید، مرور راهنمای «اصول iptables» به شما کمک می‌کند قبل از ادامه با قوانین و دستورات رایج فایروال آشنا شوید.

سروری که قالب فایروال رویش راه‌اندازی کرده‌اید، به‌عنوان فایروال و دروازه شبکه خصوصی‌تان عمل خواهد کرد. برای اهداف نمایشی، میزبان دوم با وب‌سروری پیکربندی می‌شود که فقط با اینترفیس خصوصی‌اش قابل دسترس است. ماشین فایروال را طوری پیکربندی می‌کنید که درخواست‌های دریافتی روی اینترفیس عمومی‌اش را به وب‌سرور—که روی اینترفیس خصوصی به آن می‌رسد—فوروارد کند.

جزئیات میزبان‌ها

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

پیدا کردن جزئیات شبکه‌تان

برای گرفتن جزئیات سیستم‌های خودتان، با پیدا کردن اینترفیس‌های شبکه شروع کنید. می‌توانید اینترفیس‌ها روی ماشین‌های‌تان و آدرس‌های مرتبط با آن‌ها را با اجرای این ببینید:

ip -4 addr show scope global

خروجی نمونه:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 203.0.113.1/18 brd 45.55.191.255 scope global eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 10.0.0.1/16 brd 10.132.255.255 scope global eth1
       valid_lft forever preferred_lft forever

خروجی هایلایت‌شده دو اینترفیس (eth0 و eth1) و آدرس‌های تخصیص‌یافته به هر کدام (به‌ترتیب 203.0.113.1 و 10.0.0.1) را نشان می‌دهد. برای فهمیدن اینکه کدام اینترفیس‌ها اینترفیس عمومی شماست، این دستور را اجرا کنید:

ip route show | grep default
Output
default via 111.111.111.111 dev eth0

اطلاعات اینترفیس از این خروجی (eth0 در این مثال)، اینترفیسی خواهد بود که به دروازه پیش‌فرض‌تان متصل است. این تقریباً به‌طور قطعی اینترفیس عمومی شماست.

این مقادیر را روی هر کدام از ماشین‌های‌تان پیدا و برای دنبال کردن بقیه این راهنما استفاده کنید.

داده‌های نمونه استفاده‌شده در این راهنما

برای شفاف‌تر شدن کارها، از تخصیص‌های آدرس و اینترفیس زیر در سراسر این آموزش استفاده می‌کنیم. لطفاً مقادیر خودتان را با موارد فهرست‌شده جایگزین کنید:

جزئیات شبکه وب‌سرور:

  • آدرس IP عمومی: 203.0.113.1
  • آدرس IP خصوصی: 10.0.0.1
  • اینترفیس عمومی: eth0
  • اینترفیس خصوصی: eth1

جزئیات شبکه فایروال:

  • آدرس IP عمومی: 203.0.113.2
  • آدرس IP خصوصی: 10.0.0.2
  • اینترفیس عمومی: eth0
  • اینترفیس خصوصی: eth1

راه‌اندازی وب‌سرور

با اتصال به میزبان وب‌سرورتان و ورود با کاربر sudo شروع کنید.

نصب Nginx

اولین قدم، نصب Nginx روی میزبان وب‌سرورتان و قفل‌کردنش طوری است که فقط به اینترفیس خصوصی‌اش گوش بدهد. این تضمین می‌کند وب‌سرورتان فقط وقتی در دسترس باشد که فوروارد پورت را درست راه‌اندازی کرده باشید.

با به‌روزرسانی کش پکیج محلی شروع کنید:

sudo apt update

سپس، از apt برای دانلود و نصب نرم‌افزار استفاده کنید:

sudo apt install nginx

محدود کردن Nginx به شبکه خصوصی

بعد از نصب Nginx، فایل پیکربندی بلاک سرور پیش‌فرض را باز کنید تا مطمئن شوید فقط به اینترفیس خصوصی گوش می‌دهد. فایل را با ویرایشگر متن مورد علاقه‌تان باز کنید. اینجا از nano استفاده می‌کنیم:

sudo nano /etc/nginx/sites-enabled/default

داخل، دایرکتیو listen را پیدا کنید. باید دو بار پشت سر هم به سمت بالای پیکربندی فهرست شده باشد:

/etc/nginx/sites-enabled/default
server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    . . .
}

در اولین دایرکتیو listen، آدرس IP خصوصی وب‌سرورتان و یک دونقطه قبل از ۸۰ اضافه کنید تا به Nginx بگویید فقط روی اینترفیس خصوصی گوش بدهد. ما فقط فورواردینگ IPv4 را در این راهنما نمایش می‌دهیم؛ پس می‌توانید دایرکتیو listen دوم را—که برای IPv6 پیکربندی شده—حذف کنید.

سپس، دایرکتیوهای listen را مثل زیر تغییر دهید:

/etc/nginx/sites-enabled/default
server {
    listen 10.0.0.1:80 default_server;

    . . .
}

وقتی تمام شد، فایل را ذخیره و ببندید. اگر از nano استفاده کردید، می‌توانید با فشار CTRL + X، سپس Y و ENTER این کار را بکنید.

حالا فایل را برای خطاهای سینتکس تست کنید:

sudo nginx -t
Output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

اگر خطایی در خروجی نیست، Nginx را برای فعال کردن پیکربندی جدید ری‌استارت کنید:

sudo systemctl restart nginx

تأیید محدودیت شبکه

در این نقطه، تأیید سطح دسترسی‌تان به وب‌سرور مفید است.

از سرور فایروال‌تان، سعی کنید با این دستور از اینترفیس خصوصی به وب‌سرورتان دسترسی پیدا کنید:

curl --connect-timeout 5 10.0.0.1

اگر موفق باشد، خروجی‌تان به این پیام منجر می‌شود:

Output
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
. . .

اگر سعی کنید از اینترفیس عمومی استفاده کنید، پیغامی می‌گیرید که می‌گوید نمی‌تواند وصل شود:

curl --connect-timeout 5 203.0.113.1
Output
curl: (7) Failed to connect to 203.0.113.1 port 80: Connection refused

این نتایج مورد انتظارند.

پیکربندی فایروال برای فوروارد پورت ۸۰

حالا روی پیاده‌سازی فوروارد پورت روی ماشین فایروالتان کار می‌کنید.

فعال کردن فورواردینگ در کرنل

اولین کاری که باید بکنید، فعال کردن فوروارد ترافیک در سطح کرنل است. به‌طور پیش‌فرض، بیشتر سیستم‌ها فورواردینگ خاموش دارند.

برای روشن کردن فوروارد پورت فقط برای این نشست، این را اجرا کنید:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
Output
1

برای روشن کردن دائمی فوروارد پورت، باید فایل /etc/sysctl.conf را ویرایش کنید. این کار را با باز کردن فایل با دسترسی sudo می‌توانید انجام دهید:

sudo nano /etc/sysctl.conf

داخل فایل، خطی که این‌طور است را پیدا و از کامنت دربیاورید:

/etc/sysctl.conf
net.ipv4.ip_forward=1

وقتی تمام شد، فایل را ذخیره و ببندید.

سپس تنظیمات این فایل را اعمال کنید. اول دستور زیر را اجرا کنید:

sudo sysctl -p
Output
net.ipv4.ip_forward = 1

سپس همان دستور را اجرا کنید؛ اما فلگ -p را با --system جایگزین کنید:

sudo sysctl --system
Output
. . .
* Applying /usr/lib/sysctl.d/50-pid-max.conf ...
kernel.pid_max = 4194304
* Applying /etc/sysctl.d/99-cloudimg-ipv6.conf ...
net.ipv6.conf.all.use_tempaddr = 0
net.ipv6.conf.default.use_tempaddr = 0
* Applying /etc/sysctl.d/99-sysctl.conf ...
net.ipv4.ip_forward = 1
* Applying /usr/lib/sysctl.d/protect-links.conf ...
fs.protected_fifos = 1
fs.protected_hardlinks = 1
fs.protected_regular = 2
fs.protected_symlinks = 1
* Applying /etc/sysctl.conf ...
net.ipv4.ip_forward = 1

افزودن قوانین فورواردینگ به فایروال پایه

بعد، فایروالتان را طوری پیکربندی می‌کنید که ترافیک جریان‌یافته به اینترفیس عمومی‌تان (eth0) روی پورت ۸۰، به اینترفیس خصوصی‌تان (eth1) فوروارد شود.

فایروالی که در آموزش پیش‌نیاز پیکربندی کردید، زنجیر FORWARDش به‌طور پیش‌فرض روی DROP است. باید قوانینی اضافه کنید که به شما اجازه فوروارد اتصالات به وب‌سرورتان را بدهد. برای امنیت، این را نسبتاً محکم قفل می‌کنید تا فقط اتصالاتی که می‌خواهید فوروارد شوند مجاز باشند.

در زنجیر FORWARD، اتصالات جدیدِ مقصدشان پورت ۸۰ است که از اینترفیس عمومی‌تان می‌آیند و به اینترفیس خصوصی‌تان می‌روند را می‌پذیرید. اتصالات جدید توسط افزونه conntrack شناسایی و مشخصاً توسط بسته TCP SYN مانند زیر نمایش داده می‌شوند:

sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT

این بسته اولِ در-نظر-گرفته‌شده برای برقراری اتصال را از فایروال عبور می‌دهد. همچنین باید هر ترافیک بعدی در هر دو جهتِ حاصل از آن اتصال را مجاز کنید. برای مجاز کردن ترافیک ESTABLISHED و RELATED بین اینترفیس‌های عمومی و خصوصی‌تان، دستورات زیر را اجرا کنید. اول برای اینترفیس عمومی‌تان:

sudo iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

سپس برای اینترفیس خصوصی‌تان:

sudo iptables -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

دوباره چک کنید که سیاست‌تان روی زنجیر FORWARD روی DROP تنظیم شده:

sudo iptables -P FORWARD DROP

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

افزودن قوانین NAT برای هدایت درست بسته‌ها

بعد، قوانینی را اضافه می‌کنید که به iptables می‌گویند چگونه ترافیک‌تان را مسیریابی کند. باید دو عملیات جدا انجام دهید تا iptables بسته‌ها را درست تغییر دهد تا کلاینت‌ها بتوانند با وب‌سرور ارتباط برقرار کنند.

عملیات اول، DNAT نامیده می‌شود و در زنجیر PREROUTING جدول nat رخ می‌دهد. DNAT عملیاتی است که آدرس مقصد یک بسته را تغییر می‌دهد تا بتواند هنگام عبور بین شبکه‌ها درست مسیریابی شود. کلاینت‌های روی شبکه عمومی به سرور فایروال‌تان وصل می‌شوند و هیچ دانشی از توپولوژی شبکه خصوصی‌تان ندارند. بنابراین، باید آدرس مقصد هر بسته را تغییر دهید تا وقتی روی شبکه خصوصی‌تان ارسال می‌شود، بداند چگونه درست به وب‌سرورتان برسد.

چون فقط فوروارد پورت را پیکربندی می‌کنید و NAT را روی هر بسته‌ای که به فایروالتان می‌خورد انجام نمی‌دهید، می‌خواهید پورت ۸۰ را روی قانون‌تان تطبیق دهید. بسته‌های هدف‌گرفته پورت ۸۰ را به آدرس IP خصوصی وب‌سرورتان تطبیق می‌دهید (10.0.0.1 در مثال زیر):

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1

این فرایند از نصف تصویر مراقبت می‌کند. بسته باید درست به وب‌سرورتان مسیریابی شود. اما الان، بسته همچنان آدرس اصلی کلاینت را به‌عنوان آدرس مبدأ دارد. سرور سعی می‌کند پاسخ را مستقیماً به آن آدرس بفرستد؛ که برقراری اتصال TCP قانونی را غیرممکن می‌کند.

روی پارمین کلود، بسته‌های ترک‌کننده یک سرور ابری با آدرس مبدأ متفاوت، در واقع توسط هایپروایزور حذف می‌شوند؛ پس بسته‌های‌تان در این مرحله حتی به وب‌سرور هم نمی‌رسند (که با پیاده‌سازی SNAT به‌زودی رفع می‌شود). این اقدام ضد-جعل (Anti-Spoofing) برای جلوگیری از حملاتی است که در آن‌ها با جعل آدرس مبدأ در درخواست، حجم زیادی داده برای ارسال به کامپیوتر قربانی درخواست می‌شود.

برای پیکربندی مسیریابی درست، باید آدرس مبدأ بسته را هم هنگام خروج از فایروال در مسیر وب‌سرور تغییر دهید. باید آدرس مبدأ را به آدرس IP خصوصی سرور فایروال‌تان تغییر دهید (10.0.0.2 در مثال زیر). سپس پاسخ به فایروال برگردانده می‌شود؛ که می‌تواند مثل انتظار آن را به کلاینت فوروارد کند.

برای فعال کردن این قابلیت، قانونی به زنجیر POSTROUTING جدول nat اضافه کنید؛ که درست قبل از ارسال بسته‌ها روی شبکه ارزیابی می‌شود. بسته‌های مقصد-شده به وب‌سرورتان را با آدرس IP و پورت تطبیق می‌دهید:

sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 80 -d 10.0.0.1 -j SNAT --to-source 10.0.0.2

SNAT در مقابل MASQUERADE: در این راهنما از SNAT استفاده می‌کنیم چون آدرس IP خصوصی ایستایی روی فایروال داریم. اگر آدرس IP دروازه‌تان داینامیک تخصیص می‌یابد (مثلاً از طریق DHCP)، به‌جایش از هدف MASQUERADE استفاده کنید. MASQUERADE به‌طور خودکار از آدرس IP فعلی اینترفیس خروجی استفاده می‌کند؛ اما کمی کندتر از SNAT است چون باید آدرس را به ازای هر بسته جستجو کند. برای IPهای ایستا، SNAT انتخاب بهتری است.

وقتی این قانون در جای خود قرار گرفت، وب‌سرورتان باید با اشاره مرورگر وب‌تان به آدرس عمومی ماشین فایروالتان قابل دسترس باشد:

curl 203.0.113.2
Output
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
. . .

راه‌اندازی فوروارد پورت‌تان حالا کامل است.

تنظیم مجموعه قوانین ماندگار

حالا که فوروارد پورت را راه‌اندازی کردید، می‌توانید آن را در مجموعه قوانین ماندگارتان ذخیره کنید.

اگر اهمیتی نمی‌دهید که کامنت‌های موجود در مجموعه قوانین فعلی‌تان را از دست بدهید، از دستور netfilter-persistent برای استفاده از سرویس iptables و ذخیره قوانین‌تان استفاده کنید:

sudo service netfilter-persistent save
Output
 * Saving netfilter rules...                                                    run-parts: executing /usr/share/netfilter-persistent/plugins.d/15-ip4tables save
run-parts: executing /usr/share/netfilter-persistent/plugins.d/25-ip6tables save
                                                                         [ OK ]

اگر مایلید کامنت‌های فایل‌تان را نگه دارید، بازش کنید و دستی ویرایش کنید:

sudo nano /etc/iptables/rules.v4

باید پیکربندی را در جدول filter برای قوانین زنجیر FORWARDِ اضافه‌شده تنظیم کنید. همچنین باید بخشی را که جدول nat را پیکربندی می‌کند تنظیم کنید تا بتوانید قوانین PREROUTING و POSTROUTING خود را اضافه کنید. محتوا شبیه زیر خواهد بود:

/etc/iptables/rules.v4
*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Custom per-protocol chains
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]

# Acceptable UDP traffic

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT

# Acceptable ICMP traffic

# Boilerplate acceptance policy
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT

# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP

# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For TCP, additionally only allow new SYN packets since that is the only valid
## method for establishing a new TCP connection
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

# Reject anything that's fallen through to this point
## Try to be protocol-specific w/ rejection message
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable

# Rules to forward port 80 to our web server

# Web server network details:

# * Public IP Address: 203.0.113.1
# * Private IP Address: 10.0.0.1
# * Public Interface: eth0
# * Private Interface: eth1
# 
# Firewall network details:
# 
# * Public IP Address: 203.0.113.2
# * Private IP Address: 10.0.0.2
# * Public Interface: eth0
# * Private Interface: eth1
-A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# End of Forward filtering rules

# Commit the changes

COMMIT

*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

# Rules to translate requests for port 80 of the public interface
# so that we can forward correctly to the web server using the
# private interface.

# Web server network details:

# * Public IP Address: 203.0.113.1
# * Private IP Address: 10.0.0.1
# * Public Interface: eth0
# * Private Interface: eth1
# 
# Firewall network details:
# 
# * Public IP Address: 203.0.113.2
# * Private IP Address: 10.0.0.2
# * Public Interface: eth0
# * Private Interface: eth1
-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1
-A POSTROUTING -d 10.0.0.1 -o eth1 -p tcp --dport 80 -j SNAT --to-source 10.0.0.2
# End of NAT translations for web server traffic
COMMIT

*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

وقتی محتوا را اضافه و مقادیر را برای انعکاس محیط شبکه خودتان تنظیم کردید، فایل را ذخیره و ببندید.

بعد، سینتکس فایل قوانین‌تان را تست کنید:

sudo sh -c "iptables-restore -t < /etc/iptables/rules.v4"

اگر خطایی تشخیص داده نشد، مجموعه قوانین را بارگذاری کنید:

sudo service netfilter-persistent reload
Output
 * Loading netfilter rules...                                                   run-parts: executing /usr/share/netfilter-persistent/plugins.d/15-ip4tables start
run-parts: executing /usr/share/netfilter-persistent/plugins.d/25-ip6tables start
                                                                         [ OK ]

حالا تست کنید که وب‌سرورتان همچنان از طریق آدرس IP عمومی فایروالتان قابل دسترس است:

curl 203.0.113.2

این باید مثل قبل کار کند.

بهترین روش‌های امنیتی برای فوروارد پورت

هنگام پیکربندی فوروارد پورت iptables روی یک دروازه لینوکسی، باید از این بهترین روش‌های امنیتی پیروی کنید تا شبکه‌تان محافظت بماند:

فوروارد پورت‌ها را به سرویس‌های خاص محدود کنید. فقط پورت‌هایی را فوروارد کنید که اکیداً لازم‌اند. هر پورت فورواردشده، نقطه ورودی به شبکه خصوصی‌تان می‌سازد؛ پس از باز کردن پورت‌هایی که نیاز ندارید بپرهیزید.

محدود کردن آدرس‌های IP مبدأ در حد امکان. اگر می‌دانید کدام آدرس‌های IP خارجی نیاز به دسترسی دارند، فیلتر مبدأ به قانون PREROUTING خود اضافه کنید. مثلاً برای مجاز کردن فقط 198.51.100.0/24 برای رسیدن به وب‌سرورتان از طریق پورت ۸۰:

sudo iptables -t nat -A PREROUTING -i eth0 -s 198.51.100.0/24 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1

ثبت لاگ بسته‌های حذف‌شده برای مانیتورینگ. افزودن قانون لاگینگ قبل از سیاست DROP شما با عیب‌یابی و تشخیص نفوذ کمک می‌کند:

sudo iptables -A FORWARD -j LOG --log-prefix "IPTables-FORWARD-DROP: " --log-level 4

استفاده از محدودیت نرخ روی اتصالات فورواردشده برای محافظت در برابر حملات SYN Flood و تلاش‌های brute-force. می‌توانید ماژول limit را به قانون FORWARD خود اضافه کنید:

sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -m limit --limit 25/second --limit-burst 50 -j ACCEPT

مرور منظم قوانین‌تان. از iptables -L -v -n و iptables -t nat -L -v -n برای فهرست و ممیزی دوره‌ای قوانین فایروال‌تان استفاده کنید. قوانین قدیمی یا بیش‌ازحد آسان‌گیرانه می‌توانند شبکه‌تان را افشا کنند.

به‌روز نگه داشتن iptables. sudo apt update && sudo apt upgrade را منظم اجرا کنید تا وصله‌های امنیتی اعمال شوند.

برای نگاه گسترده‌تر به استراتژی‌های فایروال، «نحوه انتخاب سیاست فایروال مؤثر برای امن کردن سرورها» را در پارمین کلود بخوانید.

عیب‌یابی مسائل رایج فوروارد پورت

اگر فوروارد پورت‌تان طبق انتظار کار نمی‌کند، این چک‌لیست را برای شناسایی مشکل مرور کنید.

۱. تأیید فعال بودن فوروارد IP:

cat /proc/sys/net/ipv4/ip_forward

این باید ۱ برگرداند. اگر ۰ برگرداند، فوروارد IP غیرفعال است. با مراحل بخش «فعال کردن فورواردینگ در کرنل» بالا دوباره فعالش کنید.

۲. چک کردن درست بارگذاری شدن قوانین NAT:

sudo iptables -t nat -L -v -n

به دنبال قوانین PREROUTING و POSTROUTING خود بگردید. مطمئن شوید IP مقصد، پورت و نام اینترفیس‌ها درست‌اند.

۳. بازرسی زنجیر FORWARD:

sudo iptables -L FORWARD -v -n

تأیید کنید قوانین FORWARD شما قبل از سیاست پیش‌فرض DROP ظاهر می‌شوند. قوانین در iptables از بالا به پایین ارزیابی می‌شوند؛ پس ترتیب مهم است.

۴. تأیید اجرا شدن سرویس بک‌اند:

curl --connect-timeout 5 10.0.0.1

اگر این از ماشین فایروال تایم‌اوت شود، مشکل از وب‌سرور است نه قوانین فایروال. چک کنید Nginx در حال اجرا و روی آدرس IP خصوصی درست گوش دادن است.

۵. چک تداخل فایروال ابری:

اگر روی پارمین کلود یا ارائه‌دهنده ابری دیگری اجرا می‌کنید، فایروال‌های ابری خارجی ممکن است قبل از رسیدن به قوانین iptables سرور ابری‌تان، ترافیک را بلاک کنند. مطمئن شوید فایروال ابری پارمین کلود (در صورت پیکربندی)، ترافیک ورودی TCP روی پورت ۸۰ به IP عمومی سرور فایروال‌تان را مجاز می‌داند.

۶. تماشای ترافیک در زمان واقعی با tcpdump:

برای دیدن اینکه آیا بسته‌ها به اینترفیس عمومی فایروالتان می‌رسند:

sudo tcpdump -i eth0 -n tcp port 80

اگر بسته‌های SYN ورودی می‌بینید اما هیچ ترافیک فورواردشده‌ای روی eth1 نیست، مشکل احتمالاً در قوانین FORWARD یا NAT شماست.

نشانهعلت محتملراه‌حل
Connection refusedبک‌اند روی IP درست گوش نمی‌دهددایرکتیو listen مربوط به Nginx را تأیید کنید
Connection timeoutزنجیر FORWARD بسته‌ها را حذف می‌کندقوانین FORWARD و ترتیب‌شان را چک کنید
مسیریابی نامتقارنقانون SNAT مفقودقانون SNAT مربوط به POSTROUTING را اضافه کنید
بدون بسته روی اینترفیس عمومیفایروال ابری بلاک کردهقوانین ورودی فایروال ابری را به‌روز کنید
قوانین بعد از ریبوت از دست رفته‌اندقوانین ذخیره نشده‌اندnetfilter-persistent save را اجرا کنید

iptables در مقابل nftables

شروع با دبیان ۱۰ (Buster) و اوبونتو 20.10، اکوسیستم لینوکس در حال گذار از iptables به nftables به‌عنوان چارچوب پیش‌فرض فیلترینگ بسته بوده است. روی اوبونتو 20.04، 22.04 و 24.04 LTS، دستور iptables همچنان کار می‌کند؛ چون اوبونتو iptables-nft را فراهم می‌کند؛ لایه سازگاری که سینتکس iptables را به بک‌اند nftables ترجمه می‌کند. یعنی دستورات این آموزش روی همه نسخه‌های LTS فعلی اوبونتو بدون تغییر کار خواهند کرد.

اینجا مقایسه سریعی آمده:

ویژگیiptablesnftables
سینتکسدستورات جدا به ازای جدول (iptables، ip6tables، arptables، ebtables)ابزار واحد منفرد (nft)
کاراییزنجیرها را خطی پیمایش می‌کنداز جستجوهای بهینه با Setها و Mapها استفاده می‌کند
اتمی بودنقوانین یک‌به‌یک اعمال می‌شوندکل مجموعه قوانین اتمی اعمال می‌شود
IPv4/IPv6ابزارهای جدا به ازای هر کدامهر دو را در قانون منفردی مدیریت می‌کند
سازگاری معکوسنیتیولایه سازگاری iptables-nft فراهم می‌کند

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

sudo nft add table ip nat
sudo nft add chain ip nat prerouting { type nat hook prerouting priority -100 \; }
sudo nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
sudo nft add rule ip nat prerouting iif eth0 tcp dport 80 dnat to 10.0.0.1
sudo nft add rule ip nat postrouting oif eth1 ip daddr 10.0.0.1 tcp dport 80 snat to 10.0.0.2

برای بیشتر کاربران LTS اوبونتو، دستورات iptables نمایش‌داده‌شده در این راهنما از طریق لایه سازگاری کاملاً پشتیبانی می‌شوند. اگر زیرساخت جدیدی راه‌اندازی می‌کنید یا مهاجرتی برنامه‌ریزی کرده‌اید، یادگیری سینتکس نیتیو nftables ارزش سرمایه‌گذاری دارد.

برای اطلاعات بیشتر درباره مدیریت قوانین فایروال، «اصول UFW: قوانین و دستورات رایج فایروال» در پارمین کلود را ببینید؛ که رابط UFW روی iptables/nftables را پوشش می‌دهد.

فوروارد پورت در محیط‌های ابری

هنگام اجرای دروازه لینوکسی‌تان روی ارائه‌دهنده ابری‌ای مانند پارمین کلود، ملاحظات شبکه‌ای اضافی‌ای هست که باید در نظر بگیرید.

VPC و شبکه خصوصی: روی پارمین کلود، شبکه خصوصی بین سرورهای ابری از طریق VPC (ابر خصوصی مجازی) فراهم می‌شود. سرورهای ابری‌تان باید در همان VPC باشند تا روی آدرس‌های IP خصوصی ارتباط برقرار کنند. هنگام راه‌اندازی فوروارد پورت، مطمئن شوید هر دوی سرورهای ابری فایروال و وب‌سرورتان در همان VPC و منطقه‌اند.

فایروال‌های ابری و iptables: فایروال‌های ابری پارمین کلود در سطح هایپروایزور—قبل از رسیدن ترافیک به سرور ابری‌تان—اعمال می‌شوند. یعنی قوانین فایروال ابری قبل از قوانین iptables شما ارزیابی می‌شوند. اگر از هر دو استفاده می‌کنید، مطمئن شوید:

  • فایروال ابری، ترافیک ورودی روی پورت فورواردشده (پورت ۸۰ در این مثال) به سرور ابری فایروال را مجاز می‌داند.
  • فایروال ابری روی سرور ابری وب‌سرور، ترافیک از آدرس IP خصوصیِ سرور ابری فایروال را مجاز می‌داند.

ضد-جعل: همان‌طور که قبلاً اشاره شد، هایپروایزور پارمین کلود بسته‌های با آدرس‌های مبدأ که با IP تخصیص‌یافته سرور ابری مطابقت ندارند را حذف می‌کند. به همین دلیل است که قانون SNAT در زنجیر POSTROUTING ضروری است. بدون آن، پاسخ‌های وب‌سرورتان (با آدرس مبدأ اصلی کلاینت) قبل از ترک شبکه توسط هایپروایزور حذف می‌شدند.

IPهای شناور: اگر سرور ابری فایروال‌تان از IP رزروشده پارمین کلود (قبلاً IP شناور) استفاده می‌کند، ترافیک عمومی روی اینترفیس لنگر خاصی می‌رسد. ممکن است لازم باشد اینترفیس -i قانون PREROUTING خود را متناسب تنظیم کنید. اینترفیس‌های‌تان را با ip addr چک کنید تا درستش را شناسایی کنید.

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

۱. تفاوت DNAT و SNAT در iptables چیست؟

DNAT (NAT مقصد)، آدرس IP مقصد بسته ورودی را تغییر می‌دهد. در زنجیر PREROUTING استفاده می‌شود تا بسته‌ها به سرور داخلی درست برسند. SNAT (NAT مبدأ)، آدرس IP مبدأ بسته خروجی را تغییر می‌دهد و در زنجیر POSTROUTING استفاده می‌شود تا بسته‌های پاسخ به‌جای ارسال مستقیم به کلاینت، از طریق دروازه به عقب مسیریابی شوند. در راه‌اندازی فوروارد پورت، معمولاً به هر دو نیاز دارید: DNAT برای تغییر مسیر درخواست ورودی و SNAT برای تضمین برگشت پاسخ از طریق فایروال. برای درک عمیق‌تر از نحوه عبور بسته‌ها از زنجیرهای iptables، «نگاه عمیق به معماری Iptables و Netfilter» را در پارمین کلود ببینید.

۲. چرا فوروارد IP برای فوروارد پورت لازم است؟

فوروارد IP، قابلیت سطح-کرنلی است که به ماشین لینوکسی اجازه می‌دهد بسته‌ها را بین اینترفیس‌های شبکه‌اش عبور بدهد. بدون فعال بودنش (net.ipv4.ip_forward=1 در /etc/sysctl.conf)، کرنل هر بسته‌ای را که به اینترفیسی برسد و مقصدش اینترفیس دیگری باشد حذف می‌کند. چون فوروارد پورت یعنی دریافت بسته روی اینترفیس عمومی و ارسال آن از طریق اینترفیس خصوصی، فوروارد IP باید روشن باشد تا فرایند کار کند.

۳. چطور چند پورت را با iptables فوروارد کنم؟

می‌توانید با افزودن قوانین DNAT، SNAT و FORWARD جدا به ازای هر پورت، چند پورت را فوروارد کنید. به‌عنوان جایگزین، از افزونه multiport استفاده کنید تا چند پورت را در قانون منفردی تطبیق دهید. مثلاً برای فوروارد هم پورت ۸۰ و هم ۴۴۳:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 10.0.0.1
sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp -m multiport --dports 80,443 -d 10.0.0.1 -j SNAT --to-source 10.0.0.2
sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp -m multiport --dports 80,443 --syn -m conntrack --ctstate NEW -j ACCEPT

همچنین می‌توانید بازه پورت‌ها را با قالب 8000:9000 تعیین کنید. برای مثال‌های بیشتر از قوانین رایج iptables، «اصول Iptables: قوانین و دستورات رایج فایروال» در پارمین کلود را ببینید.

۴. آیا می‌توانم پورت‌های UDP را با iptables فوروارد کنم؟

بله. قوانین مشابه‌اند؛ اما -p tcp را با -p udp جایگزین و فلگ --syn را حذف کنید (چون UDP بدون-اتصال است). مثلاً برای فوروارد پورت UDP شماره ۵۳ (DNS) به سرور داخلی:

sudo iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to-destination 10.0.0.1
sudo iptables -t nat -A POSTROUTING -o eth1 -p udp --dport 53 -d 10.0.0.1 -j SNAT --to-source 10.0.0.2
sudo iptables -A FORWARD -i eth0 -o eth1 -p udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT

ماژول conntrack «اتصالات» UDP را بر اساس جفت آدرس/پورت مبدأ و مقصد ردیابی می‌کند؛ پس قوانین established و related همچنان برای ترافیک بازگشتی اعمال می‌شوند.

۵. آیا iptables به نفع nftables منسوخ شده؟

در حالی که nftables چارچوب جدیدتری است و از دبیان ۱۰ بک‌اند پیش‌فرض بوده، iptables کاملاً منسوخ نشده. نسخه‌های LTS اوبونتو (20.04، 22.04، 24.04) با iptables-nft عرضه می‌شوند؛ که دستورات iptables را به API کرنلی nftables ترجمه می‌کند. یعنی می‌توانید ادامه دهید به استفاده از سینتکس آشنای iptables بدون مشکل. اما برای پروژه‌های جدید، یادگیری nftables توصیه می‌شود؛ چون کارایی بهتر، سینتکس واحد ساده‌تر و به‌روزرسانی اتمی قوانین فراهم می‌کند.

نتیجه‌گیری

تا اینجا باید با فوروارد کردن پورت‌ها روی دروازه لینوکسی با iptables راحت باشید. فرایند شامل سه قدم اصلی است: فعال کردن فوروارد IP در سطح کرنل، پیکربندی قوانین زنجیر FORWARD برای مجاز دانستن ترافیک بین اینترفیس‌ها و راه‌اندازی قوانین DNAT و SNAT در جدول NAT تا بسته‌ها درست مسیریابی و ترجمه شوند.

همچنین بهترین روش‌های امنیتی فوروارد پورت، نحوه عیب‌یابی مسائل رایج و مقایسه iptables با چارچوب جدیدتر nftables را آموختید. این رویکرد روی اوبونتو 20.04، 22.04 و 24.04 LTS کار می‌کند؛ و روشی قابل اطمینان برای کنترل نحوه جریان ترافیک از طریق ماشین فایروال-دروازه‌تان به شما می‌دهد.

نوشته های مشابه

دیدگاهتان را بنویسید

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

دکمه بازگشت به بالا