CoPP روی روتر Cisco جایی است که باید بین محافظت از control plane و قطع نکردن مدیریت، routing و مانیتورینگ تعادل بگذارید. اگر policy بیش از حد باز باشد، CPU دستگاه با scan، flood یا ترافیک ناخواسته درگیر می‌شود؛ اگر بیش از حد سخت‌گیرانه نوشته شود، ممکن است SSH، SNMP، routing protocol یا حتی troubleshooting عادی تیم شبکه مختل شود.

در طراحی عملی، اول باید ترافیک‌هایی که واقعاً به خود روتر می‌رسند جدا شوند: مدیریت، routing، ICMP لازم، مانیتورینگ، NTP و سرویس‌های کمکی. بعد برای هرکدام نرخ منطقی، log قابل استفاده و مسیر rollback مشخص شود. برای اینکه این کنترل از بقیه معماری جدا نماند، مرور مسیر Cisco در شبکه و طراحی امنیت شبکه و هاردنینگ هم کنار این موضوع مفید است.

سناریوی واقعی مسئله

سناریوی معمول این است که تیم شبکه یک تغییر ظاهراً ساده می‌دهد: یک policy اضافه می‌شود، یک interface جابه‌جا می‌شود، یک سرویس پشت load balancer قرار می‌گیرد، یا یک مسیر مانیتورینگ/احراز هویت فعال می‌شود. در همان لحظه شاید همه چیز سالم به نظر برسد، اما چند ساعت بعد کاربر می‌گوید بخشی از سرویس کند شده یا بعضی connectionها fail می‌شوند. اینجا اگر فقط به آخرین تغییر نگاه کنیم، احتمالاً علت اصلی را از دست می‌دهیم.

در طراحی Control Plane Policing برای روترهای Cisco باید مسیر داده را مرحله به مرحله دید. اول باید معلوم شود packet یا request از کجا وارد می‌شود، با چه identity یا contextی شناخته می‌شود، کدام rule روی آن match می‌شود، بعد از تصمیم امنیتی به کجا می‌رود، و در نهایت سمت مقصد چه پاسخی می‌دهد. این نگاه ساده است، اما جلوی بیشتر عیب‌یابی‌های پراکنده و حدسی را می‌گیرد.

نشانه مهم در این سناریو معمولاً CPU spike هنگام scan، حمله یا flood به سرویس‌های مدیریتی و routing است. این نشانه به‌تنهایی حکم قطعی نمی‌دهد، ولی جهت بررسی را مشخص می‌کند. اگر نشانه را درست بخوانیم، لازم نیست ده‌ها گزینه را همزمان تغییر بدهیم. تغییر همزمان چند چیز، بدترین دشمن عیب‌یابی در شبکه production است.

قبل از تغییر چه چیزهایی باید ثبت شود؟

قبل از هر اصلاح، snapshot عملیاتی لازم است. منظور فقط backup گرفتن از config نیست. باید بدانیم وضعیت sessionها، hit countها، logها، route table، objectها، certificateها و وضعیت health check در همان لحظه چه بوده است. اگر بعداً تغییر جواب نداد، بدون این snapshot نمی‌شود دقیق برگشت یا فهمید مشکل از کجا شروع شده.

  • پروتکل‌های کنترلی فعال مثل BGP، OSPF، NTP، SSH، SNMP
  • sourceهای مجاز مدیریت
  • baseline CPU و packet rate
  • امکان مانیتور کردن dropها بعد از اعمال policy

این موارد شاید بدیهی به نظر برسند، اما در عمل خیلی از downtimeها از همین جا شروع می‌شود: تغییر انجام شده، اما وضعیت قبل از تغییر ثبت نشده است. وقتی وضعیت قبلی نداریم، rollback هم فقط یک حدس خوش‌بینانه است.

روش عیب‌یابی مرحله‌ای

برای Cisco بهتر است عیب‌یابی را از ساده‌ترین لایه شروع کنیم. اول دسترسی پایه و مسیر را ببینیم، بعد سراغ policy و inspection برویم، بعد وابستگی‌های پیشرفته‌تر مثل profile، identity، certificate یا automation را بررسی کنیم. اگر از همان ابتدا سراغ گزینه‌های پیچیده برویم، احتمالاً یک مشکل ساده routing یا object اشتباه را نمی‌بینیم.

من در این نوع کار معمولاً سه سؤال ثابت می‌پرسم: آیا ترافیک به نقطه تصمیم می‌رسد؟ آیا rule درست match می‌شود؟ آیا بعد از تصمیم، مسیر برگشت و state درست است؟ همین سه سؤال برای بیشتر تجهیزات امنیتی و شبکه‌ای جواب می‌دهد، حتی اگر اسم featureها فرق کند.

show processes cpu sorted
show policy-map control-plane
show access-lists
show ip bgp summary

دستورها و خروجی‌ها باید در همان change record نگهداری شوند. اگر بعداً یک نفر دیگر بخواهد ادامه کار را بگیرد، نباید مجبور شود از صفر بفهمد چه چیزهایی بررسی شده است.

خطاهای رایج

  • نوشتن ACL خیلی عمومی
  • اعمال CoPP بدون مرحله monitor
  • ندیدن تفاوت transit traffic و traffic to router
  • فراموش کردن همسایه‌های routing

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

طراحی درست برای محیط production

در محیط production، اینکه چه ترافیکی به control plane مجاز است و هر کلاس چه rateی نیاز دارد باید از قبل مشخص باشد. یعنی تیم بداند اگر تست اول fail شد چه کاری می‌کند، اگر فقط بخشی از کاربران مشکل داشتند چه چیزی را جدا می‌کند، و اگر rollback لازم شد دقیقاً کدام object یا policy برمی‌گردد. طراحی خوب فقط دیاگرام نیست؛ طراحی خوب یعنی تصمیم‌های روز حادثه از قبل آماده باشند.

برای طراحی Control Plane Policing برای روترهای Cisco بهتر است naming هم جدی گرفته شود. اسم object، rule، profile و monitor باید طوری باشد که شش ماه بعد هم قابل فهم باشد. اسم‌های کوتاه و مبهم شاید زمان ایجاد سریع‌تر باشند، اما هزینه عیب‌یابی را بالا می‌برند. وقتی policy زیاد می‌شود، naming ضعیف خودش به یک ریسک امنیتی تبدیل می‌شود.

موضوع دیگر logging است. لاگ زیاد بدون معنا کمک نمی‌کند؛ لاگ کم هم تیم را کور می‌کند. باید مشخص باشد برای چه decisionهایی log لازم داریم، کدام logها فقط noise تولید می‌کنند، و کدام رویدادها باید به مانیتورینگ یا SIEM بروند. در Cisco این تنظیم اگر درست انجام شود، هم troubleshooting را سریع‌تر می‌کند و هم ردپای تغییرات را نگه می‌دارد.

چک‌لیست اجرا

  1. اول inventory سرویس‌های control plane بگیر
  2. کلاس‌های ضروری و غیرضروری را جدا کن
  3. rate را بر اساس baseline انتخاب کن
  4. در window کم‌ریسک اعمال کن
  5. drop counter و CPU را بعد از change ببین

این چک‌لیست جای تجربه را نمی‌گیرد، ولی جلوی بی‌نظمی را می‌گیرد. تجربه زمانی ارزش دارد که به روش تبدیل شود؛ وگرنه هر بار باید همان اشتباه‌ها را دوباره کشف کنیم.

نمونه پیکربندی مرحله‌ای CoPP روی Cisco IOS

برای اینکه CoPP قابل اجرا باشد، باید آن را مثل یک policy امنیتی واقعی ببینیم، نه چند خط command کپی‌شده. اول ترافیک‌های مجاز به خود روتر را دسته‌بندی می‌کنیم، بعد برای هر دسته rate منطقی می‌گذاریم، و در آخر policy را روی control-plane اعمال می‌کنیم. اعداد زیر نمونه هستند و نباید بدون دیدن baseline همان شبکه روی production کپی شوند.

۱. تعریف sourceهای مجاز برای مدیریت

اول باید مشخص کنیم چه IPهایی حق مدیریت روتر را دارند. اگر این بخش مبهم باشد، CoPP یا خیلی باز نوشته می‌شود یا بعداً دسترسی ادمین‌ها را قطع می‌کند. در مثال زیر فقط subnet مدیریت و jump server اجازه SSH/SNMP دارند.

ip access-list extended MGMT-TO-ROUTER
 permit tcp 10.10.10.0 0.0.0.255 any eq 22
 permit udp 10.10.10.0 0.0.0.255 any eq snmp
 permit tcp host 10.10.20.15 any eq 22
 deny ip any any log

نکته مهم این است که ACL بالا برای transit traffic نیست؛ برای ترافیکی است که مقصدش خود control plane روتر است. همین تفاوت ساده اگر جا بیفتد، خیلی از خطاهای طراحی CoPP کمتر می‌شود.

۲. جدا کردن پروتکل‌های routing و ICMP ضروری

پروتکل‌های کنترلی مثل BGP و OSPF نباید زیر همان محدودیتی بروند که برای scan یا ترافیک ناشناس می‌گذاریم. اگر همسایه‌های routing مشخص هستند، بهتر است آن‌ها را صریح تعریف کنیم. برای ICMP هم معمولاً بهتر است مقدار محدودی اجازه بدهیم تا عیب‌یابی کاملاً کور نشود.

ip access-list extended ROUTING-TO-ROUTER
 permit tcp host 172.16.0.2 any eq bgp
 permit tcp host 172.16.0.6 any eq bgp
 permit ospf 172.16.0.0 0.0.0.255 any
 deny ip any any log

ip access-list extended ICMP-TO-ROUTER
 permit icmp 10.0.0.0 0.255.255.255 any echo
 permit icmp 10.0.0.0 0.255.255.255 any echo-reply
 permit icmp 10.0.0.0 0.255.255.255 any time-exceeded
 deny icmp any any log

۳. ساخت class-mapها

بعد از ACL، کلاس‌ها را می‌سازیم. بهتر است اسم class-map دقیق باشد تا شش ماه بعد هم معلوم باشد قرار بوده چه چیزی را بگیرد. اسم‌هایی مثل CLASS1 یا TEST-COPP در محیط عملیاتی دردسر درست می‌کنند.

class-map match-any COPP-MGMT
 match access-group name MGMT-TO-ROUTER

class-map match-any COPP-ROUTING
 match access-group name ROUTING-TO-ROUTER

class-map match-any COPP-ICMP
 match access-group name ICMP-TO-ROUTER

class-map match-any COPP-UNWANTED
 match access-group name COPP-DROP-UNWANTED

برای ترافیک‌های ناخواسته هم می‌توان ACL جدا نوشت. مثلاً اگر روتر نباید Telnet، HTTP یا DNS به سمت خودش بگیرد، بهتر است این‌ها در کلاس drop یا police بسیار پایین قرار بگیرند.

ip access-list extended COPP-DROP-UNWANTED
 permit tcp any any eq 23
 permit tcp any any eq 80
 permit tcp any any eq 443
 permit udp any any eq 53
 permit tcp any any eq 445
 permit udp any any eq 1900

۴. ساخت policy-map با rate محافظه‌کارانه

در شروع کار نباید rate را تهاجمی انتخاب کرد. اول باید baseline گرفت: در ساعت عادی، هنگام backup، هنگام login ادمین‌ها، هنگام convergence routing و هنگام مانیتورینگ. بعد عددها را پایین‌تر یا بالاتر می‌بریم. مثال زیر برای شروع محافظه‌کارانه است، نه نسخه نهایی برای همه شبکه‌ها.

policy-map CONTROL-PLANE-POLICY
 class COPP-ROUTING
 police 512000 conform-action transmit exceed-action transmit
 class COPP-MGMT
 police 256000 conform-action transmit exceed-action drop
 class COPP-ICMP
 police 64000 conform-action transmit exceed-action drop
 class COPP-UNWANTED
 police 8000 conform-action drop exceed-action drop
 class class-default
 police 128000 conform-action transmit exceed-action drop

برای پروتکل routing در بعضی شبکه‌ها بهتر است در فاز اول exceed-action را drop نگذاریم و فقط monitor کنیم، مخصوصاً اگر هنوز baseline نداریم. بعد از اینکه مطمئن شدیم packetهای سالم drop نمی‌شوند، می‌شود policy را سخت‌تر کرد. CoPP خوب باید با احتیاط سخت شود.

۵. اعمال policy روی control-plane

اعمال policy مرحله‌ای است که باید در change window انجام شود. اگر دسترسی remote است، داشتن console، out-of-band یا حداقل rollback plan ضروری است. قبل از این مرحله باید مطمئن باشیم SSH ادمین از subnet مجاز در ACL مدیریت دیده شده است.

control-plane
 service-policy input CONTROL-PLANE-POLICY

۶. بررسی بعد از اعمال

بعد از اعمال، فقط ping گرفتن کافی نیست. باید counter کلاس‌ها، CPU، وضعیت همسایه‌های routing، SSH/SNMP و logها را ببینیم. اگر class-default یا COPP-UNWANTED ناگهان counter بالایی گرفت، باید بفهمیم حمله است یا ترافیک مجاز که اشتباه دسته‌بندی شده است.

show policy-map control-plane
show processes cpu sorted
show ip bgp summary
show ip ospf neighbor
show access-lists MGMT-TO-ROUTER
show logging | include COPP|SEC|DROP

سناریوی rollback برای CoPP

قبل از اعمال policy باید دستور rollback آماده باشد. اگر بعد از فعال‌سازی، دسترسی مدیریتی قطع شد یا routing neighborها unstable شدند، نباید تازه شروع کنیم به فکر کردن. ساده‌ترین rollback این است که service-policy از control-plane برداشته شود و بعد دلیل dropها بررسی شود.

configure terminal
control-plane
 no service-policy input CONTROL-PLANE-POLICY
end
write memory

در شبکه‌هایی که remote هستند، بهتر است قبل از اعمال CoPP یک زمان‌بندی برگشت هم در نظر گرفته شود؛ مثلاً با EEM یا مکانیزم change کنترل‌شده. هدف این نیست که از CoPP بترسیم؛ هدف این است که اگر policy اشتباه نوشته شد، دسترسی مدیریتی قربانی نشود.

چطور بفهمیم عددهای police درست هستند؟

عدد درست از روی اینترنت انتخاب نمی‌شود. باید چند روز counter بگیریم و ببینیم در حالت عادی هر کلاس چقدر traffic دارد. برای SSH و SNMP معمولاً burst کوتاه طبیعی است. برای ICMP، مقدار زیاد ممکن است هم عیب‌یابی باشد هم scan. برای routing، افت packet می‌تواند convergence را خراب کند. بنابراین در گزارش تحویل CoPP باید baseline و دلیل هر rate نوشته شود.

یک روش عملی این است که policy را ابتدا با rate بالاتر و logging/monitoring فعال کنیم، بعد از دیدن counterها آن را سفت‌تر کنیم. اگر از روز اول drop سخت بگذاریم، ممکن است مشکل را به شکل قطع دسترسی یا ناپایداری routing ببینیم، نه به شکل یک هشدار قابل کنترل.

تحویل کار به تیم بعدی

CoPP باید همراه با جدول sourceهای مجاز و پروتکل‌های ضروری تحویل شود. بدون این جدول، نفر بعدی نمی‌داند کدام drop طبیعی است و کدام drop خطرناک.

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

اگر این موضوع در شبکه شما درگیر چند محصول یا چند تیم است، بهتر است قبل از تغییر نهایی یک جدول مسئولیت هم داشته باشید: مالک policy، مالک route، مالک application، مالک certificate، و کسی که decision نهایی rollback را می‌گیرد. نبودن همین مالکیت‌ها معمولاً زمان حل مشکل را چند برابر می‌کند.

علیرضا عربیان

مشاور و مدرس امنیت شبکه، متخصص FortiGate، FortiWeb و F5 BIG-IP در زیرساخت‌های سازمانی.

مشاهده همه مقالات ←

دیدگاه بگذارید