Замечательным примером сетевой солидарности являются многочисленные сервисы looking-glass, позволяющие заглянуть за кулисы очень многих больших и маленьких сетей во всём мире. Это настолько удивительно в современном мире, спрятанном за сотней систем безопасности, просто так взять и выполнить команды на маршрутизаторах являющихся одними из самых критичных устройств всей инфраструктуры передачи данных.
Надо лишь ввести IP адрес или префикс в поле и получить в ответ таблицу маршрутизации или трассировку и результаты работы утилиты ping. Поэтому когда понимаешь, что можно вводить не только адреса, но и некоторые другие символы сформированные в осмысленные команды и получать осмысленные результаты, наступает ступор. Хочется бежать и кричать на всех углах: «Да что же это такое надо немедленно запретить, что за несуразность?». Это всё последствия последних лет, когда безопасность превыше открытости и удобности и на это, несомненно, есть причины.
Речь пойдёт об очень популярной реализации looking-glass от version6.net и о том что-же можно получить от этого сервиса.
Если вам вдруг покажется обычным что интерфейс looking-glass позволяет вводить что-то кроме IP адреса, то вероятно вы относитесь к «старой школе» или не читаете новости. Мне показалось это необычным, тем более что другие реализации этого сервиса такого не позволяют.
Так как это было для меня необычным я даже начал предупреждать об этом владельцев сервисов, но потом заглянул в код и понял что так и должно быть — это фича, а не баг. На сайте version6.net, который сейчас почему-то не доступен, про функционал честно написано: "all BGP show commands, ping and traceroute".
Открываем lg.cgi, который читается достаточно тяжело и Perl здесь совсем не помогает:
Команда передаётся в переменной $addr, в которой удаляются все символы кроме пробельных (включая табы, опция \s), букв, цифр, символов "-", "_", "/", "$", ".", ":".
Условие с ping значительно строже. Насколько я вижу вытирается весь ввод после пробельного символа. Поэтому добавить что-то лишнее в команду ping и traceroute значительно сложнее.
Потом формируется команда для непосредственного выполнения из шаблона $query_cmd и выполняется проверка на принадлежность ввода немного другой группе символов: исключаются табы, потому что явно указаны пробелы, символ "_" остаётся включённым потому что попадает под опцию \w вместе с цифрами, появляется символ "^". Дополнительная проверка делается на ":", которое возможно только при работе с IPv6.
Вот собственно и всё, оставшиеся проверки только на пустую строку для некоторых режимов работы. Команда для выполнения уже сформирована ранее и она без изменений уходит на устройство:
Что же мы можем? Из полезного потеряли кавычки, символы "|", "?" и все скобки. Но осталось очень много, даже очень. Шаблон формирующий команды выглядит вот так (для Cisco):
Основные команды show ip bgp, ping и traceroute. Очевидно что show ip bgp summary и show ip bgp neighbors %s advertised-routes, можно сформировать из show ip bgp %s.
Наш хлеб. Стоит отметить что на разных сайтах всё же производится дополнительная фильтрация, или доработка под другие системы отличные от стандартных, поэтому не всегда ввод произвольных символов возможен. Скорее даже он возможен, но дальнейшее выполнение команд приводит к ошибкам. Однако если мы имеем базовые устройства предусмотренные в оригинальном коде то можем вводить широкий спектр команд. Сайт Cisco, остановимся на одном вендоре, предлагает много вариантов. Немного полезных, для примера.
Смотрим все маршруты по заданному AS-PATH. Например, до всех сетей Yandex из Стокгольма, ТТК (GET отправит напрямую к результатам запроса):
Подробная информация об установленных соседствах. Команда иногда косвенно доступна в подсвеченном выводе при выполнении других команд. Например, подробная информация об одном из соседств Билайна в Ставрополе:
Можно расширить до advertised-routes, чтобы посмотреть какие маршруты анонсируются в сторону определённого соседа, часто присутствует непосредственно в интерфейсе.
Команда не всегда доступна напрямую, поэтому можно попробовать выполнить в обход. Например, для РТКОММ:
И эти команды можно расширить: увеличить размер пакета, выключить фрагментирование. Но сделать это сложнее, потому что код для фильтрации строже. Примеры, однако можно найти — Starnet, кстати здесь Juniper:
Looking-glass замечательный инструмент, даже отличный, решающий многие проблемы и сплачивающий ряды сетевых специалистов по всему миру, очень чёткий признак зрелости компании. Упомянув несколько разных компаний, в своей я пока не решился выставить подобный сервис наружу.
Экспериментировать можно долго, сервисов LG доступно очень много по всему миру и достаточное количество из них построено на версии предлагаемой version6.net. Но любой инструмент должен быть предсказуем, некоторые из нефильтруемых команд ужасно ресурсоёмки, некоторые открывают чуть больше чем можно позволить в современном мире. Загляните в свой код и сделайте так как вам будет достаточно. Будьте внимательны друг к другу, взаимовыручка и открытость позволили построить Интернет, не будем это разрушать.
Надо лишь ввести IP адрес или префикс в поле и получить в ответ таблицу маршрутизации или трассировку и результаты работы утилиты ping. Поэтому когда понимаешь, что можно вводить не только адреса, но и некоторые другие символы сформированные в осмысленные команды и получать осмысленные результаты, наступает ступор. Хочется бежать и кричать на всех углах: «Да что же это такое надо немедленно запретить, что за несуразность?». Это всё последствия последних лет, когда безопасность превыше открытости и удобности и на это, несомненно, есть причины.
Речь пойдёт об очень популярной реализации looking-glass от version6.net и о том что-же можно получить от этого сервиса.
Если вам вдруг покажется обычным что интерфейс looking-glass позволяет вводить что-то кроме IP адреса, то вероятно вы относитесь к «старой школе» или не читаете новости. Мне показалось это необычным, тем более что другие реализации этого сервиса такого не позволяют.
- У ReTN (достаточно популярная реализация) все введённые символы воспринимаются как доменное имя, если это не IP адрес.
- MSX-IX всё разделено на части, вводить можно, но только там где это предусмотрено и интерпретируется всё достаточно жёстко.
- Data IX позволяет некоторую свободу, хотя и сообщает что указан не IP адрес: «Указан недопустимый аргумент — должен быть IP или IP/n» — но всё равно выполняется birdc, который сообщает об ошибке и фильтрует все непотребства.
- А Вконтакте разрешён только ping и traceroute и только с IP адресами.
Так как это было для меня необычным я даже начал предупреждать об этом владельцев сервисов, но потом заглянул в код и понял что так и должно быть — это фича, а не баг. На сайте version6.net, который сейчас почему-то не доступен, про функционал честно написано: "all BGP show commands, ping and traceroute".
Открываем lg.cgi, который читается достаточно тяжело и Perl здесь совсем не помогает:
my %FORM = &cgi_decode($incoming); ... $FORM{addr} =~ s/\s.*// if (($FORM{query} eq "ping") || ($FORM{query} eq "trace")); $FORM{addr} =~ s/[^\s\d\.:\w\-_\/\$]//g;
Команда передаётся в переменной $addr, в которой удаляются все символы кроме пробельных (включая табы, опция \s), букв, цифр, символов "-", "_", "/", "$", ".", ":".
Условие с ping значительно строже. Насколько я вижу вытирается весь ввод после пробельного символа. Поэтому добавить что-то лишнее в команду ping и traceroute значительно сложнее.
my $command = sprintf($query_cmd, $FORM{addr}); ... if ($FORM{addr} !~ /^[\w\.\^\$\-\/ ]*$/) { if ($FORM{addr} =~ /^[\w\.\^\$\-\:\/ ]*$/) { ... } else { &print_error("Illegal characters in parameter string"); } }
Потом формируется команда для непосредственного выполнения из шаблона $query_cmd и выполняется проверка на принадлежность ввода немного другой группе символов: исключаются табы, потому что явно указаны пробелы, символ "_" остаётся включённым потому что попадает под опцию \w вместе с цифрами, появляется символ "^". Дополнительная проверка делается на ":", которое возможно только при работе с IPv6.
Вот собственно и всё, оставшиеся проверки только на пустую строку для некоторых режимов работы. Команда для выполнения уже сформирована ранее и она без изменений уходит на устройство:
$FORM{addr} = "" if ($FORM{addr} =~ /^[ ]*$/); ... if ($query_cmd =~ /%s/) { &print_error("Parameter missing") if ($FORM{addr} eq ""); } else { &print_warning("No parameter needed") if ($FORM{addr} ne ""); } ... &run_command($FORM{router}, $router_list{$FORM{router}}, $command);
Что же мы можем? Из полезного потеряли кавычки, символы "|", "?" и все скобки. Но осталось очень много, даже очень. Шаблон формирующий команды выглядит вот так (для Cisco):
my %valid_query = ( "ios" => { "ipv4" => { "bgp" => "show ip bgp %s", "advertised-routes" => "show ip bgp neighbors %s advertised-routes", "summary" => "show ip bgp summary", "ping" => "ping %s", "trace" => "traceroute %s" }, ...
Основные команды show ip bgp, ping и traceroute. Очевидно что show ip bgp summary и show ip bgp neighbors %s advertised-routes, можно сформировать из show ip bgp %s.
show ip bgp
Наш хлеб. Стоит отметить что на разных сайтах всё же производится дополнительная фильтрация, или доработка под другие системы отличные от стандартных, поэтому не всегда ввод произвольных символов возможен. Скорее даже он возможен, но дальнейшее выполнение команд приводит к ошибкам. Однако если мы имеем базовые устройства предусмотренные в оригинальном коде то можем вводить широкий спектр команд. Сайт Cisco, остановимся на одном вендоре, предлагает много вариантов. Немного полезных, для примера.
show ip bgp regexp
Смотрим все маршруты по заданному AS-PATH. Например, до всех сетей Yandex из Стокгольма, ТТК (GET отправит напрямую к результатам запроса):
show ip bgp regexp 13238$
Router: sgm01rb Command: show bgp regexp 13238$ Sat Dec 19 16:30:21.141 UTC BGP router identifier 10.146.0.1, local AS number 20485 BGP generic scan interval 60 secs BGP table state: Active Table ID: 0x0 RD version: 0 BGP main routing table version 2995757495 BGP scan interval 60 secs Status codes: s suppressed, d damped, h history, * valid, > best i - internal, r RIB-failure, S stale, N Nexthop-discard Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 20485:1 (default for vrf internet) *>i5.45.192.0/18 10.78.0.6 1000 70 0 13238 i * i 10.99.0.8 1000 70 0 13238 i * 149.6.168.201 1000 70 0 174 13238 i * 166.63.220.185 1000 70 0 1273 9002 13238 i * 212.73.250.153 1000 60 0 3356 13238 i * 213.248.99.221 1000 70 0 1299 13238 i *>i5.45.194.0/24 10.78.0.6 1000 70 0 13238 i * i 10.99.0.8 1000 70 0 13238 i * 212.73.250.153 1000 60 0 3356 13238 i * 213.248.99.221 1000 70 0 1299 13238 i *>i5.45.196.0/24 10.78.0.6 1000 70 0 13238 i * i 10.99.0.8 1000 70 0 13238 i * 149.6.168.201 1000 70 0 174 13238 i * 166.63.220.185 1000 70 0 1273 9002 13238 i * 212.73.250.153 1000 60 0 3356 13238 i * 213.248.99.221 1000 70 0 1299 13238 i *>i5.45.202.0/24 10.78.0.6 1000 70 0 13238 i * i 10.99.0.8 1000 70 0 13238 i * 212.73.250.153 1000 60 0 3356 13238 i * 213.248.99.221 1000 70 0 1299 13238 i ...
show ip bgp neighbors
Подробная информация об установленных соседствах. Команда иногда косвенно доступна в подсвеченном выводе при выполнении других команд. Например, подробная информация об одном из соседств Билайна в Ставрополе:
show ip bgp neighbors 10.255.0.2
Router: len244-bb.stv Command: show ip bgp neigh BGP neighbor is 10.255.0.2, remote AS 3216, external link BGP version 4, remote router ID 79.104.32.226 BGP state = Established, up for 1y5w Last read 00:00:40, last write 00:00:14, hold time is 180, keepalive interval is 60 seconds Neighbor sessions: 1 active, is not multisession capable Neighbor capabilities: Route refresh: advertised and received(new) Four-octets ASN Capability: advertised and received Address family IPv4 Unicast: advertised and received Multisession Capability: advertised Message statistics: InQ depth is 0 OutQ depth is 0 Sent Rcvd Opens: 1 1 Notifications: 0 0 Updates: 1 352 Keepalives: 631466 635532 Route Refresh: 0 0 Total: 631468 635885 Default minimum time between advertisement runs is 30 seconds For address family: IPv4 Unicast Session: 10.255.0.2 BGP table version 182470946, neighbor version 182470946/0 Output queue size : 0 Index 77 77 update-group member Incoming update prefix filter list is B2B-BRAS-IN Outgoing update prefix filter list is DENY-ALL Slow-peer detection is disabled Slow-peer split-update-group dynamic is disabled Sent Rcvd Prefix activity: ---- ---- Prefixes Current: 0 1 (Consumes 52 bytes) Prefixes Total: 0 176 Implicit Withdraw: 0 0 Explicit Withdraw: 0 175 Used as bestpath: n/a 1 Used as multipath: n/a 0 Outbound Inbound Local Policy Denied Prefixes: -------- ------- prefix-list 16426 0 Well-known Community: 126392327 n/a Bestpath from this peer: 347 n/a Suppressed due to dampening: 15381 n/a Invalid Path: 2886275 n/a Total: 129310756 0 Maximum prefixes allowed 500 Threshold for warning message 75%, restart interval 3 min Number of NLRIs in the update sent: max 0, min 0 Last detected as dynamic slow peer: never Dynamic slow peer recovered: never Datagrams (max data segment is 1460 bytes): Rcvd: 1268112 (out of order: 0), with data: 635885, total data bytes: 12089768 Sent: 1265174 (retransmit: 1 fastretransmit: 0),with data: 631468, total data bytes: 11997935 ...
Можно расширить до advertised-routes, чтобы посмотреть какие маршруты анонсируются в сторону определённого соседа, часто присутствует непосредственно в интерфейсе.
show ip bgp summary
Команда не всегда доступна напрямую, поэтому можно попробовать выполнить в обход. Например, для РТКОММ:
show ip bgp summary
BGP router identifier 81.176.81.18, local AS number 8342 RIB entries 1052472, using 64 MiB of memory Peers 2, using 5024 bytes of memory Peer groups 1, using 16 bytes of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 195.161.1.10 4 8342 42323357 15458 0 0 0 01w3d17h 574623 195.161.1.155 4 8342 43105981 15458 0 0 0 01w3d17h 574623 Total number of neighbors 2
Ping и Traceroute
И эти команды можно расширить: увеличить размер пакета, выключить фрагментирование. Но сделать это сложнее, потому что код для фильтрации строже. Примеры, однако можно найти — Starnet, кстати здесь Juniper:
ping count 5 detail do-not-fragment size 1200 8.8.8.8
Router: MSK-IX MX480 Command: ping count 5 detail do-not-fragment size 1200 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 1200 data bytes 1208 bytes from 8.8.8.8 via xe-3/3/0.0: icmp_seq=0 ttl=60 time=1.041 ms 1208 bytes from 8.8.8.8 via xe-3/3/0.0: icmp_seq=1 ttl=60 time=0.964 ms 1208 bytes from 8.8.8.8 via xe-3/3/0.0: icmp_seq=2 ttl=60 time=0.959 ms 1208 bytes from 8.8.8.8 via xe-3/3/0.0: icmp_seq=3 ttl=60 time=32.190 ms 1208 bytes from 8.8.8.8 via xe-3/3/0.0: icmp_seq=4 ttl=60 time=1.038 ms --- 8.8.8.8 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.959/7.238/32.190/12.476 ms ...
Looking-glass замечательный инструмент, даже отличный, решающий многие проблемы и сплачивающий ряды сетевых специалистов по всему миру, очень чёткий признак зрелости компании. Упомянув несколько разных компаний, в своей я пока не решился выставить подобный сервис наружу.
Экспериментировать можно долго, сервисов LG доступно очень много по всему миру и достаточное количество из них построено на версии предлагаемой version6.net. Но любой инструмент должен быть предсказуем, некоторые из нефильтруемых команд ужасно ресурсоёмки, некоторые открывают чуть больше чем можно позволить в современном мире. Загляните в свой код и сделайте так как вам будет достаточно. Будьте внимательны друг к другу, взаимовыручка и открытость позволили построить Интернет, не будем это разрушать.
Комментарии (13)
equand
21.12.2015 13:57Я оставлю это здесь:
github.com/ServerAstra/py-lookingglass
Для быстрого решения работает неплохо. Буду дорабатывать, кому не лень дополняйте )
phantasm1c
22.12.2015 14:01Вообще не понимаю в чем сложность написания looking glass «под себя» и не использовать не пойми что от других. Это пишется за один вечер, с учётом просмотра мануалов по html и php (сам так и написал). Главное не забывать валидировать пользовательский ввод регекспами.
Loiqig
22.12.2015 18:38Так в этом и посыл. «Не пойми что от других», про который говорится в посте — очень, даже очень популярный вариант.
JDima
Да ничего особо страшного в этом нет. Берете какой-нибудь древний, не нужный роутер (или виртуалку с CSR1k). Делаете соседства с несколькими бордерами. На тех бордерах запрещаете принятие любых префиксов с того LG, и вообще выполняете все настройки как для вражеского роутера, например, ограждаете LG средствами ACL'ей, чтобы если кто-то каким-то образом получит на нем CLI, то никуда прыгнуть с него не сможет, настраиваете со всех сторон полисеры, storm control. Ну и делаете фронтенд на http, валидирующий команды по регулярным выражениям. Или не делаете, а просто пускаете людей по telnet/ssh, но с фильтрацией команд белым списком (по tacacs, RBAC или как угодно).
Итого: если вы решите грохнуть абсолютно любой из найденных вами LG, то повлияет это только на сервис LG. Продакшн вы никому не обвалите. Надо быть идиотом, чтобы выделять под LG боевой роутер с продуктивным трафиком.
urticazoku
Долго думала при чем тут фирма LG и когда они начали выпускать роутеры. Потом дошло :)
Loiqig
Вот summary с lg RETN Воронеж соседство с Эр-Телеком:
185 активных маршрутов в default таблице. Боевой у RETN роутер или нет? А у Эр-Телеком?
JDima
По обратке пир похож на принадлежащий RETN бордер с эр-телекомом. gw-ertelecom.retn.net.
Сколько активных маршрутов — не особо важно для LG, хотя конечно странно, что оно в RIB пишется.
JDima
Хотя конечно странно, что ASN у пира чужой… Ну либо что-то хитрое делают, либо «безумству храбрых поем мы славу».
Loiqig
В том-то и дело, что такое много где.
JDima
Люди настолько уверены в отсутствии хотя бы элементарных багов? Взять любую версию IOS — у нее найдется что-то вроде «show run вызывает крэш».
Ну не верю я, что кто-то будет давать посторонним какой угодно доступ к своему боевому железу. Что мешает взять какой-нибудь древний хлам и на него пускать?
Loiqig
А я верю, когда писал пост пролез достаточно много LG. Ввод везде фильтрован так как написано в статье, если попадается что-то не стандартное команда улетает дальше и там видны сообщения об ошибках с железки. Боевые соседства тоже вполне себе видны.
Изначальное в этом же и был смысл, как мне кажется, это сейчас выглядит пугающе.
k0ldbl00d
Мы тут с коллегами интересуемся — а как при такой схеме смотреть, например, sh bgp summary или sh route receive-protocol bgp {neighbor}?
JDima
С какой целью, и что конкретно смущает?
LG нужен в первую очередь чтобы посмотреть через него на свою AS.