شبیه سازی عملکرد پوشه App_Data در IIS بر روی لینوکس توسط nginx
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۴/۰۳ ۰۸:۰۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
App_Data در IIS یک ویژگی بسیار کاربردی است که به صورت پیشفرض از محتویات آن در برابر دسترسی مستقیم از طریق وب محافظت میکند. خوشبختانه، شبیهسازی این رفتار و حتی پیادهسازی روشهای امنتر در لینوکس با NGINX بسیار ساده است. دو رویکرد اصلی و استاندارد برای این کار وجود دارد./var/www/my-awesome-app/
├── my-awesome-app.dll # فایل اجرایی اپلیکیشن
├── appsettings.json # فایل تنظیمات
├── ... (فایلهای دیگر برنامه)
│
├── AppData/ # <-- پوشه دادههای محافظت شده شما
│ ├── sensitive-data.xml
│ └── local-database.sqlite
│
└── wwwroot/ # <-- ریشه وب (فقط فایلهای عمومی)
├── css/
├── js/
├── images/
└── index.htmlroot یا ریشه وب را به پوشه wwwroot اشاره میدهید:server {
# ...
root /var/www/my-awesome-app/wwwroot;
# ...
}/var/www/my-awesome-app/wwwroot قرار دارند و به هیچ جای دیگری دسترسی نداری."http://your-domain.com/AppData/sensitive-data.xml دسترسی پیدا کند، NGINX هرگز آن فایل را پیدا نخواهد کرد، چون از نظر فیزیکی در محدوده دسترسی آن نیست. NGINX یک خطای 404 Not Found برمیگرداند. این روش به طور کامل جلوی هرگونه دسترسی وب به این پوشه را میگیرد./var/www/my-awesome-app/ اجرا میشود، به راحتی میتواند با استفاده از مسیرهای نسبی (./AppData/sensitive-data.xml) یا مسیرهای مطلق، به این پوشه دسترسی داشته باشد، فایل بخواند یا در آن بنویسد.App_Data را شبیهسازی میکند. در این حالت، شما پوشه دادهها را داخل ریشه وب قرار میدهید، اما با یک قانون صریح در NGINX، جلوی دسترسی به آن را میگیرید./var/www/my-awesome-app/wwwroot/
├── css/
├── js/
├── images/
├── index.html
│
└── AppData/ # <-- پوشه دادهها داخل ریشه وب
├── sensitive-data.xml
└── local-database.sqlitelocation ویژه به فایل کانفیگ NGINX خود اضافه میکنید تا تمام درخواستها به این پوشه را مسدود کند.server {
root /var/www/my-awesome-app/wwwroot;
index index.html index.htm;
server_name your-domain.com;
# ... سایر تنظیمات
# قانون کلیدی برای محافظت از پوشه AppData
location ~ ^/AppData/ {
# تمام دسترسیها را مسدود کن
deny all;
# بازگرداندن خطای 404 بهتر از 403 (Forbidden) است
# چون حتی وجود داشتن چنین پوشهای را هم از مهاجم مخفی میکند.
return 404;
}
location / {
try_files $uri @proxy; # ارسال سایر درخواستها به اپلیکیشن
}
# ...
}location ~ ^/AppData/: این دستور به NGINX میگوید: "یک قانون ویژه برای تمام آدرسهایی که با /AppData/ شروع میشوند، در نظر بگیر." (علامت ~ برای تطبیق با عبارات باقاعده و ^ برای مشخص کردن ابتدای مسیر است).deny all;: این دستور صریحاً به NGINX میگوید که دسترسی به این مسیر را برای همه مسدود کند.return 404;: این دستور باعث میشود که NGINX به جای خطای پیشفرض 403 Forbidden، خطای 404 Not Found را به کاربر نمایش دهد. این یک مزیت امنیتی کوچک دارد، زیرا به یک مهاجم بالقوه حتی اطلاع نمیدهد که چنین پوشهای وجود دارد.| ویژگی | روش ۱ (جداسازی فیزیکی) | روش ۲ (قانون NGINX) |
| امنیت | بسیار بالا (ذاتی و ساختاری) | بالا (وابسته به صحت کانفیگ) |
| پیچیدگی | کم (فقط نیاز به رعایت ساختار پوشه) | کم (فقط نیاز به افزودن چند خط کانفیگ) |
| شباهت به IIS | کم | زیاد (شبیهسازی دقیق رفتار App_Data) |
| توصیه | پیشنهاد اصلی برای پروژههای جدید | جایگزین خوب، خصوصاً برای انتقال پروژههای موجود |
App_Data را داخل ریشه وب دارد، روش دوم (قانون NGINX) یک راه حل سریع، مؤثر و کاملاً قابل قبول است..cs, .sln)، پایگاه داده (.sqlite, .db)، فایلهای باینری برنامه (.dll, .exe) و پوشه سورس کنترل شما (.git) دقیقاً مانند انبار و اتاق گاوصندوق شما هستند. به صورت پیشفرض، اگر این فایلها به نحوی داخل پوشه عمومی شما قرار گیرند، ممکن است یک کاربر بتواند با وارد کردن آدرس مستقیم، آنها را دانلود کند. این یک فاجعه امنیتی است. در ادامه یاد میگیریم چگونه با استفاده از قوانین قدرتمند NGINX، درب این مکانهای حساس را برای همیشه قفل کنیم.location با استفاده از عبارات باقاعده (Regular Expression یا Regex).server در فایل کانفیگ سایت خود قرار دهید.# این بلوک باید داخل بلوک server شما قرار گیرد
# ===================================================================
# قانون امنیتی: مسدود کردن دسترسی مستقیم به پسوندهای حساس و خطرناک
# ===================================================================
location ~* \.(git|sqlite|exe|dll|db|config|log|sln|cs|csproj|user|json)$ {
# تمام دسترسیها را مسدود کن
deny all;
# رویکرد بهتر: بازگرداندن خطای 404 به جای 403 (Forbidden)
# این کار حتی وجود داشتن چنین فایلی را هم از مهاجم مخفی میکند.
# return 404;
}location ~*: این به NGINX میگوید که یک قانون مبتنی بر "عبارت باقاعده" (~) و "بدون حساسیت به بزرگی و کوچکی حروف" (*) را اعمال کند. یعنی .DLL و .dll هر دو مسدود میشوند.\.: علامت \ (بکاسلش) کاراکتر بعدی را "بیاثر" میکند. از آنجایی که . (نقطه) در عبارات باقاعده معنای خاصی ("هر کاراکتری") دارد، ما با \. میگوییم که منظورمان دقیقاً خود کاراکتر "نقطه" است.(git|sqlite|...|json): پرانتزها یک گروه ایجاد میکنند و علامت | (پایپ) به معنای "یا" (OR) است. پس این بخش یعنی: "پسوند git یا sqlite یا exe یا ...". شما میتوانید هر پسوند دیگری را به این لیست اضافه کنید.$: این علامت در عبارات باقاعده به معنای "انتهای رشته" است. این بخش بسیار مهم است و تضمین میکند که قانون فقط برای فایلهایی اعمال شود که نامشان با این پسوندها تمام میشود.deny all در مقابل return 404:deny all;: به کاربر خطای 403 Forbidden را نشان میدهد. این تنظیم به مهاجم میگوید "این فایل وجود دارد، اما تو اجازه دسترسی به آن را نداری."return 404;: به کاربر خطای 404 Not Found را نشان میدهد. این به مهاجم میگوید "چنین فایلی اصلاً وجود ندارد." این رویکرد کمی امنتر است، زیرا اطلاعات کمتری در مورد ساختار فایلهای شما به بیرون درز میدهد (این یک شکل از امنیت از طریق پنهانکاری یا Security through Obscurity است)..git, .env, .htaccess) به صورت پیشفرض "مخفی" هستند و معمولاً حاوی تنظیمات حساس یا اطلاعات محرمانه میباشند. ما باید دسترسی به تمام آنها را از طریق وب مسدود کنیم.location دیگر با یک عبارت باقاعده ساده.server خود قرار دهید.# ===================================================================
# قانون امنیتی: مسدود کردن دسترسی به فایلها و پوشههایی که با نقطه شروع میشوند
# ===================================================================
location ~ /\. {
deny all;
# return 404;
}location ~: باز هم یک قانون مبتنی بر عبارت باقاعده./\.: این عبارت ساده و قدرتمند به دنبال هر الگویی میگردد که شامل یک / و بلافاصله پس از آن یک . باشد. این قانون به طور مؤثری تمام فایلها و پوشههای مخفی در تمام سطوح را پوشش میدهد. برای مثال، هم درخواست http://domain.com/.env و هم http://domain.com/sub/folder/.htaccess توسط این قانون مسدود خواهد شد.location باید داخل بلوک server اصلی شما و در کنار سایر بلوکها قرار گیرند. NGINX به اندازه کافی هوشمند است که قبل از اعمال قوانین عمومی (مانند location /)، ابتدا این قوانین خاصتر را بررسی کند.server {
listen 80;
server_name your-domain.com;
root /var/www/my-app/wwwroot;
# >> قانون اول: مسدودسازی فایلهای مخفی
location ~ /\. {
return 404;
}
# >> قانون دوم: مسدودسازی پسوندهای حساس
location ~* \.(git|sqlite|exe|dll|db|config|log)$ {
return 404;
}
# قانون اصلی برای اپلیکیشن شما
location / {
try_files $uri @proxy;
}
# ... سایر تنظیمات و location پراکسی
}