شروع جمعآوری تاریخچه BGP با استفاده از BMP
من بیش از 25 سال است که در زمینه عیبیابی (Troubleshooting) مشکلات شبکه ارائهدهندگان خدمات (Service-provider) فعالیت میکنم. در این مدت تغییرات بسیاری رخ داده است. شبکههای ارائهدهندگان خدمات از پلتفرمهای مبتنی بر IOS در سریهای 7200/7500 به سمت IOS XR بر روی ASR 9000 و CRS، و سپس به سمت NCS 5500 و پلتفرمهای جدیدتر حرکت کردهاند. روترها به نرخهای فورواردینگ (Forwarding rates) در مقیاس ترابیت دست یافتهاند و جداول مسیریابی (Routing tables) به میلیونها مسیر افزایش یافتهاند.
با وجود این تحول، پاسخ دادن به برخی از پرسشهای عملیاتی همچنان دشوار است:
- دو روز پیش در ساعت 14:15 به وقت CET، گام بعدی (Next Hop) برای یک مسیر BGP خاص چه بود؟
- در طول یک قطعی گزارششده، یک مسیر چه کامیونیتیهایی (Communities) را حمل میکرد؟
- برچسب خروجی (Egress Label)، وضعیت فورواردینگ (Forwarding State) یا ویژگی مسیر (Route Attribute) در یک لحظه خاص از زمان چه بود؟
- یک مسیر دقیقاً چه زمانی شروع به نوسان (Flapping) کرد و بهروزرسانیها از کدام همتا (Peer) دریافت شدند؟
اینها پرسشهایی درباره وضعیت گذشته شبکه هستند. بدون وجود وضعیت تاریخی BGP، پاسخ دادن به آنها همچنان دشوار است. فقدان اطلاعات تاریخی، مهندس شبکه را مجبور میکند تا به جای تکیه بر حقایق، به حدس و گمان یا ارائه نظریههای احتمالی روی آورد.
این پروژه یک خط لوله (Pipeline) عملیاتی برای جمعآوری و ذخیرهسازی BMP ارائه میدهد و همچنین دارای یک رابط کاربری وب (Web UI) است که نشان میدهد چگونه میتوان از اطلاعات تاریخی BGP جمعآوریشده برای اهداف تحلیلی پایه استفاده کرد.
چرا روشهای سنتی ناکارآمد هستند
سیستمعاملهای شبکه مدرن، ردپاهای (Traces) بسیار غنیتری نسبت به پیامهای قدیمی syslog و کنسول که بسیاری از ما با آنها بزرگ شدهایم، تولید میکنند. این ردپاها مفید هستند، اما پاسخ کاملی برای تحلیل وضعیت مسیر (Route-state analysis) در گذشته محسوب نمیشوند.
ردیابیها (Traces) دارای چندین محدودیت عملی هستند:
- آنها اغلب نیازمند یک مهندس شبکه هستند تا به صورت دستی حجم عظیمی از دادهها را جستجو کند.
- آنها معمولاً برای توسعهدهندگان و مالکان پروتکل نوشته شدهاند، نه برای پرسوجوهای سریع تاریخچه مسیر (Route-history) عملیاتی.
- آنها میتوانند حجم قابل توجهی از دادهها را بدون نمایش وضعیت BGP به شکلی که اپراتور نیاز دارد، تولید کنند.
یک رویکرد رایج دیگر، جمعآوری اطلاعات مسیر (Route) با استفاده از اسکریپتهایی است که دستورات CLI را اجرا کرده و خروجی را استخراج (Scrape) میکنند. این روش در شبکههای مدرن مقیاسپذیری (Scalability) مناسبی ندارد. خروجی دستورات دقیق BGP میتواند بسیار حجیم باشد، فرمت دستورات ممکن است بین نسخههای مختلف تغییر کند و استخراج متن (Text scraping) هم هزینهبر و هم آسیبپذیر است. در یک روتر مقیاسپذیر، اجرای یک دستور مسیر (Route) دقیق ممکن است دهها دقیقه زمان ببرد.
تلهمتری جریانی (Streaming telemetry) و رویکردهای مبتنی بر gRPC میتوانند قابلاطمینان و کارآمد باشند، بهویژه زمانی که از انتشار رویداد-محور (event-driven) بهروزرسانیهای مسیر (route updates) پشتیبانی کنند. چالش اصلی، سازگاری (consistency) است: پشتیبانی از این قابلیتها در پیادهسازیهای مختلف BGP speaker و نسخههای نرمافزاری متفاوت، متغیر است.
چرا BMP مناسب است
پروتکل نظارت بر BGP (BMP) برای حل این نوع مشکلات طراحی شده است. این پروتکل یک روش استاندارد برای نظارت بر نشستهای BGP (BGP sessions) و دریافت دیدگاههای مسیر (route views) از BGP speakers است. BMP در سند زیر تعریف شده است:RFC 7854.
پروتکل BMP یک پروتکل مسیریابی (Routing Protocol) نیست، بلکه یک پروتکل نظارتی (Monitoring Protocol) است. یک جمعآوریکننده (Collector) در BMP میتواند نمای اولیهای از مسیرهای BGP تحت نظارت را دریافت کرده و سپس به دریافت بهروزرسانیهای افزایشی مسیر، رویدادهای اتصال همتا (Peer-up events)، رویدادهای قطع اتصال همتا (Peer-down events) و آمارها ادامه دهد.
The exact visibility depends on the BGP speaker implementation, BMP configuration, and whether pre-policy, post-policy, or both views are exported. In many service-provider designs, connecting BMP collectors to route reflectors provides broad visibility into the BGP domain because route reflectors already observe a large portion of the BGP update stream.
این ویژگی، BMP را به منبعی طبیعی برای جمعآوری تاریخچه مسیر (Route-history) تبدیل میکند.
از جریان BMP به تاریخچه قابل پرسوجو (Queryable History)
جمعآوری پیامهای BMP تنها گام نخست است. برای پاسخ به پرسشهای عملیاتی، دادهها باید تجزیه (Parsed)، نرمالسازی (Normalized)، ذخیرهسازی (Persisted) و قابل جستجو (Queryable) شوند.
این راهکار از رویکرد «خط لوله پردازش» (processing pipeline) استفاده میکند که در آن هر مرحله از پردازش، مسئول مجموعهای بسیار مشخص از اقدامات است. از تولیدکننده اطلاعات BMP گرفته تا مصرفکننده اطلاعات تاریخی ذخیرهشده، هر مرحله اطلاعات را دریافت، اعتبارسنجی، تغییر و به مرحله بعدی منتقل میکند تا آن را به یک منبع قابلاطمینان و حقیقتی غیرقابلانکار از چرخه حیات یک مسیر BGP تبدیل کند.
نمودار زیر نمایشی بصری از اجزا و جریان اطلاعات ارائه میدهد.
Routers / Route Reflectors
|
| BMP (RFC 7854)
v
+---------+
| GoBMP | parses BMP and publishes JSON
+----+----+
|
| Kafka topics (gobmp.parsed.*)
v
+----------------------------------+
| GoBMP-MongoDB Connector |
| |
| Kafka consumer |
| consumes per-AFI/SAFI topics |
| |
| MongoDB writer |
| stores current route state |
| stores route event history |
| tracks statistics and damping |
+----------------+-----------------+
|
v
MongoDB
|
v
Queries, dashboards, reports,
correlation, alerting, analytics
GoBMP عملیات تجزیه (Parsing) پروتکل BMP را انجام داده و اسناد مسیر (Route) را به صورت JSON ساختاریافته در Kafka منتشر میکند، بنابراین به عنوان تولیدکننده (Producer) پیامهای ترجمهشده BGP/BMP عمل میکند. رابط (Connector) GoBMP-MongoDB این موضوعات (Topics) را از Kafka دریافت کرده و MongoDB را بهروزرسانی میکند. مهمترین نتیجه این فرآیند، یک صفحه یا گردشکار (Workflow) خاص نیست، بلکه ایجاد یک تاریخچه پایدار و قابل جستجو از وضعیت BGP است.
آنچه GoBMP-MongoDB Connector ذخیره میکند
برای هر مسیر، MongoDB وضعیت فعلی و تاریخچه رویدادها را نگهداری میکند. این قابلیت امکان پرسش درباره «وضعیت فعلی چیست؟» و «این وضعیت در طول زمان چگونه تغییر کرده است؟» را فراهم میسازد.
دادههای ذخیرهشده شامل هویت مسیر (Route Identity)، اطلاعات همتا (Peer Information)، منبع BMP، شناسه مسیر (Path ID)، ویژگیهای BGP، برچسبهای زمانی (Timestamps) و ورودیهای تاریخچه است. برای مسیرهای VPN، متمایزکننده مسیر (Route Distinguisher) بخشی از هویت مسیر است که امکان بازرسی در سطح VRF را فراهم میکند.
این کانکتور همچنین دادههای مربوط به ناپایداری مسیر (Route Instability) را نگهداری میکند. این ابزار، فراخوانیها (Withdrawals)، اعلانها (Announcements)، تغییرات ویژگیها (Attribute Changes) و معیارهای میرایی مسیر BGP (BGP Route Dampening) را ردیابی میکند تا اپراتورها بتوانند به سرعت پیشوندهای (Prefixes) ناپایدار یا با تغییرات مکرر را شناسایی کنند.
در ادامه لیست خانوادههای آدرس (Address Families) پشتیبانیشده و ذخیرهشده آمده است:
- IPv4 unicast
- IPv6 unicast
- VPNv4
- VPNv6
چرا Kafka در میانه قرار دارد
Kafka یک جداسازی مفید بین جمعآوری و ذخیرهسازی در خط لوله (Pipeline) ایجاد میکند. GoBMP میتواند بر تجزیه (Parsing) پروتکل BMP و انتشار پیامهای مسیر تمرکز کند. کانکتور MongoDB میتواند بر مصرف آن پیامها، حفظ ترتیب در موارد ضروری و نوشتن وضعیت مسیر در پایگاه داده تمرکز نماید.
این جداسازی همچنین تکامل سیستم را آسانتر میکند. مصرفکنندگان (Consumers) اضافی میتوانند بدون نیاز به تغییر در لایه جمعآوری BMP، در همان موضوعات (Topics) مشترک شوند. اپراتورها میتوانند بسته به نیازهای خود در زمینه تحلیل (Analytics)، نظارت (Monitoring) یا بایگانی (Archival)، تصمیم بگیرند که به یک مصرفکننده پاییندست (Downstream consumer) نیاز دارند یا چندین مصرفکننده.
اپراتورها چه پاسخی میتوانند بدهند
هنگامی که اطلاعات مسیر ذخیره میشود، گردش کار عیبیابی (Troubleshooting) تغییر میکند. به جای جستجو در میان ردپاها (Traces) یا تلاش برای بازتولید یک خرابی گذشته، اپراتور میتواند مستقیماً تاریخچه را جستجو (Query) کند.
لطفاً متن ورودی خود را پس از عبارت “Examples:” قرار دهید تا طبق قوانین و دستورالعملهای تعیینشده، ترجمه دقیق آن را برای شما انجام دهم.
- Show me the state of
45.8.233.0/24in theپیشوند یونیکست (unicast_prefix_v4)collection at a specific timestamp. - نمایش تمامی بهروزرسانیها برای یک مسیر (Route) از نوع VPNv4 در یک شناسهگذار مسیر (Route Distinguisher) مشخص.
- لیست مسیرهایی (Routes) که بیشترین تعداد حذف (Withdrawal count) را در یک ساعت گذشته داشتهاند، نمایش دهید.
- مقایسه تاریخچه مسیر (Route History) در میان همتایان (Peers).
- زمان تغییر در گام بعدی (Next Hop)، برچسب (Label)، مسیر AS (AS Path) یا لیست کامیونیتی (Community List) یک مسیر را پیدا کنید.
داشبورد ارائه شده همراه باGoBMP-MongoDB Connectorیک نمونه از نحوه استفاده از این دادهها است. این داشبورد بر پرسشهای عملیاتی رایج مانند تحلیل مسیرهای نوسانی (flapping-route)، تغییرات اخیر مسیر، آمار همتایان (peer statistics)، جستجوی مسیر و جزئیات مسیر تمرکز دارد.
اما داشبورد، بخش اصلی و مرکزی نیست. بخش اصلی، تاریخچه جمعآوریشده BGP است. هنگامی که دادهها موجود باشند، تیمها میتوانند تحلیلهایی را ایجاد کنند که برای محیط کاری آنها معنادار باشد: داشبوردها، گزارشها، تشخیص ناهنجاری (Anomaly Detection)، زمانبندی رخدادها (Incident Timelines)، مطالعات ظرفیت (Capacity Studies)، مقایسه همتایان (Peer Comparisons)، اعتبارسنجی سیاستهای مسیریابی (Route-policy Validation) یا یکپارچهسازی با پلتفرمهای مشاهدهپذیری (Observability Platforms) موجود.
نکته اصلی
اگر بخواهیم به پرسشهای مربوط به وضعیت گذشته BGP پاسخ دهیم، باید آن وضعیت را پیش از وقوع، در حین وقوع و پس از پایان قطعی (Outage) جمعآوری کنیم.
پروتکل BMP منبعی کاربردی از بهروزرسانیهای مسیر BGP در اختیار ما قرار میدهد. ابزار GoBMP پیامهای BMP را به دادههای ساختاریافته تبدیل میکند. Kafka یک لایه انتقال (Transport Layer) بین تولیدکنندگان و مصرفکنندگان فراهم میآورد. MongoDB تاریخچه پایداری از مسیرها را ارائه میدهد. ایناتصالدهنده GoBMP-MongoDBاین بخشها را به یکدیگر متصل کرده و جریان بهروزرسانیهای مسیر را به مجموعهدادهای ماندگار تبدیل میکند که اپراتورها و سیستمهای اتوماسیون میتوانند آن را جستجو، همبستهسازی و تحلیل کنند.
بدون داده، هیچ تحلیل (Analytics) وجود ندارد. هنگامی که تاریخچه مسیر (Route history) موجود باشد، پرسشهایی که قبلاً دشوار بودند، به پرسوجوهای پایگاه داده (Database queries) تبدیل میشوند.
در دسترس بودن (Availability)
اتصالدهنده GoBMP-MongoDBبه عنوان یک کانتینر داکر (Docker container) در داکر هاب (Docker Hub) به آدرس docker.io/sbezverk/gobmp-mongodb-connector در دسترس است
توپولوژی آزمایشگاهی نمونه
برای مثالهای این پست، من از یک آزمایشگاه کوچک استفاده میکنم که در آن مسیرها به یک نمونه Cisco XRd تزریق شده، از طریق BMP صادر شده، توسط GoBMP تجزیه (Parse) شده، از طریق Kafka تحویل داده شده و توسطGoBMP-MongoDB Connectorدر MongoDB ذخیره میشوند.
bgpinjector
(RIS Live and manual injection)
|
v
Cisco XRd 26.2.1
|
v
GoBMP collector
|
v
Kafka
|
v
GoBMP-MongoDB Connector
|
v
MongoDB
یادداشتهای محیط آزمایشگاهی و عملکرد (Performance)
در این آزمایشگاه،bgpinjectorجریان زنده RIS را دریافت کرد و همچنین از تزریق دستی مسیر (Route Injection) پشتیبانی نمود. در طول این تست، خط لوله (Pipeline) تقریباً 1500 رویداد مسیر در ثانیه را پردازش کرد. دیتابیس MongoDB به صورت یک مجموعه تکرار شونده (Replica Set) تک-شارد در همان محیط آزمایشگاهی مستقر شد.
یک پیکربندی تک ماشین مجازی (VM) با 16 گیگابایت رم (RAM) و 8 پردازنده مجازی (vCPU) که برای این بستر تست استفاده شده است، جهت نمایش مدل داده و اعتبارسنجی خط لوله جمعآوری (Collection Pipeline) تحت نرخ رویداد معنادار مفید است. این پیکربندی نباید به عنوان طرح پیشنهادی برای محیط عملیاتی (Production) در نظر گرفته شود.
برای محیطی نزدیک به محیط عملیاتی (Production)، حداقل استقرار سه ماشین مجازی (VM) را در نظر بگیرید. Kafka باید قادر به اجرا با قابلیت تکثیر کارگزار (Broker Replication) باشد و MongoDB نیز باید بتواند در حالت توزیعشده عادی خود اجرا شود: در صورت نیاز به صورت قطعهبندیشده (Sharded) و با استفاده از مجموعههای تکثیر (Replica Sets) برای فراهم کردن افزونگی (Redundancy). تعیین اندازه نهایی به تعداد همتایان (Peer Count)، مقیاس مسیر (Route Scale)، نرخ رویداد (Event Rate)، دوره نگهداری (Retention Period)، استراتژی نمایهسازی (Indexing Strategy) و حجم کاری پرسوجو (Query Workload) بستگی دارد. فضای دیسک عمدتاً توسط سیاست نگهداری (Retention Policy) مورد نظر کنترل میشود و باید با در نظر گرفتن همان سیاست محاسبه گردد.
تجسم نمونه
داشبورد گنجاندهشده، تنها یک نمونه از مصرفکنندگان دادههای تاریخچه مسیر (route-history) جمعآوریشده است. این داشبورد عمداً تنها راه استفاده از مجموعه داده (dataset) نیست، اما به نمایش این موضوع کمک میکند که چگونه میتوان پرسشهای عملیاتی رایج را بهسرعت ارائه کرد.

همان مدل داده (Data Model) از مسیرهای VPN نیز پشتیبانی میکند که در آن Route Distinguisher بخشی از هویت مسیر (Route Identity) است.

بیایید از درخواست از مهندسان برای انجام کارهای ماشینی به صورت دستی دست برداریم و استفاده از تاریخچه جمعآوریشده BGP را به عنوان منبعی از حقایق آغاز کنیم.
پیوست الف: نمونهای از پیکربندی (Configuration) پروتکل BGP در نمونه XRD استفاده شده در بستر تست
route-policy pass-all
pass
end-policy
!
router bgp 5070
bgp router-id 1.1.1.1
# Activating all address families we want to support
address-family ipv4 unicast
label mode per-vrf
redistribute connected
!
address-family vpnv4 unicast
retain route-target all
!
address-family ipv6 unicast
redistribute connected
!
address-family vpnv6 unicast
retain route-target all
!
# BGP peer connection to bgpinjecor process
neighbor 10.2.1.5
remote-as 50123
ebgp-multihop 254
tcp mtu-discovery
# Activating BMP server to send all BGP updates
# received from bgpinjector towards GoBMP collector
bmp-activate server 1
update-source GigabitEthernet0/0/0/1
address-family ipv4 unicast
route-policy pass-all in
route-policy pass-all out
!
address-family ipv4 labeled-unicast
route-policy pass-all in
route-policy pass-all out
!
address-family vpnv4 unicast
route-policy pass-all in
route-policy pass-all out
!
address-family ipv6 unicast
route-policy pass-all in
route-policy pass-all out
!
address-family vpnv6 unicast
route-policy pass-all in
route-policy pass-all out
!
!
!
# Configure BMP collector
bmp server 1
host 10.1.1.2 port 5000
!
پیوست ب: نمونههای کوئری MongoDB
موارد زیرmongoshپرسوجوها (Queries) نمونههای پیشنویس برای دادههای آزمایشگاهی هستند. آنها از مسیر (route) در مجموعه (collection) unicast_prefix_v4 استفاده میکنند.45.8.233.0/24درپیشوند تکپخشی (Unicast Prefix) نسخه 4مجموعه.
این پیوست دو نمونه معرف را در پست اصلی نگه میدارد. مجموعه پرسوجو (Query) کامل و گزیدههای نتایج در دسترس هستند در مخزن gobmp-mongodb-connector-supplements.
قبل از اجرای مثالها، متغیرهای پایگاه داده (Database)، مجموعه (Collection)، مسیر (Route) و بازه زمانی (Time-window) را تنظیم کنید:
use gobmp_history
var routeColl = "unicast_prefix_v4";
var eventColl = routeColl + "_events";
var routePrefix = "45.8.233.0";
var routeLen = 24;
var since = new Date(Date.now() - 60 * 60 * 1000);
var until = new Date();
// Fill these in after the first lookup query.
var peer = "10.2.1.5";
var bmpSource = "10.2.1.3";
var pathID = 0;
// Pick the timestamp you want to inspect. This example is just before the
// peer-down withdrawal seen in the sample output below.
var at = ISODate("2026-07-07T02:17:57.500Z");
یافتن نمونههای ذخیرهشده از مسیر (Route)
از این دستور ابتدا برای شناسایی همتایان (Peers)، منابع BMP و شناسههای مسیر (Path IDs) که در حال حاضر دارای سند برای آنها هستید، استفاده کنید.45.8.233.0/24.
db.getCollection(routeColl).find(
{
"_id.pfx": routePrefix,
"_id.len": routeLen
},
{
_id: 1,
current_state: 1,
stats: 1
}
).sort({
"current_state.last_update": -1
}).pretty()
لطفاً متن ورودی خود را ارسال کنید تا طبق قوانین و دستورالعملهای ذکر شده، ترجمه آن را انجام دهم.
[
{
_id: {
pfx: '45.8.233.0',
len: 24,
peer: '10.2.1.5',
bmp_source_ip: '10.2.1.3',
path_id: 0
},
current_state: {
attributes: null,
status: 'withdrawn',
last_update: ISODate('2026-07-07T02:17:57.613Z')
},
stats: {
advertisements: 2640,
withdrawals: 313,
instability_score: 0,
dampening_penalty: 0,
is_suppressed: false,
attribute_changes: 2327
}
}
]
این مسیر نمونه مناسبی است که نشان میدهد چرا ذخیرهسازی تاریخچه (History) اهمیت دارد. وضعیت فعلی تنها بیانگر این است که مسیر حذف (Withdrawn) شده است. شمارندهها (Counters) اطلاعات بسیار بیشتری را نشان میدهند: برای این نمونه مسیر خاص، 2,640 مورد تبلیغ (Advertisement)، 313 مورد حذف (Withdrawal) و 2,327 مورد تغییر ویژگی (Attribute change) مشاهده شده است.
نمایش وضعیت مسیر (Route State) در یک زمان مشخص
این پرسوجو آخرین رویداد برای نمونه مسیر (Route Instance) انتخابشده را در زمان یا قبل از آن پیدا میکند.atاگر آخرین رویدادwithdrawباشد، مسیر در آن نقطه حذف (Withdraw) شده است. اگرآخرین رویداد or advertiseیا
db.getCollection(eventColl).find(
{
"route_key.pfx": routePrefix,
"route_key.len": routeLen,
"route_key.peer": peer,
"route_key.bmp_source_ip": bmpSource,
"route_key.path_id": pathID,
ts: { $lte: at }
},
{
_id: 0,
route_key: 1,
ts: 1,
event: 1,
changed: 1,
kafka: 1
}
).sort({ ts: -1, _id: -1 }).limit(1).pretty()
لطفاً متن ورودی خود را برای ترجمه ارسال کنید. من آمادهام تا طبق قوانین دقیق شما، ترجمه را انجام دهم.
[
{
route_key: {
pfx: '45.8.233.0',
len: 24,
peer: '10.2.1.5',
bmp_source_ip: '10.2.1.3',
path_id: 0
},
ts: ISODate('2026-07-07T02:17:57.467Z'),
event: 'update',
changed: {
as_path: [ Long('50123'), Long('58308'), Long('29075'), Long('41765')],
community_list: [
'41765:8000',
'41765:9400',
'51706:64601',
'51706:64650',
'51706:65011',
'51706:65012'
]
},
kafka: {
topic: 'gobmp.parsed.unicast_prefix_v4',
partition: 1,
offset: Long('2520143')
}
}
]
باat = ISODate("2026-07-07T02:17:57.500Z")، آخرین رویداد پیش از آن برچسب زمانی (Timestamp)، عبارت است ازبهروزرسانی (update) at 2026-07-07T02:17:57.467Zاین بدان معناست که مسیر (route) درست پیش از2026-07-07T02:17:57.613Zاعلام خروج (withdrawal) همتا (peer-down) همچنان تبلیغ میشد. این رویداد همچنین مسیر AS، کامیونیتیها (communities)، موضوع (topic) کافکا، پارتیشن و آفست مرتبط با آن مشاهده را نشان میدهد.