آموزش امن کردن Nginx با رمزگذاری Let’s Encrypt

نصب let's encrypt و nginx

با نام خدا و سلام، اول از همه اینکه قبلا آموزش نصب Nginx روی بلاگ گذاشته شده، و در مورد بلاک سرورهای Nginx نیز جداگانه بحث شده بود. حالا نیز میخواهیم انجین ایکس نصب شده را secure کنیم. برای این کار از کدگذاری Let’s Encrypt استفاده می کنیم که یک مرجع صدور گواهینامه رایگان و متن باز (open source) هست که توسط گروه تحقیقات امنیتی اینترنت (Internet Security Research Group (ISRG)) ارائه شده است.

گواهینامه های ارائه توسط Let’s Encrypt امروزه تقریبا توسط تمامی مروگرها مورد قبول بوده و پذیرش می شوند.

در این آموزش مرحله به مرحله با شما هستیم تا نشان دهیم چگونه Nginx خودتون رو با Let’s Encrypt و با استفاده از ابزار certbot روی لینوکس اوبونتو امن کنید.

پیش نیاز ها

نصب CertBot

سرت بات یک ابزار کامل و آسان است که می تواند task ها را برای دریافت و تمدید گواهینامه های Let’s Encrypt SSL خودکارسازی کند و وب سرور ها را جهت استفاده از گواهینامه ها کانفیگ کند.

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

sudo apt update
sudo apt install certbot

ایجاد گروه قوی Dh (Diffie-Hellman)

کلید تبادل دیف – هلمن (Diffie–Hellman) با مخفف DH، روشی برای تبادل ایمن کلیدهای رمزنگاری از طریق یک کانال ارتباطی غیر امن می باشد. در اینجا قصد داریم یک مجموعه از پارامترهای 2048 بیتی برای تقویت امنیت تولید کنیم:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

نکته: اگر بخواهید می توانید سایز ۲۰۱۴۸ را به ۴۰۹۶ تغییر دهید، منتهی ممکن است زمان تولید با توسجه به سیستم شما تا حدود ۳۰ دقیقه طول بکشد.

گرفتن یک گواهی Let’s Encrypt SSL 

جهت گرفتن یک گواهی ssl برای دامنه مان ما از پلاگین Webroot استفاده می کنیم که با ساخت یک فایل موقت جهت اعتبارسنجی دامنه درخواست شده، داخل دایرکتوری ${webroot-path}/.well-known/acme-challenge کار می کند. سرور  Let’s Encrypt  درخواست های Http را داخل فایل موقت می کند تا اعتبار سنجی کند که دامنه درخواست شده قصد عزیمت به سمت سروری که Certbot روی آن اجرا شده است را دارد.

برای ساده تر کردن، ما به این می پردازیم که تمامی درخوسات های HTTP برای .well-known/acme-challenge را به یک دایرکتوری جداگانه /var/lib/letsencrypt نگاشت کنیم.

با سه دستور پیش رو، دایرکتوری ساخته شده و آن را برای سرور Nginx قابل نوشتن می کند:

sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp www-data /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt

برای جلوگیری از دونسخه شدن کد (duplicating code)، دو snippets زیر را بسازید که در فایل تمامی بلاک سرور های Nginx به کار خواهیم برد.

پس با دستور زیر ویرایشگر متن خودر ا باز کنید و snippetاول را بسازید:

sudo nano /etc/nginx/snippets/letsencrypt.conf
location ^~ /.well-known/acme-challenge/ {
  allow all;
  root /var/lib/letsencrypt/;
  default_type "text/plain";
  try_files $uri =404;
}

اسنیپت دوم رو با نام ssl.conf بسازید که شامل chippers های پیشنهاد شده از سمت Mozile ، فعال سازی OCSP Stapling، HTTP Strict Transport Security (HSTS) و تعداد کمی از هدرهای HTTP مبتنی برامنیت می باشد.

sudo nano /etc/nginx/snippets/ssl.conf
ssl_dhparam /etc/ssl/certs/dhparam.pem;

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 30s;

add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;

همین که snippetها ایجاد شدند، بلاک سرور دامنه را باز کنید و اسنیپت letsencrypt.conf را مشابه زیر در آن include کنید.

sudo nano /etc/nginx/sites-available/example.com.conf
server {
  listen 80;
  server_name example.com www.example.com;

  include snippets/letsencrypt.conf;
}

جهت فعال سازی فایل بلاک سرور جدید، نیاز داریم که یک سیمبل لینک از فایل به دایرکتوری sites-enabled ایجاد شود که توسط Ngind بهنگام شروع خوانده می شود.

sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/

سرویس Nginxرا ریست کنید تا تغییرات اعمال شود:

sudo systemctl restart nginx

حال می توانید Certbot را پلاگین webroot و گرفتن فایل های گواهینامه SSL اجرا کنید:

sudo certbot certonly --agree-tos --email admin@example.com --webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com

به ایمل در دستور بالا توجه کنید (بدلخواه تغییرش دهید)، اگر گواهینامه به درستی دریافت شود، Certbot پیام زیر را خروجی خواهد داشت:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2018-07-28. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

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

sudo nano /etc/nginx/sites-available/example.com.conf
server {
    listen 80;
    server_name www.example.com example.com;

    include snippets/letsencrypt.conf;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    include snippets/ssl.conf;
    include snippets/letsencrypt.conf;

    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    include snippets/ssl.conf;
    include snippets/letsencrypt.conf;

    # . . . other code
}

با کانفیگ بالا ما اجبار به HTTPSمی کنیم و همچنین از WWW به غیر www ریدایرکت می کنیم.

حال سرویس Nginx را reload کنید:

sudo systemctl reload nginx

جدید سازی خودکار گواهینامه Let’s Encrypt SSL

گواهینامه Let’s Encrypt’s برای مدت ۹۰ روز معتبر می باشد. جهت جدید سازی خودکار گواهینامه قبل از انقضا، پکیج certbot یک cronjob می سازد که دو بار در روز اجرا می شود و هر گواهینامه را ۳۰ روز قبل از منقضی شدنش جدید می کند.

چون از پلاگین webroot از certbot استفاده می کنیم، همینکه سرتیفیکیت جدید شد، ما نیاز داریم تا سرویس nginxرا نیز reload کنیم. دستور –renew-hook “systemctl reload nginx” را به فایل /etc/cron.d/certbot باید اضافه کرد که به شکل زیر خواهد شد:

sudo nano /etc/cron.d/certbot
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload nginx"

برای تست فرآیند جدید سازی، می توانید از سوییچ –dry-run از certbotاستفاده کنید:

sudo certbot renew --dry-run

و تمام …. مراجع :