Инструменты классификации трафика и маршрутов в Cisco IOS: списки доступа, префикс-листы и карты маршрутов.
Что такое implicit deny в ACL и prefix-list?
Как интерпретируются биты wildcard-маски?
Что происходит при удалении строки из нумерованного ACL?
Почему IPv6 ACL обязательно должен разрешать ICMPv6?
Как работают ge/le в prefix-list?
Классификация и фильтрация трафика: route-map в Cisco vs routing policy в Junos
Фильтрация BGP-маршрутов использует prefix-list — тот же инструмент классификации из CCNP ROUTE
Модуль у нас следующий будет посвящен обработке маршрутов. Когда мы говорим про динамическую маршрутизацию, к нам маршруты могут прибегать из самых разных мест. Иногда мы маршрутам, которые будут приходить, будем доверять безусловно. И, допустим, всё, что к нам приходит от соседей, мы будем добавлять в таблицу маршрутизации. А иногда мы не можем настолько хорошо доверять соседу, потому что сосед, например, может быть BGP-шный. BGP-шный сосед непростой, а находящийся в другой автономке. Поэтому мы с ним дружим по eBGP. Это режим BGP, в котором мы не доверяем соседям. Соответственно, нам нужно будет каким-то образом классифицировать те маршруты, которые к нам приходят, на те, которым мы верим и которые мы будем добавлять в таблицу маршрутизации, и те, которым мы не верим. Мы, соответственно, их выкинем, не будем их добавлять, или, по крайней мере, сейчас не будем добавлять, а потом, может быть, что-то с ними сделаем ещё. Равным образом мы можем хотеть отправлять не все маршруты соседям.
Опять же, BGP — прекрасный пример. Если у нас есть какие-то маршруты в таблице BGP, которые каким-то образом организовались, не всегда мы все подряд маршруты хотим отправлять всем подряд пирам. Потому что если у нас, например, есть два провайдера, и один провайдер прислал нам дефолтный маршрут, мы не хотим этот дефолтный маршрут отправлять другому провайдеру, потому что другой провайдер тогда будет ходить в интернет через нас. Какой в этом интерес? Если мы обычное предприятие, то мы в этом случае, конечно же, не будем показывать второму провайдеру, что через нас можно в интернет ходить. Ещё пример: маршруты иногда могут быть ограничены даже не по BGP, а по протоколам каким-нибудь типа OSPF, или EIGRP, или даже RIP. Если у нас есть какие-то маршруты, которые мы, например, хотим вкладывать из внешнего источника в OSPF
и порождать LSA пятёрки, про которые мы ещё не говорили, но обязательно будем говорить. У нас есть в таблице маршрутизации какая-то пачка маршрутов, и мы хотим некоторые из них отобрать и рассказать про них нашим OSPF-соседям. Нам требуется каким-то образом классифицировать те маршруты, которые мы потенциально можем вбросить в OSPF, на те, которые мы будем вбрасывать, и те, которые мы вбрасывать не будем. Нам нужно взять какой-то инструмент классификации и пропустить через него все маршруты, которые подозрительные, которые мы хотим как-то проклассифицировать, и получить результат. Либо да, либо нет. Иногда мы, помимо того что хотим классифицировать маршруты, ещё дополнительно захотим что-нибудь модифицировать. Допустим, если мы говорим «да» на какой-нибудь маршрут, то мы хотим сказать «окей, не просто «да», а ещё давайте как-нибудь над ним поиздеваемся». А если нет, то, соответственно, издеваться не будем, потому что мы с этим маршрутом работать дальше не хотим. Соответственно, нам потребуется какой-то инструмент или какие-то инструменты,
которые мы можем использовать для анализа множества объектов, в частности маршрутов, и дальше с такими объектами что-нибудь, возможно, нам придётся делать. У нас на входе есть какие-то объекты, которые мы хотим изучать, мы пропускаем эти объекты через изучатель, и он нам на выходе на каждый объект даёт меточку. Либо «да», либо «нет». Соответственно, фактически мы, когда пропускаем эти объекты через анализатор, мы делаем два действия. Первое — задаём вопрос «да» или «нет». «Да» / «нет». Оно именно такое двоичное. Либо «да», либо «нет». Причём мы заранее не знаем, что будет, если мы скажем «да» или «нет». Может быть, если мы скажем «да», с объектом случится что-то хорошее. А может быть, если мы скажем «нет», с объектом случится что-то хорошее, а если мы скажем «да», с объектом случится что-то плохое. Сам вопрос не подразумевает, что с объектом обязательно что-то должно случиться именно в какой-то определённой логике.
Мы можем один и тот же анализатор использовать в разных местах, и в разных местах он будет нам давать разный результат. Как вы понимаете, здесь речь идёт про access-листы в первую очередь. Если у нас есть какой-то access-лист, мы задаём вопрос: IP-шник, который мы пропускаем через access-лист, он чётный? И access-лист нам говорит: да, он чётный, или нет, он нечётный. На основании чётности или нечётности IP-шника нельзя сделать вывод, что с этим IP-шником дальше что-то хорошее или что-то плохое случится. Может быть такое, что если мы говорим «да», мы дальше пакет, содержащий этот IP-шник, пропускаем, и тогда это в кавычках «хорошо». А может быть такое, что всё, на что access-лист сказал «да», мы дальше дропаем. Такое тоже может быть. Поэтому «да» или «нет» в английской терминологии будут переводиться как permit и deny. Соответственно, permit и deny. Пожалуйста, не пытайтесь переводить это дословно. Permit — просто «да», deny — это «нет».
Если вы возьмёте словарь, там будет написано: permit — это разрешить, deny — это запретить. Это брехня. Когда-то очень давно, в 70-х, 80-х годах, когда Cisco делала первые роутеры, действительно, access-листы, permit и deny выносили вердикт. И пакеты, которые они классифицировали, действительно либо пропускались, либо запрещались. Сегодня access-листы — это намного более универсальный инструмент. И логика, которая будет стоять за ответом permit или deny, она уже не означает, что мы что-то разрешаем или что-то запрещаем. Поэтому «да» или «нет». Лучше это воспринимать так. После того как мы пропустили объекты — например, пакеты, или маршруты, или что-то ещё — через анализатор, он нам развесил метки «да»/«нет». И дополнительно, если у нас достаточно продвинутый анализатор, он может сказать, что именно мы хотим сделать с теми объектами, которым мы сказали «да». Мы, например, на некоторые объекты можем флажок поставить, а на некоторые не будем ставить. Инструменты, которые у нас будут использоваться для решения задачи классификации и какой-то модификации проходящих объектов, у нас будут следующие.
Во-первых, конечно же, это access-листы, которые мы с вами в CCNA проходили. Во-вторых, это новая штука, которая умеет хорошо работать с маршрутами. Называется prefix-листы. По сути своей это те же access-листы, только в более удобной обёртке. И, соответственно, ещё один новый инструмент, который называется route-map. И эта штука уже действительно мощная и продвинутая. Если мы говорим про BGP, он как раз будет в основном работать с route-map. И route-map позволяют модифицировать проходящие через него объекты. Например, можно сказать, что если у нас есть пачка маршрутов, мы их пропускаем через route-map, и она в зависимости от каких-то условий, достаточно продвинутых условий, может маршруты модифицировать, изменять их. Это очень клёвая вещь, и мы с вами обязательно будем их использовать достаточно активно. Самый простой механизм — это access-листы, которые вы, несомненно, помните по CCNA. В принципе, access-листы будут только классифицировать объекты, но не манипулировать этими объектами.
Модифицировать эти объекты будет нельзя. В CCNA мы с вами проходили работу с access-листами только с IP-пакетами, но, в принципе, access-листы могут работать с чем угодно. Им на вход вы даёте множество каких-то объектов, они смотрят на какие-то поля в этих объектах, и в зависимости от того, что там видят, выносят какой-то результат. Access-листы будут состоять из отдельных блоков. На самом деле это строчки. Отдельная строчка будет называться ACE — Access Control Entry. И каждая строчка будет состоять из эталона того, с чем мы сравниваем наш объект, из критерия, как мы сравниваем с эталоном наш объект, и вердикта. Соответственно, здесь просто — permit или deny. Если наш изучаемый объект сравним с эталоном по заданному критерию, то выносится вердикт. Если он не сравним, то вердикт не выносится. И из первого блока мы переходим во второй. Дальше во втором блоке уже свой другой эталон,
свой другой критерий сравнения и свой другой вердикт. Если опять есть совпадение, выносим вердикт. И дальше уже не идём. Если нет совпадения, переходим к следующему блоку. Точно так же дальше следующий, следующий, следующий, до тех пор, пока либо мы не попадём под сравнение, либо у нас не закончится access control list. И в этом случае неявный вердикт будет, соответственно, deny. Оно же «нет». Что можно анализировать с помощью access list? Практически всё. Можно анализировать IP-пакеты. В IP-пакетах у нас есть стандартные access list и расширенные. На самом деле всё это наследие старины глубокой, когда давным-давно, в начале 80-х годов, access list умели работать только с IP-шниками источника. И такие access list назывались стандартными. Но через некоторое время появились расширенные access list, которые были типа потормознее, чем стандартные. Но на самом деле уже довольно скоро Cisco сделала расширенные access list
такими же быстрыми, как и стандартные. И с тех пор на самом деле все access list расширенные, даже если на них написано, что они стандартные, на самом деле они будут расширенные. В 15-м IOS вы можете работать со стандартными access list как с расширенными, потому что они по факту расширенные. И это даёт вам возможность сделать всякие вещи, которые при работе с именно стандартными access list могут быть недоступны. Но потом покажу, как это можно будет сделать. Ещё там есть именованные и нумерованные access list. Опять же, когда-то давным-давно именованные были медленнее, чем нумерованные. Но потом это всё изменилось, и по факту сегодня все access list будут именованные. И опять же, вы можете работать с нумерованным access list как с именованным. И это опять же даёт вам всякие разные клёвые плюшки. Если вы работаете с расширенным access list, он может смотреть на всё, что есть в IP-пакете. Всё, что знает Cisco, скажем. Это IP-шники источника или получателя.
Это тип содержимого, то есть поле протокола в IP-пакете. Если там лежит что-то известное, например TCP или UDP, можно смотреть на порты. Причём можно достаточно гибко сравнивать порты. Можно, например, сказать, что мы вынесем какой-то вердикт, если порты будут, например, больше чем 1024. Дальше. Можно заказывать сравнение с определёнными типами операций в ICMP, типы и коды. Можно, допустим, сказать, что если мы видим тип операции 3 в ICMP, то это destination unreachable, и такой пакет надо пропустить. А если мы видим, допустим, 4, если меня память не изменяет, redirect, такой пакет надо дропнуть. Дальше. Что ещё бывает? Можно анализировать отдельно OSPF и EIGRP. Это фактически тип содержимого.
Что ещё? Можно будет анализировать с помощью access-листов не только IP-пакеты. Если мы используем access-лист для анализа пакетов, то чаще всего мы смотрим на IP-шники источника и получателя. Если у нас есть пакет, в котором два адреса — IP источника и IP получателя, то фактически здесь у нас 4 байта и здесь у нас 4 байта. Плюс дополнительно мы можем что-то ещё сравнивать, но это на самом деле не так интересно. Чаще всего мы будем на эти два поля внимательнее всего смотреть. Фишка в том, что если у нас есть маршрут IPv4, то у него тоже есть те же самые 4 байта. У него есть IP-шник и маска. Если мы маску запишем в десятичном виде, у нас получится, что маршрут состоит из IP-шника и чего-то длиной 4 байта, которое тоже можно сравнивать как IP-шник получателя при анализе IP-пакета. Можно даже ещё сказать, что у нас может быть ещё адрес шлюза, и он тоже IP-шник.
Мы можем IP-маршруты анализировать: у нас есть next hop, у нас есть IP-шник, у нас есть маска. Тоже это всё можно сравнивать с какими-то эталонами. Правда, всё одновременно сравнить не получится. Мы можем в какой-то логике либо IP-шник плюс шлюз, либо IP-шник плюс маска. Одновременно и то, и другое сравнить не получится. Просто потому что у Cisco есть ограничение, что access control листы для IPv4, что пакетов, что маршрутов, могут смотреть только в два четырёхбайтовых поля за раз. Дальше. Можно анализировать не только IPv4, можно IPv6 анализировать. То же самое: IP-шник источника, получателя, тип содержимого, что внутри лежит, какие порты. Можно анализировать кадры Ethernet. Там есть MAC-и. MAC-и источника, MAC-и получателя и что внутри лежит. Ethertype, правда, анализировать нельзя, но LLC/SNAP-положение можно. Достаточно гибкий инструмент, которому на входе даём какой-то объект.
Говорим: сравни по первой строчке; сравни, если не получилось, со второй строчкой; если там тоже не получилось, сравни с третьей строчкой. И у нас в каждой строчке есть: с чем сравниваем, как сравниваем и что получилось, если сравнилось. Access-листы у нас будут делиться на нумерованные и именованные. На самом деле в 15-м IOS все access-листы именованные. То, что некоторые из них в конфигурации могут показываться как нумерованные, это тяжёлый пережиток прошлого, деревянные игрушки, прибитые к полу, 10-битовые VLAN ID и так далее. На самом деле вы можете к нумерованному access-листу обратиться как к именованному. С таким же синтаксисом, просто имя у него будет состоять из цифирок. И вы получите доступ ко всем инструментам работы с именованными access-листами. Даже если вы сделаете access-лист номер, не знаю, 15. Это как бы стандартный нумерованный access-лист. Но это можно расценивать как IP access-лист с именем «15». И тогда у него можно будет перенумеровать строчки, можно будет удалить отдельную строку и всякое такое.
Если у нас есть IPv4 access-листы, опять же, тяжёлые пережитки прошлого. Есть стандартные access-листы, которые могут смотреть только на IP-шник источника и больше никуда. И есть расширенные access-листы, которые могут заглядывать куда захотят. Сегодня все access-листы расширенные. Просто стандартные access-листы, если вы объявите access-лист как стандартный, он будет на уровне конфигурации запрещать вам работать с этим access-листом как с расширенным. Но в таблице самой Cisco стандартный access-лист будет по факту выглядеть точно так же, как расширенный. С access-листами можно анализировать, как я говорил, IPv4 и IPv6, Ethernet-кадры. Если вдруг вы достаточно наркоман — MPLS можно, MPLS-метки access-листами мониторить можно. DECnet, если вдруг кто-то застал, — DEC, старый древний протокол, очень старый, очень древний, сегодня не встречается нигде, но access-листы для него в Cisco до сих пор есть.
В большинстве случаев, если мы говорим для IPv4, мы будем работать с access-листами с указанием критерия сравнения в виде wildcard-маски. У нас в каждой строчке access-листа есть эталон и, соответственно, указание, как сравнивать с эталоном изучаемый IP-шник. И этот критерий сравнения будет как раз wildcard-маска. Маска будет состоять из нулей и единиц, она будет 32 бита размером. Соответственно, каждый бит будет указывать, надо ли соответствующий бит изучаемого образца сравнивать с соответствующим битом эталона. Если в wildcard-маске стоит 0 в соответствующем поле, значит, этот бит образца и этот бит эталона обязаны совпадать. Если они совпадают, мы выносим вердикт. Если хотя бы один битик,
где в маске стоит 0, в эталоне и в изучаемом образце не совпадает, то, соответственно, нет сравнения, мы переходим к следующей строчке. Единица в wildcard-маске означает, что соответствующий бит образца не обязан совпадать с соответствующим битом эталона. Не важно, что будет в эталоне, не важно, что будет в образце. Если совпали все биты, которые помечены ноликами, то, соответственно, мы выносим вердикт. Если не совпал хотя бы один битик, помеченный ноликом, то, соответственно, мы не выносим вердикт. На единички мы просто не смотрим. Почему эта штука называется маской? Потому что вы можете представить себе, что вы возьмёте, вырежете из бумажки — возьмёте такую длинную бумажную полоску и нарисуете на ней 32 квадратика. Каждый квадратик будет отдельный бит. И соответственно, вы сделаете таких полосок две. В одной полоске вы напишете IP-шник, там свой 100110 и так далее. А в другой полоске вы вырежете соответствующие окошки. Скажете: там, где нолик в wildcard-маске, мы окошко вырезаем, а там, где единичка, мы не вырезаем —
нам не интересно, что там. И если вы взяли IP-шник, который хотите изучить, взяли IP-шник, который у вас эталонный, наложили маску сначала на один, а потом на другой и сравниваете — то, что в окошке видно, там, где нолики были, должно совпасть. Если наложили маску на один IP-шник и наложили маску на другой IP-шник, результат получился одинаковый — значит, результат у нас совпадает, значит, критерий сравнения у нас сработал. Если хотя бы один битик различается — значит, критерий сравнения не сработал, мы переходим к следующей ACE. Пример: IP-шник 10.0.17.0, и мы хотим с помощью access-листа посмотреть на изучаемые, допустим, маршруты и
сказать, что мы хотим сказать permit на те маршруты, у которых первый октет будет десяткой, третий октет будет 17, а что во втором и в четвёртом — нам в принципе не важно, там уже всё что угодно. Мы в этом случае эталонный IP-шник записываем вот таким образом: здесь число 10, здесь не важно что — например, могут быть все нули, — здесь число 17 (16 плюс 1), и здесь опять же не важно что. В эталонном IP-шнике не важно, что вы будете записывать в те октеты, в те биты, которые закрыты маской с единицей — там можно записать нули, можно написать всё что угодно, они по факту ни с чем не сравниваются, они могут быть любыми. Есть правило, точнее не правило, а рекомендация: те биты, которые в эталоне не сравниваются, которые закрыты маской с единицей, выставлять в ноль — это более красиво, просто более легко читается. И в маске мы говорим: сравниваем первый октет, сравниваем третий октет, а второй и четвёртый не сравниваем. Если у нас есть какой-то IP-шник, у которого действительно
первый октет — десятка, а третий — 17, то мы скажем permit. А если мы видим, что хотя бы в одном битике есть различие, то мы не скажем permit. Да, это реально работает, вы можете access-листом действительно отловить такие кривые сравнения. Единственное, что не везде, где в Cisco применяются wildcard-маски, вам разрешено делать разрывные. Изначально wildcard-маски были сделаны специально для того, чтобы отличаться от нормальных масок — вот эти перевёрнутые, что логика не «там, где единичка, мы сравниваем, там, где нолик, мы не сравниваем», а наоборот — именно для того, чтобы визуально просто отличаться от нормальных масок. Потому что в нормальной маске не допускаются разрывные нолики и единички: у нас сначала в нормальной маске должны быть единички все, а потом нули. В wildcard-маске вы можете записывать нолики и единички вперемешку, вам это
разрешается делать. Но, например, wildcard-маски мы используем в динамической маршрутизации в команде network, про них сейчас отдельно будем говорить. Но тем не менее, там, несмотря на то что маска как бы wildcard, по факту она должна быть неразрывная — она должна начинаться со всех ноликов, потом продолжаться всеми единичками. Потому что по факту в Cisco просто по-дурацки очень сделано — команда network, я искренне ненавижу в Cisco за то, что она абсолютно нелогичная, абсолютно дурацкая, и там просто опять тяжёлое наследие древних-древних артефактов зашито в неё. Там на самом деле нужно было бы сделать, конечно, прямую маску. Если бы сделали прямую маску, это было бы ещё хуже, поэтому ладно, сделали как сделали. Когда у нас есть эталон и маска, они записываются вместе, одно без другого смысла не имеет. Когда мы производим какое-то сравнение, нам надо: что сравнивать, с чем сравнивать, как сравнивать.
«Что сравнивать» — это изучаемый образец, «с чем сравнивать» — эталон, и «как сравнивать» — это маска. Образец каждый раз новый, а эталон и маска прописываются в каждой Access Control Entry — она будет содержать в себе одну маску и один эталон. произвольно, то вы просто записываете эталон и маску и радуйтесь жизни. Если у вас маска будет специфическая — 0 0 0 0, все 32 бита нолика, это значит что у вас требуется совпадение всех битов эталона со всеми битами изучаемого образца, и тогда короткая запись такой маски с эталоном будет иметь вид host пробел эталонный IP-шник. Штука работает с IPv4, с IPv6. Если у вас маска состоит из всех единиц, это значит что вы не сравниваете ни один бит с эталоном, вам всё равно что будет в изучаемом образце, мы не сравниваем ни один его бит ни с чем, поэтому у нас всегда будет выноситься вердикт: все 0 бит, которые мы затребовали сравнивать, они все совпадают с теми нулями битами эталона, которые мы будем сравнивать,
потому что эта маска говорит: из всех 32 бит изучаемого образца 0 должны совпасть. 0 бит всегда совпадут, и в таком случае мы можем записать, что нас не интересует вообще какой IP будет, и тогда IP-шник плюс маска — вместо такой конфигурации мы пишем слово any. Оно заменяет и эталон, и маску. Так, как записывать access-листы. Я думаю, что вы помните: CCNA, CCNA, и нужно, если мы используем стандартный нумерованный access-лист, использовать номера с 1 по 99 либо с 1300 по 1999. Первая сотня — стандартный access-лист, самые первые, которые появились. 700 штук перед второй тысячей — это дополнительный блок, который появился чуть позже. Записи в access-листе нужно вводить с одинаковым
номером access-листа, и тогда они будут формировать один и тот же access-лист. Порядок записей важен. Вы не можете поменять порядок в нумерованном access-листе. Вы ввели нумерованный access-лист, и где-то сделали ошибку — единственное, что вы можете сделать, это удалить access-лист целиком и заново перенабить его. Более специфичные условия должны идти в начале, более общие — в конце. Если вы сначала более общим условием что-то сделаете, то потом более специфичное уже не сработает. Мы не переходим к следующему условию, если у нас сработало предыдущее. Поэтому если у нас есть что-то типа того, что у нас на слайде нарисовано — разрешите IP-шник 10.0.0.1, разрешите IP-шник 10.0.0.2, но запретить всю сетку по /24 маске — окей, мы не можем поменять порядок этих строчек местами. Первые две мы можем поменять, они по специфичности одинаковые, а вот третья строчка должна обязательно идти после них, потому что если мы сначала скажем deny 10.0.0.0 0.0.0.255 маски, то и 10.0.0.1, и 10.0.0.2 тоже задинаятся. Поэтому порядок строчек в access-листе будет важен: более специфичные условия в начале, более общее условие в конце.
Если у вас стандартный access-лист и у вас есть только один IP-шник, который вы хотите проверять, можно написать host и IP-шник, а можете ничего не писать, просто указать IP-шник — permit 10.0.0.1 — результат будет одинаковый. На самом деле внутри машины все эти записи будут храниться абсолютно идентично. Что вы напишете 10.0.0.1 с маской 0.0.0.0, что вы запишете просто 10.0.0.1, что вы запишете host 10.0.0.1 — машина всё равно это преобразует в одно и то же, скомпилирует и сохранит в памяти одинаково. Но я вам рекомендую не использовать такую запись, несмотря на то что она легко читается. Я рекомендую вам использовать запись host — она лучше на самом деле будет читаться, если вы привыкнете к записи в access-листах. Неподготовленный человек сможет легко понять, что это означает, но когда вы работаете с access-листами постоянно, вам удобнее будет, когда каждая
строчка в access-листе, каждый эталонный IP-шник плюс маска, будет храниться в виде host 10.0.0.2. Просто это удобнее по практике. Могу сказать, что даже если у вас стандартный access-лист, не надо пользоваться сокращением без указания host, без указания маски. Cisco это примет, да, для Cisco это тяжёлое наследие старых времён, поэтому она это позволяет сделать. Это совместимость с очень древними штуками, но если есть возможность, не используйте такое. Дальше, если у вас есть расширенный access-лист. Расширенные access-листы — это вторая сотня, со 100-го по 199, и 700 штук после второй тысячи, с 2000-го по 2699. Расширенный нумерованный access-лист точно так же вводится, как и стандартный, с поправкой на то, что у нас указывается два условия: первое условие на IP-шник источника, второе условие на
IP-шник получателя, плюс ещё дополнительно могут быть какие-то ограничения, связанные с конкретным протоколом, который вы требуете. Если вы не хотите требовать никакие ограничения на вложение, то вы указываете permit, дальше протокол просто указываете ip — любые IP- пакеты, неважно какое вложение будет, будут срабатывать по этому условию, и дальше указываете эталон и маску источника, эталон и маску получателя. В нашем случае host 10.0.0.1 — понятно, что any тоже понятно, что source — это source, а destination — это destination. Если вы хотите наложить дополнительные условия, то вы можете указать, какой протокол вас интересует, можете указать IP-шник источника. В нашем случае мы говорим 192.168.0.0 по /16 маске — это ограничение на IP-шник источника, а это — ограничение на IP-шник получателя. На самом деле более строго здесь
надо будет сказать, что в TCP у нас не IP-шники, у нас сокеты, и поэтому это ограничение на сокет получателя. IP-шник там может быть любой, а вот эта штука eq 80 означает, что порт получателя destination port должен быть именно 80. eq — это equal, требуется строгое совпадение порта получателя с числом 80. Есть ещё ne — not equal. Есть ge или le, gt и lt соответственно: greater or equal, less or equal, greater than и less than. Greater or equal — это нестрогое сравнение, less or equal тоже нестрогое сравнение, greater than — строгое, less than — тоже строгое. И есть ещё диапазон — вы задаёте два числа, и по-моему там слово range
указывается. Если вы хотите сказать, что вас устроит вынести вердикт, допустим, permit, в случае если порт получателя будет в диапазоне от 1000 до 2000, то вы указываете range 1000 2000. На порт источника точно так же можно наложить ограничения. Eq 80 в нашем случае стоит в конце, и в конце не просто так, а после слова any, который означает destination IP-шник. Если вы хотите на порт источника тоже наложить ограничения, то вы должны это сделать после IP-шника источника, но перед IP-шником получателя, где стрелочка показывает. Так, дальше. Если мне память не изменяет, на курсе по свитчингу у нас будет ещё разбор того, как хранятся access-листы. Если мне память не изменяет, мы с вами разберём это достаточно общо, в том числе разберём, как
хранятся access-листы внутри памяти Cisco. В книжках, официальных книжках-руководствах по сертификации, этот механизм описан более детально. Я призываю вас на самом деле уделить некоторое время тому, как внутри Cisco всё это дело хранится, и постараться это осмыслить. Я сейчас рамочно по этому делу пробегусь, не помню, то ли в этом курсе, то ли в следующем это у нас будет. Рамочно по этому процессу пробегусь, но детально мы всё-таки в него углубляться не будем. Там довольно много особенностей, что-то я расскажу, остальное вам лучше будет посмотреть по книжке. Так, в конце любого access-листа есть неявный вердикт deny any any. Соответственно, если вы хотите, чтобы у вас что-то задинаилось, но не всё, чтобы всё, что не запрещено, было разрешено, то в конце access-листа вы должны будете добавить строчку permit ip any any. Или в случае стандартного access-листа —
permit any. Дело в том, что если её не указать, если у вас просто будет указание: это разрешить, это запретить, это разрешить, это запретить, и не будет в конце этой строчки, то всё остальное тоже будет динаиться. Эта штука называется implicit deny — неявный запрет на то, что всё остальное будет отбрасываться. Это фактически deny ip any any. Вы можете сделать explicit deny — в явном виде сказать deny ip any any, или permit ip any any — explicit permit, явное разрешение на прохождение любого трафика. Если у нас есть именованные access-листы, то на самом деле все access-листы именованные. Если мы хотим с каким-то access-листом обращаться как с именованным, мы должны будем указать, какой access-лист мы создали или с
каким собираемся работать. Если он уже создан, указываем команду ip access-list, дальше указываем тип access-листа, с которым мы собираемся работать — это либо standard, либо extended, и указываем имя access-листа. Имя может состоять только из цифр. Если у вас есть нумерованный access-list с номером 1, вы можете сказать ip access-list standard 1 и работать с этим access-листом дальше как с именованным. Никто вам это делать не мешает. Синтаксис ввода команд в именованном access-листе такой же, как в нумерованном, только не надо писать каждый раз access-list и номер. Всё, что кроме access-list и номер, здесь просто: permit такое-то, deny такое-то, permit any. Логика примерно та же самая. Если вы расширенный access-лист используете, тоже не надо просто писать access-list номер, сразу начинаете: permit, что разрешаем, какой протокол. В нашем случае там UDP,
какой IP-шник источника — любой, какой IP-шник получателя — 8.8.8.8 с ограничением на порт 53. Можно легко понять, что это Google DNS. Любой UDP — остальное запретить: deny UDP any any. И permit IP any any — всё остальное разрешить. Мы хотим сбросить весь UDP-трафик, кроме четвёрки восьмёрок. Вы должны будете сами понимать, какой access-лист в вашем случае будет удобнее. Если вам достаточно работать только с IP-шником источника, вы можете объявить access-лист стандартным, и тогда немножко синтаксис будет попроще при работе с ним. Не надо будет писать много IP-шников. Если всё равно вы работаете только с IP-шником источника, то какой смысл постоянно писать IP, постоянно писать IP-шник получателя. Например, при работе с фильтрацией трафика на линиях управления VTY очень удобно работать со стандартными access-листами, потому что там не надо говорить, что при подключении по протоколу SSH,
единственному разрешённому на наших VTY-ках, мы хотим проверять, что протокол там действительно TCP и порт назначения действительно 22. А какой он ещё может быть, если мы по SSH подключаемся? Соответственно, IP-шник получателя — какой смысл нам анализировать? Это наш собственный IP-шник, какой бы он ни был. А вот IP-шник источника при подключении по SSH нам очень интересен, поэтому стандартный access-лист на линиях управления VTY как раз полезен и удобен. При работе с NAT тоже, чаще всего, нас интересуют только IP-шники источника. Там нужен access-лист при создании правила NAT с overloading — обычный NAT, классический для выхода в интернет. И там тоже IP-шники источника интересны, а всё остальное нет. Поэтому стандартные access-листы имеют свою область применения, просто с ними в некоторых случаях попроще работать и экономия ценных калорий. Да, наше всё. А расширенные access-листы позволяют заглянуть в какие-то поля, которые стандартным access-листам недоступны.
Это IP-шники получателя, тип вложения, номера портов. Стандартный access-лист не может заглянуть внутрь тех полей, которые отличаются от IP-шника источника. Если вы хотите с access-листом работать, чтобы он анализировал что-то отличное от IP-шника источника, то у вас один только вариант — расширенный access-лист. При работе с именованными access-листами вы на самом деле можете делать всякие разные клёвые штуки. В частности, вы можете добавлять, удалять строчки в них, если вы хотите. Удалять можно любую строчку, а не только целиком access-лист, как с нумерованными access-листами. И дополнительно можно вставить строчку в любое место access-листа, а не только в конец. И вы должны будете знать, что на самом деле все access-листы в памяти IOS являются именованными. Даже если вы видите, что access-лист, который вы создали, имеет номер 1, который мы только что создали командой
access-list 1 permit чего-то там, на самом деле он всё равно в памяти хранится как именованный access-лист. И вы можете после того, как вы с ним только что пообращались как с нумерованным, немедленно перейти в новую концепцию, и обратиться к нему как к именованному и редактировать его во все поля. Для того чтобы вам это продемонстрировать, можно просто сделать show ip access-list — команда, которая показывает access-листы, используемые для IPv4, или просто show access-list — это покажет все access-листы. И показывается, что у нас есть access-лист с идентификатором 1. Это фактически имя, состоящее из одной циферки. И у этого access-листа все команды пронумерованы, все access control entry. Первая будет иметь номер 10, вторая 20, 30. И ровно такая же нумерация будет у всех access-листов. Она будет начинаться с десятки, и шаг нумерации тоже будет десяткой. Эта нумерация очень полезна для того, чтобы как раз вставлять новые записи внутрь access-листа.
Если вам нужно добавить новую строчку между 10-м и 20-м условиями, то вы делаете новую строчку с номером 15, и она встанет между 10-й и 20-й строчкой. У вас получится, что не в конец она добавится, а куда скажете. Ровно так же можно и удалить строчку с нужным номером. Если вам не нравится строчка 20, можно только её удалить. С нумерованным access-листом вы не можете такое сделать. Можно удалить только весь access-лист целиком. Нельзя удалить отдельную строчку в нумерованном access-листе. Если вы скажете, допустим, добавим новую строчку, которая в первый access-лист будет. Access-list 1, permit, host, допустим, host и дальше вы пишете 1.1.1.1. Такой хост вы хотите добавить. А потом написали, нажали Enter и поняли, что вы ошиблись. На самом деле вы имели в виду 1.1.1.2.
Вы не можете сказать no access-list 1 permit host 1.1.1.2. Это логичная команда. Если вы попытаетесь её выполнить, Cisco её сожрёт. Но только она сожрёт от неё только вот эту часть. Она скажет: удалим access-лист номер 1 целиком. Она не даст вам удалить отдельную строчку в нумерованном access-листе. Даже если вы только что набили эту команду и сказали no и дальше та же самая команда. Типичное явление в Cisco, когда вы что-то сделали, поняли, что ошиблись, отменяете действие командой no. Нет, Cisco удалит access-лист целиком. Очень неприятное явление, если этот access-лист у вас использовался для доступа к самой Cisco. Типичный сценарий — это, например, у вас есть access-лист для NAT. Вы хотите добавить новую сетку в NAT и добавляете в access-лист что-нибудь, а потом понимаете, что вы ошиблись, и говорите: отменить, убрать это. Убивается весь access-лист целиком, и у вас NAT перестаёт работать. К сожалению, да, иногда сам на такое натыкался раньше.
Сейчас уже боевые шрамы не дают это забыть. Рано или поздно все на это накалываются. Если мы хотим удалить целиком нумерованный access-лист, это единственное, что с ним можно сделать — просто no access-list и номер. Нельзя удалить отдельную строчку. Если вы хотите удалить именованный access-лист, то no, дальше ip access-list, указываете тип access-листа и его имя. Если вы хотите удалить отдельную строчку в именованном access-листе, то вы заходите в редактирование этого access-листа, так же как если вы добавляли в него что-нибудь или создавали его, и указываете no и дальше номер строчки, который вам не нравится. Возвращаясь на предыдущий слайд — нумерация: если хотите удалить строчку с номером 20, заходите в редактирование access-листа, который вы создали,
можно именованного, можно нумерованного, неважно. Вы к нему обращаетесь как к именованному access-листу и говорите no пробел 20, или no 10, и у вас удаляется строчка с номером 10. Если вы хотите добавить строчку в нужное место, то перед самой строчкой при её добавлении вы указываете номер, который у неё должен получиться. Например, с пятёрки строчку начинаете, и у вас вставится строчка с номером 5, то есть самая первая. Если у вас нумерация используется по умолчанию, то самая первая строчка была 10, вы добавляете новую строчку с номером 5, и она вставляется в самое начало. Естественно, может сложиться ситуация, при которой вы постоянно хотите что-то добавлять в начало. Сначала добавили строчку с номером 5, потом с номером 3, потом с номером 2, потом с номером 1, а потом получается, что у вас всё, больше номеров не осталось. Есть команда по перенумерации access-листа: ip access-list, дальше вместо standard или extended вы указываете resequence и название access-листа. И у вас нумерация возвращается в своё начальное состояние.
Первая строчка будет 10, вторая 20, 30. Порядок их останется, только у них номера сменятся, и можно будет снова добавлять в начало access-листа всё что угодно. Можно дополнительно указать, с каким шагом вы хотите перенумеровать. Допустим, вы хотите не с шагом в 10 нумерацию сделать, а с шагом в 20 или шагом в 5. Вы можете это сделать. Или можно сказать стартовый номер, с которого вы хотите перенумеровать access-лист. Можно сделать так, чтобы первая строчка получила номер, например, 100. Поступил вопрос: не проще ли редактировать access-лист в блокноте? С одной стороны, проще. С другой стороны, не любой access-лист вы можете отредактировать в блокноте. Если вы сидите, допустим, на Cisco удалённо, и вы сами подключаетесь через что-то, через какой-то интерфейс, например, трафик в котором обрабатывается access-листом, то вы не можете отправить на Cisco ваш новый access-лист, потому что вы для этого должны удалить старый.
И вы сначала удалите старый, и после этого у вас связь отвалится, вы уже новый загрузить не сможете. Это можно, конечно, с помощью всяких разных хитрых трюков сделать. Например, взять файлик, в котором будут лежать команды по составлению нового access-листа, и перед составлением нового там будет команда с удалением старого. И уже загрузить файлик, сказать copy tftp чего-то там running-config, но это всё костыли. А так, чтобы просто взять и отредактировать, удалить одну ненужную строчку в access-листе, Cisco позволяет это сделать через интерфейс редактирования именованных access-листов. Некоторое время назад был очень популярен программный продукт, который Cisco позиционировала как GUI для редактирования конфигов на Cisco, назывался SDM. Это не Switch Database Manager, это Security Device Manager. И для ASA он ещё был ASDM, он до сих пор используется. Ну, ASA, да, с ней всё грустно.
А для IOS был просто обычный SDM, и этот самый SDM позволял как раз редактировать access-листы. И причём делал это довольно удобно. И фактически это было единственное применение, зачем SDM вообще люди использовали. Потому что всё кроме access-листов им было делать крайне неудобно. Он портил конфиги, он делал много всяких разных других гадостей. Но access-листы с его помощью можно было делать довольно удобно. Вроде resequence нет на каталистах — ничего не готов по этому поводу сказать. Не могу подтвердить, не могу опровергнуть. Знаю, что resequence нет в IPv6. Это одна из болей при работе с access-листами в IPv6. Вы должны сразу использовать правильную нумерацию, потому что перенумеровать access-лист будет нельзя.
С access-листами для IPv6 — никаких нумерованных access-листов, только именованные, только расширенные. Никаких wildcard-масок. Соответственно, только нормальные прямые маски. Если вы хотите сказать, что какая-то сетка может ходить куда-то, например any, дальше вы указываете 2000::/3. В IPv6 это значит просто global unicast адреса. И такое же ограничение, UCO SMTP. Говорите, что по TCP можно откуда угодно ходить в интернет по SMTP. Или нельзя в нашем случае, deny, нельзя. Весь остальной IPv6 трафик можно. Такой аксесс-лист есть. Вывод команды show ipv6, аксесс-лист немножко отличается. Отличается в том смысле, что секвенсинг. Раньше номера были перед строчками, а здесь они в конце. Если вы хотите удалить строчку какую-то, вы уже просто не пишете no 10, а пишете no sequence 10. Или если добавляете новую строчку с нужным номером,
тоже указываете её номер и указываете в конце sequence 10. Вот так, как она здесь указана. Если вы работаете с аксесс-листами, которые должны будут использоваться в фильтрации трафика, я напоминаю, что есть типичное применение для аксесс-листов — это вешать их на интерфейсы для простейшей пакетной фильтрации, то не забудьте, пожалуйста, разрешить ICMP. Если вы не разрешите ICMP в явном виде, у вас можно поломать Neighbor Discovery. Либо должны разрешать всё, либо должны в явном виде разрешить ICMP. Потому что если у вас в IPv4 протокол ARP работал не по IPv4, он работал рядом с ним, и разрешить или запретить его с помощью IPv4 аксесс-листов было нельзя. Поэтому Neighbor Discovery в IPv4, это разрешение канальных адресов с помощью протокола ARP, оно работало независимо от IPv4 аксесс-листов, которые вы вешали.
А в IPv6 Neighbor Discovery работает поверх IPv6. Поэтому если вы повесите фильтрацию в IPv6 с помощью команды Traffic Filter, аналог аксесс-групп, и вы скажете, что трафик надо фильтровать, если вы там в явном виде ICMPv6 не разрешите, у вас канальные адреса соседей резолвиться не смогут. Поэтому будьте аккуратнее. Ещё один инструмент, который нам будет полезен, это префикс-листы. Срывая покровы, я вам расскажу страшную вещь. Префикс-лист — это хорошо переодетый аксесс-лист. По сути своей это та же самая вещь. Но префикс-лист специально сделан таким, чтобы быть удобным для работы с маршрутами. Вы можете всё то же самое, что можно сделать с префикс-листом, сделать и с аксесс-листом. И в большей части механизмов, которые принимают префикс-листы,
вы можете использовать аксесс-листы. Просто это становится менее удобным. Префикс-листы удобны именно тем, что они достаточно очевидным образом работают. И если нас интересует именно работа с маршрутами, то они как раз предоставляют те удобные инструменты, которые облегчают жизнь администратору. Можно сделать всё то же самое и с аксесс-листами. Это как можно любую программу написать в двоичных кодах. Просто вопрос в том, сколько времени вам понадобится для этого, сколько усилий вы потратите по сравнению с каким-то высокоуровневым языком программирования. Префикс-лист — это удобная обёртка для аксесс-листов. Аксесс-листы у нас умеют анализировать множество всяких разных вещей. Но среди прочих они умеют анализировать, если мы говорим про IPv4, два айпишника. В пакете, если мы берём пакет и даём аксесс-листу, он смотрит на айпишник-источник, айпишник-получателя. И каждый из этих айпишников он может независимо сравнивать по разным условиям. Разным эталонам и разным wildcard-маскам.
Если вы берёте маршрут IPv4, у него тоже есть два 32-битных числа. Одно из них означает айпишник самой сети, и другое означает маску. И вы можете с айпишником и с маской работать как с пакетом. Вы можете взять их, дать на вход аксесс-листу, и он проанализирует отдельно айпишник сети, отдельно маску, и скажет да или нет. Но то же самое можно сделать с префикс-листом. Формат записи префикс-листа будет напоминать аксесс-лист. Мы точно так же будем давать название префикс-листу. В нашем случае мы даём название pfl, и мы можем сделать несколько строчек с одним и тем же именем. И тогда у нас будет работать та же самая логика, что в аксесс-листах. Сначала выполняется первое сравнение. Если оно срабатывает, мы говорим вердикт, который там есть. Если нет, то мы переходим к следующей строчке, проверяем вторую часть, и выносим тот вердикт, если там есть совпадение.
То же самое, что в аксесс-листах, потому что по сути своей аксесс-листы и есть. Но различие с аксесс-листами будет в том, что нам не нужно будет указывать айпишник и кривую маску. Мы можем указать только нормальную, прямую, обычную человеческую сетку. Сетку с префиксом. Если вы указываете только сетку с префиксом, в нашем случае permit 10.10.11.0/24, этот префикс-лист скажет да, скажет permit, ровно на сетку 10.10.11.0, ровно с маской 24. Ему требуется прямо точное совпадение. Точно так же, как в случае с аксесс-листами, если у нас есть расширенный аксесс-лист, расширенный именованный аксесс-лист, можно его перенумеровать, можно добавлять новые строчки в нужные места. С префикс-листами всё это тоже работает, поскольку по сути своей это аксесс-лист. Если вы хотите добавить новую строчку, указывайте номер с последовательностью, sequence 5.
И show ip prefix-list вам покажет, какие строчки какие номера будут иметь. Точно так же можно удалить отдельную строчку: no ip prefix-list, там что-то sequence 10, к примеру, и так далее. Добавлять строчки бывает иногда полезно, а удалять мне как-то ещё ни разу не приходилось. Но допускаю, что это может быть кому-то интересно. Если вы хотите работать с сетками именно в жёстко заданном виде, говорите: такой префикс — да, такой префикс — нет, такой префикс — да, такой префикс — нет, то, конечно, префикс-лист намного удобнее, потому что вы должны будете сказать, что вас интересует анализ и айпишника сети, и маски, и вам требуется точное совпадение айпишника и маски с заданными значениями. Но префикс-листы — намного более мощная штука. Они могут анализировать попадание префикса внутрь каких-то больших префиксов. И вы можете задавать условия, как именно вы хотите это сделать.
Если вы знакомы, например, с оборудованием Juniper, то там такая штука называется route filter, и у них есть матчи. Имена этих матчей хорошо известны, там есть exact, range, longer, or longer и так далее. В Cisco это всё кастомное, вы можете сделать любые сравнения, которые захотите. У вас просто есть инструменты для этого, и вы можете отдельно указывать, в какую сетку должен попадать айпишник в вашей сети, и какого размера должна быть маска. Фактически, если вы ничего не указываете после айпишника сети, здесь ничего нет, то вам требуется строгое совпадение. 10.10.11.0 именно с 24-й маской. На него мы будем говорить permit, если он будет в таблице или он будет поступать нам на анализ. Если же нам требуется сказать, что префикс попадает в какую-то другую большую сетку, и у него есть такая маска,
то тогда мы должны будем указать дополнительные ограничения. И эти дополнительные ограничения указываются после айпишника и после маски. Если ничего не задано, требуется точное совпадение. Если задано что-то, то вы проверяете, что айпишник у вас попадает в эту сетку, а маска попадает под дополнительные заданные ограничения. Это своего рода двоичная логика, либо то, либо другое. Если вы ничего не указали, требуется совпадение и айпишника, и маски, заданное здесь. Если вы указали дополнительные ограничения, то сначала айпишник анализируется на попадание в эту сетку, а потом маска изучаемого маршрута проверяется отдельно. Это важно. Все на этом рано или поздно накалываются. Я могу даже вам это рассказывать, могу не рассказывать, но на самом деле, если вы будете работать с префикс-листами, я вам гарантирую, что вы обязательно забудете то, что я вам сейчас говорю. Сколько бы вы книжку ни читали, всё равно, как только в первый раз вы встретитесь с аксесс-листами,
вы забудете, что если вы не указываете дополнительные ограничения, то проверяется именно айпишник и именно маска. Айпишник проверяется по айпишнику, маска проверяется по маске. Если же вы указываете дополнительные ограничения, как здесь какие-то дополнительные ограничения есть, то айпишник сравнивается отдельно по всей этой штуке, что айпишник попадает в эту сеть, а маска проверяется по этой части. Дурацкая вещь, но тем не менее работает она так. Если ничего не указано, то и айпишник, и маска должны совпадать с указанными. Если указаны дополнительные ограничения, то айпишник проверяется отдельно. И этот слэш 24 начинает работать в другом смысле. Он начинает уже ограничивать именно IP-адрес. А маска проверяется по тому, что справа. Сравнивается именно длина префикса или размер сети. А какая между ними разница? Не совсем понял. Да, здесь идёт сравнение самой маски как числа.
Если у нас есть сетка слэш 24, то здесь требуется строгое совпадение. Если же у нас есть сетка слэш 25, то 24 и 25 — это не совпадает. Но если у нас есть какое-то требование, чтобы оно совпадало с числом 25, то сравнивается именно число одно с числом другим или с некоторыми двумя другими числами. Для анализа длины маски у нас будут использоваться операторы greater or equal, GE, или less or equal, LE. Примеры того, как можно с этими операторами работать. Если мы никакие операторы не указываем, то нам требуется строгое совпадение 10.10.11.0/24. Я сейчас сознательно приведу вам пример того, как то же самое можно сделать, указав ограничение на длину маски. Вот этот exact 1 префикс-листа: exact 2, permit 10.10.11.0/24 GE 24 LE 24. Он делает абсолютно то же самое. В одном случае мы говорим: айпишник сети должен быть 10.10.11.0, а маска сети должна быть 24.
В другом случае мы говорим: айпишник сети должен попадать в эту сетку, а маска сети должна быть больше либо равна 24 и меньше либо равна 24. Эта штука по сути своей делает то же самое. Если у нас есть айпишник, который попадает в сеть 10.10.11.0 по 24-й маске, и маска там именно 24, то это значит, что айпишник самой сети может быть только 10.10.11.0. Он никаким другим быть не может. Что можно сделать более продвинутого, чем требовать точное совпадение префикса? Можно, например, сказать, что нас интересуют все сетки, которые попадают в определённый диапазон, с масками, которые будут тоже в определённом диапазоне. Например, то, что здесь префикс-лист range указан. Опять же, имена этих префикс-листов сделаны специально, чтобы напоминать аналогичные концепции в Juniper.
Там есть route-матчи. Но тем не менее они работают как такой конструктор — сделай сам. Вы указываете, что вас интересуют айпишники префиксов, которые попадают в сетку, а размер маски должен быть больше либо равен 26 и меньше либо равен 28. Например, сетка 10.10.11.0/24 сама не получит permit. А 10.10.11.0/26 получит permit. 10.10.11.64/26 тоже получит permit, потому что айпишник сети 10.10.11.64 входит в сетку 10.10.11.0 по 24-й маске. И маска 26 входит в диапазон от 26 до 28 включительно. Эта штука довольно удобная. Когда вам нужно, например, отобрать все сетки, которые зародились в определённом distribution-блоке. Нам известно, что сеть строится поблочно.
У нас есть блок номер 1. В нём 10.1.0.0/16. Есть сетка 10.2.0.0/16. Таких блоков у нас много. И нас интересуют все сети, которые будут в определённом блоке. Но, например, мы хотим сказать, что нас интересуют сети не сильно мелкие. Нас не интересуют, например, сетки лупбеков. И чтобы отобрать все сети, которые из второго блока, но они хотя бы /24 или крупнее, то есть /24, /23, /22 нас будут интересовать, в этом случае вы можете сказать, что нас интересует permit. Дальше айпишник родительской сети 10.0.0.0 по 16-й маске. И ограничение на маску, например, LE 28. Что маски нас интересуют числово меньше, чем 28. Это должна быть 28-я сетка или крупнее. 27-я, 26-я, 25-я. Если нас, наоборот, будет интересовать всякая мелочь, то мы можем сделать GE.
Допустим, GE 25. Значит, нас интересуют 25-я, 26-я, 27-я, вплоть до 32-й. Разница между этим примером Longer, который требует 25 или больше, и Or Longer, 24 или больше, заключается в том, что сама сетка 10.10.11.0 здесь будет попадать. А здесь, в просто Longer 10.10.11.0 по 24-й GE 25, сама 24-я сетка попадать туда не будет. Здесь любая сеть, которая является подсетью 10.10.11.0 по 24-й маске. GE 26 и LE 28 — будут попадать все сетки, у которых айпишник попадает в родительскую сеть, а маска будет 26, 27 или 28. GE и LE — это greater or equal и less or equal. Больше либо равно, меньше либо равно. Поэтому здесь везде сравнение не строгое. Если мы указываем GE 25, то это 25 или больше.
Если вы хотите разрешить, например, дефолтный маршрут, то вам требуется совпадение и айпишника, и маски с заданными значениями. И вы указываете ip prefix-list, например, default, указываете, что вас интересует айпишник 0.0.0.0 и маска слэш 0. Это как раз пример фактически такой, когда мы не указываем дополнительные ограничения, мы говорим: ровно один единственный маршрут 0.0.0.0/0. Если вы добавите какое-то ограничение, любое, то в этом случае у вас будут проверяться айпишники и проверяться маски. И в родительскую сеть 0.0.0.0/0 попадёт абсолютно любой айпишник. Поэтому по факту вы будете сравнивать только маски. Вы можете сказать, что хотите отобрать абсолютно любые сетки, которые, допустим, имеют маску ровно 24. В этом случае будете указывать 0.0.0.0/0 GE 24 LE 24.
Этот префикс-лист отберёт абсолютно любые префиксы, у которых маска ровно 24, ни больше, ни меньше. Айпишник неважно какой. Например, вы можете отобрать любые маршруты вообще. 0.0.0.0/0 LE 32. GE 0 сделать нельзя, а LE 32 сделать можно. И это означает, что вы скажете permit на абсолютно любой маршрут. У абсолютно любого маршрута айпишник попадает в сетку 0.0.0.0/0, а маска будет меньше либо равна 32. Этот механизм позволяет достаточно гибко работать с префиксами. Если нас интересуют префиксы, которые были порезаны на части из какой-то одной большой сети, для этого есть сравнение айпишника префикса. Если нас интересует размер маски, то для этого есть механизм сравнения с маской. Так, GE 24, LE 24, это только 24?
Да, это только 24. Как уже было сказано, на самом деле префикс-листы — это просто обёртка для аксесс-листов. Всё, что можно сделать префикс-листом, можно сделать и аксесс-листом. Я сейчас приведу примеры того, как одну и ту же задачу можно решить и префикс-листом, и аксесс-листом. Например, у нас есть простенький префикс-лист. ip prefix-list pfl1 permit, дальше мы указываем сетку 10.0.0.0/8. Мы не указываем дополнительные ограничения на маску. Нас интересуют такие маршруты, у которых айпишник сети ровно 10.0.0.0, а маска сети ровно 8. Для того, чтобы это сделать, нам подойдёт обычный стандартный аксесс-лист. Стандартный аксесс-лист умеет сравнивать одну запись. Но если мы будем работать с маршрутами, то в случае работы с маршрутами с аксесс-листами
стандартный аксесс-лист немножко получается имеющим такую двойственную природу. У него будет отдельно эталон — сравнивать точное совпадение с айпишником. И отдельно wildcard-маска будет сравнивать фактическое совпадение с нормальной прямой маской. То же самое можно сделать и расширенным аксесс-листом. Если бы у нас был расширенный аксесс-лист, мы бы сказали, что у нас есть отдельно ограничение на айпишник источника, отдельно ограничение на айпишник получателя. Точнее, правильнее сказать, отдельно ограничение на айпишник 1, отдельно ограничение на айпишник 2. Это мы бы проверяли одной частью, а это мы бы проверяли другой частью. Но если именно речь идёт про стандартные аксесс-листы, которые можно использовать для динамической маршрутизации, то не пугайтесь, если вдруг вы увидите что-то аналогичное. Стандартный аксесс-лист, если вы будете использовать для фильтрации маршрутов, у него есть указание на эталон и указание на маску. Эта маска фактически будет означать, что вы хотите использовать эту маску в качестве сравнения с самой маской.
Это получается не wildcard-маска, это получается уже фактически эталон для маски сети. 10.0.0.0 тут и 10.0.0.0 тут — строгое совпадение, и слэш 8 здесь. Эта штука — это фактически слэш 8: 0.255.255.255, тут как раз 8 нулей и 24 единички. Требуется строгое совпадение и здесь, и здесь. Если бы мы это делали расширенным аксесс-листом, то мы бы сказали: давайте мы сначала айпишник эталонный плюс маску проверим 10.0.0.0, и отдельно 32 бита эталонных, 32-битная wildcard-маска проверим этот слэш 8. Тогда у нас был бы расширенный аксесс-лист, и десятку мы бы проверяли: 10.0.0.0 по маске 0.0.0.0. И слэш 8 мы бы сказали: 255.0.0.0 по маске 0.0.0.0.
Это уже просто обычная нормальная запись обычного расширенного аксесс-листа, с которым вы привыкли работать. Это ограничение на один айпишник — требуем совпадение с 10.0.0.0. Это ограничение на другой, в кавычках, айпишник — требуем совпадение с 255.0.0.0. И тогда только префикс 10.0.0.0/8 получит указание permit. Один префикс-лист может содержать в себе несколько записей. Если мы хотим дополнительные ограничения на маску указывать, хотим сказать, что нас не только один префикс будет интересовать, а все, которые удовлетворяют определённому условию, например, у нас есть такой префикс-лист: 10.0.0.0/8 GE 16. Мы будем говорить permit на 10.1.0.0/16, 10.2.0.0/17, 10.3.0.0/24, 10.1.2.4/32.
Любая маска, которая будет числово больше, чем 16, или равна 16, нас устроит. Но саму сетку 10.0.0.0/8 мы при этом не будем пропускать. В этом случае получается, что эта штука должна анализировать маску, а эта штука должна анализировать префикс. Поэтому мы указываем, что нас интересует расширенный аксесс-лист. И указываем, что мы хотим, чтобы айпишник сети начинался на 10 и мы сравнивали бы этот айпишник. Если мы хотим сказать, что айпишник сети попадает в сетку 10.0.0.0 по 8-й маске, у него первая часть обязана быть десяткой, а остальные неважно какие. Здесь это можно в принципе опустить. Любой айпишник, который начинается на 10, он попадает в сетку 10.0.0.0 по 8-й маске. И мы говорим: айпишник сети должен быть 10 по 8-й маске. Это можно в принципе опустить. 255 в перевернутой маске означает, что мы это не сравниваем. Соответственно, ограничение на маску 16 или больше.
Указывает, что у нас есть еще вторая половина Extended Access-листа. И мы говорим: Маска, которая будет у префикса, она будет иметь вид 255, 255, точка... И здесь уже не важно что. Может быть 0, 0. Может быть 128, 0. 252, 0. Неважно что здесь, неважно что здесь. Но первые два октета должны быть 255. Поэтому мы пишем эталонная маска 255, 255, 0, 0. И нам требуется сравнение с эталонной маской только по первым двум октетам. Поэтому если маска будет 255, 255, 0, 0 — мы скажем: да, всё хорошо, матч есть. Если маска будет 255, 255, 255, 0 — мы скажем: всё хорошо, матч есть. Первые два октета мы требуем совпадения с 255, 255. Если маска будет, например, слэш 8 — мы скажем: нет, матча нету. Потому что слэш 8 маска — это 255, 0, 0, 0.
Здесь требуется, чтобы второй октет был 255, а он по факту 0. Поэтому эта штука ловит маски, которые Greater or Equal 16. Далее. Если у нас есть другое ограничение — мы хотим ловить сетки, которые не слишком мелкие. Например, Less or Equal 24. Меньше либо равно 24. Опять же, IP-шник нам надо, чтобы попадал в некоторую сетку. Ограничение на маску — чтобы маска не была слишком мелкой. Маска не слишком мелкая означает, что если у нас есть, например, 24-я сетка — это сетка 255, 255, 255, 0. Если у нас есть плохая сетка, например /25, которая нас не устроит — это значит, что у неё в четвёртом октете будут не все нолики, а какие-то появятся единички. Если вдруг в четвёртом октете у нас есть что-то с единичками — оно нас не устраивает.
В то же время, если сетки, которые нас устроят, будут больше, чем /24, то третий октет начнёт обращаться в ноль постепенно, начиная с самого правого битика. Он будет всё время меньше, меньше, меньше. Неважно, что в третьем октете будет, неважно, что во втором октете, неважно, что в первом октете у маски. Но в последнем октете десятичной маски должен быть ноль для того, чтобы эта сетка была меньше либо равна 24. Поэтому мы указываем IP Access List Extended. Дальше, ограничение на IP-шник самой сети: неважно, какой IP-шник, главное, чтобы начинался на десятку. Первый октет мы требуем совпадения, и эталонный IP-шник, с которым мы требуем совпадения, начинается на десятку. А в маске мы говорим: наше ограничение на маску — что мы требуем совпадения в четвёртом октете с эталонным октетом ноль. Если у нас есть совпадение с эталонным октетом ноль — то это как раз и есть ограничение на LE24. Можно сочетать это.
Если у нас есть какой-то префикс-лист, в котором мы и GE используем, и LE — мы говорим, что маска должна быть больше, чем 16, но меньше либо равна 24. Соответственно, IP-шник — здесь всё понятно, всё то же самое. А в маске мы говорим: требуем совпадение первых двух октетов, потому что нам требуется GE16, и требуем совпадение четвёртого октета с нулём, чтобы было LE24. Неважно, что в третьем октете у сетки. Любая сетка, у которой 255, 255 в начале и 0 в конце, а в третьем октете неважно что — может 0, может 255, может 192 — она пойдёт под это условие. По сути своей префикс-лист — это Access List в красивой обёртке. Но, естественно, работать со строчкой типа «10.0.0.0/8 маске от 16 до 24» намного удобнее, чем с этой наркоманией. Правда? Если вы знаете, как это работает, вы в этом разберётесь. Но писать это с нуля — невозможно.
И когда вы работаете с маршрутами, вы можете легко сказать: отбери мне все маршруты, которые из второго дата-центра пришли. Префикс-листом это делается легко и приятно. А Access-листом — технически сделать можно, но это неудобно. Эта хрень — она работать будет, если вы знаете, как это работает. Вы можете это написать в качестве разминки для ума. Но в продакшене это невозможно было бы использовать. Если вы работаете с префикс-листами, вы можете легко работать с ними и анализировать IP-шники префиксов, маски префиксов. Это действительно удобно. И если вдруг вы захотите — вы знаете, что можете анализировать маршруты с помощью Access List. Это ровно то же самое по сути своей, потому что префикс-лист на самом деле просто изощрённый Access List. Если вдруг вы эстет — есть люди-эстеты, они не любят префикс-листы, потому что это слишком просто.
Есть люди, которые любят всё делать с Access-листами. Знайте, что Access List, если вы будете их использовать для того, что в принципе можно сделать префикс-листами, они анализируют как раз IP-шник и маску. Если это Extended Access List, он первым IP-шником анализирует IP-шник префикса и вторым — маску префикса. Если вы будете использовать Extended Access List для анализа маршрутов при редистрибьюции в EIGRP или в BGP — там немножко другая логика. Там вторая часть будет означать не маску префикса, а IP-шник Next Hop. Будьте осторожны, если вдруг вы потом когда-нибудь расковыряете эти видео, слайды и попытаетесь это сделать в продакшене. Там как раз будет интересно, что с помощью этих Access List можно будет сказать: если к нам приходят какие-то маршруты, которые Next Hop указывают на Васю — мы их используем, а Next Hop указывают на Петю — мы их не используем.
Но это уже отдельная тема для отдельного разговора. В большинстве случаев, когда мы с маршрутами работаем, мы используем как раз префикс-листы, просто потому что это удобно. Специальный механизм создан для анализа префиксов, и они действительно позволяют очевиднейшим образом с ними работать. Но не надо забывать, что если вы ничего не указываете, то требуется строгое совпадение и IP-шника, и маски. Так, пример префикс-листа, который будет что-нибудь фильтровать. Я предлагаю здесь вам сделать самостоятельную разминку для ума. У нас есть префикс-лист, который будет разрешать 0.0.0.0 по нулевой маске и, соответственно, GE32. Вопрос: что именно этот префикс-лист будет разрешать? Вы мне предложили несколько версий. Давайте попытаемся понять, что имелось в виду.
Смотрите. Если у нас есть ограничение на IP-шник и ограничение на маску, то IP-шник сети может быть входящий в сеть 0.0.0.0/0 — он может быть абсолютно любой. А маска может быть больше либо равна 32. Если маска больше либо равна 32, то это, например, слэш 32 — и всё, потому что больше, чем 32, маска быть не может. Поэтому если у нас есть какой-то IP-шник, который входит в сеть 0.0.0.0/0, с маской 32 — какой-то маршрут — это фактически любой маршрут с маской 32. Соответственно, мы на него скажем permit. Этот префикс-лист отберёт все маршруты на лупбеках, если вы их анонсируете по 32 маске. Так, дальше. Вторая загадка. У нас есть префикс-лист B, который указывает permit 128.0.0.0/2 GE16 LE16. Что эта штука будет делать?
Давайте разбираться, что здесь имелось в виду. Если нас просят, чтобы IP-шник попадал в сеть 128.0.0.0/2, то 128 — это у нас 10000000 в двоичной записи, и /2 означает первые два бита. Если мы хотим, чтобы маска была слэш 16 — она должна быть больше либо равна 16 и одновременно меньше либо равна 16 — значит, она должна быть точно 16. Мы будем говорить permit на любые IP-шники, которые входят в эту сетку с маской слэш 16. Если у нас есть IP-шник, начинающийся на первые 2 бита «10», а следующие 14 бит неважно какие, и маска — это 16... Это адреса класса B. В классовом мире классовые сетки класса B начинались на «10», дальше было 14 бит неважно каких, и, соответственно, слэш 16.
Если вы с этим не встречались — не страшно. В том, чтобы в 2018 году не помнить, как выглядит класс B, ничего такого нету. С 92-го года, слава богу, никаких классовых сетей больше не осталось. Поэтому только наркоманы вроде меня про это помнят. Дальше. Следующий префикс-лист. Permit 0.0.0.0/0 LE32. Что эта штука будет делать? Здесь вы единодушны. Любой маршрут, действительно: IP-шник сети может быть любой — любой IP-шник попадает в сеть 0.0.0.0/0. И LE32 — это любая маска. Любая маска будет меньше либо равна 32. Других просто не бывает. В то же время префикс-лист D очень похож на этот. Permit 0.0.0.0/0. Что он будет делать? Вы уже сразу готовы.
Он только один единственный маршрут — восьминулёвку — матчит. Действительно, никаких ограничений на маску нет, а это значит, что нам требуется точное совпадение и IP-шника, и одновременно маски. Поэтому эта штука матчит только дефолт. И, соответственно, предпоследний. Permit 0.0.0.0/1 LE24. Что эта штука делает? Здесь вы достаточно единодушны. 0.0.0.0/1 — это намёк на первую половину адресного пространства, которая когда-то давным-давно называлась классом A. Сегодня это уже бесклассовая адресация, поэтому сегодня нет никакого смысла матчить адреса по классам. Но тем не менее, если углубляться в историю, это адресное пространство действительно было зарезервировано за классом A. Всё, что от 0 до 127 включительно в первом октете, будет сюда попадать. LE24 — это значит, что нас интересуют сетки не мельче 24. Маска может быть 24, 23, 22, 21 и так далее, вплоть до единички включительно.
Дефолт уже матчиться при этом не будет. Или будет? Нет, подождите, будет. Будет дефолт матчиться, простите, наврал. 0.0.0.0/1 означает, что IP-шник дефолтного маршрута действительно в 0.0.0.0/1 попадает, и LE24 тоже всё хорошо. Класс A, когда он был, он был с маской слэш 8. И, соответственно, последний префикс-лист F. Permit 0.0.0.0/0 GE8 LE24. Здесь очень похоже на предыдущее. Мы опять же требуем совпадение IP-шника с любым — мы не требуем никаких ограничений на IP-адрес. Но мы требуем ограничения на маску. Любые префиксы с длиной маски от 8 до 24 будут сюда попадать.
Здесь дефолт уже, очевидно, не пройдёт, потому что, несмотря на то, что в дефолте 0.0.0.0/0 есть, но маска у него слэш 0, а здесь мы требуем, чтобы она была больше или хотя бы равна 8. Так что с помощью префикс-листов можно всякое разное ловить. В реальности вы, конечно же, будете работать с префикс-листами не с такими экзотическими. Вы будете говорить, что нас интересуют, например, сетки определённого блока адресов. У нас есть родительская сеть — distribution-блок 10.7.0.0/16. Здесь внутри него есть отдельные 24-е сетки. И мы говорим: отбери нам, пожалуйста, IP prefix-list, permit 10.7.0.0/16, и нас интересуют сетки ровно по 24-й маске — GE24 LE24. И тем самым мы отбираем все 24-е сетки, которые есть в блоке 10.7.0.0.
Ещё раз напоминаю, что рано или поздно вы забудете про то, что если не указывать GE и LE, то префикс-лист требует точного совпадения и IP-шника, и маски. Когда вы на это наколетесь — напишите мне, что прогноз сбылся. Если вдруг никогда не наколетесь — я буду удивлён.
Так, продолжим. Следующий инструмент, который у нас есть — это роутмапы. Роутмапы устроены более сложно по сравнению с аксесс-листами и с префикс-листами.
Если вы посмотрите на аксесс-листы и на префикс-листы тоже, то фактически, если вы знаете какой-нибудь язык программирования, устроены они по логике «если — то — иначе», «если — то — иначе». Мы берём первое сравнение. Если попадает под сравнение с эталоном по заданному критерию — мы выносим вердикт. Иначе переходим к следующему. «Если — то — иначе», «если — то — иначе». Мы не можем там сделать какое-то ветвление, мы не можем сказать что-то типа «посмотри туда», «посмотри сюда, но не туда». Такие более сложные критерии сравнения нам будут недоступны. Route-map позволяет сделать сравнение по более сложным алгоритмам, чем это позволяют аксесс-листы. Во-первых, route-map — это инструмент, который может смотреть не только в те заголовки, которые можно анализировать с помощью...
Те поля, точнее, те свойства, которые можно анализировать с помощью access-листов. Access-листы могут смотреть на адреса, могут смотреть на какие-то части IP-адресов, но они не могут смотреть на свойства, которые не являются частью, допустим, если мы говорим про пакеты, заголовка IP-пакета. Например, пакет может прийти через определённый интерфейс, и мы не можем в access-листе проанализировать интерфейс, через который пакет пришёл. Либо, если мы говорим про маршруты, мы не можем в access-листе проверить, например, источник маршрутной информации, пришёл ли маршрут через OSPF. Или, к примеру, если мы знаем, что он пришёл через OSPF, какого типа это был маршрут? Какого типа был маршрут? Если OSPF-ский маршрут, он может быть внутренний, как intra-area маршрут, может быть inter-area маршрут, или он может быть external маршрут, полученный через LSA пятёрку.
Все эти дополнительные сравнения доступны только в route-map. Мы можем с помощью route-map смотреть на разные свойства изучаемых объектов, использовать какие-то сложные критерии сравнения, и самое интересное — мы можем модифицировать эти объекты. Если к нам приходит на вход набор чего-нибудь, например, набор маршрутов, мы можем взять их, проанализировать, на некоторые из них сказать «нет», на некоторые из них сказать «да», и те объекты, которым мы сказали «да», с ними что-то сделать, выполнить над этими объектами какие-то манипуляции. Access-листы только расставляют «да» или «нет», они не могут больше ничего делать. Вы им на вход даёте маршруты, они говорят «да», «нет», «да», «да», «нет», «да», «да», «нет», «нет», «нет», «нет», «да», «да». Но они больше ничего не делают. Route-map может взять маршрут и перебить ему, например, NextHop. Может взять маршрут и перебить ему тип: к вам пришёл OSPF inter-area маршрут,
вы взяли его на лету, переделали, и дальше показываете его, как будто он intra-area. Такие вещи в route-map сделать можно. Устроены route-map будут похожим образом на access-листы. Они тоже будут состоять из блоков. Тоже блоки будут работать последовательно. Сначала работает первый блок, потом, если он не сработал, срабатывает второй блок, потом третий блок, потом четвёртый. И так до конца, если мы проверили все блоки и ни один блок не сработал, то выносится неявный вердикт, который говорит «нет». То есть deny. Здесь тоже такие же термины. Permit и deny будут использоваться. Permit — мы говорим «да», deny — мы говорим «нет». И в каждом конкретном блоке мы говорим либо permit, либо deny. И в каждом блоке у нас есть пачка критериев сравнения и пачка манипуляций, которые мы будем проводить с изучаемым объектом, если у нас есть вердикт.
Если мы говорим «да», то мы можем поменять то, что мы через себя пропускаем. И этот набор сравнений — это уже не банальный эталон и критерий сравнения. Там будет более сложная логика. Внутри каждого блока она может быть своя. Здесь мы можем сравнивать что-то одно, здесь мы можем сравнивать что-то другое, здесь мы можем сравнивать что-то третье. И в каждом блоке каждое сравнение может быть достаточно сложным, достаточно комплексным. Блоки будут содержать в себе вердикт permit or deny, будут содержать условия сравнения. Они будут называться критерии match. И блоки манипуляции. Это критерии set. Здесь у нас есть route-map, который состоит из трёх блоков. Route-map с первым блоком, вторым блоком, третьим блоком. И на самом деле здесь ещё четвёртый блок есть. Я его сразу не заметил, но он тоже есть.
В каждом блоке у нас есть какие-то match, какие-то set. Может быть такое, что какие-то либо match, либо set не указаны. Тогда просто подразумевается, что есть какое-то значение по умолчанию. Но вердикт в любом случае должен быть. Хотя тоже его можно не указывать. Тогда предполагается, что вердикт — permit. Если вы указываете route-map, дальше название, дальше указываете вердикт и номер блока. Дальше то же самое здесь. Route-map, название, вердикт, номер блока. Вот это блок 1, это блок 2, это блок 3, это блок 4. Каждый блок у нас имеет номер 10, 20, 30, 1000. Так же, как в access-листах, мы можем строчки пронумеровать. И они будут срабатывать в порядке возрастания цифр. Если хочется новый блок добавить в начало — не проблема. У нас самый первый блок сейчас имеет номер 10. Следующий блок мы будем рисовать с номером, например, 5. Если номер не указан, нумерация будет такая же, как в access-листах.
10, 20, 30 и так далее. Мы возьмём самый большой номер, который есть сейчас, и добавим новый блок в конец, прибавим десятку к нему. Если вы не указываете номер, он берётся автоматически. Если вы не указываете вердикт, он тоже берётся автоматически. Считается permit, если вы просто указываете route-map, дальше какое-то название, это создаёт новый блок, даёт ему какой-то новый номер, и предполагается, что если вы не указали в явном виде, то вердикт будет permit. Дальше. В каждом блоке критерий match, критерий set. Здесь у нас 3 match и 2 set. Здесь у нас только 2 match и ни одного критерия set. Значит, мы никак не модифицируем изучаемые объекты. Они через нас проходят, мы им дадим вердикт deny. При вердикте deny нет смысла как-то изменять объекты, потому что с ними дальше ничего не произойдёт. А если мы выносим вердикт permit, мы можем модифицировать. Мы можем сказать set и перебить свойства в объекте каким-нибудь образом, которым мы захотим.
А можем не перебивать, это наше право. Не обязательно у вас set будет в каждом блоке. Можно не писать set, просто сказать permit и всё пропускаем как есть. Здесь, соответственно, есть match и set. По одному. Пожалуйста, окей. Причём, если у вас есть несколько критериев match, которые находятся в одном блоке, они должны будут сработать все одновременно. Используется логика «и». Мы говорим: если это... Допустим. Если у этого есть хобот. Критерий сравнения 1. Если у этого есть 4 ноги. И если у этого большие уши, то мы говорим: да, мы это обрабатываем. Если вы захотите, вы можете сделать логику «или». Должно сработать или одно, или другое. Тогда в одной строчке вы указываете: если у этого есть хобот или если у этого есть большие уши. Либо одно, либо другое, либо оба сразу. Любое должно сработать, чтобы мы сказали: у нас есть match.
Таким образом вы можете использовать достаточно хитрые штуки. Если вы в одной строке указываете, то у вас работает «или», но сравнивать можно при этом значение только одной природы. Например, мы можем сказать, если мы хотим проанализировать IP-адреса: IP-адрес должен попадать под access-list такой, или под access-list такой, или под access-list пятый, или под access-list десятый. Под любой попал — значит, хорошо. Если мы указываем разные критерии match, то они обязаны иметь разную природу. Мы не можем сказать, что адрес должен попасть и под один access-list, и под второй access-list, и под третий. Так сделать нельзя. Можно только «или». В class-map там чуть-чуть иначе. Там вы можете регулировать это. В route-map, если вы указываете последовательно, то это «и». Если вы указываете в одной строчке, то это «или». Дальше.
Set вы можете указывать или не указывать, как вы хотите модифицировать объекты. Если хотите — можете указать. Если не хотите — можете не указывать. И каждая отдельная строчка set изменяет объект каким-то своим образом. Вы можете сказать: в этом set-statement мы указываем, что мы перебиваем NextHop. В этом set мы перебиваем, допустим, выходной интерфейс. Вы можете перебивать самые разные свойства. Но два раза перебить одно и то же нельзя. Это единственное ограничение. Что можно матчить? Если у нас есть блок, в котором мы хотим отбирать какие-то объекты для того, чтобы им сказать permit, например. Матчить можно у разных объектов разное. Route-map устроены не так, как access-листы.
У access-листов по внешнему виду сразу понятно, с чем он работает. Если вы берёте access-лист, на нём большими буквами написано: это access-лист для протокола IPv4, это access-лист для протокола IPv6. Даже если мы создавали нумерованные access-листы, там по номеру было видно. Если мы создаём именованные access-листы, то мы указываем IP access-list или IPv6 access-list или MAC access-list. Нельзя было взять IPv6 access-list и присобачить его для анализа Ethernet-кадров. Так бы не сработало, и это лишено смысла. С route-map всё хуже. Route-map может работать с абсолютно любыми объектами. Нет специальных отдельных route-map для Ethernet и отдельных route-map для IPv4 и отдельных route-map для IPv6. Это одни и те же route-map. И матчить в этих route-map можно вообще всё. Гипотетически вам никто не мешает сказать: давайте матчить одновременно и IP-адреса, и MAC-адрес источника, и тип маршрута, и что-нибудь ещё.
Свойства, которые изначально принадлежат объектам разных типов. Гипотетически вы можете это сделать. По факту логически это сделать нельзя, потому что потом этот route-map надо будет использовать в качестве классификатора. И как только вы Cisco скажете: пожалуйста, используй этот route-map, в котором ты матчишь и MAC-адреса, и IP-адреса, и типы маршрутов, и что-то ещё, она скажет: извините, я не могу это использовать. Потому что мы сначала отдельно создаём route-map как классификатор, отдельно пытаемся его как-то использовать. Вы не должны делать неразумные вещи. Это ваша ответственность как оператора Cisco — создавать route-map, которые будут матчить только то, что разумно. Поэтому, если вы собираетесь route-map использовать для анализа IP-пакетов, вы должны будете использовать только match по тем полям, которые есть в IP-пакете. Если вы используете route-map для маршрутов, вы должны использовать только те поля, которые есть в маршрутах. Вы не должны пытаться использовать MAC-адреса у маршрута, правильно? Если вы работаете, например, с IP-пакетами или с маршрутами, потому что у маршрутов тоже есть IP-адреса, если мы говорим про IPv4-маршруты и IPv4-пакеты, то матчить вы можете IP-адреса.
Вы берёте либо проходящий через вас пакет, который вы анализируете route-map, либо маршрут, который вы анализируете route-map, и говорите: посмотрим на IP-адреса. И вы можете сказать: либо эти IP-адреса должны удовлетворять некоторым access-листам, access-лист на них должен сказать permit, либо можно задать IP-адрес через prefix-list, и тогда вы матчите IP-адреса с помощью prefix-list. Это как раз один из немногих случаев, когда prefix-list может отработать и будет использоваться в анализе пакетов, потому что route-map может работать с пакетами. И вы можете route-map сказать «матчим IP-адреса по prefix-list», хотя на самом деле матчить вы будете внутри пакета. Но если вы просто prefix-list будете использовать, то мы это обычно всё-таки делаем для префиксов, а не для пакетов. Если у вас есть маршрут, у этого маршрута есть свойство, которое называется NextHop, и этот NextHop тоже можно каким-то образом анализировать.
И тоже можно его по access-листу матчить или по prefix-list. Если речь идёт про маршрут, именно про маршрут, не про пакет, то у маршрута есть однозначное свойство, откуда он известен. Например, OSPF, например, BGP. Route source — это как раз откуда мы его знаем. Или сосед, откуда мы его получили, кто нам прислал такой маршрут. Если у нас IPv6-пакеты или маршруты, то будет уже не IP-адрес, а IPv6-адрес. Опять же, вы можете заказать в одном и том же классификаторе анализ и IP-адресов, и IPv6-адресов, но Cisco вам потом не даст использовать этот классификатор с теми объектами, у которых хотя бы чего-нибудь одного нет. И одновременно, чтобы были и IPv4-адреса в чём-то, и IPv6-адреса в чём-то — мне такие объекты ещё не попадались.
Поэтому матчить вы можете либо IPv4-адреса, либо IPv6, но одновременно вам не следует этого делать. Cisco позволит написать в одном правиле route-map match и того, и другого. Она вам не даст ошибку, но логически это, конечно, будет ошибка. Опять же, prefix-list можно писать IPv6, если захотите — пожалуйста, никто вам это сделать не мешает. Можно матчить метрику маршрута. Если у нас есть маршруты OSPF, RIP, BGP, EIGRP, у них у всех есть такой параметр, как метрика, и можно тоже по нему ориентироваться. Если у нас есть пачка маршрутов в таблице маршрутизации, мы можем сказать: отберите, пожалуйста, только те OSPF-овские маршруты, у которых метрика ровно 17. И match мы такие маршруты можем отобрать. Если у вас маршрут будет EIGRP-шный, или OSPF-овский, или BGP-шный, то у него будет тип маршрута.
Соответственно, external, internal, local, NSSA external. Это из OSPF, мы про это ещё дальше поговорим. Опять же, в этих протоколах можно на маршруты вешать метки. Они не передаются, как правило. Если вы захотите, вы можете свои маршруты раскрасить в таблице маршрутизации, и после того, как вы их раскрасите, вы будете с по-разному раскрашенными маршрутами по-разному работать. Дальше в курсе это тоже будет, поэтому мы с этим ещё встретимся. Манипулировать маршрутами тоже можно. Если у нас есть маршруты, можно перебивать NextHop. У нас есть маршрут, который указывает в сторону Васи, а мы говорим: все маршруты, которые красные, мы перемечаем и говорим, что они смотрят в сторону Пети. Это очень интересная штука на самом деле. И, например, её можно будет использовать для сценариев не совсем очевидных.
К примеру, я, наверное, не открою большого секрета, есть такой сервис, который называется Роскомнадзор, который периодически вводит всякие запреты. Есть очень много людей, которым эти запреты не нравятся, которые хотят эти запреты обходить. И они говорят: нам бы каким-нибудь образом получать в таблицу маршрутизации маршруты, которые были заблокированы Роскомнадзором. И такие сервисы действительно есть, которые позволяют, например, по протоколу BGP получать пачки маршрутов, которые блокируются Роскомнадзором. Самого пиринга по BGP — пиринг сам есть, а передачи пакетов при этом нет. Вы можете взять и, например, сказать, что вы поднимаете VPN до какого-нибудь совершенно постороннего ресурса, где-нибудь виртуалку поднимаете, поднимаете VPN-туннель до неё, с внешним сервисом пиритесь по BGP, принимаете BGP-шные маршруты,
которые заблокированы Роскомнадзором, и дальше, принимая такие маршруты, route-map перепиливаете им NextHop на VPN-туннель. Такие вещи позволяют получить маршрут из одного источника, а пакеты направить в сторону совершенно другого назначения. Вы можете им NextHop на лету менять. Что ещё тут у нас есть? NextHop позволяет нам сделать ещё одну, например, штуку. Вы можете route-map использовать для так называемого policy-based routing. Я думаю, что сегодня мы это сделать уже не успеем, а завтра как раз у нас самое начало занятия будет с policy-based routing начинаться. И вы можете пакеты, проходящие через ваш роутер, через ваш интерфейс, направлять в разные стороны в зависимости от содержимого этих пакетов. По таблице маршрутизации вы не можете по-разному обрабатывать, например, голосовые пакеты и пакеты с абстрактными данными.
А route-map вы можете проанализировать, что внутри лежит, и перебить таким пакетам IP-адрес NextHop и выходной интерфейс. И тогда, если вы это сделаете, у вас пакеты с голосом пойдут по одной трассе, а пакеты с иным содержимым пойдут по другой трассе, даже если у них IP-адрес назначения будет один и тот же. С таблицей маршрутизации такое сделать нельзя. С policy-based routing можно, и route-map как раз там будет использоваться. Мы это будем завтра проходить. Можно будет поиздеваться над маршрутами, можно будет метрику перебить, можно будет тип маршрута перебить, можно будет с BGP всякие параметры проставить. Опять же, будем проходить BGP, обязательно это посмотрим. Вот пример route-map, который может чего-нибудь делать. У нас есть route-map, и он показывает, что он будет что-нибудь делать. Первый блок у нас показывает route-map. Дальше название route-map,
set metric rm, намекает на то, что этот route-map будет что-то делать с метрикой. Первый блок не пронумерован, поэтому он будет иметь номер 10. И он будет иметь вердикт deny. Если у нас здесь какие-то match будут, то мы на эти match будем говорить deny. Вставляем. И на самом деле здесь set бесполезен. По-хорошему. Здесь прописано set metric 100. При deny нет смысла выставлять set. Здесь я не знаю, зачем я это сделал. Ну окей, пусть будет так. Да, этот set metric, наверное, должен был быть где-то вот тут. Второй блок, set metric rm, permit 5. Мы вставляем перед запретом permit. Указываем, что если у нас есть какие-то маршруты, у которых IP-шники, match IP адрес, попадает под список access control list vip users.acl,
то мы их permitим. И здесь set metric надо было бы как раз указать, что если у нас есть этот самый set metric, то мы с ними как-то работаем. Еще один блок. Route-map set metric rm просто без ничего. Здесь не указан номер, поэтому номер здесь у нас получается 5, 10, скорее всего 20. И вердикт не указан permit. Если у нас нет ни одного правила match, если нет ни одного ничего указанного, то, соответственно, матчится вообще все. Это тот самый аналог permit IP any any, который есть в конце access list. Если вы ничего не указываете в конце своего route-map, то предполагается неявный запрет на все остальное, неявный deny. Но если вы указываете вот такую конструкцию route-map set metric rm, название route-map, и просто ничего не указываете в матчах, то значит вы матчить будете все. Если вы не указываете здесь permit, то предполагается, что этот permit был указан неявно.
Поэтому все остальные маршруты вы тоже через себя будете пропускать. Вот у нас получается show route-map set metric rm. Пятый номер. Сейчас сотру все эти пометки свои. Пятый номер. Это вот этот блок. Мы матчим по access list. И мы каким-то образом пропускаем через себя маршруты. Здесь ничего не показано в качестве set. По идее, здесь логично было бы этот set metric 100 поставить. Второй блок. Блок с номером 10. Мы запрещаем обработку таких маршрутов. Мы их сначала матчим, мы их потом не пропускаем через себя. И этот set по факту не работает.
Матчим мы по признаку, что IP-шники попадают в список troublemakers ACL. И все остальное мы пропускаем. Мы ничего в явном виде не матчим, поэтому мы матчим все. Здесь пусто в match clauses. Set clauses тоже пустой. Соответственно, мы пропускаем через себя маршруты, через этот блок. И говорим, что все маршруты, которые проходят через этот блок, которые не были обработаны предыдущими блоками, мы просто пермитим тихо и все. Нужно это для того, чтобы не было неявного deny на все остальное. С route-map мы будем с вами работать, во-первых, в следующем модуле, который будет посвящен policy-based routing. Мы там на него сделаем лабу. А во-вторых, мы с вами на route-map будем очень большое внимание обращать при работе с BGP. BGP будет очень сильно зависеть от route-map, потому что там все будет основано на политиках. Когда мы принимаем какие-то маршруты, и тем более, когда мы отправляем какие-то маршруты соседям, мы очень часто хотим отправлять не все.
А если даже что-то мы отправляем и принимаем, мы хотим это зачастую немножко модифицировать перед тем, как отправлять соседу или перед тем, как принимать маршруты от соседа. Поэтому там без route-map фактически никуда. Поэтому если вдруг вы с ними не встречались, то практики на них у нас будет достаточно много. Самые популярные способы использования route-map. Это, во-первых, PBR, Policy Based Routing. Это не табличная маршрутизация, это маршрутизация на основе политик. Мы с помощью route-map пишем политику, и трафик, который приходит на наш роутер, мы отправляем не на таблицу маршрутизации, а мы отправляем на анализатор политики, на анализатор route-map. И route-map может для приходящих пакетов перебить адрес NextHop и перебить выходной интерфейс. И, соответственно, если мы это сделаем, то Policy Based Routing позволит нам ориентироваться на какие-то поля пакета, отличные от IP-шника назначения.
Например, мы можем сделать разные условия для проходящего трафика. Если мы увидим внутри содержимое голосовое, мы отправляем по одному интерфейсу. Если мы увидим другой трафик, не голосовой, мы его отправим по другому интерфейсу. Очень часто используемый сценарий, когда в организации есть два канала, один из которых хороший, надежный, быстрый, но платный, и второй, соответственно, дешевый и бесплатный или околобесплатный, но похуже качеством. И вы хотите, чтобы голосовые пакеты использовали быстрый, пусть даже и дорогой канал, потому что голос приоритетный и удобнее его пропускать по быстрому каналу, даже если за деньги. Просто абстрактный какой-то трафик, условный торрент, чтобы он использовал бесплатный интернет или околобесплатный, нелимитированный. Довольно частое применение. Route-map в BGP являются основой использования. Фактически нормально работать в BGP можно только при хорошем понимании route-map.
И, наконец, это всякие перекладывания маршрутов между разными протоколами. Если у нас прибежал какой-то маршрут в один протокол, а мы его берем и перекладываем в другой. Мы что-то изучили по OSPF и хотим рассказать про это нашим EIGRP-шным соседям. Получили что-то по RIP и перекладываем это в условный BGP. Это все перекладывание, редистрибуция, или по-русски есть красивое слово перераспределение, которое я никогда не слышал в реальном мире. Все говорят редистрибуция. Это все тоже зачастую основано на route-map. На этом теоретическая часть закончена. Дальше как раз модуль PBR.