چگونه ExpressVPN سرورهای وب خود را به صورت پستی و ایمن نگه می دارد

سرور ExpressVPN از خاکستر بالا می رود.

این مقاله رویکرد ExpressVPN را توضیح می دهد مدیریت وصله امنیتی برای زیرساخت های وب سایت ExpressVPN (نه سرورهای VPN). به طور کلی ، رویکرد ما به امنیت این است:

  1. سیستم ها را خیلی درست کنید هک کردن سخت.
  2. آسیب های احتمالی را به حداقل برسانید اگر یک سیستم به صورت فرضی هک شود و این واقعیت را تصدیق کند که برخی از سیستم ها کاملاً ایمن نیستند. به طور معمول ، این مرحله در مرحله طراحی معماری شروع می شود ، جایی که ما دسترسی یک برنامه را به حداقل می رسانیم.
  3. مقدار زمان را به حداقل برسانید که یک سیستم می تواند به خطر بیفتد.
  4. تایید اعتبار این نقاط با توقیف منظم ، داخلی و خارجی.

امنیت در فرهنگ ما ریشه دار است و دغدغه اصلی هدایت همه کارهای ما است. مباحث بسیاری دیگر مانند شیوه های توسعه نرم افزار امنیتی ما ، امنیت برنامه ها ، فرآیندهای کارکنان و آموزش و غیره وجود دارد ، اما موضوعاتی برای این پست از دسترس خارج نیستند.

در اینجا ما چگونگی دستیابی به موارد زیر را توضیح می دهیم:

  1. اطمینان حاصل کنید که کلیه سرورها به طور کامل ذخیره شده اند و هرگز بیش از 24 ساعت پشت انتشار CVE ها نباشد.
  2. اطمینان حاصل کنید که هیچ سرور بیش از 24 ساعت استفاده نشده است, بنابراین یک مقدار بالاتر از مقدار زمانی که یک مهاجم می تواند پایداری داشته باشد ، قرار می دهد.

ما هر دو هدف را از طریق آن انجام می دهیم سیستم اتوماتیک که سرورها را با استفاده از سیستم عامل و همه جدیدترین نسخه ها شروع به بازسازی می کند و حداقل هر 24 ساعت یکبار آنها را از بین می برد.

هدف ما از این مقاله این است که برای سایر توسعه دهندگان که با چالش های مشابه روبرو هستند مفید باشد و شفاف سازی در عملکرد ExpressVPN را به مشتریان و رسانه های خود ارائه دهیم.

نحوه استفاده ما از کتابهای پخش و Cloudform از Ansible

زیرساخت های وب ExpressVPN در AWS میزبان است (بر خلاف سرورهای VPN ما که روی سخت افزار اختصاصی کار می کنند) و ما از ویژگی های آن استفاده می کنیم تا بازسازی مجدد امکان پذیر شود.

کل زیرساخت های وب ما با Cloudformation فراهم شده است ، و ما سعی می کنیم تا آنجا که می توانیم فرایندهای مختلف را به صورت خودکار انجام دهیم. با این حال ، به دلیل نیاز به تکرار ، خوانایی کلی ضعیف ، و محدودیت های نحوی JSON یا YAML ، کار با الگوهای Cloudformate خام بسیار ناخوشایند است..

برای کاهش این مسئله ، ما از DSL به نام cloudform-ruby-dsl استفاده می کنیم که به ما امکان می دهد تعاریف الگو را در Ruby بنویسیم و قالب های Cloudformation را در JSON صادر کنیم..

به طور خاص ، DSL به ما اجازه می دهد تا اسکریپت های داده کاربر را به عنوان اسکریپت های منظم که به طور خودکار به JSON تبدیل می شوند بنویسیم (و فرایند دردناک ساختن هر خط از اسکریپت را به یک رشته JSON معتبر طی نکنیم)..

یک نقش عمومی مسؤولانه با نام cloudstruction-infrastruktur مراقبت می کند تا الگوی واقعی را به یک پرونده موقت تبدیل کند ، که در ادامه توسط ماژول Cloud Ansible استفاده می شود:

- نام: 'ارائه {{مؤلفه}} پشته ابرشبکه json'
پوسته: یاقوت "{قالب_نام | پیش فرض (جزء)}}. rb" گسترش - name-name {{stack}} --region {{aws_region}} > {{tempfile_path}} '
استدلال می کند:
chdir: ../cloudformation/templates
change_when: false

- name: 'ایجاد / بروزرسانی {{مؤلفه}} stack'
ساختار ابری:
stack_name: '{{stack}} - {{xv_env_name}} - {{مؤلفه}}'
حالت: حال
منطقه: '{{aws_region}'
قالب: '{{tempfile_path}}'
template_parameters: '{{قالب_پارامتر | پیش فرض ({})}} '
stack_policy: '{{stack_policy}}'
ثبت نام: cf_result

در playbook ، ما چندین بار با استفاده از متغیرهای مؤلفه مختلف ، نقش Cloudformation- زیرساختی را ایجاد می کنیم تا چندین پشته Cloudformation ایجاد کنیم. به عنوان مثال ، ما یک پشته شبکه داریم که VPC و منابع مرتبط را تعریف می کند و یک برنامه کاربردی را که گروه Auto Scaling را تعیین می کند ، پیکربندی راه اندازی ، قلاب چرخه عمر و غیره را تعریف می کند..

سپس ما از یک ترفند تا حدودی زشت اما مفید استفاده می کنیم تا خروجی ماژول cloud cloud را برای نقش های بعدی به متغیرهای قابل اعتماد تبدیل کنیم. ما باید از این روش استفاده کنیم زیرا Ansible اجازه ایجاد متغیرهایی با نامهای پویا را نمی دهد:

- شامل: _tempfile.yml
- کپی ��:
محتوا: '{{مؤلفه | regex_replace ("-", "_")}} _ stack: {{cf_result.stack_outputs | to_json}} '
dest: '{{tempfile_path}}. json'
no_log: درست است
change_when: false

- شامل_vars: '{{tempfile_path}}. json'

به روزرسانی گروه Scaling Auto EC2

وب سایت ExpressVPN در چندین گروه EC2 در یک گروه Auto Scaling در پشت برنامه Load Balancer میزبان است که ما را قادر می سازد سرورها را بدون هیچگونه خرابی از بین ببریم ، زیرا balancer bal می تواند اتصالات موجود را قبل از خاتمه دادن تخلیه کند..

Cloudstruction کل بازسازی را سازماندهی می کند ، و ما می توانیم لیست پخش Ansible شرح داده شده در بالا را هر 24 ساعت یکبار برای بازسازی کلیه نمونه ها ، استفاده از ویژگی AutoScalingRollingUpdate UpdatePolicy از AWS :: AutoScaling :: منبع AutoScalingGroup شروع کنیم..

هنگامی که به سادگی و بدون هیچ گونه تغییر و تحرکی ایجاد می شود ، از ویژگی UpdatePolicy استفاده نمی شود - فقط در شرایط خاص همانطور که در مستندات توضیح داده می شود ، فراخوانی می شود. یکی از این شرایط ، بروزرسانی در تنظیمات راه اندازی خودکار Scaling است - الگویی که یک گروه Auto Scaling برای راه اندازی نمونه های EC2 از آن استفاده می کند - که شامل اسکریپت داده کاربر EC2 است که در ایجاد نمونه جدید اجرا می شود:

منبع "AppLaunchConfiguration" ، نوع: "AWS :: AutoScaling :: LaunchConfiguration" ،
خواص: {
نام کلیدی: param ('AppServerKey') ،
ImageId: param ('AppServerAMI') ،
InstanceType: param ('AppServerInstanceType') ،
گروه های امنیتی: [
پارام ("SecurityGroupApp") ،
] ،
IamInstanceProfile: param ('RebuildIamInstanceProfile') ،
InstanceMonitoring: درست است ،
BlockDeviceMappings: [
{
نام دستگاه: '/ dev / sda1' ، # حجم ریشه
Ebs: {
VolumeSize: param ('AppServerStorageSize') ،
VolumeType: param ('AppServerStorageType') ،
DeleteOnTermination: درست ،
،
،
] ،
UserData: base64 (درون یابی (پرونده ('اسکریپت ها / app_user_data.sh'))) ،
}

در صورت بروزرسانی در اسکریپت داده های کاربر ، حتی یک نظر ، پیکربندی راه اندازی تغییر یافته در نظر گرفته خواهد شد و Cloudformation تمام موارد موجود در گروه Auto Scaling را به روز می کند تا با پیکربندی راه اندازی جدید مطابقت داشته باشد..

با تشکر از Cloudformy-ruby-dsl و عملکرد مطلوبیت آن ، می توانیم از منابع Cloudform در اسکریپت app_user_data.sh استفاده کنیم:

readonly rebuild_timestamp ="{{پارام ('RebuildTimestamp')}}"

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

قلاب چرخه عمر

ما از قلاب چرخه چرخ دستی اتومبیل استفاده می کنیم تا اطمینان حاصل کنیم که مصادیق ما کاملاً تأمین شده است و قبل از شروع زندگی ، بررسی های لازم را انجام می دهیم.

استفاده از قلاب چرخه عمر به ما امکان می دهد چرخه حیات مشابه را در هنگام بروزرسانی با Cloudformation و هنگامی که یک رویداد خودکار مقیاس گذاری رخ می دهد ، داشته باشیم (برای مثال ، وقتی که یک نمونه از بررسی سلامتی EC2 ناموفق باشد و خاتمه یابد). ما از سیگنال cfn و خط مشی به روزرسانی خودکار مقیاس WaitOnResourceSignals استفاده نمی کنیم ، زیرا آنها فقط هنگامی اعمال می شوند که Cloudformation باعث بروزرسانی شود.

هنگامی که یک گروه مقیاس خودکار خودکار نمونه جدیدی را ایجاد می کند ، قلاب چرخه عمر EC2_INSTANCE_LAUNCHING شروع می شود و به طور خودکار نمونه را در حالت انتظار قرار می دهد: منتظر بمانید.

بعد از این که نمونه کاملاً پیکربندی شد ، شروع به ضربه زدن به نقاط انتهای چک سلامتی خود با استفاده از حلقه های اسکریپت داده های کاربر می کند. پس از بررسی سلامتی برنامه سالم بودن برنامه ، ما یک اقدام CONTINUE برای این قلاب چرخه چرخه عمر صادر می کنیم ، بنابراین نمونه به بالانسور بار وصل می شود و شروع به خدمت به ترافیک می کند..

اگر بررسیهای بهداشتی انجام نشود ، ما یک اقدام ABANDON را صادر می کنیم که نمونه معیوب را خاتمه می دهد و گروه پوسته پوسته شدن خودکار یک مورد دیگر را راه اندازی می کند.

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

ما می خواهیم به محض این که فهمیدیم که هرگز سالم نخواهد شد ، ایجاد یک نمونه جدید شکست بخورد. برای دستیابی به این هدف ، ما یک تله ERR در اسکریپت داده کاربر به همراه set-o errtrace قرار داده ایم تا تابع را فراخوانی کنیم که یک عمل چرخه عمر ABANDON را ارسال می کند تا یک نمونه معیوب بتواند در اسرع وقت خاتمه یابد.

اسکریپت های داده های کاربر

اسکریپت داده های کاربر وظیفه نصب تمام نرم افزارهای مورد نیاز را به عنوان نمونه را دارد. ما با استفاده موفقیت آمیز از Ansible به عنوان نمونه و Capistrano برای استقرار برنامه ها برای مدت طولانی استفاده کرده ایم ، بنابراین ما همچنین از آنها در اینجا استفاده می کنیم و اختلاف بین استقرارهای منظم و بازسازی ها را ممکن می سازیم..

اسکریپت داده های کاربر مخزن برنامه ما را از Github بررسی می کند ، که شامل اسکریپت های تهیه کننده Ansible است ، سپس Ansible را اجرا می کند و Capistrano به localhost اشاره کرد.

هنگام چک کردن کد ، باید مطمئن شویم که نسخه مستقر در حال حاضر برنامه در حین بازسازی مستقر شده است. اسکریپت استقرار Capistrano شامل وظیفه ای است که یک پرونده را در S3 به روز می کند که مرتباً SHA را اجرا می کند. هنگامی که بازسازی اتفاق می افتد ، تعهدی را که قرار است از آن پرونده مستقر شود انتخاب می کند.

به روزرسانی های نرم افزار با اجرای بروزرسانی بدون نظارت در پیش زمینه با دستور بدون دستور ارتقا -d اعمال می شوند. پس از اتمام ، نمونه بارگیری مجدد و شروع به بررسی سلامتی می شود.

پرداختن به اسرار

سرور به دسترسی موقت به اسرار نیاز دارد (مانند رمز عبور Ansible طاق) که از فروشگاه پارامتر EC2 گرفته می شود. سرور فقط می تواند در طول بازسازی به اسرار کوتاه مدت دسترسی داشته باشد. پس از واکشی ، بلافاصله نمایه نمونه اولیه را با دیگری متفاوت جایگزین می کنیم که فقط به منابعی که برای اجرای برنامه مورد نیاز هستند دسترسی پیدا می کنیم..

ما می خواهیم از ذخیره هرگونه راز در حافظه پایدار آن مثال جلوگیری کنیم. تنها راز صرفه جویی در دیسک ، کلید Github SSH است ، اما عبارت عبور آن نیست. ما رمز عبور طاقچه Ansible را نیز ذخیره نمی کنیم.

با این حال ، ما باید این عبارات عبور را به ترتیب به SSH و Ansible منتقل کنیم ، و فقط در حالت تعاملی (یعنی ابزار باعث می شود کاربر به ورودی دستی عبارات را به صورت دستی بخواهد) به یک دلیل خوب - اگر یک عبارت عبور جزئی از دستور باشد. در تاریخچه پوسته ذخیره شده است و اگر ps را اجرا کنید ، برای همه کاربران سیستم قابل مشاهده است. ما از ابزار برنامه انتظار برای خودکار سازی تعامل با آن ابزارها استفاده می کنیم:

انتظار << EOF
cd $ {repo_dir
spawn make ansible_local env = $ deploy_env} stack = $ {stack name name host = $ {server_hostname}
تنظیم زمان 2
انتظار رمز عبور خرک
ارسال "$ {vault_password \ r"
تنظیم زمان 900
انتظار {
"دست نیافتنی = 0 شکست خورده = 0" {
خروج از 0
}
eof
خروج از 1
}
زمان بندی {
خروج از 1
}
}
EOF

شروع به بازسازی

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

ما با تعیین یک خط مشی محدود در پشته های Cloudformation به این هدف می رسیم تا فقط منابع لازم برای بازسازی به روز شوند:

{
"بیانیه" : [
{
"اثر" : "اجازه",
"عمل" : "بروزرسانی: اصلاح کنید",
"مدیر اصلی": "*",
"منبع" : [
"LogicalResourceId / * AutoScalingGroup"
] ،
{
"اثر" : "اجازه",
"عمل" : "بروزرسانی: جایگزین کنید",
"مدیر اصلی": "*",
"منبع" : [
"LogicalResourceId / * LaunchConfiguration"
] }
] }

هنگامی که ما باید به روزرسانی های زیرساخت واقعی را انجام دهیم ، باید سیاست پشته را به صورت دستی به روز کنیم تا به روز رسانی های آن منابع به صراحت انجام شود.

از آنجا که نام و سرورهای IP سرور ما هر روز تغییر می کند ، ما یک اسکریپت داریم که موجودی های محلی و تنظیمات SSH محلی قابل اطمینان را به روز می کند. این نمونه ها را از طریق API AWS با برچسب ها کشف می کند ، پرونده های موجودی و پیکربندی را از قالب های ERB ارائه می دهد ، و IP های جدید را به SSH معروف_هست اضافه می کند..

ExpressVPN از بالاترین استانداردهای امنیتی پیروی می کند

بازسازی سرورها از ما در برابر یک تهدید خاص محافظت می کند: مهاجمین از طریق آسیب پذیری هسته / نرم افزار به سرورهای ما دسترسی پیدا می کنند.

با این حال ، این تنها یکی از روش های بسیاری است که ما زیرساخت های خود را ایمن نگه می داریم ، از جمله اما محدود به انجام ممیزی های امنیتی منظم و ساخت سیستم های مهم و غیرقابل دسترسی از اینترنت..

علاوه بر این ، ما اطمینان حاصل می کنیم که تمام کد و فرایندهای داخلی ما بالاترین استانداردهای امنیتی را رعایت می کنند.

چگونه ExpressVPN سرورهای وب خود را به صورت پستی و ایمن نگه می دارد
admin Author
Sorry! The Author has not filled his profile.