Смотрим в looking-glass

    Замечательным примером сетевой солидарности являются многочисленные сервисы looking-glass, позволяющие заглянуть за кулисы очень многих больших и маленьких сетей во всём мире. Это настолько удивительно в современном мире, спрятанном за сотней систем безопасности, просто так взять и выполнить команды на маршрутизаторах являющихся одними из самых критичных устройств всей инфраструктуры передачи данных.

    looking-glass version6


    Надо лишь ввести 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. Но любой инструмент должен быть предсказуем, некоторые из нефильтруемых команд ужасно ресурсоёмки, некоторые открывают чуть больше чем можно позволить в современном мире. Загляните в свой код и сделайте так как вам будет достаточно. Будьте внимательны друг к другу, взаимовыручка и открытость позволили построить Интернет, не будем это разрушать.
    Support the author
    Share post

    Similar posts

    Comments 14

      +3
      в своей я пока не решился выставить подобный сервис наружу.

      Да ничего особо страшного в этом нет. Берете какой-нибудь древний, не нужный роутер (или виртуалку с CSR1k). Делаете соседства с несколькими бордерами. На тех бордерах запрещаете принятие любых префиксов с того LG, и вообще выполняете все настройки как для вражеского роутера, например, ограждаете LG средствами ACL'ей, чтобы если кто-то каким-то образом получит на нем CLI, то никуда прыгнуть с него не сможет, настраиваете со всех сторон полисеры, storm control. Ну и делаете фронтенд на http, валидирующий команды по регулярным выражениям. Или не делаете, а просто пускаете людей по telnet/ssh, но с фильтрацией команд белым списком (по tacacs, RBAC или как угодно).

      Итого: если вы решите грохнуть абсолютно любой из найденных вами LG, то повлияет это только на сервис LG. Продакшн вы никому не обвалите. Надо быть идиотом, чтобы выделять под LG боевой роутер с продуктивным трафиком.
        +3
        Долго думала при чем тут фирма LG и когда они начали выпускать роутеры. Потом дошло :)
          0
          Надо быть идиотом, чтобы выделять под LG боевой роутер с продуктивным трафиком.

          Вот summary с lg RETN Воронеж соседство с Эр-Телеком:
          Peer          AS       InPkt    OutPkt      OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
          87.245.243.62 9049     412381   45106746       0      18     19w0d1h Establ  inet.0: 185/773/769/0

          185 активных маршрутов в default таблице. Боевой у RETN роутер или нет? А у Эр-Телеком?
            0
            По обратке пир похож на принадлежащий RETN бордер с эр-телекомом. gw-ertelecom.retn.net.

            Сколько активных маршрутов — не особо важно для LG, хотя конечно странно, что оно в RIB пишется.
              +1
              Хотя конечно странно, что ASN у пира чужой… Ну либо что-то хитрое делают, либо «безумству храбрых поем мы славу».
                0
                В том-то и дело, что такое много где.
                  +1
                  Люди настолько уверены в отсутствии хотя бы элементарных багов? Взять любую версию IOS — у нее найдется что-то вроде «show run вызывает крэш».

                  Ну не верю я, что кто-то будет давать посторонним какой угодно доступ к своему боевому железу. Что мешает взять какой-нибудь древний хлам и на него пускать?
                    0
                    А я верю, когда писал пост пролез достаточно много LG. Ввод везде фильтрован так как написано в статье, если попадается что-то не стандартное команда улетает дальше и там видны сообщения об ошибках с железки. Боевые соседства тоже вполне себе видны.
                    Изначальное в этом же и был смысл, как мне кажется, это сейчас выглядит пугающе.
            0
            Мы тут с коллегами интересуемся — а как при такой схеме смотреть, например, sh bgp summary или sh route receive-protocol bgp {neighbor}?
              0
              С какой целью, и что конкретно смущает?

              LG нужен в первую очередь чтобы посмотреть через него на свою AS.
            0
            Я оставлю это здесь:
            github.com/ServerAstra/py-lookingglass

            Для быстрого решения работает неплохо. Буду дорабатывать, кому не лень дополняйте )
              0
              Вообще не понимаю в чем сложность написания looking glass «под себя» и не использовать не пойми что от других. Это пишется за один вечер, с учётом просмотра мануалов по html и php (сам так и написал). Главное не забывать валидировать пользовательский ввод регекспами.
                0
                Так в этом и посыл. «Не пойми что от других», про который говорится в посте — очень, даже очень популярный вариант.
                0
                У других можно вполне подходящий выбрать. Народ аж коллекционирует ссылки на LG:
                LookingGlass.org
                traceroute.org

                Only users with full accounts can post comments. Log in, please.