پیکربندی nginx Load balancing

پیکربندی nginx به عنوان load balancer

 

در این آموزش قصد داریم تا پیکربندی nginx  را به عنوان لود بالانسر جهت ایچاد توازن بین درخواست های  وب و به همراه فعال سازی گواهینامه  SSL  مورد بررسی قرار دهیم.

نیازمندی ها:

برای انجام این سناریو چهار سرور به صورت زیر مورد نیاز می باشد.

Server1: load balancer

Server2: web server 1

Server3: web server 2

Server4: web server 3

در این سناریو فرض بر این است که nginx بر روی سرور 1 و httpd بر روی سه سرور دیگر نصب شده است.

ایجاد گواهینامه SSL:

از آنجا که اطالاعات HTTP به صورت متن ساده یا به عبارتی فنی تر Clear Text تبادل می شوند، امکان شنود اطلاعات تبادلی خصوصا اطلاعات مهمی مانند نام کاربری و رمز عبور مورد استفاده در آنها نیز فراهم خواهد بود. بدین منظور از گواهینامه SSL یا پروتکل HTTPS که اطلاعات را به صورت رمز نگاری شده تبادل میکند استفاده می کنیم. توجه داشته باشید که حتما در محیط های عملیاتی از گواهینامه SSL جهت افزایش سطح ایمینی برنامه های خود استفاده نمایید. در صورتی که با این گواهینامه آشنا نیستید، میتوانید جهت کسب اطلاعات بیشتر در خصوص این پروتکل TLS میتوانید به این صفحه رجوع کنید

در این آموزش جهت ساده سازی آموزش و دوری از موارد مرتبط به ایجاد گواهینامه معتبر، ما از گواهینامه self-signed استفاده خواهیم کرد. ایجاد گواهینامه self-singed با استفاده از دستور openssl انجام خواهد شد.

ترتیب ایجاد این گواهینامه نیز به صورت زیر خواهد بود.

•	sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/myapp.key -out /etc/ssl/certs/myapp.crt

که در دستور بالا:

  • openssl: دستوری اصلی است است برای ایجاد گواهینامه، کلید ها و فایل های مربوط به آن
  • req: با مقدار –x509 عنوان میکند که قصد داریم از استاندارد x509 برای درخواست و ایجاد گواهینامه جدید استفاده کنیم. استاندارد x509 ساختاری استاندارد برای ایجاد کلید عمومی است که SSL و TLS از آن استفاده میکنند.
  •  -nodes:  مشخص میکند که قصد نداریم تا بر روی گواهینامه خود رمزی قرار دهیم. علت آن این است که nginx  میبایست بتواند به گواهینامه دسترسی داشته باشد در غیر این صورت میبایست رمز را در فایلی به سرویس معرفی نمائیم تا در هر بار راه اندازی مجدد سرویس جهت باز نمودن گواهینامه از آن استفاده کند که با از بین رفتن این رمز یا عدم دسترسی پروسس nginx  به این فایل به هر دلیلی پروسه مربوطه قادر به اتمام فرایند راه اندازی خود را نخواهد داشت.
  • -day:  بیانگر تعداد روز هایی است که قصد داریم گواهینامه برای آن مدت معتبر باشد. که در اینجا ما با قرار دادن عدد 365 عملا گواهینامه ای با طول عمر یک سال ایجاد خواهیم کرد.
  • -newkey: با مقدار rsa:2048 بیانگر این خواهد بود که قصد داریم گواهینامه و کلید آن را همزمان و در همین دستور و با استفاده از مکانیزم RSA با طول 2048 بیت ایجاد کنیم.
  • -keyout: بیانگر مسیر ذخیره سازی کلدی خصوصی است که ایجاد خواهد شد.
  • -out:  بیانگر محل ذخیره سازی گواهینامه می باشد.

با ورود دستور بالا سوالاتی از ما پرسیده خواهد شد  که مهترین آن سوالات Common Name (e.g. server FQDN or YOUR name) خواهد بود که میبایست نام دامنه یا آدرس سرور را در آن وارد کرد.

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

openssl dhparam -out /etc/nginx/dhparam.pem 4096

پیکربندی nginx جهت استفاده از ssl

بعد از ایجاد گواهینامه، نیاز است تا nginx به گونه ای پیکربندی شود تا از Ssl استفاده کند.

در ابتدا  فایل هایی را ایجاد میکنیم که به کلید SSL و فایل گواهینامه اشاره میکند. برای این کار دایکتوری ای به نام snippets در مسیر /etc/nginx ایجاد میکنیم.

mkdir /etc/nginx/snippet

سپس فایلی با نام self-signed.conf در این مسیر ایجاد میکنیم.

vim /etc/nginx/snippets/self-signed.conf

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

ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1; 
ssl_session_timeout  10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; 
ssl_stapling on; 
ssl_stapling_verify on; 
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

از آنجا که ما از گواهینامه Self-signed  استفاده میکنیم، پارامتر های Stapling استفاده نخواهد شد و nginx  پیامی warning  برای این موضوع ایجاد خواهد کرد. ولی در صورتی که از certificate  ارائه شده از سازمان های معتبر استفاده میکنید این پارامترها استفاده خواهند شد.

بعد از ذخیره سازی این تنظیمات، به سراغ فایل پیکربندی nginx میرویم

vim  /etc/nginx/nginx.conf

معرفی Upstream

درون بلاک http در ابتدا سرور هایی که قصد داریم بار بین آنها توزیع شود را معرفی کنیم. این سرور ها به عنوان upstream معرفی میشوند.

upstream Backend {
    server 192.168.163.44;
    server 192.168.163.45;
    server 192.168.163.46;
}

جهت هدایت کلیه درخواست های http به https می بایست دو بلاک سرور ایجاد نماییم. یکی برای http  که در آن به https ریدایرکت انجام شود و دومی برای https . درون هر  بلاک server،  مقادیر را به شکل زیر تغییر می دهیم.

server {
         listen 80 default_server;
         listen [::]:80 default_server;
         rewrite ^ https://$host$uri last;
}
server  {
        listen 443 ssl;
        include snippets/myapp.conf;
        include snippets/ssl-params.conf;
        server_name maaleki.ir;
        ssl on;
        location / {
        proxy_pass http://Backend ;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
}
}

از پارامتر های proxy-set-header برای ارسال اطلاعات مهم به سرور های upstream استفاده می شود.

بعد از ذخیره کردن این تغییرات با دستور فایل پیکربندی را تست میکنیم تا در صورت وجود خطایی در آن به ما نمایش دهد. دستور زیر تنها فایل پیکربندی را بدون راه اندازی سرویس تست میکند.

nginx –t

در خروجی دستور قبل همانطور که گفته شد برای پارامتر ssl_stapling پیام هشداری ایجاد میشود که علت آن استفاده از گواهینامه Self-singed است و قابل چشم پوشی میباشد.

در نهایت سرویس nginx را جهت اعمال تغییرات مجددا راه اندازی میکنیم.

systemctl restart nginx

حال که سرور لود بالانسر پیکربندی شده است میتوان بر روی سرور های web کد php زیر را در مسیر /var/www/html/test.php وارد نماییم.

<?php
    header( 'Content-Type: text/plain' );
    echo 'Host: ' . $_SERVER['HTTP_HOST'] . "\n";
    echo 'Remote Address: ' . $_SERVER['REMOTE_ADDR'] . "\n";
    echo 'X-Forwarded-For: ' . $_SERVER['HTTP_X_FORWARDED_FOR'] . "\n";
    echo 'X-Forwarded-Proto: ' . $_SERVER['HTTP_X_FORWARDED_PROTO'] . "\n";
    echo 'Server Address: ' . $_SERVER['SERVER_ADDR'] . "\n";
    echo 'Server Port: ' . $_SERVER['SERVER_PORT'] . "\n\n";
?>

دستور بالا آدرس سرور لود بالانسر، سروری که درخواست را پاسخ داده است و آدرس کلاینت، پروتکل و پورت سرور را نمایش خواهد داد. با هر بار فراخوانی دستور زیر و با توجه به پیکربندی انجام شده خواهید دید که آدرس مقابل Server Address تغییر خواهد کرد.

Curl maaleki.ir/test.php

نکات مهم:

امنیت:

  1. جهت ایجاد امنیت بیشتر بر روی سرور های خود بهتر است رول های مربوط به firewall را نیز تنظیم کنید. بدین منظور ارتباط از طریق http و https به شبکه خارج برای لود بالانسر باید فراهم شود. و در سرور های upstream دسترسی به سرور از روی پورت http تنها به آدرس های مطمئن باز باشد. یکی از این آدرس های ممطمون می بایست آدرس سرور لود بالانسر باشد.

متد های لودبالانسینگ:

  1. متد پیش فرض در توزیع بار در nginx متد round robin می باشدو درخواست ها به ترتیب به سرور های تعریف شده در upstream ارسال خواهد شد. برای تغیر متد توزیع بار می بایست بلاک upstream  به صورت زیر تغییر کند.
upstream Backend{
     least_con;
        server 192.168.163.44;
        server 192.168.163.45;
        server 192.168.163.46;
}

که در این مثال متد بر اساس کمترین کانکشن جاری به سرور تنظیم خواهد شد.

سایر متدها به شرح زیر می باشند.

  • Hash: در هر درخواست لود بالانسر هشی را محاسبه می کند که ترکیبی از متن و پارامتر هایی از nginx است که شما انتخاب میکنید و آن را به یکی از سرور ها اختصاص می دهد. از این پس هر درخواستی با این هش محاسبه شده به سروری که انتخاب شده است ارسال می شود.به عنوان نمونه در زیر نمونه ای از هش که بر اساس Scheme(http or https) و url  درخواست شده hash را ایجاد میکند.
    shash $scheme$requset_url;
  • IP Hash: فقط برای http در دسترس است و بر اساس IP کلاینت hash را ایجاد میکند. در این روش اگر IP کلاینت IPv6 باشد بر اساس کل IP آدرس و در صورتی که IPv4 باشد بر اساس سه octed اول آدرس کاربر hash  اتفاق می افتد. در صورتی که کاربرانی که قصد اتصال به سرور را دارند از یک شبکه (مثلا /24) باشند این روش روش مناسبی نخواهد بود چرا که کلیه درخواست ها به سمت یک سرور هدایت خواهند شد.
hash $remote_addr;
  • leas connections: در این متد لود بالانسر تعداد کانکشن های فعال به هر سرور را محاسبه می کند و درخواست را به سمت سروری ارسال می نماید که کمترین کانکشن فعال به آن برقرار است.
  • Least time: این متد فقط در ورژن nginx plus که ورژن پولی و سازمانی nginx است فعال است و براساس دو فاکتور که عبارتند از تعداد کانکشن ها فعال سرور میانگین زمان پاسخ دهی سرور ها به درخواست های اخیر است، تصمیم میگیرد درخواست را به سروری ارسال کند که بار کمتری دارد.
حامد
اشتراک دانش رو دوست دارم برای همین سعی میکنم مطالب آموزشی ای تهیه شده دارای جزئیات خوب و به صورت کامل تهیه بشوند.استفاده از مطالب این سایت در هر جایی بلا مانع می باشد. اما ذکر منبع رفتاری حرفه ای و اخلاقی خواهد بود. من را از نظرات خود مطلع سازید. و اگر میخواهید در مورد من بیشتر بدانید سری به صفحه "در باره من" بزنید.