بستن IP خارجی روی سرور لینوکس یعنی فایروال فقط به رنج‌های ثبت‌شده ایران اجازه ورود بدهد و بقیه دنیا را drop کند. این کار در یک وضعیت باریک منطقی است: سروری که کاربرش داخل کشور است و زیر اسکن گسترده قرار دارد. برای وب‌سایت عمومی تقریباً همیشه اشتباه است، چون خزنده گوگل و تمدید گواهی SSL هم از بیرون می‌آیند.

  • ابزار کار: ipset با نوع hash:net روی iptables، یا named set در nftables، یا ipset دائمی firewalld
  • منبع فهرست: فایل delegated-extended مرکز RIPE؛ در فایل ۲۳ اکتبر ۲۰۲۶، ۱۹۶۹ رکورد IPv4 برای کد IR
  • اندازه: بعد از ادغام، ۱۷۴۷ بلوک CIDR و ۱۰٬۸۴۰٬۰۶۴ آدرس
  • ریسک: قفل‌شدن از SSH، نرسیدن خزنده گوگل، باز ماندن IPv6

💡 دو پیش‌نیاز، پیش از اولین دستور

فیلتر کشوری یعنی فایروال، آدرس منبع هر بسته را با فهرست رنج‌های ثبت‌شده یک کشور می‌سنجد؛ یک دفتر ثبت اداری، نه اندازه‌گیری موقعیت جغرافیایی.
✅ یک راه ورود مستقل از شبکه داشته باشید: کنسول سرور یا حالت Rescue پنل. اگر سرور شما هیچ‌کدام را ندارد، این آموزش را اجرا نکنید.
✅ بازگشت زمان‌دار را قبل از اولین قانون drop بگذارید.

این راهنما اول خط قرمزها را روشن می‌کند تا بدانید چه چیزی را از دست می‌دهید؛ بعد دستورها را با ترتیبی می‌آورد که نشست SSH شما را زنده نگه می‌دارد. 👇

ترتیب قوانین فایروال لینوکس برای فیلتر کشوری منبع بسته روی یک سرور، بستن IP خارجی

بستن IP خارجی در چه شرایطی منطقی است و چه چیزی را می‌شکند؟

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

چهار سرویسی که با یک قانون drop از کار می‌افتند

ترافیک ورودی و خروجی را جدا در نظر بگیرید. اگر فقط زنجیره INPUT را فیلتر کنید و قانون conntrack سر جایش باشد، سرور همچنان خودش به بیرون وصل می‌شود. چیزی که از بین می‌رود، اتصال‌های آغازشده از بیرون است.

سرویسجهتبا drop ورودیبا drop خروجی
خزنده گوگلورودیگوگل صفحه را دریافت نمی‌کندبی‌اثر
اعتبارسنجی HTTP-01 گواهی SSLورودیتمدید خودکار شکست می‌خوردصدور قطع می‌شود
کال‌بک درگاه پرداخت خارجیورودیتأیید تراکنش نمی‌رسددرخواست اولیه می‌شکند
مخزن بسته‌ها و میرورهاخروجیسالم می‌ماند، چون پاسخ ESTABLISHED استدستور apt می‌شکند
دسترسی خودتان از بیرون ایرانورودیهمان لحظه SSH قطع می‌شودبی‌اثر

⚠️ فهرست‌های کشوری تقریبی‌اند و کهنه می‌شوند

رنج IP به یک کشور «تخصیص» داده می‌شود، ولی تضمینی نیست که دستگاه همان لحظه همان‌جا باشد. مثل پلاک خودرو است: پلاک اصفهان روی ماشینی که در تبریز پارک شده هم اصفهان می‌ماند. پس هر فهرستی از روز دوم کمی غلط است.

جایگزین‌هایی که اغلب بهتر از فیلتر کشوری جواب می‌دهند

  • محدود کردن پورت مدیریتی به چند IP مشخص و باز گذاشتن ۸۰ و ۴۴۳
  • احراز هویت کلید عمومی به‌جای رمز، و سقف اتصال همزمان هر IP
  • نرخ‌گیری روی اتصال‌های جدید، که حمله را کُند می‌کند ولی کاربر واقعی را قطع نمی‌کند
  • مسدود کردن هدفمند همان چند رنجی که در لاگ دیده می‌شوند

🔶 نکته درباره IP مستقیم

روی سرور مجازی ایرانی وب‌داده هر سرور IP مستقیم دارد که از اینترنت بین‌الملل هم در دسترس است، و کنسول VNC و حالت Rescue در پنل هست. فیلتر کشوری همین دسترسی را خودتان می‌بندید.

ساخت فهرست رنج‌های IP ایران از داده رسمی RIPE

ساخت فهرست رنج‌های IP ایران از داده رسمی RIPE

منبع درست، فایل آماری خود مرکز RIPE است؛ همان جایی که تخصیص‌ها ثبت می‌شوند. این فایل روزانه تازه می‌شود و هر رکورد را با کد کشور، نوع آدرس و وضعیت نشان می‌دهد. فایل delegated-extended مرکز RIPE کلید نمی‌خواهد.

curl -fsSL -o /tmp/delegated-ripencc-extended-latest \
  https://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest

head -n 1 /tmp/delegated-ripencc-extended-latest

فیلدهای هر سطر با کاراکتر | جدا می‌شوند: رجیستری، کد کشور، نوع آدرس، آدرس شروع، مقدار، تاریخ و وضعیت. برای بستن IP خارجی همین فهرست ورودی فایروال است. فقط رکوردهای allocated و assigned را بردارید.

🔸 تله‌ای که اسکریپت‌های رایج در آن می‌افتند

در رکوردهای IPv4، ستون پنجم تعداد آدرس است، نه طول پیشوند؛ فرمت رسمی RIR هم می‌گوید این عدد لازم نیست یک رنج CIDR را نشان بدهد. بیشتر آموزش‌ها آن را با تقسیم ساده به prefix تبدیل می‌کنند و فرض می‌کنند توانی از دو است. در فایل ۲۳ اکتبر ۲۰۲۶ سه رکورد ایرانی چنین نبودند.

اسکریپت زیر هر رکورد را به بلوک‌های هم‌تراز می‌شکند و بلوک‌های مجاور را ادغام می‌کند. فقط کتابخانه استاندارد پایتون ۳.۵ یا بالاتر لازم است.

#!/usr/bin/env python3
# cc-cidr.py <delegated-file> <CC>
import ipaddress, sys

src, cc = sys.argv[1], sys.argv[2]
nets = []
with open(src, encoding="utf-8", errors="replace") as fh:
    for line in fh:
        f = line.rstrip("\n").split("|")
        if len(f) < 7 or f[1] != cc or f[2] != "ipv4":
            continue
        if f[6] not in ("allocated", "assigned"):
            continue
        start, remain, off = int(ipaddress.IPv4Address(f[3])), int(f[4]), 0
        while remain > 0:
            size = 1
            while size * 2 <= remain and (start + off) % (size * 2) == 0:
                size *= 2
            nets.append(ipaddress.IPv4Network((start + off, 33 - size.bit_length())))
            off += size
            remain -= size
for net in ipaddress.collapse_addresses(nets):
    print(net)
install -d -m 0755 /etc/ipset
python3 /usr/local/sbin/cc-cidr.py /tmp/delegated-ripencc-extended-latest IR \
  > /etc/ipset/iran-v4.cidr

wc -l < /etc/ipset/iran-v4.cidr

اجرای این اسکریپت روی فایل ۲۳ اکتبر ۲۰۲۶ نتیجه‌ای قابل بازتولید داد: ۱۹۶۹ رکورد IPv4 با کد کشور IR که بعد از ادغام به ۱۷۴۷ بلوک CIDR و ۱۰٬۸۴۰٬۰۶۴ آدرس رسیدند. این اسکریپت فقط IPv4 می‌سازد.

پیاده‌سازی با ipset و iptables بدون قفل‌شدن از سرور

پیاده‌سازی با ipset و iptables بدون قفل‌شدن از سرور

برای بستن IP خارجی، ابزار ipset یک ساختار hash در هسته می‌سازد و iptables با یک قانون به کل مجموعه نگاه می‌کند. در hash:net به ازای هر طول پیشوندِ موجود یک جست‌وجو انجام می‌شود؛ این فهرست ۱۳ طول پیشوند دارد، یعنی ۱۳ جست‌وجو به‌جای پیمایش ۱۷۴۷ قانون.

گام صفر؛ وضعیت فعلی و آدرس خودتان را بدانید

قوانین این بخش با سوئیچ -A به انتهای زنجیره اضافه می‌شوند، پس نتیجه به محتوای فعلی زنجیره بستگی دارد. اول زنجیره INPUT را ببینید و آدرسی که با آن وصل‌اید را بخوانید. یک نشست SSH دوم هم باز کنید و تا آخر نبندید.

echo "$SSH_CLIENT" | awk '{print $1}'   # آدرسی که همین حالا با آن وصل‌اید
iptables -S INPUT                        # قوانین فعلی زنجیره
iptables -S INPUT | wc -l

⚠️ اگر زنجیره INPUT از قبل قانون دارد

اگر خروجی بالا چیزی بیش از -P INPUT ACCEPT داشت، یعنی ufw، CSF، docker یا پنل میزبانی پیش از شما قانون گذاشته‌اند. دستورهای -A این بخش را اجرا نکنید: با یک DROP قبلی، قوانین ACCEPT بعدی بی‌اثر می‌مانند و قفل می‌شوید؛ با یک ACCEPT عمومی قبلی، قانون drop بی‌اثر است. قوانین را با همان ابزار موجود بنویسید، یا از -I با شماره سطر استفاده کنید.

ساخت مجموعه و بار کردن فهرست

طبق صفحه man رسمی ipset، نوع hash:net شبکه‌هایی با طول پیشوند مختلف را نگه می‌دارد و maxelem سقف تعداد عضو است؛ پیش‌فرضش ۶۵۵۳۶ است. فرمان restore یک نشست کامل را یک‌جا می‌خواند، پس برای هزاران عضو از تکرار add بهتر است.

apt install -y ipset       # در راکی و آلما: dnf install -y ipset

# maxelem دو برابر پیش‌فرض، فقط برای جای رشد؛ ۱۷۴۷ عضو با پیش‌فرض هم جا می‌شد.
{ echo "create iran_v4 hash:net family inet hashsize 4096 maxelem 131072"
  sed 's/^/add iran_v4 /' /etc/ipset/iran-v4.cidr; } | ipset restore -exist

ipset -t list iran_v4

بازگشت زمان‌دار؛ قبل از اولین قانون drop

این گام را قبل از بخش بعدی اجرا کنید، نه بعد از آن. یک کار تأخیری می‌سازیم که ۱۰ دقیقه بعد قانون drop را حذف کند. اگر دسترسی سالم ماند تایمر را متوقف می‌کنید؛ اگر قطع شدید، سرور خودش قانون را برمی‌دارد. فرمان systemd-run کنار سرویس یک تایمر گذرا هم می‌سازد؛ اگر فهرست تایمرها خالی برگشت، شبکه ایمنی ساخته نشده و نباید جلو بروید.

systemd-run --on-active=10min --unit=fw-rollback --collect \
  /bin/sh -c 'iptables -D INPUT -m set ! --match-set iran_v4 src -j DROP'

systemctl list-timers 'fw-rollback*'    # باید یک سطر با زمان باقی‌مانده نشان بدهد

# فقط بعد از اینکه از نشست دوم دسترسی را تست کردید:
# systemctl stop fw-rollback.timer

ترتیب قوانین iptables؛ اجازه قبل از drop

قانون drop را هرگز اول ننویسید. ترتیب زیر را از بالا به پایین بخوانید: لوپ‌بک، اتصال‌های برقرار، اجازه صریح SSH از IP مدیریتی خودتان و تنها در انتها drop. ماژول set با نشانه src آدرس منبع را می‌سنجد و علامت ! شرط را برعکس می‌کند.

ADMIN_IP=203.0.113.10   # آدرس نمونه RFC 5737؛ آدرس خودتان را بگذارید

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s "$ADMIN_IP" -j ACCEPT
iptables -A INPUT -m set ! --match-set iran_v4 src -j DROP

iptables -L INPUT -n --line-numbers

⚠️ قوانین بالا هیچ اثری روی IPv6 ندارند

دستور iptables فقط جدول IPv4 را عوض می‌کند و ip6tables دست‌نخورده می‌ماند. اگر سرور آدرس IPv6 دارد، کل دنیا از همان مسیر باز است و این کار بی‌اثر می‌شود. چون فهرست کشوری IPv6 نساخته‌ایم، حالت ایمن بستن اتصال ورودی IPv6 است: ACCEPT برای -i lo و ESTABLISHED,RELATED و -p ipv6-icmp، و در آخر ip6tables -A INPUT -j DROP.

پایداری بعد از ریبوت در دبیان و اوبونتو

قوانین iptables و محتوای ipset هر دو در حافظه‌اند و با ریبوت پاک می‌شوند. در دبیان و اوبونتو بسته iptables-persistent قوانین را و ipset-persistent مجموعه‌ها را ذخیره می‌کند؛ دومی در مخزن universe است. افزونه ۱۰-ipset پیش از ۱۵-ip4tables اجرا می‌شود، چون قانونی که به مجموعه ناموجود ارجاع بدهد بار نمی‌شود.

DEBIAN_FRONTEND=noninteractive apt install -y iptables-persistent ipset-persistent

netfilter-persistent save   # rules.v4 و /etc/iptables/ipsets

# بعد از ریبوت، پایداری را تأیید کنید:
ipset -t list iran_v4 && iptables -S INPUT

فرمان ذخیره را فقط بعد از انقضای تایمر و تأیید دسترسی بزنید. اگر پیش از آن ذخیره کنید، قانون drop در rules.v4 می‌نشیند و تایمر بعداً تنها نسخه حافظه را حذف می‌کند. ناپایدار ماندن قوانین حالت ایمن است: بازگشت دسترسی بعد از ریبوت یعنی ذخیره نشده. ترتیب زنجیره‌ها را در راهنمای پیکربندی پیشرفته iptables ببینید.

اجرای همان سیاست با nftables و firewalld و نگه‌داشتن فهرست

اجرای همان سیاست با nftables و firewalld و نگه‌داشتن فهرست

روی توزیع‌های تازه، nftables جایگزین پیش‌فرض است و خودش named set دارد؛ روی راکی و آلما هم firewalld یک لایه بالاتر می‌دهد. هر دو همان سیاست را برای بستن IP خارجی پیاده می‌کنند، ولی فوراً و دائمی اثر می‌گذارند، پس بازگشت زمان‌دار واجب‌تر است.

پیکربندی nftables با named set

طبق ویکی رسمی nftables، یک named set با نوع ipv4_addr و پرچم interval پیشوند CIDR نگه می‌دارد و با @ صدا زده می‌شود. فایل زیر قوانین را در جدول جداگانه wd_geo می‌گذارد؛ دو سطر اول آن را اعلام و بعد حذف می‌کنند تا اجرای دوباره، جدول تکراری نسازد.

nft list ruleset > /root/nft-backup.conf   # پشتیبان، برای بازگشت
ADMIN_IP=203.0.113.10                     # آدرس نمونه RFC 5737

cat > /etc/nftables-geo.conf <<EOF
table inet wd_geo
delete table inet wd_geo

table inet wd_geo {
    set iran_v4 {
        type ipv4_addr
        flags interval
        elements = { $(paste -sd, /etc/ipset/iran-v4.cidr) }
    }

    chain input {
        type filter hook input priority filter; policy accept;
        iif lo accept
        ct state established,related accept
        tcp dport 22 ip saddr $ADMIN_IP accept
        icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert } accept
        meta nfproto ipv6 drop
        ip saddr != @iran_v4 drop
    }
}
EOF

nft -c -f /etc/nftables-geo.conf   # فقط بررسی نحوی

سوئیچ -c فایل را فقط بررسی می‌کند، پس با خطای نحوی فایروال فعلی دست‌نخورده می‌ماند. دقت کنید فرمان enable –now روی سرویسِ از قبل فعال کاری نمی‌کند و فایل جدید هرگز بار نمی‌شود؛ پس بار کردن را صریح انجام بدهید و نتیجه را تأیید کنید.

systemd-run --on-active=10min --unit=fw-rollback --collect \
  /bin/sh -c 'nft delete table inet wd_geo'
systemctl list-timers 'fw-rollback*'

nft -f /etc/nftables-geo.conf              # بار کردن صریح
nft list set inet wd_geo iran_v4 | head    # تأیید

echo 'include "/etc/nftables-geo.conf"' >> /etc/nftables.conf   # پایداری
systemctl enable nftables

⚠️ از فرمان flush ruleset در این فایل استفاده نکنید

نمونه‌های رایج nftables با سطر flush ruleset شروع می‌شوند. اگر آن سطر در فایلی باشد که هر بوت بار می‌شود، کل ruleset پاک می‌شود، از جمله قوانین docker و fail2ban. به همین دلیل جدول جداگانه ساخته‌ایم؛ اول nft list ruleset را ببینید.

همان کار روی راکی و آلما با firewalld

در صفحه man ابزار firewall-cmd آمده که می‌توانید ipset دائمی بسازید، ورودی‌ها را از فایل بخوانید و همان مجموعه را منبع یک منطقه کنید. منطق برعکس iptables است: منطقه public را فقط به منبع ایرانی می‌دهید و منطقه پیش‌فرض را drop می‌کنید.

firewall-cmd --permanent --new-ipset=iran_v4 --type=hash:net \
  --option=family=inet --option=maxelem=131072
firewall-cmd --permanent --ipset=iran_v4 \
  --add-entries-from-file=/etc/ipset/iran-v4.cidr

firewall-cmd --permanent --zone=public --add-source=203.0.113.10/32
firewall-cmd --permanent --zone=public --add-source=ipset:iran_v4
firewall-cmd --permanent --zone=public --add-service=http --add-service=https
firewall-cmd --reload
firewall-cmd --get-active-zones

systemd-run --on-active=10min --unit=fw-rollback --collect \
  /usr/bin/firewall-cmd --set-default-zone=public
firewall-cmd --set-default-zone=drop   # آخرین قدم

⚠️ دو شرطی که مسیر firewalld را بی‌اثر یا ویرانگر می‌کند

اول، طبق همان صفحه man، فرمان set-default-zone فقط روی اتصال‌ها و اینترفیس‌هایی اثر دارد که منطقه‌شان انتخاب نشده است. اگر کانکشن NetworkManager مقدار connection.zone صریح داشته باشد، این فرمان کاری نمی‌کند و خیال می‌کنید فیلتر فعال است؛ خروجی get-active-zones این را نشان می‌دهد. دوم، منطقه public پیش‌فرض فقط ssh را باز دارد.

به‌روزرسانی خودکار فهرست با جابه‌جایی مجموعه

فهرست را نمی‌شود وسط کار flush کرد، چون در آن فاصله قانون drop همه را می‌اندازد. راه درست، مجموعه موقت و جابه‌جا کردن نام‌ها با فرمان swap است؛ هر دو مجموعه باید موجود و از نوع سازگار باشند. اسکریپت زیر را هفتگی با cron اجرا کنید.

#!/bin/sh
# /usr/local/sbin/cc-update.sh
set -eu
F=$(mktemp); N=$(mktemp)
curl -fsSL -o "$F" https://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest
python3 /usr/local/sbin/cc-cidr.py "$F" IR > "$N"
[ "$(wc -l < "$N")" -ge 1000 ] || { rm -f "$F" "$N"; exit 1; }

# باقی‌مانده اجرای ناتمام قبلی را پاک کن، وگرنه add روی محتوای کهنه جمع می‌شود
ipset destroy iran_v4_new 2>/dev/null || true
{ echo "create iran_v4_new hash:net family inet maxelem 131072"
  sed 's/^/add iran_v4_new /' "$N"; } | ipset restore
ipset swap iran_v4_new iran_v4 && ipset destroy iran_v4_new
install -m 0644 "$N" /etc/ipset/iran-v4.cidr
command -v netfilter-persistent >/dev/null && netfilter-persistent save || true

برای مستثنا کردن خزنده گوگل، مستندات تأیید خزنده‌های گوگل فهرست رنج‌ها را در فایل common-crawlers.json می‌دهد. مقدارهای ipv4Prefix را در مجموعه دومی بریزید و قانون -m set --match-set allow_v4 src -j ACCEPT را پیش از drop بگذارید. برای فیلتر کشوری در سطح وب‌سرور، نصب GeoIP در لینوکس مسیر دیگری است.

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

آیا این قانون باعث افت رتبه سایت در گوگل می‌شود؟

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

در روش HTTP-01 بله، چون طبق RFC 8555 مرجع صدور باید خودش به پورت ۸۰ دامنه وصل شود. روش DNS-01 اعتبارسنجی را روی رکورد DNS انجام می‌دهد و اتصال ورودی نمی‌خواهد. پیش از بستن پورت، روش تمدید را عوض کنید.

آدرس ثابت خودتان را پیش از قانون drop به‌عنوان اجازه صریح بنویسید، یا به مجموعه مجاز اضافه کنید. اگر IP شما ثابت نیست، این سیاست مناسب شما نیست.

فایل آماری RIPE روزانه تازه می‌شود؛ یک به‌روزرسانی هفتگی کافی است. فهرست دست‌نخورده بعد از چند ماه هم رنج‌های تازه داخلی را از دست می‌دهد و هم رنج‌هایی را نگه می‌دارد که دیگر داخلی نیستند.

اگر بازگشت زمان‌دار را قبل از قانون drop تنظیم کرده باشید، سرور خودش بعد از ۱۰ دقیقه قانون را حذف می‌کند. اگر نکرده باشید، تنها راه کنسول یا حالت Rescue پنل ارائه‌دهنده است؛ به همین دلیل یکی از این دو پیش‌نیاز شروع کار است.

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

ترافیک بازدیدکننده از IP لبه‌های CDN می‌رسد که عمدتاً خارجی‌اند و با قانون drop بسته می‌شوند؛ یعنی سایت برای همه از کار می‌افتد. رنج‌های همان سرویس را در مجموعه مجاز بگذارید.

جمع‌بندی؛ بستن IP خارجی یک ابزار باریک است، نه سیاست پیش‌فرض
فهرست رنج‌های کشوری را می‌شود از داده رسمی RIPE ساخت و با ipset یا معادل‌هایش در nftables و firewalld اعمال کرد. ولی ترتیب کار مهم‌تر از خود قانون است: راه ورود مستقل از شبکه، آگاهی از وضعیت فعلی زنجیره، بازگشت زمان‌دارِ تأییدشده، و تنها در پایان قانون drop. سه تله هم هر سه مسیر را بی‌اثر یا ویرانگر می‌کند: باز ماندن IPv6، پاک کردن ruleset موجود با flush، و منطقه پیش‌فرضی که در firewalld روی اینترفیس دارای منطقه صریح اثر ندارد. مهم‌تر از همه، همان سوال عنوان است: این سیاست برای سرویس داخلی و ماشینی که زیر فشار اسکن است جواب می‌دهد، ولی برای وب‌سایت عمومی هزینه‌اش بیشتر از فایده‌اش است. در بیشتر مواردی که با «حمله از خارج» شروع می‌شود، محدود کردن پورت مدیریتی به چند آدرس و نرخ‌گیری روی اتصال‌های جدید همان نتیجه را با ریسک کمتری می‌دهند.

🚀 سرور را روی شبکه داخلی بالا بیاورید

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

اگر سوالی داشتید، در بخش نظرات با ما در ارتباط باشید.

وب داده
وب داده

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

مقاله‌ها: 256
پاسخی بگذارید

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