Как стать автором
Обновить

Принципы работы протокола BGP

Время на прочтение14 мин
Количество просмотров202K
Сегодня мы рассмотрим протокол BGP. Не будем долго говорить зачем он и почему он используется как единственный протокол. Довольно много информации есть на этот счет, например тут.

Итак, что такое BGP? BGP — это протокол динамической маршрутизации, являющийся единственным EGP( External Gateway Protocol) протоколом. Данный протокол используется для построения маршрутизации в интернете. Рассмотрим как строится соседство между двумя маршрутизаторами BGP.

My Image
Рассмотрим соседство между Router1 и Router3. Настроим их при помощи следующих команд:
router bgp 10
  network 192.168.12.0
  network 192.168.13.0
  neighbor 192.168.13.3 remote-as 10

router bgp 10
  network 192.168.13.0
  network 192.168.24.0
  neighbor 192.168.13.1 remote-as 10

Соседство внутри одной автономной системы — AS 10. После ввода данных на маршрутизаторе, например на Router1, данный маршрутизатор пытается настроить отношения соседства с маршрутизатором Router3. Начальное состояние, когда ничего не происходит называется Idle. Как только будет настроен bgp на Router1, он начнет слушать TCP порт 179 — перейдет в состояние Connect, а когда пытается открыть сессию с Router3, то перейдет в состояние Active.

После того, как сессия установится между Router1 и Router3, то происходит обмен Open сообщениями. Когда данное сообщение отправит Router1, то данное состояние будет называться Open Sent. А когда получит Open сообщение от Router3, то перейдет в состояние Open Confirm. Рассмотрим более подробно сообщение Open:

My Image
В данном сообщение передается информация о самом протоколе BGP, который использует маршрутизатор. Обмениваясь Open сообщениями, Router1 и Router3 сообщают друг другу информацию о своих настройках. Передаются следующие параметры:
  • Version: this includes the BGP version that the router is using. The current version of BGP is version 4 which is described in RFC 4271. Two BGP routers will try to negotiate a compatible version, when there is a mismatch then there will be no BGP session.
  • My AS: this includes the AS number of the BGP router, the routers will have to agree on the AS number(s) and it also defines if they will be running iBGP or eBGP.
  • Hold Time: if BGP doesn’t receive any keepalive or update messages from the other side for the duration of the hold time then it will declare the other side ‘dead’ and it will tear down the BGP session. By default the hold time is set to 180 seconds on Cisco IOS routers, the keepalive message is sent every 60 seconds. Both routers have to agree on the hold time or there won’t be a BGP session.
  • BGP Identifier: this is the local BGP router ID which is elected just like OSPF does:
    • Use the router-ID that was configured manually with the bgp router-id command.
    • Use the highest IP address on a loopback interface.
    • Use the highest IP address on a physical interface.
  • Optional Parameters: here you will find some optional capabilities of the BGP router. This field has been added so that new features could be added to BGP without having to create a new version.Things you might find here are:

    • support for MP-BGP (Multi Protocol BGP).
    • support for Route Refresh.
    • support for 4-octet AS numbers.
Для установления соседства необходимо выполнения следующих условий:

  • Номер версии. Нынешняя версия 4.
  • Номер AS должен совпадать с тем, что вы настроили neighbor 192.168.13.3 remote-as 10.
  • Router ID должен быть отличным от соседа.

Если какой-то из параметров не удовлетворяет этим условиям, то маршрутизатор отправит Notification сообщение, где укажет ошибку. После отправки и получения Open сообщений, отношения соседства переходит в состояние ESTABLISHED. После этого уже маршрутизаторы могут обмениваться информацией о маршрутах и делают это при помощи Update сообщений. Вот такое Update сообщение отправляет Router1 к Router3:

My Image

Здесь указывают сети, о которых сообщает Router1 и Path attributes, которые являются аналогом метрик. О Path attributes мы поговорим более подробно. Также внутри TCP сессии передаются Keepalive сообщения. Они передаются, по умолчанию, каждые 60 секунд. Это Keepalive Timer. Если в течении Hold Timer-а не будет получено Keepalive сообщение, то это будет означать потерю связи с соседом. По умолчанию, он равен — 180 секундам.

Полезная табличка:

My Image

Вроде бы разобрались как маршрутизаторы передают друг другу информацию, теперь попытаемся разобраться с логикой работы протокола BGP.

Чтобы анонсировать какой-нибудь маршрут в таблицу BGP, как и в протоколах IGP, используется команда network, но логика работы отличается. Если в IGP, после указание маршрута в команде network, IGP смотрит — какие интерфейсы принадлежат данной подсети и включает их в свою таблицу, то команда network в BGP смотрит в таблицу маршрутизации и ищет точное совпадение с маршрутом в команде network. При нахождении таких, данные маршруты попадут в таблицу BGP.
Look for a route in the router’s current IP routing table that exactly matches the parameters of the network command; if the IP route exists, put the equivalent NLRI into the local BGP table.
Теперь поднимем BGP на всех оставшихся и посмотрим как происходит выбор маршрута внутри одной AS. После того, как BGP маршрутизатор получит маршруты от соседа, то начинается выбор оптимального маршрута. Здесь надо понять какого вида соседи могут быть — внутренние и внешние. Маршрутизатор по конфигурации понимает является ли сконфигурированный сосед внутренним или внешним. Если в команде:

neighbor 192.168.13.3 remote-as 10 

в качестве параметра remote-as указан AS, который сконфигурирован на самом маршрутизаторе в команде router bgp 10. Маршруты, пришедшие из внутренней AS считаются внутренними, а маршруты из внешней соответственно внешними. И по отношению к каждому работает разная логика получения и отправки. Рассмотрим такую топологию:

My Image

На каждом маршрутизаторы настроен loopback интрефейс с ip: x.x.x.x 255.255.255.0 — где x номер маршрутизатора. На Router9 у нас есть loopback интерфейс с адресом — 9.9.9.9 255.255.255.0. Его мы будем анонсировать по BGP и посмотрим как он распространяется. Данный маршрут будет передан на Router8 и Router12. С Router8 данный маршрут попадет на Router6, но на Router5 в таблице маршрутизации его не будет. Также и на Router12 данный маршрут попадет в таблицу, но на Router11 его также не будет. Попытаемся разобраться с этим. Рассмотрим какие данные и параметры передается Router9 своим соседям, сообщая об этом маршруте. Пакет внизу будет отправлен с Router9 на Router8.

My Image
Информация о маршруте состоит из аттрибутов пути (Path attributes).

Атрибуты пути разделены на 4 категории:

  1. Well-known mandatory — все маршрутизаторы, работающие по протоколу BGP, должны распознавать эти атрибуты. Должны присутствовать во всех обновлениях (update).
  2. Well-known discretionary — все маршрутизаторы, работающие по протоколу BGP, должны распознавать эти атрибуты. Могут присутствовать в обновлениях (update), но их присутствие не обязательно.
  3. Optional transitive — могут не распознаваться всеми реализациями BGP. Если маршрутизатор не распознал атрибут, он помечает обновление как частичное (partial) и отправляет его дальше соседям, сохраняя не распознанный атрибут.
  4. Optional non-transitive — могут не распознаваться всеми реализациями BGP. Если маршрутизатор не распознал атрибут, то атрибут игнорируется и при передаче соседям отбрасывается.

Примеры атрибутов BGP:

  • Well-known mandatory:
    • Autonomous system path
    • Next-hop
    • Origin

  • Well-known discretionary:
    • Local preference
    • Atomic aggregate
  • Optional transitive:
    • Aggregator
    • Communities
  • Optional non-transitive:
    • Multi-exit discriminator (MED)
    • Originator ID
    • Cluster list

В данном случае нас пока будут интересовать Origin, Next-hop, AS Path. Так как маршрут передает между Router8 и Router9, то есть внутри одной AS, то он считается внутренним и обратим внимание на Origin.

Атрибут Origin — указывает на то, каким образом был получен маршрут в обновлении. Возможные значения атрибута:

  • 0 — IGP: NLRI получена внутри исходной автономной системы;
  • 1 — EGP: NLRI выучена по протоколу Exterior Gateway Protocol (EGP). Предшественник BGP, не используется
  • 2 — Incomplete: NLRI была выучена каким-то другим образом

В нашем случае, как видно из пакета равен 0. Когда данный маршрут будет передаваться к Router12, то данный код будет иметь код — 1.

Далее, Next-hop. Атрибут Next-hop

  • Это IP-адрес eBGP-маршрутизатора, через который идет путь к сети назначения.
  • Атрибут меняется при передаче префикса в другую AS.

В случае же iBGP, то есть внутри одной AS, Next-hop будет указан тот, который узнал или рассказал об этом маршруте. В нашем случае, это будет 192.168.89.9. Но когда будет передавать данный маршрут от Router8 к Router6, Router8 его изменит и заменит на свой. Next-hop будет — 192.168.68.8. Это нас приводит к двум правилам:

  1. Если маршрутизатор передает маршрут своему внутреннему соседу, то он не меняет параметр Next-hop.
  2. Если маршрутизатор передает маршрут своему внешнему соседу, то меняет Next-hop на ip интерфейса, с которого передает данный маршрутизатор.

Это приводит нас к пониманию первой проблемы — Почему не будет маршрута в таблице маршрутизации на Router5 и Router11. Рассмотрим более детально. Итак, Router6 получил информацию о маршруте 9.9.9.0/24 и благополучно добавил ее в таблицу маршрутизации:

Router6#show ip route bgp
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       a - application route
       + - replicated route, % - next hop override, p - overrides from PfR

Gateway of last resort is not set

      9.0.0.0/24 is subnetted, 1 subnets
B        9.9.9.0 [20/0] via 192.168.68.8, 00:38:25

Теперь Router6 передал маршрут Router5 и первому правилу Next-hop не изменил. То есть, Router5 должен добавить 9.9.9.0 [20/0] via 192.168.68.8, но у него нет маршрута до 192.168.68.8 и поэтому данный маршрут добавлен не будет, хотя информация о данном маршруте будет храниться в таблице BGP:

<b>Router5#show ip bgp
BGP table version is 1, local router ID is 5.5.5.5
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
              x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
 * i 9.9.9.0/24       192.168.68.8             0    100      0 45 i</b>

Та же самая ситуация произойдет и между Router11-Router12. Чтоб избежать такой ситуации необходимо настроить, чтоб Router6 или Router12, передавая маршрут своим внутренним соседям, подставляли в качестве Next-hop свой ip адрес. Делается при помощи команды:

neighbor 192.168.56.5 next-hop-self

После данной команды, Router6 отправит Update сообщение, где для маршрутов в качества Next-hop будет указан ip интерфейса Gi0/0 Router6 — 192.168.56.6, после чего данный маршрут уже попадет в таблицу маршрутизации.

Пойдем дальше и посмотрим появиться ли этот маршрут на Router7 и Router10. В таблице маршрутизации его не окажется и мы могли бы подумать, что проблема как в первом с параметром Next-hop, но если мы посмотрим вывод команды show ip bgp, то увидим, что там маршрут не был получен даже с неправильным Next-hop, что означает, что маршрут даже не передавался. И это нас приведет к существованию еще одного правила:
Маршруты, полученные от внутренних соседей не передаются другим внутренним соседям.
Так как, Router5 получил маршрут от Router6, то другому своему внутреннему соседу он передаваться не будет. Для того, чтобы передача произошла необходимо настроить функцию Route Reflector, либо настроить полносвязные отношения соседства ( Full Mesh), то есть Router5-7 каждый будет соседом с каждым. Мы будем в данном случае использовать Route Reflector. На Router5 необходимо использовать данную команду:

neighbor 192.168.57.7 route-reflector-client

Route-Reflector меняет поведение BGP при передаче маршрута внутреннему соседу. Если внутренний сосед указан как route-reflector-client, то данным клиентам будут анонсироваться внутренние маршруты.

Маршрут не появился на Router7? Не забываем также и про Next-hop. После данных манипуляций маршрут должен и на Router7, но этого не происходит. Это нас подводит к еще одному правилу:
Правило next-hop работает только для External маршрутов. Для внутренних маршрутов замена атрибута next-hop не происходит.

И мы получаем ситуацию, в которой необходимо создать среду при помощи статичной маршрутизации или протоколов IGP сообщить маршрутизаторам о всех маршрутах внутри AS. Пропишем статические маршруты на Router6 и Router7 и после этого получим нужный маршрут в таблице маршрутизаторе. В AS 678 же мы поступим немного иначе — пропишем статические маршруты для 192.168.112.0/24 на Router10 и 192.168.110.0/24 на Router12. Далее, установим отношения соседства между Router10 и Router12. Также настроим на Router12 отправку своего next-hop для Router10:

neighbor 192.168.110.10 next-hop-self

Итогом будет то, что Router10 будет получать маршрут 9.9.9.0/24, он будет получен и от Router7 и от Router12. Посмотрим какой выбор сделает Router10:

Router10#show ip bgp
BGP table version is 3, local router ID is 6.6.6.6
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
              x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network              Next Hop            Metric LocPrf Weight Path
 *>i 9.9.9.0/24       192.168.112.12           0    100       0      45 i

                               192.168.107.7                                0     123 45 i  

Как мы видим, два маршрута и стрелка ( > ) означает, что выбран маршрут через 192.168.112.12.
Посмотрим как происходит процесс выбора маршрута:

  1. Первым делом при получении маршрута, проверяется доступность его Next-hop. Именно поэтому, когда мы получали маршрут на Router5 без настройки Next-hop-self, данный маршрут далее не отдавался на обработку.
  2. Далее идет параметр Weight. Данный параметр не является Атрибутом пути ( PA ) и не передается в сообщениях BGP. Он настраивается локально на каждом маршрутизаторе и используется только для манипуляции выбора маршрута на самом маршрутизаторе. Рассмотрим пример. Чуть выше показано, что Router10 выбрал маршрут для 9.9.9.0/24 через Router12 ( 192.168.112.12 ). Чтоб изменить параметр Wieght, можно использовать route-map, чтоб задать для определенных маршрутов, либо присвоить его соседу вес при помощи команды:

     neighbor 192.168.107.7 weight 200       

    Теперь все маршруты от данного соседа будут иметь такой вес. Посмотрим как изменится выбор маршрута после данной манипуляции:

    Router10#show bgp
    *Mar  2 11:58:13.956: %SYS-5-CONFIG_I: Configured from console by console
    BGP table version is 2, local router ID is 6.6.6.6
    Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
                  r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
                  x best-external, a additional-path, c RIB-compressed,
    Origin codes: i - IGP, e - EGP, ? - incomplete
    RPKI validation codes: V valid, I invalid, N Not found
    
         Network          Next Hop            Metric LocPrf Weight      Path
     *>  9.9.9.0/24       192.168.107.7                        200      123 45 i
     * i                          192.168.112.12           0          100      0 45 i

    Как видите теперь выбран маршрут через Router7, но никакого эффекта на остальные маршрутизаторы это иметь не будет.
  3. На третьей позиции у нас идет — Local Preference. Данный параметр является Well-known discretionary атрибутом, а это означает, что его присутствие необязательно. Данный параметр имеет силу только внутри одной AS и влияет на выбор пути только для внутренних соседей. Именно поэтому, он передается только в Update сообщениях предназначенных для внутреннего соседа. В Update сообщениях для внешних соседей он отсутствует. Поэтому он и был отнесен к Well-known discretionary. Попытаемся применить его на Router5. На Router5 у нас должно быть два маршрута для 9.9.9.0/24 — один через Router6 и второй через Router7.

    Смотрим:

    Router5#show bgp
    BGP table version is 2, local router ID is 5.5.5.5
    Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
                  r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
                  x best-external, a additional-path, c RIB-compressed,
    Origin codes: i - IGP, e - EGP, ? - incomplete
    RPKI validation codes: V valid, I invalid, N Not found
    
         Network          Next Hop            Metric LocPrf Weight Path
     *>i 9.9.9.0/24       192.168.56.6             0    100      0 45 i

    Но как видим один маршрут через Router6. А где же маршрут через Router7? Может и на Router7 его нет? Смотрим:

    Router#show bgp
    BGP table version is 10, local router ID is 7.7.7.7
    Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
                  r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
                  x best-external, a additional-path, c RIB-compressed,
    Origin codes: i - IGP, e - EGP, ? - incomplete
    RPKI validation codes: V valid, I invalid, N Not found
    
         Network                Next Hop            Metric LocPrf  Weight    Path
     *>i 9.9.9.0/24       192.168.56.6             0     100           0      45 i
    
                                  192.168.107.10                                  0     678 45 i 

    Странно, вроде все в порядке. Почему же он не передается на Router5? Все дело в том, что у BGP есть правило:
    Маршрутизатор передает только те маршруты, которые использует сам.

    Router7 используется маршрут через Router5, поэтому маршрут через Router10 передаваться не будет. Вернемся к Local Preference. Давайте зададим Local Preference на Router7 и посмотрим как отреагирует на это Router5:

    route-map BGP permit 10
     match ip address 10
     set local-preference 250
    access-list 10 permit any
    router bgp 123
     neighbor 192.168.107.10 route-map BGP in</b>

    Итак, мы создали route-map, в который попадаются все маршруты и сказали Router7, чтоб при получение он менял параметр Local Preference на 250, по умолчанию равен 100. Смотрим, что произошло на Router5:

    Router5#show bgp
    BGP table version is 8, local router ID is 5.5.5.5
    Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
                  r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
                  x best-external, a additional-path, c RIB-compressed,
    Origin codes: i - IGP, e - EGP, ? - incomplete
    RPKI validation codes: V valid, I invalid, N Not found
    
         Network          Next Hop            Metric LocPrf Weight        Path
     *>i 9.9.9.0/24       192.168.57.7             0          250      0 678 45 i

    Как мы видим теперь Router5 предпочитает маршрут через Router7. Такая же картина будет и на Router6, хотя ему выгодней выбрать маршрут через Router8. Добавим также, что изменения данного параметра требует рестарт соседства, чтобы изменение вошло в силу. Читать тут. С Local Preference разобрались. Переходим к следующему параметру.
  4. Предпочтение маршрута с параметром Next-hop 0.0.0.0, то есть локальные или агрегированные маршруты. Данным маршрутам автоматически после ввода команды network присуждается параметр Weight равный максимуму — 32678:

    Router#show bgp
    BGP table version is 2, local router ID is 9.9.9.9
    Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
                  r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
                  x best-external, a additional-path, c RIB-compressed,
    Origin codes: i - IGP, e - EGP, ? - incomplete
    RPKI validation codes: V valid, I invalid, N Not found
    
         Network          Next Hop            Metric LocPrf Weight    Path
     *>  9.9.9.0/24       0.0.0.0                  0            32768    i
  5. Кратчайший путь через AS. Выбирается самый короткий параметр AS_Path. Чем через меньшее количество количество AS проходит маршрут, тем он и лучше. Рассмотри маршрут к 9.9.9.0/24 на Router10:

    Router10#show bgp
    BGP table version is 2, local router ID is 6.6.6.6
    Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
                  r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
                  x best-external, a additional-path, c RIB-compressed,
    Origin codes: i - IGP, e - EGP, ? - incomplete
    RPKI validation codes: V valid, I invalid, N Not found
    
         Network          Next Hop            Metric LocPrf Weight Path
     *   9.9.9.0/24     192.168.107.7                           0           123 45 i
     *>i                     192.168.112.12           0    100       0       45 i

    Как видите, Router10 выбрал маршрут через 192.168.112.12 потому, что для данного маршрута параметр AS_Path содержит только 45, а в другом случае 123 и 45. Интуитивно понятно.
  6. Следующий параметр — Origin. IGP ( маршрут получен при помощи BGP) лучше, чем EGP ( маршрут получен при помощи предшественника BGP, ныне не используется), а EGP лучше Incomplete? (получен каким-либо другим способ, например редистрибуцией).
  7. Следующий параметр — MED. У нас был Wieght, который работал только локально на маршрутизаторе. Был Local Preference, который работал только в пределах одной автономной системе. Как нетрудно догадаться, MED — параметр, который будет передаваться между автономными системами. Очень хорошая статья о данном параметре.

Больше атрибутов использоваться не будет, но если у двух маршрутов они одинаковые, то используются следующие правила:

  1. Выбрать путь через ближайшего IGP-соседа.
  2. Выбрать самый старый маршрут для eBGP-пути.
  3. Выбрать путь через соседа с наименьшим BGP router ID.
  4. Выбрать путь через соседа с наименьшим IP-адресом.

Теперь рассмотрим вопрос сходимости BGP.

Посмотрим, что произойдет, если допустим Router6 потеряет маршрут 9.9.9.0/24 через Router9. Отключим интерфейс Gi0/1 Router6, который сразу поймет, что BGP сессия с Router8 оборвана и сосед пропал, а значит и маршрут, полученные от него не действительны. Router6 сразу отправляет Update сообщения, где указывает сеть 9.9.9.0/24 в поле Withdrawn Routes. Как только Router5 получит подобное сообщение, отправит его к Router7. Но так как у Router7 есть маршрут через Router10, то в ответ сразу отправит Update c новым маршрутом. Если детектировать падения соседа по состоянию интерфейса не получается, то придеться ждать срабатывания Hold Timer-а.

Конфедерация.

Если помните, то мы говорили о том, что часто приходится использовать полносвязную топологию. С большим количеством маршрутизаторов в одной AS это может доставить большие проблемы, чтоб избежать этого необходимо использовать конфедерации. Одна AS разбивается на несколько sub-AS, что позволяет работать им без требования полносвязной топологии.

My Image

Здесь ссылка на данную лабу, а тут конфигурация для GNS3.

Например, при такой топологии нам пришлось бы связывать все маршрутизаторы в AS 2345 между собой, но используя Confederation, мы можем установить отношения соседства только между маршрутизаторами непосредственно подключенных друг к другу. Поговорим об этом подробно. Если у нас была только AS 2345, то laForge получив маршур от Picard рассказал бы его маршрутизаторам Data и Worf, но они не рассказали бы о нем маршрутизатору Crusher . Также маршруты, которые распрастраняет сам маршрутизатор laForge, не были бы переданы Crusher ни Worf-ом, ни Data.

Пришлось бы настраивать Route-Reflector или полносвязые отношения соседства. Разбивая одну AS 2345 на 4 sub-AS ( 2,3,4,5) для каждого маршрутизатора, мы в итоге получаем другую логику работы. Все отлично описано здесь.

Источники:

  1. CCIE Routing and Switching v5.0 Official Cert Guide, Volume 2, Fifth Edition, Narbik Kocharians, Terry Vinson.
  2. Сайт xgu.ru
  3. Сайт GNS3Vault.
Теги:
Хабы:
+15
Комментарии8

Публикации

Изменить настройки темы

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн