I see the bad moon rising.
I see trouble on the way.
I see earthquakes and lightnin'.
I see bad times today.
I see earthquakes and lightnin'.
I see bad times today.
Мне совсем перестало нравиться, как IDR WG проектирует BGP.
Не так давно мы всем интернетом слегка хлебнули фекалий по поводу 32-bit ASN. Там было много разных приколов, но один был очень показательным:
RFC4893 вводит два новых атрибута: AS4_PATH и AS4_AGGREGATOR, оба optional/transitive. Кто умеет, тот обрабатывает, кто не умеет, тот пропускает дальше. Все, вроде бы, замечательно. Однако, получилось как всегда. Спецификация BGP предписывает при ошибке в атрибутах отбиваться notification'ом и класть сессию. Поэтому ошибочный AS4_PATH мог пропутешествовать довольно далеко через цепочку old speakers, которые его не понимают и ошибку обнаружить не могут, и, добравшись, наконец, до new speaker'а, обрушить тому сессию. Совершенно невинную сессию, заметим. В чужой автономной системе. Более подробно об инциденте написано в Арборовском блоге: http://asert.arbornetworks.com/2009/03/more-as4_path-triggered-global-routing-instability/.
Очевидно, что это дефект дизайна BGP, как такового, а не rfc4893, т.е. это могло случиться с любым другим optional/transitive атрибутом.
Общий принцип "fail early" - это хороший принцип, он позволяет проблеме не расползаться, он ограничивает failure domain. Казалось бы, этот принцип противоречит приципу "be conservative in what you send; be liberal in what you accept". На самом деле особого противоречия здесь нет. Вернее, я бы сказал, что эти два принципа находятся в диалектическом противоречии. Баги, увы, случаются, и если мы в какой-то момент получаем явный и откровенный мусор, лучше остановиться сейчас, чем допрыгаться до отдаленных и, скорее всего, очень серьезных последствий. В распределенных системах "garbage in, garbage out" лучше формулировать, как "some garbage in, lots of garbage out". Поэтому, залог успешного протокольного дизайна - это грамотный синтез тезиса (be liberal) и антитезиса (fail early).
Однако, в случае optional/transitive атрибутов принцип "fail early" просто неприменим. Мы не знаем, кто и когда обнаружит ошибку, соответственно, никакого ограничения failure domain'а не получается. В этом случае гораздо лучше реагировать на ошибки умнее и мягче, чем просто гашение сессии. На этот счет есть целых два драфта: draft-chen-rfc4893bis и draft-ietf-idr-optional-transitive. Первый затыкает конкретную дыру с 32-bit ASN, а второй подходит к проблеме более общо.
А вот теперь в нашу сторону катит draft-ietf-idr-add-paths. Замечательная, очень полезная и долгожданная фича, которая решает массу очень противных проблем. Но мне не нравятся детали дизайна. Одна из проблем состоит в том, что предложенное кодирование NLRI не устойчиво к ошибкам.
Пускай два пира A и B пытались договориться об add-path capability, и из-за баги тут или там договорились криво. A думает, что B умеет понимать NLRI в формате add-path, а B ничего про них не знает. Вы мне скажете, что такого быть не может? Еще как может! Таких багов была больше, чем одна.
Теперь A начинает слать апдейты в сторону B в формате add-path (если кому лень заглядывать в драфт, то формат очень простой: 4 октета Path Identifier, а дальше обычный старый NLRI). А B, в свою очередь, будет интерпретировать эти апдейты как будто они в обычном формате.
Казалось бы, B прочитает мусор, произведет синтаксическую проверку, поймет, что дело тут нечисто и, как предписано в случае синтаксических ошибок в NLRI, положит сессию, отбившить положенным notification'ом в сторону A. Все круто?
А вот и не совсем. Совсем нетрудно привести пример комбинации Path Identifier и NLRI, которая не будет распознана, как ошибка синтаксиса. Например, A шлет префикс 15.42.42.0/24 с Path Identifier равным 8. В проводе это будет: 00 00 00 08 18 0F 2A 2A. Если B будет интерпретировать это как обычный NLRI, то он увидит синтаксически верный набор:
0.0.0.0/0
0.0.0.0/0
0.0.0.0/0
24.0.0.0/8
42.42.0.0/15,
и сессию не сбросит. Мало того, B примет эти откровенно мусорные префиксы и распространит их по eBGP, например. Что дальше? Кровь, расчлененка, кишки по сте^Wвсему интернету. Internet-wide routing disruption. Нетадмины умываются слезами, арбор пишет очередной псто с красивыми графиками.
Не надо мне говорить, что вероятность мала. Таких комбинаций можно придумать очень много (если кому не лень, можно подсчитать). А интернет - это один большой Infinite Improbability Drive. Если что-то может случиться, в интернетах оно случится обязательно, уж будьте уверены. "Ford, there's an infinite number of monkeys out here who want to talk to us about this script for Hamlet they've worked out."
Принцип "fail early" опять не срабатывает, хотя в данном случае, это было бы совершенно верным подходом. Просто у нас нет надежного способа отличить мусор от немусора.
Меня очень не устраивает, что IDR не уделяет должного внимания устойчивости протокола и ограничению последствий потенциальных ошибок в реализации.
А побороться с этой неустойчивостью не сложно. Есть много способов. В сегодняшней дискуссии в idr@сами-знаете-где я предложил сделать кодирование add-path заведомо синтаксически невалидным с точки зрения старого способа. Robert Raszuk предложил радикально переработать способ передачи add-path'нутых префиксов. Можно придумать еще с десяток способов с разными достоинствами и недостаткам. Но, ведь, блин, надо же взять и таки придумать. А деплоить add-path в сегодняшнем виде мне немного ссыкотно. Чуть-чуть совсем.
Don't go around tonight,
Well, it's bound to take your life,
There's a bad moon on the rise.
There's a bad moon on the rise.