بلاگ/ارتقای امنیت اپلکیشن Node با پروکسی بازگشتی Nginx
بهروز شده
ارتقای امنیت اپلکیشن Node با پروکسی بازگشتی Nginx
راههای مختلفی برای ارتقای انعطافپذیری و امنیت یک اپلیکیشن Node.js وجود دارند. استفاده از یک پروکسی بازگشتی مانند Nginx به شما این امکان را میدهد که درخواست متعادلی را بارگذاری کنید، محتوای استاتیک داشته باشید و از قابلیت موسوم به «امنیت لایه انتقال» یا TLS استفاده نمایید. فعالسازی پروتکل...
1400/04/103514 بازدید
راههای مختلفی برای ارتقای انعطافپذیری و امنیت یک اپلیکیشن Node.js وجود دارند. استفاده از یک پروکسی بازگشتی مانند Nginx به شما این امکان را میدهد که درخواست متعادلی را بارگذاری کنید، محتوای استاتیک داشته باشید و از قابلیت موسوم به «امنیت لایه انتقال» یا TLS استفاده نمایید. فعالسازی پروتکل رمزنگاریشده HTTPS در سرور موجب میشود که امنیت ارتباطی اپلیکیشن شما حفظ شود.
بکارگیری یک پروکسی بازگشتی همراه با TLS/SSL در کانتینرها شامل یک سری مراحل مستقیم در سیستمعامل میزبان میشود. به عنوان مثال، اگر گواهیها از طریق Let’s Encrypt برای اپلیکیشن در حال اجرا بر روی سرور بهدست میآیند، شما میبایست نرمافزار موردنیاز خود را مستقیماً بر روی هاست نصب کنید. کانتینرها شرایطی فراهم میکنند که بتوانید که از رویکرد متفاوت در این زمینه استفاده کنید. شما با استفاده از Docker Compose قادر خواهید بود که برای اپلیکیشن، وبسرور و کلاینت Certbot، کانتینر ایجاد کنید. کلاینت Certbot همان ابزاری است که امکان دسترسی به گواهیهای SSL را به شما میدهد. با دنبال کردن کردن مراحل زیر، میتوانید از مزایای یک جریان کاری انعطافپذیر و مقرونبهصرفه بهرهمند شوید.
در این آموزش، از یک اپلیکیشن Node.js همراه با یک پروکسی بازگشتی Nginx برای Docker Compose استفاده خواهیم کرد. گواهیهای TLS/SSL دامین مرتبط با اپلیکیشن بهدست میآیند و حتماً دقت میکنیم که رتبه امنیتی بالایی در SSL Labs داشته باشیم. نهایتاً یک عملیات cron برای تازهسازی گواهیها به گونهای تنظیم میکنیم که از امنیت دامین اطمینان حاصل گردد.
پیشنیازها
برای طیکردن مراحل این آموزش، موارد زیر موردنیاز هستند.
یک سرور اوبونتو 04، یک کاربر غیر روت با دسترسیهای sudo و یک فایروال فعال. حتماً در این حالت، تنظیمات اولیه سرور را انجام داده باشید.
نصب Docker و Docker Compose در سرور. برای اطلاعات بیشتر میتوانید به مقالات قبلی وبلاگ آریانت در این زمینه مراجعه کنید.
یک دامین ثبتشده. در سراسر این مطلب از دامین نمونه com استفاده میشود. از برخی جاها مانند Freenom امکان دریافت دامین رایگان وجود دارد و در عین حال، میتوانید از مرجع ثبت دامین خودتان استفاده کنید.
تنظیم این دو رکورد DNS نیز برای سرور؛ یک رکورد A با هدایت com به آدرس IP عمومی سرور و یک رکورد A با هدایت www.example.com باز هم به آدرس IP عمومی سرور.
گام ۱) شبیهسازی و تست اپلیکیشن Node
به عنوان گام نخست، منبع را با کد اپلیکیشن Node شبیهسازی میکنیم که شامل Dockerfile مورد استفاده برای ساخت ایمیج اپلیکیشن با Compose میشود. آزمایش اولیه به این صورت است که پس از ساخت اپلیکیشن، بدون استفاده از پروکسی بازگشتی یا SSL، با کمک فرمان docker run آن را اجرا میکنیم.
در دایرکتوری خانگی کاربری که دسترسی روت ندارد، منبع nodejs-image-demo را از گیتهاب دریافت کنید. این منبع شامل کدهای موردنیاز برای ساخت یک اپلیکیشن Node.js با داکر نیز میشود.
این منبع را داخل یک دایرکتوری با نام node_project ذخیره کنید.
حالا مسیر را به دایرکتوری node_project تغییر دهید.
php
1cd node_project
این دایرکتوری شامل یک Dockerfile که در آن دستورالعملهای ساخت یک اپلیکیشن Node با استفاده از ایمیج Docker node:10 وجود دارد. میتوانید با استفاده از فرمان زیر به محتوای یک Dockerfile دسترسی داشته باشید.
با این دستورالعمل ها یک ایمیج Node ساخته میشود که در آن کد پروژه از دایرتوری کنونی به کانتینر کپی شده و متعلقات آن نیز با فرمان npm install نصب میشوند. همچنین با جداسازی کپیهای package.json و package-lock.json از کپیهای ساید بخشهای کد اپلیکیشن، از مزایای کچینگ و لایهبندی ایمیج داکر استفاده میشود. نهایتاً این دستورالعملها مشخص میکنند که کانتینر با کاربری غیر روت با دسترسیهای مناسب تنظیمشده در کد اپلیکیشن و دایرکتوریهای node_modules اجرا میگردد.
برای تست اپلیکیشن بدون SSL میتوانید برای ساخت و برچسبزدن ایمیج از گزینه -t در فرمان docker build استفاده کنید. در این عنوان node-demo را برای ایمیج به کار میبریم، ولی شما میتوانید عنوان دلخواه خود را داشته باشید.
php
1docker build -t node-demo .
وقتی روند ساخت به پایان رسید، میتوانید با فرمان docker images لیستی از ایمیجهای خود در اختیار داشته باشید.
php
1docker images
در نتیجه، با خروجی زیر مواجه میشوید که تأیید ساخت ایمیج اپلیکیشن خواهد بود.
php
1REPOSITORY TAG IMAGE ID CREATED SIZE23node-demo latest 23961524051d 7 seconds ago 73MB45node 10-alpine 8a752d5af4ce 3 weeks ago 70.7MB
سپس یک کانتینر با فرمان docker run ایجاد میکنیم. سه گزینه در این فرمان به کار ما میآیند:
<ul>
<li>-p : این گزینه باعث انتشار پورت به کانتینر و ارجاع آن به یک پورت در هاست ما میشود. در اینجا از پورت 80 برای این منظور استفاده میکنیم، ولی شما میتوانید در صورت لزوم، شماره پورت دیگری وارد کنید.</li>
<li>-d : این گزینه موجب اجرای کانتینر در پسزمینه میشود.</li>
<li>--name: با استفاده از این گزینه میتوانیم یه عنوان خاص به کانتینر اختصاص دهیم.</li>
</ul>
فرمان زیر را برای ساخت کانتینر اجرا کنید.
php
1docker run --name node-demo -p 80:8080 -d node-demo
با استفاده فرمان docker ps، کانتینرهای در حال اجرا را بررسی نمایید.
php
1docker ps
در خروجی متوجه میشوید که کانتینر اپلیکیشن شما در حال اجراست.
php
1CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES234133b72391da node-demo "node app.js" 17 seconds ago Up 16 seconds 0.0.0.0:80->8080/tcp node-demo
اکنون میتوانید با رفتن به آدرس دامین، از نصب خود مطمئن شوید. در نتیجه، با صفحه لندینگ اپلیکیشن به صورت زیر روبرو خواهید شد.
صفحه لندینگ اپلیکیشن Node
بعد از تست اپلیکیشن میتوانید کانتینر را متوقف کرده و ایمیجها را حذف کنید. دوباره فرمان docker ps را اجرا کنید تا شناسه کانتینر یا CONTAINER ID را در اختیار داشته باشید.
php
1docker ps
خروجی
php
1CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES234133b72391da node-demo "node app.js" 17 seconds ago Up 16 seconds 0.0.0.0:80->8080/tcp node-demo
با فرمان docker stop کانتینر را متوقف نمایید. حتماً دقت کنید که شناسه کانتینر خودتان را در این فرمان وارد کنید.
php
1docker stop 4133b72391da
حالا میتوانید کانتینر متوقفشده و تمام ایمیجها را حذف کنید.
php
1docker system prune -a
برای تأیید حذف این موارد، کلید حرف Y را فشار دهید. به خاطر داشته باشید که این کار باعث پاکشدن حافظه نهان داکر نیز میشود.
پس از تست ایمیج اپلیکیشن میتوانید به سراغ سایر قسمتها با استفاده از Docker Compose بروید.
گام ۲) تعریف تنظیمات وبسرور
پس از قرارگیری Dockerfile در جای مناسب، میتوانیم یک فایل تنظیمات برای اجرای کانتینر Nginx بسازیم. کار با یک تنظیمات حداقلی شامل نام دامین، مسیر ریشه داکیومنت، اطلاعات پروکسی و یک بلوک موقعیت برای هدایت درخواست Certbot به دایرکتوری .well-known آغاز میشود. در دایرکتوری .well-known یک فایل موقتی برای تأیید اعتبار DNS دامین به سرور قرار میگیرد.
یک دایرکتوری در دایرکتوری کنونی پروژه برای فایل تنظیمات ایجاد میکنیم.
php
1mkdir nginx-conf
این فایل را با استفاده از ویرایشگر متنی nano یا هر ویرایشگر دلخواه دیگری باز کنید.
php
1nano nginx-conf/nginx.conf
بلوک سرور زیر را به درخواستهای کاربر پروکسی در کانتینر اپلیکیشن Node اضافه کنید. همچنین این کار برای هدایت درخواستهای Certbot به دایرکتوری .well-known صورت میگیرد. حتماً دقت کنید که example.com را با عنوان دامین خودتان جایگزین نمایید.
این بلوک سرور به ما اجازه میدهد که کانتینر Nginx را به عنوان یک پروکسی بازگشتی اجرا کنیم. این کار باعث میشود که درخواست به کانتینر اپلیکیشن Node هدایت شوند. همچنین به این وسیله میتوانیم از پلاگین وبروت Certbot برای بهدست آوردن گواهیهای دامین خود استفاده کنیم. این پلاگین به روش تأییدیه HTTP-01 وابسته است. در این روش، از یک درخواست HTTP برای اثبات توانایی دسترسی Certbot به منابع سرور مربوط به دامین استفاده میشود.
وقتی ویرایش به اتمام رسید، فایل را ذخیره کرده و ببندید.
پس از کاملشدن جزئیات تنظیمات وبسرور میتوانیم به سراغ ساخت فایل docker-compose.yml برویم. این فایل به ما اجازه میدهد که سرویسهای اپلیکیشن و همینطور کانتینر Certbot را بسازیم.
گام ۳) ایجاد فایل Docker Compose
فایل docker-compose.yml سرویسهای ما، شامل اپلیکیشن Node و وبسرور را تعریف میکند. جزئياتی مانند حجمها، شبکهها و اطلاعات پورت در این فایل مشخص میشوند؛ جزئیاتی که برای رد و بدل کردن اعتبارهای SSL بین کانتینرها حیاتی خواهند بود. همچنین این فایل برای تعریف اجرای فرمانهای خاص بعد از ساخت کانتینرها مورد استفاده قرار میگیرد. این فایل یک منبع مرکزی برای تعریف نحوه همکاری سرویسهای ما با یکدیگر است.
این فایل در دایرکتوری کنونی باز کنید.
build: این عبارت تعریفکننده گزینههای تنظیمات شامل context و dockerfile است. این گزینهها در هنگام ساخت ایمیج اپلیکیشن توسط Compose به کار گرفته میشوند. اگر قصدتان استفاده از ایمیجهای آماده از منبعی مانند Docker Hub است، می توانید به جای آن، از image instruction استفاده کنید که شامل اطلاعاتی در مورد نام کاربری، منبع و برچسب ایمیج خواهد بود.
context: در این بخش، کانتکست ساخت برای ساخت ایمیج اپلیکیشن تعریف میشود. در اینجا، از دایرکتوری کنونی پروژه استفاده میشود.
dockerfile: در اینجا Dockerfile مورد استفاده Compose برای ساخت مشخص میشود. یعنی همان Dockerfile که در گام اول داشتیم.
image, container_name: عنوانهای ایمیج و کانتینر
restart: روند راهاندازی دوباره و ریاستارت در اینجا تعریف میشود. حالت پیشفرض به صورت «غیرفعال» و گزینه no است. با این وجود باید کانتینر را برای راهاندازی دوباره تنظیم کنیم، مگر اینکه متوقف شده باشد.
به خاطر داشته باشید که در این سرویس bind mount نداریم. به این دلیل که تنظیمات ما متمرکز بر «بهکارگیری» و نه «توسعه» است.
به منظور فعالسازی ارتباط بین اپلیکیشن و کانتینرهای وبسرور، یک شبکه بریج با نام app-network درنظر میگیریم.
یک شبکه بریج تعریفشده توسط کاربر باعث ایجاد ارتباط بین کانتینرها در هاست Docker میشود. در نتیجه، ترافیک و ارتباط درون اپلیکیشن به راحتی انجام خواهد گرفت. چرا که در این حالت، تمام پورتها بین کانتینرها در شبکه بریج باز میشوند و در همین حال، دنیال خارج نمیتواند به این پورتها دسترسی داشته باشد. به این ترتیب، شما میتوانید پورتهای دلخواه خود را برای سرویسهای نهایی انتخاب کنید.
در مرحله بعد، سرویس وبسرور را تعریف میکنیم.
برخی از تنظیماتی که قبلاً برای سرویس nodejs تعریف کردیم، به همان صورت باقی میمانند. با این وجود، برخی تغییرات را به صورت زیر نیز انجام دادهایم:
image: این گزینه باعث میشود که Compose آخرین نسخه ایمیج Nginx بر پایه Alpine را از Docker Hub دریافت نماید.
ports: در اینجا، پورت 80 برای فعالسازی گزینههای تنظیمات Nginx مورد استفاده قرار میگیرد.
همچنین حجمها و bind mount های زیر را تعریف کردهایم:
web-root:/var/www/html: با این گزینه بخشهای استاتیک سایت را اضافه میکنیم. این بخشها در حجمی با عنوان web-root در دایرکتوری /var/www/htmlواقع در کانتینر کپی میشوند.
./nginx-conf:/etc/nginx/conf.d: این گزینه موجب ارتباط bind mount بین دایرکتوری تنظیمات Nginx در هاست با دایرکتوری متناظر آن در کانتینر میشود. در نتیجه، هر گونه تغییری که در فایلهای هاست ایجاد میکنیم، در کانتینر نیز منعکس خواهد شد.
certbot-etc:/etc/letsencrypt: با این گزینه، گواهیها و کلیدهای Let’s Encrypt دامین در دایرکتوری مربوطه در کانتینر نیز مورد استفاده قرار خواهند گرفت.
certbot-var:/var/lib/letsencrypt: این گزینه دایرکتوری پیشفرض Let’s Encrypt را با دایرکتوری متناسب با آن در کانتینر هماهنگ میکند.
سپس باید تنظیمات را برای کانتینر certbot اضافه کنیم. حتماً دقت کنید که اطلاعات مربوط به دامین و ایمیل را به شکل مناسب برای وبسایت خودتان وارد کنید.
این تعریف موجب میشود که Compose ایمیج certbot/certbot را از Docker Hub دریافت کند. همچنین از حجمهای یاد شده برای به اشتراک گذاری منابع با کانتینر Nginx استفاده میشود. این منابع شامل مواردی چون گواهیها و کلیدهای دامین در certbot-etc، دایرکتوری Let’s Encrypt در certbot-var و کد اپلیکیشن در web-root میشوند.
همچنین از depends_on برای مشخصکردن این موضوع که کانتینر certbot میبایست حتماً بعد از اجرای سرویس وبسرور، شروع به کار کند، استفاده کردهایم.
به همین ترتیب، از گزینه command استفاده کردهایم که موجب اجرای فرمان بعد از شروع به کار کانتینر میشود. آیتمهای زیر در این فرمان به کار رفتهاند:
--webroot: استفاده از پلاگین webroot برای جانمایی فایلها در فولدر webroot جهت تأییدیه.
--webroot-path: مسیر دایرکتوری webroot
--email: ایمیل ترجیحی برای ثبتنام و بازیابی
--agree-tos: موافقت با توافقنامه عضویت ACME
--no-eff-email: عدم به اشتراکگذاری ایمیل با بنیاد الکترونیک فرونتیر یا EFF. در صورت تمایل میتوانید این مورد را حذف کنید.
--staging: این گزینه تمایل شما را برای استفاده از محیط استیجینگ Let’s Encrypt برای دریافت گواهیهای آزمایشی نشان میدهد. استفاده از این گزینه این امکان را برایتان ایجاد میکند و گزینههای مختلف تنظیمات را امتحان کنید و از برخی محدودیتهای درخواست دامین در امان بمانید.
-d: برای مشخصکردن عنوان دامین موردنظر به منظور ثبت درخواست. در اینجا، از آدرسهای com و www.example.com استفاده کردهایم. حتماً دقت کنید که موارد مرتبط با دامین خود را جایگزین کنید.
به عنوان گام نهایی، تعاریف حجم و شبکه را اضافه میکنیم. در اینجا نیز باید کاربر غیر روت خودتان را وارد کنید.
حجمهای یاد شده شامل گواهی Certbot و دایرکتوری کاری و همینطور، حجم مورد استفاده برای بخشهای استاتیک وبسایت، یعنی web-root میشوند. در بسیاری از موارد، درایور پیشفرض برای حجمهای Docker به صورت local driver است که در لینوکس گزینههای مشابه با فرمان mount را قبول میکند. در نتیجه، میتوانیم با استفاده از driver_opts، فهرستی از گزینههای درایور را بین دایرکتوری هاست و حجم رانتایم در اختیار داشته باشیم. در این حالت، محتوای دایرکتوری میتواند بین کانتینرها به اشتراک گذاشته شود.
نهایتاً فایل docker-compose.yml تکمیلشده به صورت زیر خواهد بود:
بعد از تعریف سرویسها، همهچیز برای شروع به کار کانتینرها و آزمایش درخواستهای گواهی آماده خواهد بود.
گام ۴) دریافت اعتبار و گواهیهای SSL
میتوانیم با استفاده از docker-compose up کانتینرهای خود را اجرا کنیم. در نتیجه این فرمان، کانتینرهای ما ایجاد و اجرا میشوند و همین طور، سرویسها به ترتیبی که مشخص کردهایم، شروع به کار میکنند. در صورت درخواستهای دامین ما موفقیتآمیز باشند، وضعیت درست خروج را مشاهده خواهیم کرد و همینطور گواهیها در فولدر /etc/letsencrypt/live در کانتینر webserver قرار میگیرند.
سرویسها را با فرمان docker-compose up و گزینه -d ایجاد میکنیم. این گزینه موجب میشود که کانتینرهای nodejs و webserver در پسزمینه اجرا شوند.
php
1docker-compose up -d
در خروجی مشاهده میکنید که سرویسها بهدرستی ایجاد شدهاند.
حالا با کمک فرمان docker-compose ps وضعیت سرویسهای خود را بررسی کنید.
php
1docker-compose ps
در صورتی که همه موارد با موفقیت به پیش رفته باشند، سرویسهای nodejs و webserver با وضعیت فعال یا Up و کانتینر certbot با پیام خروج صفر نشان داده میشوند.
php
1Name Command State Ports23certbot certbot certonly --webroot … Exit 045nodejs node app.js Up 8080/tcp67webserver nginx -g daemon off; Up 0.0.0.0:80->80/tcp
در صورتی که وضعیت به غیر از Up برای سرویسها و یا وضعیت خروجی غیر از صفر برای کانتینر certbot وجود داشته باشد، حتماً وضعیت سرویس را با فرمان docker-compose logs بررسی کنید.
php
1docker-compose logs service_name
همچنین با استفاده از فرمان docker-compose exec میتوانید وضعیت اعتبار گواهی را در کانتینر webserver بررسی کنید.
php
1docker-compose exec webserver ls -la /etc/letsencrypt/live
در صورتی که درخواست موفقیتآمیز باشد، با خروجی زیر مواجه خواهید شد.
php
1total 1623drwx------ 3 root root 4096 Dec 23 16:48 .45drwxr-xr-x 9 root root 4096 Dec 23 16:48 ..67-rw-r--r-- 1 root root 740 Dec 23 16:48 README89drwxr-xr-x 2 root root 4096 Dec 23 16:48 example.com
حالا که از موفقبودن درخواست خود مطمئن شدید، میتوانید تعریف سرویس certbot را برای برداشتن گزینه --staging ویرایش کنید.
برای این منظور، فایل docker-compose.yml را باز کنید.
php
1nano docker-compose.yml
بخش مربوط به تعریف سرویس certbot را پیدا کرده و گزینه --staging را با --force-renewal جایگزین کنید. در حال حاضر، تعریف سرویس certbot به صورت زیر خواهد بود.
حالا میتوانید فرمان docker-compose up را اجرا کنید تا کانتینر certbot و حجمهای مربوط به آن ایجاد شوند. همچنین از گزینه --no-deps برای عبور ار مرحله شروع سرویس webserver استفاده میکنیم؛ چرا که این سرویس هماکنون در حال اجراست.
php
1docker-compose up --force-recreate --no-deps certbot
خروجی نشاندهنده موفقیتآمیز بودن درخواست گواهی شماست.
php
1certbot | IMPORTANT NOTES:23certbot | - Congratulations! Your certificate and chain have been saved at:45certbot | /etc/letsencrypt/live/example.com/fullchain.pem67certbot | Your key file has been saved at:89certbot | /etc/letsencrypt/live/example.com/privkey.pem1011certbot | Your cert will expire on 2019-03-26. To obtain a new or tweaked1213certbot | version of this certificate in the future, simply run certbot1415certbot | again. To non-interactively renew *all* of your certificates, run1617certbot | "certbot renew"1819certbot | - Your account credentials have been saved in your Certbot2021certbot | configuration directory at /etc/letsencrypt. You should make a2223certbot | secure backup of this folder now. This configuration directory will2425certbot | also contain certificates and private keys obtained by Certbot so2627certbot | making regular backups of this folder is ideal.2829certbot | - If you like Certbot, please consider supporting our work by:3031certbot |3233certbot | Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate3435certbot | Donating to EFF: https://eff.org/donate-le3637certbot |3839certbot exited with code 0
پس از جانمایی گواهیها، می توانیم به سراغ اصلاح تنظیمات Nginx و وارد کردن SSL برویم.
گام ۵) اصلاح تنظیمات و سرویس وبسرور
فعالسازی SSL در تنظیمات Nginx شامل اضافهکردن یک ارجاع HTTP به HTTPS و مشخصکردن محل کلید و گواهی SSL است. همچنین این موضوع شامل مشخصکردن گروه Diffie-Hellman به منظور «محرمانگی پیشرو» یا PFF نیز میشود.
در اینجا میخواهیم سرویس webserver را به منظور اضافهکردن این موارد، بازسازی کنیم. بر این اساس، ابتدا باید آن را متوقف کنیم.
php
1docker-compose stop webserver
اول از همه، یک دایرکتوری در دایرکتوری کنونی پروژه ایجاد کنید تا کلید Diffie-Hellman در آن قرار گیرد.
ایجاد کلیدها به چند دقیقه زمان احتیاج خواهد داشت.
به منظور اضافهکردن اطلاعات مربوط به Diffie-Hellman و SSL به تنظیمات Nginx، قبل از هر کاری، فایل تنظیمات Nginx را که قبلاً ایجاد کرده بودید، حذف کنید.
php
1rm nginx-conf/nginx.conf
یک نسخه دیگر از فایل باز کنید.
php
1nano nginx-conf/nginx.conf
کد زیر را برای هدایت HTTP به HTTPS و اضافهکردن اعتبارها، پروتکلهای و هدرهای امنیتی SSL اضافه کنید. حتماً به یاد داشته باشید که آدرس example.com را با دامین خودتان جایگزین کنید.
بلوک HTTP server مشخص میکند که webroot برای درخواستهای تازهسازی Certbot در دایرکتوری .well-known/acme-challenge مورد استفاده قرار گیرد. همچنین این بلوک شامل یک ارجاعدهنده درخواستهای HTTP دایرکتوری روت به HTTPS میشود.
بلوک HTTPS server موجب فعالسازی ssl و http2 میشود. همچنین این بلوک شامل یک سری گزینهها برای اطمینان از کاربرد آخرین نسخه پروتکلها و رمزنگاریهای SSL و فعالبودن استپلینگ OSCP است. استپلینگ OSCP این امکان را به شما میدهد که در طول فرآیند اولیه TLS handshake، بتوانید پاسخ بر اساس فواصل زمانی از مرجع صدور گواهی داشته باشید. این کار مسلماً باعث افزایش سرعت فرآیند تأییدیه میشود.
این بلوک همچنین موقعیت اعتبارها و کلید SSL و Diffie-Hellman را مشخص میکند.
نهایتاً اطلاعات عبور پراکسی را در این بلوک وارد کردهایم که شامل یک بلوک location با پارامتر try_files میشود. این پارامتر درخواستها را به کانتینر اپلیکیشن Node.js ما هدایت میکند. همینطور یک بلوک location شامل هدرهای امنیتی که موجب کسب رتبه A از مراجعی مانند SSL Labs و وبسایت Security Headers میشود.
وقتی کار ویرایشتان تمام شد، فایل را ذخیره کرده و آن را ببندید.
قبل از اینکه سرویس webserver را دوباره بازسازی کنیم، باید برخی موارد را در تعریف سرویس در فایل docker-compose.yml اضافه نماییم؛ از جمله اطلاعات مرتبط با پورت HTTPS و همینطور تعریف حجم Diffie-Hellman.
بر این اساس، فایل را باز کنید.
php
1nano docker-compose.yml
در بخش تعریف سرویس webserver، ارجاع پورت و حجم با عنوان dhparam را اضافه کنید.
همانند حجم web-root، حجم dhparam نیز کلید Diffie-Hellman ذخیرهشده در هاست را با کانتینر webserver مرتبط میکند.
پس از انجام ویرایش، فایل را ذخیره کرده و ببندید.
اکنون سرویس webserver را بازسازی کنید.
php
1docker-compose up -d --force-recreate --no-deps webserver
با فرمان docker-compose ps سرویسها را بررسی کنید.
php
1docker-compose ps
در خروجی میبایست اجرای سرویسهای nodejs و webserver را مشاهده کنید.
php
1Name Command State Ports23----------------------------------------------------------------------------------------------45certbot certbot certonly --webroot ... Exit 067nodejs node app.js Up 8080/tcp89webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
نهایتاً از دامین خود بازدید کنید تا از درستبودن تمام موارد مطابق انتظار مطمئن شوید. در نتیجه، صفحه لندینگ زیر برایتان نمایش داده میشود.
صفحه لندینگ اپلیکیشن Node
همچنین باید آیکون قفل را در نمایشگر امنیتی مرورگر خود ببینید. در صورت تمایل، می توانید به صفحه لندینگ SSL Labs Server Test و یا سرور تست Security Headers بروید. تنظیماتی که قبلاً اِعمال کردیم، میتوانند در هر دوی این صفحات رتبه A را برایتان ایجاد کنند.
گام ۶) تازهسازی گواهیها
گواهیهای Let’s Encrypt برای مدت ۹۰ روز معتبر خواهند بود. بر این اساس، میبایست یک الگوی تازهسازی گواهیها تنظیم کنید تا گواهیهای منقضیشده مورد استفاده قرار نگیرند. یکی از روشهای برای این منظور، ابزار زمانبندی انجام کارها موسوم به cron است. در اینجا ما با استفاده از یک اسکریپت، یک وظیفه cron برای تازهسازی گواهیها و بارگذاری دوباره تنظیمات Nginx ایجاد میکنیم.
برای این منظور، یک اسکریپت با نام ssl_renew.sh در دایرکتوری پروژه باز کنید.
php
1nano ssl_renew.sh
حالا کد زیر را به اسکریپت اضافه کنید.
php
1#!/bin/bash23COMPOSE=”/usr/local/bin/docker-compose --no-ansi”45DOCKER=”/usr/bin/docker”67cd /home/ammy/node_project/89$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver1011$DOCKER system prune -af
این اسکریپت ابتدا کد باینری docker-compose را به صورت یک متغیر با نام COMPOSE درنظر میگیرد. همچنین استفاده از گزینه --no-ansi باعث میشود که فرمانهای docker-compose بدون کنترل کاراکترهای ANSI اجرا شوند. همین کار با باینری docker نیز انجام میگیرد. نهایتاً دایرکتوری به ~/node_project تغییر پیدا میکند و فرمانهای docker-compose به صورت زیر اجار میگردند.
docker-compose run: اجرای یک کانتینر certbot و بازیابی فرمان تعریفشده در سرویس certbot. به جای استفاده از زیرفرمان certonly، از renew استفاده میکنیم. در نتیجه، گواهیهایی که نزدیک به تاریخ انقضای خود هستند، تازهسازی میشوند. گزینه --dry-run برای تست اسکریپت وارد شده است.
docker-compose kill: یک سیگنال SIGHUP به کانتینر webserver ارسال میشود تا تنظیمات Nginx بارگذاری شوند.
سپس اجرای فرمان docker system prune برای حذف کلیه کانتینرها و ایمیجهای بلااستفاده انجام میشود.
وقتی کار ویرایش به اتمام رسید، فایل را ببندید. حالا آن را به فایل اجرایی تبدیل کنید
php
1chmod +x ssl_renew.sh
حالا فایل روت crontab را باز کنید تا اسکریپت تازهسازی در فواصل مشخص اجرا شود.
php
1sudo crontab -e
در صورتی که برای اولین بار این فایل را ویرایش میکنید، از شما درخواست میشود که یک ویرایشگر انتخاب کنید.
php
1no crontab for root - using an empty one23Select an editor. To change later, run 'select-editor'.4<ol>5 <li>/bin/ed</li>6 <li>/bin/nano <---- easiest</li>7 <li>/usr/bin/vim.basic</li>8 <li>/usr/bin/vim.tiny</li>9</ol>10Choose 1-4 [2]:1112...
در نتیجه، این کار هر پنج دقیقه یک بار انجام میشود و میتوانید درخواست تازهسازی را در این فاصله بررسی کنید. همچنین یک فیال ثبت تاریخچه با نام cron.log برای این کار ایجاد کردهایم.
بعد از پنج دقیقه، فایل cron.log را برای موفقبودن تازهسازی گواهی بررسی کنید.
php
1tail -f /var/log/cron.log
در نتیجه، میبایست خروجیای مشابه زیر مشاهده کنید.
php
1- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -23** DRY RUN: simulating 'certbot renew' close to cert expiry45** (The test certificates below have not been saved.)67 89Congratulations, all renewals succeeded. The following certs have been renewed:1011/etc/letsencrypt/live/example.com/fullchain.pem (success)1213** DRY RUN: simulating 'certbot renew' close to cert expiry1415** (The test certificates above have not been saved.)1617- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -1819Killing webserver ... done
حالا میتوانید فایل crontab برای تنظیم فواصل روزانه تازهسازی گواهیها تغییر دهید. برای اجرای اسکریپت در هر بعدازظهر، میتوانید اصلاح زیر را انجام دهید.
ضمن اینکه حالا میتوانید گزینه --dry-run را از اسکریپت ssl_renew.sh حذف کنید.
php
1#!/bin/bash23COMPOSE="/usr/local/bin/docker-compose --no-ansi"45DOCKER="/usr/bin/docker"67cd /home/sammy/node_project/89$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver1011$DOCKER system prune -af
این وظیفه cron باعث میشود که از عدم منقضیشدن گواهیهای Let’s Encrypt اطمینان حاصل گردد. همچنین میتوانید با استفاده از ابزاری مانند Logrotate حجم کمتری برای فایلهای ثبت تاریخچه داشته باشید.
جمعبندی
در اینجا از کانتینرها برای تنظیم و اجرای یک اپلیکیشن Node همراه با پروکسی بازگشتی Nginx استفاده کردیم. همچنین گواهیهای امنیتی SSL برای دامین اپلیکیشن و یک وظیفه cron برای تازهسازی این گواهیها تنظیم شد. امیدواریم که این مطلب نیز مورد استفاده شما قرار گرفته باشد و در ادامه مطالب وبلاگ آریانت نیز با ما همراه باشید.