حفظ یا SNAT کردن IPهای کلاینت VPN در مرز ابر
حفظ مبدأ هویت کلاینت را در هر گزارش نگه میدارد، SNAT جدول مسیریابی را کوچک نگه میدارد. سه شرط میگویند برنامه کدام را لازم دارد.
نگه داشتن آدرس کلاینت VPN تا خود برنامه باعث میشود هر خط گزارش و هر ورودی فهرست مجاز یک معنا داشته باشند. بازنویسی آن در لبه ابر جدول مسیریابی را سادهتر و گزارشها را کمفایدهتر میکند. هیچیک از دو انتخاب بهتنهایی غلط نیست و استدلالی که آن را تعیین میکند بهندرت درباره کارایی است. سه شرط آن را روشن میکند: آیا برنامه باید بداند کدام انسان متصل شده است، آیا بافت ابر مبدأیی را که میخواهید بفرستید میپذیرد، و چه کسی بعداً مسئولیت مسیر بازگشت را میپذیرد.
سه شرط آن را تعیین میکند
از نیاز برنامه شروع کنید، نه از نمودار شبکه. اگر مجوزدهی یا حسابرسی به آدرس فردی کلاینت وابسته باشد، حفظ آن یک نیاز کارکردی است و ترجمه یک پسرفت. اگر برنامه فقط باید بداند که ترافیک از مسیر دسترسی از راه دور رسیده است، آدرس ترجمهشده کافی است و بهمراتب ارزانتر اداره میشود.
شرط دوم مکانیکی است. یک شبکه مجازی بهطور خودکار به بستهای اعتماد نمیکند که ادعای آدرسی را دارد که به رابط فرستنده اختصاص داده نشده است. بیشتر بافتهای ابر این را به روشها و نامهای متفاوت اعمال میکنند و طراحیای که آن را نادیده بگیرد در نمودار درست به نظر میرسد و در تولید بیصدا حذف میشود.
شرط سوم سازمانی است. حفظ مبدأها یعنی جدول مسیریابی زیرشبکه برنامه باید برای پیشوند کلاینت به دروازه اشاره کند و هر تیمی که بعداً زیرشبکهای اضافه میکند باید آن مسیر را سازگار نگه دارد. این یک هزینه کوچک یکباره و هزینهای تکرارشونده در دهها حساب است. پیش از وعده دادن این رفتار تعیین کنید چه کسی آن را میپردازد.
مسیر اجازه جعل هویت نیست
افزودن مسیر بازگشت به زیرشبکه شما میگوید پاسخها باید کجا بروند. این به بافت نمیگوید که نمونهای که آن بستهها را ارسال میکند مجاز است آنها را با مبدأ بیگانه بفرستد. در AWS کنترل مربوطه بررسی مبدأ و مقصد است و برای هر نمونه قابل مشاهده است:
aws ec2 describe-instances --instance-ids i-0a1b2c3d4e5f60718 \
--query "Reservations[].Instances[].SourceDestCheck"
aws ec2 modify-instance-attribute --instance-id i-0a1b2c3d4e5f60718 \
--no-source-dest-check
آن را فقط برای نمونهای خاموش کنید که کار مستندش ارسال است و برای هیچ چیز دیگری. هر ماشین مجازی برنامه که بررسی را روشن نگه میدارد یک ماشین کمتر است که میتوان از آن برای فرستادن ترافیک با مبدأ قرضی استفاده کرد. اگر پلتفرم شما AWS نیست، تنظیم معادل ضد جعل یا آدرسهای مجاز را جستجو کنید نه اینکه فرض کنید رفتار منتقل میشود.
یک ضبط سریع بسته سؤال را سریعتر از خواندن کنسول حل میکند. اگر پاسخها خارج شوند و کلاینت هرگز آنها را نبیند، بافت مبدأ جعلی را دور میریزد و این برنامه نیست که شکست میخورد.
ترجمه چه میخرد و چه هزینه دارد
بازنویسی مبدأ در دروازه مشکل مسیر بازگشت را از میان برمیدارد. برنامه آدرسی را میبیند که از قبل میداند چگونه به آن برسد و پیشوند کلاینت هرگز لازم نیست در جدول مسیریابی ابر ظاهر شود. در Linux قاعده یک خط است و ارزش دارد تنگترین نسخهای را که میتوانید بنویسید:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 172.20.8.0/24 -o ens5 -j SNAT --to-source 10.40.3.10
توجه کنید برنامه اکنون چه ثبت میکند: 10.40.3.10 برای هر کاربر، در هر اتصال، برای همیشه. هر فهرست مجاز آدرسی که بر این مقدار ساخته شود اکنون به تمام جمعیت دسترسی از راه دور دسترسی میدهد و هر بازبینی حادثه باید به دروازه برگردد تا پاسخ دهد این چه کسی بود.
راهحل رها کردن ترجمه نیست، دست برداشتن از این ادعاست که آدرس هویت است. هویت کلاینت را در یک فیلد احراز هویتشده حمل کنید، آن را در دروازه همراه با چندگانه ترجمهشده ثبت کنید و بگذارید برنامه بر آن پیوند بزند. بدون کلید پیوند، ترجمه یک مشکل شبکه را به یک مشکل دائمی جرمیابی تبدیل میکند.
رله رابط دیگری است
یک پروکسی معکوس در جلوی برنامه مسئله مسیر مسیریابیشده را کاملاً دور میزند. پروکسی اتصال بکاند خودش را باز میکند، بنابراین پیشوند کلاینت هرگز لازم نیست درون شبکه مجازی قابل مسیریابی باشد و برنامه میتواند هویت را در سرآیندی که پروکسی تنظیم میکند دریافت کند.
این سرآیند تنها زمانی قابل اعتماد است که بکاند آن را از پروکسی بپذیرد و از هیچ جای دیگری نه. در اصطلاح nginx این یعنی همتای مورد اعتماد را صریحاً نام بردن بهجای باور کردن هر چیزی که میرسد:
set_real_ip_from 10.40.3.10;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
هر کلاینتی که بتواند مستقیماً به بکاند برسد میتواند همان سرآیند را جعل کند، پس بکاند باید جز از طریق پروکسی دسترسناپذیر باشد. این یک واقعیت دیوار آتش است، نه یک نظر پیکربندی، و همان فرضی است که مردم هنگام کپی کردن قطعه از آن میگذرند.
رله همچنین چیزی را که میخرید تغییر میدهد. هویتی در سطح برنامه و جای طبیعی برای ثبت آن به دست میآورید؛ از عمومیت دست میکشید، زیرا هر پروتکل جدید به پشتیبانی پروکسی خودش نیاز دارد. برای سرویسهای HTTP این مبادله معمولاً خوب است و برای هر چیزی که HTTP نیست معمولاً اصلاً در دسترس نیست.
بنویسید هر مرز چه میبیند
هر چه انتخاب کنید، بازبینی طراحی باید با یک جدول پایان یابد که آدرس مبدأ و هویت قابل اثبات را در هر گام نام میبرد. بدون آن، نخستین حادثه سه تیم تولید میکند که هر یک کلاینت متفاوتی را توصیف میکند.
| Boundary | Source the next hop sees | What is actually proven |
|---|---|---|
| Client to gateway | 172.20.8.14 | A certificate or credential was presented |
| Gateway to app subnet, preserved | 172.20.8.14 | The same session, if the return route exists |
| Gateway to app subnet, translated | 10.40.3.10 | Only that traffic came through the gateway |
| Proxy to backend | 10.40.3.10 plus a header | The proxy asserted an identity it authenticated |
سپس انتخاب کنید. مبدأ را حفظ کنید وقتی مجوزدهی برنامه واقعاً به آدرس کلاینت وابسته است و میتوانید مسیر را بر عهده بگیرید. ترجمه کنید وقتی چنین نیست و میتوانید هویت را خارج از باند حمل کنید، و برای تنظیمات ارسال ویژه پلتفرم از راهنمای AWS برای نمونههای ارسالکننده استفاده کنید. وقتی سرویس HTTP صحبت میکند و میخواهید هویت دیگر آدرس نباشد به سراغ رله بروید.