امنیت لایه انتقال (TLS) و متعاقب آن، SSL که مخفف عبارت «لایه سوکت‌های امن» است، هر دو پروتکل‌های وبی هستند که برای محافظت و رمزنگاری ترافیک در بستر یک شبکه کامپیوتری مورد استفاده قرار می‌گیرند. سرورها با کمک TLS/SSL می‌توانند بدون اینکه تفسیر اطلاعات برای یک طرف ثالث ممکن باشد، ترافیک را با کلاینت‌ها رد و بدل کنند. همچنین سیستم‌های گواهی به کاربران در تشخیص هویت وب‌سایت‌ها کمک می‌کنند. در این آموزش، به نحوه تنظیم یک گواهی خودامضایی SSL با وب سرور Nginx در سرور اوبونتو 20.04 خواهیم پرداخت. با ما همراه باشید.

نکته:

یک گواهی خودامضایی باعث رمزنگاری ارتباط بین سرور و تمام کلاینت‌ها می‌شود. با این وجود، با توجه به اینکه اعتبار آن از مراجع گواهی مرورگرهای وب تأیید نشده، کاربران نمی‌توانند برای آن برای تأیید هویت خودکار سرور شما استفاده کنند.

استفاده از گواهی خودامضایی زمانی مناسب است که یک عنوان دامین همراه با سرور خود نداشته باشید. به عنوان مثال، شرایطی را درنظر بگیرید که رابط کاربری رمزنگاری‌شده در معرض تماس کاربران قرار نداتشه باشد. در صورتی که عنوان دامین داشته باشید، در بسیاری از موارد بهتر است که از گواهی CA استفاده کنید. چنین کاری به راحتی از طریق پروژه رایگان Let’s Encrypt ممکن است.

پیش‌نیازها

پیش از اینکه کار خود را در این آموزش آغاز کنید، باید یک کاربر غیر روت با دسترسی‌های sudo و همین‌طور یک فایروال فعال داشته باشید. لازمه این موارد تنظیمات اولیه سرور اوبونتو 20.04 است.

همچنین باید وب‌سرور Nginx را نصب کنید.

گام ۱) ایجاد گواهی SSL

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

ایجاد یک کلید و گواهی خودامضایی با استفاده از OpenSSL در یک فرمان به صورت زیر انجام می‌گیرد.


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

در اینجا مفهوم بخش‌های مختلف این فرمان را مرور می‌کنیم.

  • sudo: فرمان sudo به کاربران گروه sudo این امکان را می‌دهد که سطح دسترسی خود را به صورت موقتی ارتقا دهند. استفاده از sudo در اینجا از این جهت ضروری است که ساخت گواهی و جفت کلیدها در دایرکتوری sudo صورت می‌گیرد و این مسیر تنها توسط کاربر روت یا هر کاربر هم‌سطح دیگر قابل‌دسترسی است.
  • openssl: ابزار خط فرمان پایه برای ایجاد و مدیریت گواهی‌ها، کلیدها و سایر فایل‌های OpenSSL.
  • req: این زیرفرمان مشخص می‌کند که از CSR یا سیستم مدیریت درخواست گواهی 509 استفاده شود. X.509 یک استاندارد زیرساخت کلید عمومی است که SSL و TLS برای مدیریت کلیدها و گواهی به کار می‌برند. در اینجا می‌خواهیم که یک گواهی X.509 جدید بسازیم و بنابراین از این «زیرفرمان» استفاده می‌کنیم.
  • nodes: این بخش به OpenSSL می‌گوید که از این گزینه رمزنگاری با یک «عبارت پسورد» گذر کند. Nginx باید بتواند این فایل را بدون دخالت کاربر بخواند. «عبارت پسورد» مانع از انجام این کار شده و موجب می‌شود که پس از هر بار راه‌اندازی دوباره سرور، نیاز به ورود این عبارت باشد.
  • days 365: این گزینه بازه زمانی اعتبار گواهی را مشخص می‌کند. در اینجا آن را به مدت یک سال تنظیم می‌کنیم.
  • newkey rsa:2048: در اینجا مشخص می‌کنیم که می‌خواهیم یک گواهی و همین‌طور، یک کلید به صورت همزمان ایجاد کنیم. بخش rsa:2048 مشخص می کند که قرار است یک کلید RSA با طول 2048 بیت ساخته شود.
  • keyout: این گزینه برای OpenSSL محل قرارگیری فایل کلید اختصاصی تولیدی را مشخص می‌کند.
  • out: این گزینه برای مشخص‌کردن محل گواهی ساخته‌شده استفاده می‌شود.

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

بر این اساس، موارد خواسته‌شده را به‌درستی وارد کنید. مهمترین مورد درخواست Common Name (مثلاً سرور FQDN یا نام شخصی) است. در اینجا باید عنوان دامین مرتبط با سرور و یا آدرس IP عمومی سرور را وارد کنید.

شکل کامل اطلاعات درخواستی به صورت زیر خواهد بود.


Country Name (2 letter code) [AU]:US

State or Province Name (full name) [Some-State]:New York

Locality Name (eg, city) []:New York City

Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc.

Organizational Unit Name (eg, section) []:Ministry of Water Slides

Common Name (e.g. server FQDN or YOUR name) []:server_IP_address

Email Address []:admin@your_domain.com

هر دو فایلی که ایجاد کرده‌اید، در ساب‌دایرکتوری‌های مناسب در مسیر /etc/ssl قرار می‌گیرند.

در هنگام کار با OpenSSL می‌بایست یک گروه قدرتمند Diffie-Hellman یا DH ایجاد کنید. این گروه برای رویکرد امنیتی ارتباطی موسوم به «محرمانگی پیشرو» با کلاینت‌ها کاربرد خواهد داشت.

چنین کاری را می‌توانید با تایپ فرمان زیر انجام دهید.


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

این کار اندکی زمان احتیاج دارد. ولی پس از انجام آن، یک گروه قدرتمند DH در مسیر /etc/nginx/dhparam.pem خواهید داشت که در ‌ فرآیند تنظیمات مورد استفاده قرار خواهد گرفت.

گام ۲) تنظیم Nginx برای استفاده از SSL

اکنون با ساخت کلیدها و گواهی در دایرکتوری /etc/ssl، نوبت به تنظیم Nginx برای استفاده از آنها رسیده است.

ابتدا بخشی از تنظیمات را که حاوی اطلاعاتی در مورد موقعیت کلید SSL و فایل گواهی است، ایجاد می‌کنید. سپس نوبت به تنظیمات سطح بالای SSL است که توسط هر گواهی دیگری در آینده استفاده خواهد شد. نهایتاً تنظیمات بلوک‌های سرور Nginx را به گونه‌ای انجام می‌دهیم که بتواند از این دو نوع تنظیمات به‌شکلی مناسب در درخواست‌های SSL استفاده نماید.

این روش از تنظیم Nginx به شما اجازه می‌دهد که بلوک‌های سرور منظمی در اختیار داشته باشید و همین‌طور بخش‌های کاربردی‌تر تنظیمات را در ماژول‌هایی که قابلیت بازیابی دارند، قرار دهید.

ایجاد بخش تنظیمات مرتبط با کلید و گواهی SSL

ابتدا از ویرایشگر متنی دلخواه برای ایجاد فایل تنظیمات بخشی Nginx در دایرکتوری /etc/nginx/snippets استفاده کنید. در مثال زیر از ویرایشگر nano استفاده شده است.

برای اینکه هدف اصلی این فایل به‌درستی مشخص شود، از عنوان self-signed.conf استفاده می‌کنیم.


sudo nano /etc/nginx/snippets/self-signed.conf

در این فایل باید پارامتر ssl_certificate را برای فایل گواهی و پارامتر ssl_certificate_key را به کلید مطابق با آن تنظیم کنیم. چنین کاری به صورت زیر خواهد بود.


ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;

ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

وقتی این خطوط را اضافه کردید، فایل را ذخیره کنید واز ویرایشگر خارج شوید. در صورتی از nano برای این منظور استفاده می‌کنید، می‌توانید ابتدا کلیدهای CTRL + X، Y و در انتها Enter بزنید.

ایجاد تنظیمات بخشی با سطح بالای رمزنگاری

حالا نوبت تنظیمات بخشی دیگری که حاوی برخی تنظیمات SSL است، می رسد. این تنظیمات  حاوی برخی ویژگی‌های پیشرفته برای حفظ امنیت سرور شما هستند.

پارامترهایی که در اینجا تنظیم می‌کنید می‌توانند در آینده مجدداً در تنظیمات Nginx مورد استفاده قرار گیرند. بنابراین می‌توانید یک عنوان پایه برای فایل انتخاب کنید.


sudo nano /etc/nginx/snippets/ssl-params.conf

برای تنظیمات امن SSL در Nginx از توصیه‌های Cipherlist.eu استفاده می‌کنیم. Cipherlist.eu یک منبع مفید و قابل‌اتکا برای درک تنظیمات رمزنگاری برای این نرم‌افزار محبوب است.

نکته:

این تنظیمات پیشنهادی Cipherlist.eu امنیت بسیار بالایی را ایجاد می‌کنند. گاهی اوقات این تنظیمات موجب هزینه‌های بالای تطبیق‌پذیری در کلاینت‌ها می‌شود. در صورتی که بخواهید از کلاینت‌های قدیمی‌تر پشتیبانی کنید، می‌توانید با کلیک بر روی لینک “Yes, give me a ciphersuite that works with legacy / old software.” از لیست جایگزین استفاده نمایید. در صورت تمایل، می‌توانید محتویات لیست در بلوک کدی که در ادامه می‌آید، جایگزین کنید.

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

برای این منظور، می‌توانید تمام تنظیمات موردنظرتان را کپی کنید. ولی در ابتدا لازم است که برخی اصلاحات را انجام دهید.

ابتدا DNS resolver دلخواه خود را برای درخواست‌های آپ‌استریم اضافه کنید. برای این منظور از گوگل  با آدرس‌های 8.8.8.8 و 8.8.4.4 استفاده خواهیم کرد.

سپس خطی را که حاوی تنظیمات سخت امنیت انتقال است، از حالت کامنت خارج کنید. البته قبل از اینکه این کار را انجام دهید، باید اندکی وقت بگذارید و در مورد HTTP Strict Transport Security یا HSTS و به خصوص عملکرد پیش‌بارگذاری یا “preload” مطالعه کنید. پیش‌بارگذاری HSTS موجب افزایش امنیت می‌شود، امّا در عین حال با فعال‌سازی یا غیرفعال‌سازی نامناسب، می‌تواند برخی پیامدهای منفی را نیز داشته باشد.

موارد زیر را به فایل ssl-params.conf اضافه کنید.


ssl_protocols TLSv1.3;

ssl_prefer_server_ciphers on;

ssl_dhparam /etc/nginx/dhparam.pem;

ssl_ciphers EECDH+AESGCM:EDH+AESGCM;

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;

# Disable strict transport security for now. You can uncomment the following

# line if you understand the implications.

#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";

add_header X-Frame-Options DENY;

add_header X-Content-Type-Options nosniff;

add_header X-XSS-Protection "1; mode=block";

به دلیل اینکه از گواهی خودامضایی استفاده می‌کنید، ویژگی موسوم به SSL stapling کارآیی نخواهد داشت. Nginx یک خروجی هشدار نشان داده و ویژگی stapling را برای گواهی خودامضایی غیرفعال می‌کند. Nginx سپس به عملکرد خود ادامه می‌دهد.

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

اصلاح تنظیمات Nginx برای استفاده از SSL

با داشتن فایل‌های تنظیمات بخشی، اکنون می‌توانید تنظیمات Nginx را برای فعالسازی SSL انجام دهید.

در این ‌آموزش فرض می‌شود که شما از یک فایل سفارشی تنظیم بلوک سرور در دایرکتوری /etc/nginx/sites-available استفاده می‌کنید. همچنین از تنظیما پیش‌فرض و آدرس /etc/nginx/sites-available/your_domain برای این منظور استفاده شده است. در عین حال، می‌توانید عنوان فایل‌های مدنظر خودتان را نیز جایگزین کنید.

قبل از اینکه جلوتر برویم، از فایل تنظیمات کنونی پشتیبان‌گیری می‌کنیم.


sudo cp /etc/nginx/sites-available/your_domain /etc/nginx/sites-available/your_domain.bak

حالا فیال تنظیمات را به منظور انجام اصلاحات باز می‌کنیم.


sudo nano /etc/nginx/sites-available/your_domain

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


server {

listen 80;

listen [::]:80;

root /var/www/your_domain/html;

index index.html index.htm index.nginx-debian.html;

server_name your_domain www.your_domain;

location / {

try_files $uri $uri/ =404;

}

}

ممکن است فایل شما را دارای یک ترتیب متفاوت باشد و به جای پارامترهای root و index با عبارت‌هایی مانند location و proxy_pass سر و کار داشته باشید. امّا مشکلی در این زمینه برایتان وجود نخواهد داشت. چرا که تنها نیاز به بروزرسانی پارامترهای listen و وارد کردن بخش‌های SSL دارید. بلوک سرور را برای دریافت ترافیک SSL در پورت 443 تنظیم کنید و همچنین یک بلوک سرور جدید برای واکنش به ورودی پورت 80  و هدایت خودکار آن به پورت 443 ایجاد نمایید.

نکته: تا مطمئن شدن از عملکرد صحیح تمام اجزا، از 302 redirect استفاده کنید. پس از کسب اطمینان لازم، آ‌ن را به صورت همیشگی به 301 redirect تغییر دهید.

در فایل تنظیمات کنونی، دو عبارت listen را برای استفاده از پورت 443 و SSL بروزرسانی کرده و سپس دو فایل تنظیمات بخشی مراحل قبل را وارد کنید.


server {

listen 443 ssl;

listen [::]:443 ssl;

include snippets/self-signed.conf;

include snippets/ssl-params.conf;

root /var/www/your_domain/html;

index index.html index.htm index.nginx-debian.html;

server_name your_domain.com www.your_domain.com;

location / {

try_files $uri $uri/ =404;

}

}

سپس بلوک دوم server را پس از علامت (}) در انتهای بلوک قبلی اضافه کنید.


server {

listen 80;

listen [::]:80;

server_name your_domain.com www.your_domain.com;

return 302 https://$server_name$request_uri;

}

این یک تنظیمات مختصر برای دریافت ورودی پورت 80 و هدایت آن به HTTPS خواهد بود. پس از انجام ویرایش، این فایل را ابتدا ذخیره و سپس ببندید.

گام ۳) ویرایش فایروال

در صورتی که فایروال ufw برایتان فعال باشد، باید آن را برای ترافیک SSL تنظیم کنید. خوشبختانه Nginx چند پروفایل مرتبط با ufw را ثبت کرده است.

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


sudo ufw app list

در نتیجه لیستی به مانند زیر نمایش داده می‌شود.


Available applications:

Nginx Full

Nginx HTTP

Nginx HTTPS

OpenSSH

همچنین می‌توانید با تایپ فرمان زیر وضعیت تنظیمات کنونی را ببینید.


sudo ufw status

احتمالاً با پاسخ زیر روبرو می‌شوید. بدان معنا که تنها ترافیک HTTP برای وب‌سرور مجوّز دارد.


Status: active

To                         Action      From

--                         ------      ----

OpenSSH                    ALLOW       Anywhere

Nginx HTTP                 ALLOW       Anywhere

OpenSSH (v6)               ALLOW       Anywhere (v6)

Nginx HTTP (v6)            ALLOW       Anywhere (v6)

برای اعطای مجوّز به ترافیک HTTPS، می‌تونید مجوّزها را برای پروفایل “Nginx Full” بروزرسانی کنید. سپس باید پروفایل اضافی “Nginx HTTP” را حذف کنید.


sudo ufw allow 'Nginx Full'

sudo ufw delete allow 'Nginx HTTP'

پس از اجرای فرمان sudo ufw status می بایست خروجی زیر را مشاهده کنید.


Status: active

To                         Action      From

--                         ------      ----

OpenSSH                    ALLOW       Anywhere

Nginx Full                 ALLOW       Anywhere

OpenSSH (v6)               ALLOW       Anywhere (v6)

Nginx Full (v6)            ALLOW       Anywhere (v6)

این خروجی تأیید می‌کند که تغییرات در فایروال با موفقیت انجام گرفته‌اند و می‌توانید آنها را در Nginx فعال کنید.

گام ۴) فعالسازی تغییرات در Nginx

با تکمیل تغییرات و اصلاحات در فایروال، نوبت به راه‌اندازی دوباره Nginx می‌رسد تا تغییرات جدید اِ‌عمال شوند.

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


sudo nginx -t

اگر همه‌چیز با موفقیت انجام گرفته باشد، با نتیجه زیر روبرو خواهید شد.

خروجی


nginx: [warn] "ssl_stapling" ignored, issuer certificate not found for certificate "/etc/ssl/certs/nginx-selfsigned.crt"

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is successful

اگر به خاطر داشته باشید، قبلاً به هشدار ابتدایی این نتیجه اشاره کردیم.  این هشدار به این دلیل است که گواهی خودامضایی شما نمی‌تواند از قابلیت SSL stapling استفاده کند. این هشدار مطابق انتظار است و سرور شما همچنان می‌تواند ارتباطات را به شکل مناسب رمز نگاری کند.

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


sudo systemctl restart nginx

بعد از این مرحله، نوبت به تست اقدامات صورت‌گرفته می‌رسد.

گام ۵) تست رمزنگاری

اکنون برای تست سرور SSL آماده خواهید بود.

مرورگر وب خود را باز کنید و پس از https:// آدرس دامین یا IP سرور خود را تایپ نمایید.


https://server_domain_or_IP

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

هشدار گواهی خودامضایی Nginx

هشدار گواهی خودامضایی Nginx

این هشدار قابل‌انتظار و طبیعی است. تنها به جنبه رمزنگاری گواهی احتیاج داریم و نیازی به تأیید طرف ثالث نیست.  بر روی “ADVANCED” کلیک کنید. در نتیجه، لینک برای هدایت به هاست برایتان نمایش داده می‌شود.

استفاده از گواهی خودامضایی Nginx

استفاده از گواهی خودامضایی Nginx

در این حالت، باید به وب‌سایت خودتان هدایت شوید. در این مثال، نوار آدرس مرورگر یک قفل با یک علامت ضربدر بر روی آن نشان می‌دهد. به این معنا که گواهی ما تأیید نشده است. با این وجود، هنوز هم ارتباط ما رمزنگاری می کند. به خاطر داشته باشید که این آیکون ممکن است در مرورگرهای مختلف متفاوت باشد.

اگر Nginx را با دو بلوک سرور تنظیم کرده باشید، محتوای HTTP به صورت اتوماتیک به HTTPS هدایت می‌شود. در همین حال می‌توانید بررسی کنید که این هدایت به‌درستی صورت می‌گیرد یا خیر.


http://server_domain_or_IP

در صورتی که نتیجه همان آیکون باشد، به این معناست که هدایت به‌درستی انجام گرفته است.

گام ۶) تغییر به حالت هدایت دائمی

در صورتی که هدایت شما به‌درستی کار کند و بخواهید که حتماً به ترافیک رمرنگاری‌شده مجوّز بدهید، می‌بایست تنظیمات Nginx را به گونه‌ای اصلاح کنید که این هدایت به صورت دائمی باشد.

دوباره فایل تنظیمات بلوک سرور را باز کنید.


sudo nano /etc/nginx/sites-available/your_domain

عبارت return 302 را پیدا کرده و آن را به return 301 تغییر دهید.


return 301 https://$server_name$request_uri;

حالا فایل را ذخیره کرده و ببندید.

تنظیما برای خطاهای قالبی بررسی کنید.


sudo nginx -t

پس از انجام کار، وب‌سرور Nginx را دوباره راه‌اندازی کنید تا تغییرات دائمی شوند.


sudo systemctl restart nginx

جمع‌بندی

در این مطلب، تنظیم سرور Nginx را برای استفاده از رمزنگاری قدرتمند برای ارتباط‌های کلاینت انجام دادیم. در نتیجه، امکان خدمت‌رسانی به درخواست‌ها به شکلی امن فراهم می‌شود و طرف‌های ثالث نمی‌توانند به ترافیک شما دسترسی داشته باشند. در همین حال، می‌توانید گزینه گواهی‌های چندامضایی TLS/SSL را نیز انتخاب کنید که از مرجع رایگان Let’s Encrypt در دسترس هستند.