- مقدمه
- خواندن و نوشتن در سوکتهای مدیریت کلید
- دامپ کردن پایگاه داده ارتباط امن (SADB)
- ایجاد ارتباط امن (SA) ایستا
- مدیریت و نگهداری پویای SA
- خلاصه
۱۹.۱ مقدمه
با معرفی معماری امنیتی برای پروتکل IP (که به اختصار IPsec نامیده میشود)، نیاز مبرمی به یک سازوکار استاندارد برای مدیریت کلیدهای رمزنگاری محرمانه و احراز اصالت احساس شد. در همین راستا، استاندارد RFC 2367 یک API عمومی مدیریت کلید معرفی میکند که هم برای IPsec و هم برای سایر سرویسهای امنیت شبکه قابل استفاده است.
این API دقیقاً مانند سوکتهای مسیریابی (Routing Sockets)، یک خانواده پروتکل جدید به نام دامنهٔ PK_KEY (مخفف protocol family key) ایجاد میکند. در این دامنه نیز تنها نوع raw socket پشتیبانی میشود و باز کردن چنین سوکتی در سیستمهای معمولی UNIX نیازمند دسترسی کاربری ریشه (superuser) است.
پروتکل IPsec خدمات امنیتی خود را بر پایهٔ مفهوم «ارتباط امن» یا همان Security Association (به اختصار SA) به بستهها ارائه میدهد. در واقع یک SA ترکیبی از آدرسهای مبدأ و مقصد، سازوکار امنیتی (مانند احراز اصالت) و دادههای کلید (key material) است و بهصورت اختیاری میتواند پروتکل انتقال و پورتها را نیز در بر بگیرد. ممکن است برای یک جریان ترافیکی خاص، چندین SA مختلف (مانند احراز اصالت و رمزنگاری همزمان) اعمال شود. مجموعهٔ تمام این ارتباطهای امنِ ذخیرهشده در سیستم را پایگاه داده ارتباط امن یا SADB (مخفف Security Association Database) مینامند.
پایگاه داده SADB علاوه بر IPsec در بخشهای متعدد دیگری نیز کاربرد دارد؛ از این رو سوکتهای PK_KEY منحصراً به IPsec محدود نمیشوند.
علاوه بر این، IPsec به پایگاه داده سیاستهای امنیتی یا SPDB (مخفف Security Policy Database) نیز نیاز دارد که الزامات و قوانین ترافیک را تعیین میکند؛ به عنوان مثال: «ترافیک میان هاست A و هاست B باید با استفاده از پروتکل IPsec AH (هدر احراز اصالت) تأیید اعتبار شود و هر ترافیکی غیر از این باید دور ریخته (drop) شود».
در نقطهٔ مقابل، SADB نحوهٔ اجرای مراحل امنیتیِ مورد نیاز را مشخص میکند. برای نمونه، اگر ترافیک بین هاست A و هاست B از پروتکل IPsec AH استفاده کند، SADB تعیین میکند که کدام الگوریتمها و چه کلیدهایی باید به کار گرفته شوند.
هیچ سازوکار استانداردی برای مدیریت و نگهداری SPDB وجود ندارد. پروتکل PF_KEY امکان نگهداری SADB را فراهم میکند اما از SPDB پشتیبانی نمیکند. پیادهسازی IPsec پروژهٔ KAME برای نگهداری SPDB از افزونههای PF_KEY بهره میبرد، اما هیچ استاندارد رسمی برای آن تعریف نشده است.
سه نوع عملیات پشتیبانیشده در سوکتهای مدیریت کلید
۱) نوشتن (Write): ارسال پیام به کرنل و تمام فرآیندهایی (process) که یک سوکت مدیریت کلیدِ باز دارند. از این طریق میتوان آیتمهای SADB را اضافه یا حذف کرد. همچنین فرآیندهایی مانند OSPFv2 که امنیت اختصاصی خود را مدیریت میکنند، با این روش کلیدهای مورد نیازشان را از دیمن مدیریت کلید درخواست مینمایند.
۲) خواندن (Read): خواندن پیامها از سوی کرنل یا سایر فرآیندها. کرنل با بهرهگیری از این قابلیت میتواند از دیمن مدیریت کلید درخواست کند تا برای یک نشست TCP جدید که طبق سیاستها نیازمند حفاظت است، یک SA مستقر نماید.
۳) درخواست دامپ (Dump Request): یک فرآیند میتواند پیام درخواست دامپ را به کرنل بفرستد و کرنل با ارائهٔ دامپ کاملی از وضعیت فعلی SADB پاسخ خواهد داد. این قابلیت عمدتاً جنبهٔ خطایابی و دیباگ دارد و ممکن است در تمام سیستمها در دسترس نباشد.
۱۹.۲ خواندن و نوشتن در سوکتهای مدیریت کلید
تمام پیامها در سوکتهای مدیریت کلید، هدر پایهٔ یکسانی دارند. بسته به اینکه چه اطلاعات مضاعفی در دسترس بوده یا درخواست شده باشد، پس از هر پیام ممکن است افزونهها (extensions) گوناگونی قرار بگیرند.
هر پیام و افزونههای آن به صورت ۶۴ بیتی تراز (aligned) شدهاند و طولی مضرب از ۶۴ بیت دارند. تمامی فیلدهای طول بر حسب واحدهای ۶۴ بیتی محاسبه میشوند؛ به این معنی که مقدار طول ۱ نشاندهندهٔ ۸ بایت است.
چنانچه طول داده به مضرب ۶۴ بیت نرسد، بایتهای پدینگ (padding) اضافه میشوند تا به مضرب بعدی ۶۴ بیت برسد. مقدار این پدینگها تعریفنشده و نامشخص است.
مقدار فیلد sadb_msg_type مشخص میکند که کدامیک از ۱۰ دستور جدول زیر فراخوانی شده است.
به دنبال هر ساختار پیام SADB، صفر یا چند افزونه قرار میگیرد. اکثر انواع پیامها دارای افزونههای اجباری و اختیاری هستند.
در جدول زیر، ۱۶ افزونه و نام ساختارهایی که از آنها استفاده میکنند فهرست شده است.
۱۹.۳ دامپ کردن SADB
برای دامپ گرفتن از وضعیت فعلی SADB، فرآیند از پیام SADB_DUMP استفاده میکند. این پیام سادهترین پیام ممکن است، چرا که به هیچ افزونهای نیاز ندارد و تنها به یک هدر ۱۶ بایتی sadb_msg بسنده میکند.
کرنل از طریق همان سوکت، مجموعهای از پیامهای SADB_DUMP را ارسال میکند که هر یک حاوی یک ورودی از SADB است. پیامی که مقدار فیلد sadb_msg_seq در آن برابر با ۰ باشد، نشاندهندهٔ پایان این توالی است.
با تنظیم مقدار فیلد sadb_msg_satype در درخواست، میتوان نوع SAهای بازگشتی را محدود کرد؛ در حالی که مقدار SADB_SATYPE_UNSPEC باعث بازگرداندن تمامی SAها میشود.
تمام پیادهسازیها از همهٔ انواع SA پشتیبانی نمیکنند. اگر نوعی از SA درخواست شود که پیادهسازی نشده باشد، کد خطای errno EINVAL بازگردانده میشود؛ و اگر نوع درخواستی فاقد هرگونه داده در جدول باشد، errno ENOENT دریافت خواهد شد.
نمونهای از دامپ کردن SADB
key/dump.c
نمونه اجرای برنامه در سیستمی با دو SA ایستا
۱۹.۴ ایجاد SA ایستا
سادهترین روش برای افزودن یک SA، ارسال پیام SADB_ADD به همراه تمامی پارامترهای لازم است که این مقادیر معمولاً بهصورت دستی تعیین میشوند.
تعیین دستی دادههای کلید (key material)، فرآیند «تعویض کلید» را — که برای پیشگیری از حملات تحلیل رمزنگاری (cryptanalysis) حیاتی است — دشوار میسازد؛ اما با این حال، پیکربندی بسیار ساده و سرراستی دارد.
پیام SADB_ADD نیازمند سه افزونهٔ اجباری است (SA، آدرس و کلید). علاوه بر این، میتواند شامل افزونههای اختیاری دیگری (مانند طول عمر، شناسه و سطح حساسیت) نیز باشد. در ادامه ابتدا به افزونههای اجباری میپردازیم. افزونهٔ SA توسط ساختار sadb_sa در زیر توصیف میشود:
sadb_sa_api: شناسه SPI همراه با آدرس مقصد و پروتکل، برای شناسایی یکتای SA به کار میرود. هنگام دریافت بسته، این مقدار برای یافتن SA مربوطه استفاده میشود و موقع ارسال بسته نیز درون آن قرار میگیرد تا طرف مقابل بتواند از آن بهره ببرد.
از آنجا که این مقدار فینفسه بار معنایی خاصی ندارد، میتوان آن را به صورت ترتیبی یا تصادفی و بر اساس ترجیح سیستم مقصد تولید کرد.
sadb_sa_replay: اندازهٔ پنجره برای محافظت در برابر حملات بازپخش (replay attacks) را تعیین میکند. از آنجا که کلیدگذاری ایستا با کلیدهای ثابت مانع از کارکرد محافظت در برابر بازپخش میشود، این مقدار را برابر با ۰ قرار میدهیم.
sadb_sa_state: این مقدار در طول چرخهٔ حیات SAهایی که به صورت پویا ایجاد میشوند تغییر میکند؛ با این حال، SAهایی که به صورت دستی ساخته شدهاند همواره در وضعیت SADB_SASTATE_MATURE قرار دارند.
sadb_sa_flags: برای این فیلد تنها یک فلگ به نام SADB_SAFLAGS_PFS تعریف شده است. این فلگ ویژگی رازداری پیشرو کامل (Perfect Forward Secrecy یا PFS) را درخواست میکند؛ به این معنا که مقدار کلید فعلی نباید به کلیدهای قبلی یا هیچ مستر کی (Master Key) خاصی وابسته باشد. این فلگ صرفاً هنگام درخواست کلید از برنامههای مدیریت کلید به کار میرود و در زمان افزودن SAهای ایستا استفاده نمیشود.
در ادامه به دومین افزونهٔ لازم برای دستور SADB_ADD یعنی افزونهٔ آدرس (Address Extension) میپردازیم.
آدرس مبدأ (SADB_EXT_ADDRESS_SRC) و آدرس مقصد (SADB_EXT_ADDRESS_SRC) اجباری هستند، در حالی که آدرس پروکسی (SADB_EXT_ADDRESS_PROXY) اختیاری است.
sadb_address_proto: پروتکل IP که قرار است با این SA تطبیق داده شود.
sadb_address_prefixlen: تعیین طول پیشوند (Prefix) برای آدرسهای مهم، که از طریق آن امکان تطبیق با دو یا چند آدرس فراهم میشود.
بلافاصله پس از ساختار sadb_address، ساختار آدرس سوکت مربوط به Family مناسب قرار میگیرد. شماره پورت در این ساختار تنها در صورتی اهمیت دارد که sadb_address_proto پروتکلی را مشخص کرده باشد که از شماره پورت پشتیبانی میکند (مانند IPPROTO_TCP).
آخرین افزونهٔ الزامی برای پیام SADB_ADD، کلیدهای احراز اصالت و رمزنگاری هستند.
sadb_key_exttype: مشخص میکند که کلید از نوع احراز اصالت است یا رمزنگاری.
sadb_key_bits: تعداد بیتهای موجود در کلید.
دادههای اصلی کلید نیز درست پس از این ساختار قرار میگیرند.
نمونهبرنامه برای ایجاد SA ایستا (Static SA)
key/add.c
نمونه نحوه اجرای برنامه
پاسخ دریافتی شامل کلید نیست؛ چراکه این پاسخ برای تمام سوکتهای PF_KEY ارسال میشود و کلید نباید فاش گردد.
پس از افزودن SA به SADB، با دستور ping استفاده از این SA را فعال کرده و سپس با گرفتن خروجی (Dump) از SADB، صحت عملکرد آن را بررسی میکنیم.
همانطور که مشاهده میکنید، کرنل پروتکل IP شماره ۰ را به ۲۵۵ تغییر داده است؛ البته این رفتار جزو ویژگیهای عمومی سوکتهای PF_KEY نیست، بلکه از خصوصیات خاص همین پیادهسازی بهشمار میرود.
علاوه بر این، مشخص است که کرنل طول پیشوند آدرس را از ۳۲ به ۱۲۸ تغییر داده که به نظر میرسد ناشی از نوعی تداخل و سردرگمی میان IPv4 و IPv6 در داخل کرنل باشد.
کرنل در پاسخ، افزونهٔ شماره ۱۹ را بازمیگرداند که برنامهٔ ما قادر به تحلیل آن نیست؛ چنین افزونههای ناشناختهای با استفاده از فیلد طول افزونه نادیده گرفته شده و رد (Skip) میشوند.
مشاهده میشود که افزونهٔ طول عمر کلید، حاوی اطلاعات مربوط به چرخهٔ حیات فعلی SA، در پاسخ بازگردانده شده است.
کرنل در صورت رسیدن به طول عمر موقت (soft lifetime)، پیام SADB_EXPIRE را ارسال میکند و با رسیدن به طول عمر قطعی (hard lifetime)، استفاده از SA کاملاً متوقف میشود.
افزونهٔ SADB_EXT_LIFETIME_CURRENT در پاسخ پیامهای SADB_DUMP، SADB_EXPIRE و SADB_GET گنجانده شده و بازگردانده میشود تا وضعیت و مقادیر فعلی SA را تشریح کند.
۱۹.۵ مدیریت و نگهداری پویای SA
برای حفظ امنیت در سطحی ایدهآل، نیاز به بازتولید دورهای کلیدها (Rekeying) امری ضروری است.
برای آگاهی از زمان نیاز به یک SA بین یک جفت هاست جدید، دیمن با ارسال پیام SADB_REGISTER خود را در کرنل ثبت میکند. در این فرایند، نوع SA قابلپشتیبانی (بر اساس مقادیر Figure 19.3) در فیلد sadb_msg_satype تعیین میشود. اگر دیمن توانایی پردازش چندین نوع SA را داشته باشد، چندین پیام SADB_REGISTER مجزا ارسال میکند تا هر نوع بهطور جداگانه ثبت شود.
کرنل در پیام پاسخ SADB_REGISTER، افزونهٔ الگوریتمهای پشتیبانیشده را ضمیمه میکند؛ این افزونه مکانیزمهای رمزنگاری و/یا احراز اصالت مورد پذیرش و طول کلیدهای مربوطه را مشخص میسازد. این افزونه با ساختار sadb_supported تعریف میشود که صرفاً از یک هدر افزونه و در ادامه، مجموعهای از ساختارهای sadb_alg برای تشریح الگوریتمهای رمزنگاری یا احراز اصالت تشکیل شده است.
نمونهبرنامه برای ثبت در سوکت مدیریت کلید
برنامهٔ زیر صرفاً مکانیزم مورد نظر را در کرنل ثبت کرده و در ادامه، لیست الگوریتمهای پشتیبانیشده دریافتی در پاسخ را در خروجی چاپ میکند.
key/register.c
نمونه نحوه اجرای برنامه
جریان مدیریت پویای کلید
هنگامی که کرنل قصد برقراری ارتباط با یک پییر (Peer) را دارد و طبق پالیسیها به یک SA نیاز است اما SA فعالی وجود ندارد، کرنل پیام SADB_ACQUIRE را برای سوکتهای مدیریت کلیدی که نوع SA مورد نظر را ثبت کردهاند ارسال میکند. این پیام شامل یک افزونهٔ پیشنهادی است که الگوریتمها و طول کلیدهای مدنظر کرنل را مشخص میکند.
این پیشنهاد در اصل فهرستی از الگوریتمها، طول کلیدها و طول عمر آنها است که به ترتیب اولویت مرتب شدهاند.
به محض دریافت پیام SADB_ACQUIRE توسط دیمن مدیریت کلید، اقدامات لازم برای انتخاب کلیدی متناسب با یکی از ترکیبهای پیشنهادی کرنل انجام شده و این کلید روی کرنل نصب میگردد.
دیمن با استفاده از پیام SADB_GETSPI از کرنل میخواهد تا یک SPI مناسب را از محدودهٔ مورد نظر انتخاب کند. پاسخ کرنل به SADB_GETSPI شامل ایجاد یک SA در وضعیت مقدماتی (Larval) خواهد بود. سپس دیمن با بهرهگیری از SPI ارائهشده، پارامترهای امنیتی (الگوریتمها، روش تبادل کلید، نسخهٔ پروتکل و...) را با طرف مقابل مذاکره کرده و در نهایت با ارسال پیام SADB_UPDATE، ساختار SA را تکمیل و آن را به وضعیت نهایی و پایدار (Mature) منتقل میکند.
ساختارهای SA ایجادشده بهصورت پویا معمولاً هم دارای soft lifetime و هم hard lifetime هستند. با انقضای هر یک از این دو، کرنل با ارسال پیام SADB_EXPIRE اعلام میکند که کدام طول عمر به پایان رسیده است. در صورت انقضای soft lifetime، وضعیت SA به حالت در حال زوال (Dying) درمیآید؛ در این حالت هنوز میتوان از SA استفاده کرد اما باید هرچه سریعتر یک SA جدید دریافت شود. اما با انقضای hard lifetime، وضعیت SA به حالت منقضی (Dead) درآمده، دیگر برای اهداف امنیتی استفاده نمیشود و از پایگاه دادهٔ SADB حذف خواهد شد.
۱۹.۶ جمعبندی
- سوکتهای مدیریت کلید وظیفهٔ برقراری ارتباط و تبادل اطلاعات SA میان کرنل، دیمنهای مدیریت کلید، دیمنهای مسیریابی و سایر بخشها را بر عهده دارند.
- تخصیص و نصب SA میتواند بهصورت دستی و ایستا (Static) یا بهشکل پویا (Dynamic) از طریق پروتکلهای مذاکرهٔ کلید انجام پذیرد.
- کلیدهای پویا دارای طول عمر مشخصی هستند و مدیریت آنها بر پایهٔ دو مفهوم طول عمر موقت (Soft) و قطعی (Hard) تعریف میشود.
- از طریق سوکتهای مدیریت کلید، ۱۰ نوع پیام مختلف میان پردازهها و کرنل رد و بدل میشود.
- هر یک از این انواع پیامها شامل مجموعهای از افزونههای الزامی و اختیاری هستند.
- پیامهای ارسالی توسط یک پردازه، پس از حذف اطلاعات حساس و محرمانه، به سایر سوکتهای بازِ مدیریت کلید نیز ارسال (Forward) میشوند.