По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Мы продолжим рассмотрение вопроса об устранении неполадок в объявлениях о маршрутах BGP. Все маршрутизаторы будут иметь рабочие соседние узлы BGP. Рекомендуем также почитать первую часть статьи по траблшутингу протокола BGP. Видео: Основы BGP за 7 минут Урок 1 Новый сценарий. R1 и R2 находятся в разных автономных системах. Мы пытаемся объявить сеть 1.1.1.0 / 24 от R1 до R2, но она не отображается на R2. Вот конфигурации: На первый взгляд, здесь все в порядке. Однако R2 не узнал никаких префиксов от R1 Может быть, используется distribute-list. Но нет, это не тот случай. Это означает, что нам придется проверять наши все команды network. Проблема заключается в команде network. Она настраивается по-разному для BGP и нашего IGP. Если мы применяем команду network для BGP, она должна быть полной. В этом случае забыли добавить маску подсети R1(config)#router bgp 1 R1(config-router)#network 1.1.1.0 mask 255.255.255.0 Мы должны убедиться, что ввели правильную маску подсети. Итак, видно, что мы узнали префикс, и R2 устанавливает его в таблицу маршрутизации ... проблема решена! Итог урока: введите правильную маску подсети ... BGP требователен! Урок 2 Давайте перейдем к следующей проблеме. Системный администратор из AS1 хочет объявить summary в AS 2. Системный администратор из AS 2 жалуется, однако, что он ничего не получает..., давайте, выясним, что происходит не так! Вот конфигурация. Вы можете увидеть команду aggregate-address на R1 для сети 172.16.0.0 / 16. Жаль ... префиксы не были получены R2. Здесь мы можем проверить две вещи: Проверьте, не блокирует ли distribute-list префиксы, как это мы сделали в предыдущем занятии. Посмотрите, что R1 имеет в своей таблице маршрутизации (Правило: "не могу объявлять то, чего у меня нет!"). Давайте начнем с таблицы маршрутизации R1. Из предыдущих уроков вы знаете, как выглядит distribute-list. Здесь нет ничего, что выглядело бы даже близко к 172.16.0.0 /16. Если мы хотим объявить summary, мы должны сначала поместить что-то в таблицу маршрутизации R1. Рассмотрим различные варианты: R1(config)#interface loopback 0 R1(config-if)#ip address 172.16.0.1 255.255.255.0 R1(config-if)#exit R1(config)#router bgp 1 R1(config-router)#network 172.16.0.0 mask 255.255.255.0 Это вариант 1. Создам интерфейс loopback0 и настроим IP-адрес, который попадает в диапазон команды aggregate-address. Теперь мы видим summary в таблице маршрутизации R2. По умолчанию он все равно будет объявлять другие префиксы. Если вы не хотите этого, вам нужно использовать команду aggregate-address summaryonly! Второй вариант объявления summary: R1(config)#ip route 172.16.0.0 255.255.0.0 null 0 R1(config)#router bgp 1 R1(config-router)#network 172.16.0.0 mask 255.255.0.0 Сначала мы поместим сеть 172.16.0.0 / 16 в таблицу маршрутизации, создав статический маршрут и указав его на интерфейсе null0. Во-вторых, будем использовать команду network для BGP для объявления этой сети. Итог урока: Вы не можете объявлять то, чего у вас нет. Создайте статический маршрут и укажите его на интерфейсе null0, чтобы создать loopback интерфейс с префиксом, который попадает в диапазон суммарных адресов. Урок 3 Следующая проблема. Вы работаете системным администратором в AS 1, и однажды получаете телефонный звонок от системного администратора AS 2, который интересуется у вас, почему вы публикуете сводку для 1.0.0.0 / 8. Вы понятия не имеете, о чем, он говорит, поэтому решаете проверить свой роутер. Это то, что видит системный администратор на R2. Мы видим, что у нас есть сеть 1.0.0.0 / 8 в таблице BGP на R1. Давайте проверим его таблицу маршрутизации. Сеть 1.1.1.0 / 24 настроена на loopback интерфейс, но она находится в таблице BGP как 1.0.0.0 / 8. Это может означать только одну вещь ... суммирование. Беглый взгляд на выводы команды show ip protocols показывает, что автоматическое суммирование включено. Отключим это: R1(config)#router bgp 1 R1(config-router)#no auto-summary Мы отключим его на R1. Теперь мы видим 1.1.1.0 / 24 на R2 ... проблема решена! Итог урока: если вы видите classful сети в своей таблице BGP, возможно, вы включили автоматическое суммирование. Некоторые из проблем, которые были рассмотрены, можно легко решить, просто посмотрев и/или сравнив результаты команды "show run". И это правда, но имейте в виду, что у вас не всегда есть доступ ко ВСЕМ маршрутизаторам в сети, поэтому, возможно, нет способа сравнить конфигурации. Между устройствами, на которых вы пытаетесь устранить неисправности или которые вызывают проблемы, может быть коммутатор или другой маршрутизатор. Использование соответствующих команд show и debug покажет вам, что именно делает ваш маршрутизатор и что он сообщает другим маршрутизаторам. Урок 4 Та же топология, другая проблема. Персонал из AS 2 жалуются, что они ничего не получают от AS 1. Для усложнения проблемы, конфигурация не будет показана. Для начала, мы видим, что R2 не получает никаких префиксов. Так же можем убедиться, что R1 не имеет каких-либо distribute-lists. Мы видим, что R1 действительно имеет сеть 1.1.1.0 /24 в своей таблице маршрутизации, так почему же он не объявляет ее в R2? Давайте посмотрим, может на R1 есть какие-то особенные настройки для своего соседа R2: Будем использовать команду show ip bgp neighbors, чтобы увидеть подробную информацию о R2. Мы видим, что route-map была применена к R2 и называется "NEIGHBORS". Имейте в виду, что помимо distribute-lists мы можем использовать также route-map для фильтрации BGP. Существует только оператор соответствия для prefix-list "PREFIXES". Вот наш нарушитель спокойствия ... он запрещает сеть 1.1.1.0 / 24! R1(config)#router bgp 1 R1(config-router)#no neighbor 192.168.12.2 route-map NEIGHBORS out Удалим route-map И наконец R2 узнал об этом префиксе ... проблема решена! Итог урока: убедитесь, что нет route-map, блокирующих объявление префиксов. BGP иногда может быть очень медленным, особенно когда вы ждете результатов, когда вы работаете на тестовом или лабораторном оборудовании. "Clear ip bgp *" - это хороший способ ускорить его ... просто не делайте этого на маршрутизаторах в производственной сети) Урок 5 Наконец, третий участник выходит на арену, чтобы продемонстрировать новую проблему. R1-это объявляемая сеть 1.1.1.0 / 24, но R3 не изучает эту сеть. Здесь представлены конфигураций: Соседство настроено, R1 - объявляемая сеть 1.1.1.0 / 24. R3#show ip route bgp Мы можем видеть сеть 1.1.1.0 / 24 в таблице маршрутизации R2, но она не отображается на R3. Технически проблем нет. Если вы внимательно посмотрите на конфигурацию BGP всех трех маршрутизаторов, то увидите, что существует только соседство BGP между R1 и R2 и между R2 и R3. Из-за split horizon IBGP R2 не пересылает сеть 1.1.1.0 / 24 в направлении R3. Чтобы это исправить, нам нужно настроить R1 и R3, чтобы они стали соседями. R1(config)#ip route 192.168.23.3 255.255.255.255 192.168.12.2 R3(config)#ip route 192.168.12.1 255.255.255.255 192.168.23.2 Если мы собираемся настроить соседство BGP между R1 и R3, нам нужно убедиться, что они могут достигать друг друга. Мы можем использовать статическую маршрутизацию или IGP ... чтобы упростить задачу, на этот раз мы будем использовать статический маршрут. R1(config)#router bgp 1 R1(config-router)#neighbor 192.168.23.3 remote-as 1 R3(config)#router bgp 1 R3(config-router)#neighbor 192.168.12.1 remote-as 1 Примените правильные настройки команды neighbor BGP. И R3 имеет доступ к сети 1.1.1.0 / 24! Итог урока: соседство по IBGP должно быть полным циклом! Другим решением было бы использование route-reflector или confederation. Урок 6 Очередная проблема. R3 является объявляемой сетью 3.3.3.0 / 24 через EBGP, а R2 устанавливает ее в таблицу маршрутизации. R1, однако, не имеет этой сети в своей таблице маршрутизации. Вот конфигурации: Вот конфигурации. Для простоты мы используем IP-адреса физического интерфейса для настройки соседей BGP. Мы можем проверить, что сеть 3.3.3.0 / 24 находится в таблице маршрутизации R2. R1#show ip route bgp Однако в таблице маршрутизации R1 ничего нет. Первое, что мы должны проверить - это таблицу BGP. Мы видим, что он находится в таблице BGP, и * указывает, что это допустимый маршрут. Однако мы не видим символа >, который указывает лучший путь. По какой-то причине BGP не может установить эту запись в таблице маршрутизации. Внимательно посмотрите на следующий IP-адрес прыжка (192.168.23.3). Доступен ли этот IP-адрес? R1 понятия не имеет, как достичь 192.168.23.3, поэтому наш следующий прыжок недостижим. Есть два способа, как мы можем справиться с этой проблемой: Используйте статический маршрут или IGP, чтобы сделать этот next hop IP-адрес доступным. Измените next hop IP-адрес. Мы изменим IP-адрес следующего прыжка, так как мы достаточно изучили применение статических маршрутов и IGPs. R2(config)#router bgp 1 R2(config-router)#neighbor 192.168.12.1 next-hop-self Эта команда изменит IP-адрес следующего перехода на IP-адрес R2. Теперь мы видим символ >, который указывает, что этот путь был выбран как лучший. IP-адрес следующего перехода теперь 192.168.12.2. Ура! Теперь он есть в таблице маршрутизации. Мы уже закончили? Если наша цель состояла в том, чтобы она отобразилась в таблице маршрутизации, то мы закончили...однако есть еще одна проблема. Наш пинг не удался. R1 и R2 оба имеют сеть 3.3.3.0 / 24 в своей таблице маршрутизации, поэтому мы знаем, что они знают, куда пересылать IP-пакеты. Давайте взглянем на R3: R3 получит IP-пакет с пунктом назначения 3.3.3.3 и источником 192.168.12.1. Из таблицы маршрутизации видно, что она не знает, куда отправлять IP-пакеты, предназначенные для 192.168.12.1. Исправим это: R2(config)#router bgp 1 R2(config-router)#network 192.168.12.0 mask 255.255.255.0 Мы будем объявлять сеть 192.168.12.0 / 24 на R2. Теперь R3 знает, куда отправлять трафик для 192.168.12.0 / 24. Проблема устранена! Итог урока: убедитесь, что IP-адрес следующего перехода доступен, чтобы маршруты могли быть установлены в таблице маршрутизации, и чтобы все необходимые сети были достижимы.
img
REST API – один из самых распространенных типов доступных веб-сервисов, но проектировать их сложно. Они позволяют разным клиентам, включая браузер, настольные приложения, мобильные приложения и практически любое устройство с подключением к Интернету, взаимодействовать с сервером. Именно поэтому очень важно правильно проектировать REST API, чтобы в будущем не было проблем. Создание API с нуля может оказать непосильной задачей из-за большого количества вещей, которые необходимо учесть – от базовой безопасности до использования правильных методов HTTP, реализации аутентификации, определения того, какие запросы и ответы среди многих других принимаются и возвращаются. В этой статье я очень постарался сжать материал в 15 пунктов с важными рекомендациями, которые позволят создать хороший API. Все рекомендации никак не зависят от языка, поэтому потенциально применимы к любой платформе или технологии. 1. Обязательно используйте имена существительные в названиях путях к конечным точкам Вам всегда следует использовать имена существительные, которые обозначают объект, который вы извлекаете или которым вы манипулируете. В качестве имени пути всегда предпочтительнее использовать множественное число. Избегайте использования глаголов в названиях путях к конечным точкам, потому что наш метод HTTP-запроса уже является глаголом и по сути не добавляет никакой новой информации. Действие должно быть произведено с помощью методов HTTP-запроса. Наиболее распространенными являются методы GET, POST, PATCH, PUT и DELETE. GET извлекает ресурсы POST отправляет новые данные на сервер PUT/PATCH модифицируют уже существующие данные DELETE удаляет данные Глаголы сопоставляются с функциями CRUD (Create, read, update и delete). Помня об этих принципах, мы должны создавать маршруты типа GET /books для получения списка книг, а не GET /get-books или GET /book. Аналогично, POST /books - для добавления новой книги, PUT /books/:id - для модификации полных данных книги с заданным идентификатором (id), а PATCH /books/:id обновляет частичные изменения в книге. И наконец, DELETE /books/:id предназначен для удаления существующей книги в заданным идентификатором. 2. JSON как основной формат отправки и получения данных Несколько лет назад прием и ответы на запросы API выполнялись в основном в XML. Но сейчас «стандартным» форматом для отправки и получения данных API в большинстве приложений стал JSON. Поэтому наш второй пункт рекомендует убедиться, что конечные точки возвращают формат данных JSON в качестве ответа, а также при приеме информации через полезную нагрузку HTTP-сообщений. Несмотря на то, что FormData хорошо подходит для отправки данных от клиента, особенно если нам нужно отправлять файлы, они не очень подходят для текста и чисел. Нам не нужны FormData для их передачи, так как в большинстве фреймворков можно передавать JSON непосредственно на стороне клиента. При получении данных от клиента нам необходимо убедиться, что клиент правильно интерпретирует данные JSON, и для этого при выполнении запроса в заголовке ответа Content-Type должен быть установлен на application/json. Стоит еще раз упомянуть исключение, когда мы пытаемся отправлять и получать файлы между клиентом и сервером. В этом конкретном случае нам необходимо обрабатывать файл ответа и отправлять FormData с клиента на сервер. 3. Используйте коды состояний HTTP Коды состояний HTTP всегда полезно использовать для того, чтобы указать на выполнение или невыполнение запроса. Не используйте слишком много кодов состояний и всегда используйте одни и те же коды для одних и тех же результатов в API. Вот некоторые примеры: 200 – общее выполнение 201 – успешное создание 400 – неверные запросы от клиента, такие как неверные параметры 401 – несанкционированные запросы 403 – отсутствие прав доступа к ресурсам 404 – отсутствуют ресурсы 429 – слишком много запросов 5хх – внутренние ошибки (их следует избегать насколько это возможно) В зависимости от ситуаций их может быть и больше, но ограничение количества кодов состояний помогает клиенту использовать более предсказуемый API. 4. Возвращайте стандартизированные сообщения Помимо использования кодов состояния HTTP, которые указывают на результат запроса, всегда используйте стандартизированные ответы для аналогичных конечных точек. Пользователи могут всегда рассчитывать на одинаковую структуру и действовать соответственно. Это также относится к статусу, указывающему на выполнение запроса, и сообщениях об ошибках. В случае выборки коллекций придерживайтесь определенного формата, независимо от того, включает ли тело ответа массив данных, подобный этому: [ { bookId: 1, name: "The Republic" }, { bookId: 2, name: "Animal Farm" } ] или вот такой комбинированный ответ: { "data": [ { "bookId": 1, "name": "The Republic" }, { "bookId": 2, "name": "Animal Farm" } ], "totalDocs": 200, "nextPageId": 3 } Здесь рекомендация заключается в том, чтобы быть последовательным независимо от того, какой подход вы выберете для этого. Аналогичное поведение должно быть реализовано при извлечении объекта, а также при создании и модификации ресурсов, которым обычно рекомендуется возвращать последний экземпляр объекта. // Ответ после успешного вызова POST /books { "bookId": 3, "name": "Brave New World" } Хоть это и никак не навредит, но все же излишнем будет включать универсальное сообщение, например, «Книга успешно создана», так как это уже следует из кода состояния HTTP. И последнее, но не менее важное: при наличии стандартного формата ответа коды ошибок также важны (и даже более важные). Это сообщение должно включать информацию, которую клиент может использовать для представления ошибок конечному пользователю, а соответственно, это должно быть не общее предупреждение, такое как «то-то пошло не так», которого следует избегать, насколько это возможно. Вот пример: { "code": "book/not_found", "message": "A book with the ID 6 could not be found" } Опять же, нет необходимости включать код состояния в содержимое ответа, но полезно определить набор кодов ошибок, таких как book/not_found, чтобы пользователь мог сопоставить их с разными строками и создать свое собственное сообщение об ошибке для конечного пользователя. В частности, для сред разработки или промежуточных сред может показаться правильным также включить стек ошибок в ответ с целью помочь в отладке ошибок. Но не включайте те, что находятся в промышленной эксплуатации, так как это создаст угрозу безопасности, раскрывая незапланированную информацию. 5. Используйте разбиение на страницы, фильтрацию и сортировку при выборе коллекций записей Как только будет создана конечная точка, которая возвращает список элементов, необходимо будет установить разбиение на страницы. Обычно коллекции со временем растут, поэтому важно всегда следить за тем, чтобы возвращалось ограниченное и контролируемое количество элементов. Справедливо будет позволить пользователям API выбирать, сколько объектов получить, но всегда полезно заранее определить число и установить для него максимум. Основная причина, почему нужно это сделать, заключается в том, что для возврата огромного массива данных потребуется очень много времени и большая пропускная способность. Для реализации нумерации страниц есть два хорошо известных способа: skip/limit или keyset. Первый вариант обеспечивает более удобный для пользователя способ извлечения данных, но обычно он менее эффективен, так как базы данных сканируют множество документов для извлечения нужных записей. Мне больше нравится второй вариант. Разделения на страницы с помощью keyset получает идентификатор (id) в качестве ссылки для «вырезания» коллекции или таблицы с условием без сканирования записей. Также API должны предоставлять фильтры и возможности сортировки, которые упрощают способы получения данных. Частью решения повышения производительности являются индексные базы данных, которые позволяют максимизировать производительность при помощи шаблонов доступа, которые применяются с фильтрами и параметрами сортировки. При проектировании API эти свойства разбиения на страницы, фильтрации и сортировки определяются как параметры запроса в URL-адресе. Например, если вы хотим получить информацию о первых 10 книгах, принадлежащих к категории «роман», то наша конечная точка будет выглядеть вот так: GET /books?limit=10&category=romance 6. PATCH вместо PUT Маловероятно, что необходимо будет сразу полностью обновить всю запись, обычно есть конфиденциальные или полные записи, которые следует уберечь от манипуляций пользователя. Именно поэтому для выполнения частичных обновлений ресурса следует использовать PATCH, а вот PUT полностью меняет существующий ресурс. Они оба должны использовать тело запроса для передачи информации, подлежащей модификации. Разница лишь в том, что для PATCH это поля, а для запроса PUT – полный объект. Тем не менее, стоит отметить, что ничто не мешает нам использовать PUT для частичной модификации, нет никаких «ограничений на передачу по сети», которые бы это подтверждали. Это просто факт, которого стоит придерживаться. 7. Предоставьте более подробные ответы Шаблоны доступа являются ключевыми при создании доступных ресурсов API и возвращаемых данных. Когда система растет, то и свойства записи также растут, но не всегда все эти свойства нужны клиентам для работы. Именно в таких ситуациях становится полезным предоставление возможности возвращать сокращенные или полные ответы для одной и той же конечной точки. Если пользователю нужны только некоторые поля, то упрощенный ответ помогает снизить расход трафика и потенциально сложность получения других вычисляемых полей. Простой способ реализовать – предоставить дополнительный параметр запроса, чтобы включить или отключить предоставление более подробного ответа. GET /books/:id { "bookId": 1, "name": "The Republic" }GET /books/:id?extended=true { "bookId": 1, "name": "The Republic" "tags": ["philosophy", "history", "Greece"], "author": { "id": 1, "name": "Plato" } } 8. Обязанность конечной точки Принцип единственной обязанности фокусируется на концепции удержания функции, метода или класса на одной обязанности, которую они выполняют хорошо. Мы можем сказать, что это наш API - хороший API, если он выполняет одну конкретную вещь и никогда не меняется. Это помогает пользователям лучше понять наш API и сделать его более предсказуемым, что облегчит общую интеграцию. Лучше всего расширить список доступных конечных точек, а не создавать очень сложные конечные точки, которые пытаются решить множество задач одновременно. 9. Предоставьте полную документацию по API Пользователи вашего API должны понимать, как использовать доступные конечные точки и чего ожидать. Это возможно только при наличии хорошей и подробной документации. Обратите внимание на следующие аспекты, чтобы ваша документация была полной. Доступные конечные точки с описанием их назначения Права доступа, необходимые для выполнения конечной точки Примеры вызовов и ответов Сообщения о предполагаемых ошибках Немаловажным является постоянное обновление документации после внесения изменений и дополнений в систему. Лучший способ для этого – сделать документацию по API неотъемлемой частью разработки. Двумя хорошо известными инструментами в данном вопросе являются Swagger и Postman – они доступны для большинства сред разработки API. 10. Используйте SSL для обеспечения безопасности и настройте CORS Безопасность – еще одно очень важной свойство, которым должен обладать наш API. Настройка SSL путем установки действительного сертификата на сервер обеспечит безопасную связь с пользователями и предотвратит некоторые виды потенциальных атак. CORS (Cross-origin resource sharing – Обмен ресурсами с запросом происхождения) – это функция безопасности браузера, которая ограничивает HTTP-запросы из различных источников, которые инициируются сценариями, запущенными в браузере. Если ресурсы вашего REST API получают непростые HTTP-запросы из разных источников, то вам нужно включить поддержку CORS для того, чтобы пользователи работали соответствующим образом. Протокол CORS требует, чтобы браузер отправил предварительный запрос на сервер и дождался утверждения (или запрос учетных данных) с сервера перед отправкой фактического запроса. Запрос предварительной проверки отображается в API как HTTP-запрос, использующий метод OPTIONS (среди других заголовков). Значит, для поддержки CORS в ресурсе REST API необходимо реализовать метод OPTIONS, который будет отвечать на предварительный запрос, по крайней мере, со следующими заголовками ответа, предусмотренными стандартом Fetch: Access-Control-Allow-Methods Access-Control-Allow-Headers Access-Control-Allow-Origin Какие значения назначать этим ключам, зависит от того, настолько открытым и гибким должен быть наш API. Мы можем назначить определённые методы и известные источники или использовать специальные символы, чтобы иметь открытые ограничения CORS. 11. Управление версиями API В процессе разработки конечные точки начинают меняться и перестраиваться. Но мы должны, насколько это возможно, избегать внезапного изменения конечных точек для пользователя. Рекомендуется рассматривать API как ресурс с обратной совместимость, в котором новые и обновленные конечные точки должны быть доступны, но не должны влиять на предыдущие стандарты. Вот где управление версиями API приходит на помощь – когда клиенты должны иметь возможность выбирать, к какой версии подключаться. Есть несколько способов описать управление версиями API: Добавление нового заголовка x-version=v2 Наличие параметра запроса ?apiVersion=2 Версия как часть URL: /v2/books/:id 12. Кэшируйте данные для повышения производительности Чтобы повысить производительность нашего API, полезно следить за данными, которые редко меняются и к которым часто обращаются. Для таких данных мы можем рассмотреть возможность использования базы данных в памяти или кэш-памяти, которая избавит от доступа к основной базе данных. Главная проблема здесь заключается в том, что данные могут устареть, поэтому следует решить вопрос с внедрением последней версии. Использование кэшированных данных будет полезным для пользователей для загрузки конфигураций и каталогов информации, которые не предназначены для постоянного изменения в течение долгого времени. При использовании кэширования не забудьте включить Cache-Control в заголовки. Это поможет пользователям эффективно использовать систему кэширования. 13. Используйте даты в формате UTC Сложно представить системы, которые в какой-то момент перестает работать из-за дат. На уровне данных важно быть логичным в том, как даты отображаются на клиентских приложениях. ISO 8601 – это международный стандартный формат данных для даты и времени. Данные должны быть в формате Z или UTC, для которых пользователи могут могли бы выбрать часовой пояс в случае, если такая дата должны отображаться при любых условиях. Вот пример того, как должны выглядеть даты: { "createdAt": "2022-03-08T19:15:08Z" } 14. Конечная точка проверки работоспособности Может произойти ситуация, когда наш API перестанет работать, и для его запуска потребуется время. При таких обстоятельствах клиенты хотят знать, что службы недоступны, и быть в курсе ситуации. Для этого предоставьте конечную точку (например, GET /health), которая бы определяла работоспособность API. Эта конечная точка может вызываться и другими приложениями, такими как балансировщики нагрузки. Можно продвинуться еще дальне и сообщать о периодах технического обслуживания или работоспособности частей API. 15. Разрешите аутентификацию по ключу API Аутентификация с помощью ключей API даст возможность сторонним приложениям легко создавать интеграцию с нашим API. Эти ключи API следует передавать с помощью пользовательского заголовка HTTP (например, Api-Key или X-Api-Key). Ключи должны иметь дату окончания срока действия, и должна быть возможность их отозвать с целью признания недействительными по соображениям безопасности.
img
Предыдущая статья из цикла про соответствие пакетов в IP ACL. Обратные маски, такие как значения dotted-decimal number (DDN), фактически представляют собой 32-разрядное двоичное число. Как 32-разрядное число, маска WC фактически направляет логику маршрутизатора бит за битом. Короче говоря, бит маски WC (wildcard), равный 0, означает, что сравнение должно выполняться как обычно, но двоичный 1 означает, что бит является подстановочным знаком и может быть проигнорирован при сравнении чисел. Кстати, наш калькулятор подсетей показывает и сам считает WC (wildcard) маску. Вы можете игнорировать двоичную маску WC. Почему? Что ж, обычно мы хотим сопоставить диапазон адресов, которые можно легко идентифицировать по номеру подсети и маске, будь то реальная подсеть или сводный маршрут, который группирует подсети вместе. Если вы можете указать диапазон адресов с помощью номера подсети и маски, вы можете найти числа для использования в вашем ACL с помощью простой десятичной математики, как описано далее. Если вы действительно хотите знать логику двоичной маски, возьмите два номера DDN, которые ACL будет сравнивать (один из команды access-list, а другой из заголовка пакета), и преобразуйте оба в двоичный код. Затем также преобразуйте маску WC в двоичную. Сравните первые два двоичных числа бит за битом, но также игнорируйте любые биты, для которых маска WC случайно перечисляет двоичный 1, потому что это говорит вам игнорировать бит. Если все биты, которые вы проверили, равны, это совпадение! Нахождения правильной обратной маски, соответствующей подсети Во многих случаях ACL должен соответствовать всем хостам в определенной подсети. Чтобы соответствовать подсети с помощью ACL, вы можете использовать следующие сочетания: Используйте номер подсети в качестве исходного значения в команде access-list. Используйте обратную маску, полученную путем вычитания маски подсети из 255.255.255.255. Например, для подсети 172.16.8.0 255.255.252.0 используйте номер подсети (172.16.8.0) в качестве параметра адреса, а затем выполните следующие вычисления, чтобы найти обратную маску: Продолжая этот пример, завершенная команда для той же подсети будет следующей: access-list 1 permit 172.16.8.0 0.0.3.255 Соответствие любому/всем адресам В некоторых случаях вам может понадобиться одна команда ACL для сопоставления всех без исключения пакетов, которые достигают этой точки в ACL. Во-первых, вы должны знать (простой) способ сопоставить все пакеты с помощью ключевого слова any. Что еще более важно, вам нужно подумать о том, когда сопоставить все без исключения пакеты. Во-первых, чтобы сопоставить все пакеты с помощью команды ACL, просто используйте ключевое слово any для адреса. Например, чтобы разрешить все пакеты: access-list 1 permit any Итак, когда и где вы должны использовать такую команду? Помните, что все ACL Cisco IP заканчиваются неявным отрицанием любой концепции в конце каждого ACL. То есть, если маршрутизатор сравнивает пакет с ACL, и пакет не соответствует ни одному из настроенных операторов, маршрутизатор отбрасывает пакет. Хотите переопределить это поведение по умолчанию? Настроить permit any в конце ACL. Вы также можете явно настроить команду для запрета всего трафика (например, access-list 1 deny any) в конце ACL. Почему, когда та же самая логика уже находится в конце ACL? Что ж, ACL показывает счетчики списка для количества пакетов, соответствующих каждой команде в ACL, но нет счетчика для этого не явного запрета любой концепции в конце ACL. Итак, если вы хотите видеть счетчики количества пакетов, совпадающих с логикой deny any в конце ACL, настройте явное deny any. Внедрение стандартных IP ACL В этой лекции уже представлены все этапы настройки по частям. Далее суммируются все эти части в единую конфигурацию. Эта конфигурация основана на команде access-list, общий синтаксис которой повторяется здесь для справки: access-list access-list-number {deny | permit} source [source-wildcard] Этап 1. Спланируйте локацию (маршрутизатор и интерфейс) и направление (внутрь или наружу) на этом интерфейсе: Стандартные списки ACL должны быть размещены рядом с местом назначения пакетов, чтобы они случайно не отбрасывали пакеты, которые не следует отбрасывать. Поскольку стандартные списки ACL могут соответствовать только исходному IP-адресу пакета, идентифицируйте исходные IP-адреса пакетов по мере их прохождения в направлении, которое проверяет ACL. Этап 2. Настройте одну или несколько команд глобальной конфигурации списка доступа для создания ACL, учитывая следующее: Список просматривается последовательно с использованием логики первого совпадения. Действие по умолчанию, если пакет не соответствует ни одной из команд списка доступа, - отклонить (отбросить) пакет. Этап 3. Включите ACL на выбранном интерфейсе маршрутизатора в правильном направлении, используя подкоманду  ip access-group number {in | out}. Далее рассмотрим несколько примеров. Стандартный нумерованный список ACL, пример 1 В первом примере показана конфигурация для тех же требований, что и на рисунках 4 и 5. Итак, требования для этого ACL следующие: Включите входящий ACL на интерфейсе R2 S0/0/1. Разрешить пакеты, приходящие от хоста A. Запретить пакеты, приходящие от других хостов в подсети хоста A. Разрешить пакеты, приходящие с любого другого адреса в сети класса A 10.0.0.0. В исходном примере ничего не говорится о том, что делать по умолчанию, поэтому просто запретите весь другой трафик. В примере 1 показана завершенная правильная конфигурация, начиная с процесса настройки, за которым следует вывод команды show running-config. R2# configure terminal Enter configuration commands, one per line. End with CNTL/Z. R2(config)# access-list 1 permit 10.1.1.1 R2(config)# access-list 1 deny 10.1.1.0 0.0.0.255 R2(config)# access-list 1 permit 10.0.0.0 0.255.255.255 R2(config)# interface S0/0/1 R2(config-if)# ip access-group 1 in R2(config-if)# ^Z R2# show running-config ! Lines omitted for brevity access-list 1 permit 10.1.1.1 access-list 1 deny 10.1.1.0 0.0.0.255 access-list 1 permit 10.0.0.0 0.255.255.255 Во-первых, обратите внимание на процесс настройки в верхней части примера. Обратите внимание, что команда access-list не изменяет командную строку из приглашения режима глобальной конфигурации, поскольку команда access-list является командой глобальной конфигурации. Затем сравните это с выводом команды show running-config: детали идентичны по сравнению с командами, которые были добавлены в режиме конфигурации. Наконец, не забудьте указать ip access-group 1 в команде под интерфейсом R2 S0/0/1, который включает логику ACL (как локацию, так и направление). В примере 2 перечислены некоторые выходные данные маршрутизатора R2, которые показывают информацию об этом ACL. Команда show ip access-lists выводит подробную информацию только о списках ACL IPv4, а команда show access-lists перечисляет сведения о списках ACL IPv4, а также о любых других типах ACL, настроенных в настоящее время, например, списки ACL IPv6. Вывод этих команд показывает два примечания. В первой строке вывода в этом случае указывается тип (стандарт) и номер. Если существовало более одного ACL, вы бы увидели несколько разделов вывода, по одной на каждый ACL, каждая со строкой заголовка, подобной этой. Затем эти команды перечисляют счетчики пакетов для количества пакетов, которые маршрутизатор сопоставил с каждой командой. Например, на данный момент 107 пакетов соответствуют первой строке в ACL. Наконец, в конце примера перечислены выходные данные команды show ip interface. Эта команда перечисляет, среди многих других элементов, номер или имя любого IP ACL, включенного на интерфейсе для подкоманды интерфейса ip access-group. Стандартный нумерованный список ACL, пример 2 Для второго примера используйте рисунок 8 и представьте, что ваш начальник в спешке дает вам некоторые требования в холле. Сначала он говорит вам, что хочет фильтровать пакеты, идущие от серверов справа к клиентам слева. Затем он говорит, что хочет, чтобы вы разрешили доступ для хостов A, B и других хостов в той же подсети к серверу S1, но запретили доступ к этому серверу хостам в подсети хоста C. Затем он сообщает вам, что, кроме того, хостам в подсети хоста A следует отказать в доступе к серверу S2, но хостам в подсети хоста C должен быть разрешен доступ к серверу S2 - и все это путем фильтрации пакетов, идущих только справа налево. Затем он говорит вам поместить входящий ACL на интерфейс F0/0 R2. Если вы просмотрите все запросы начальника, требования могут быть сокращены до следующего: Включите входящий ACL на интерфейсе F0/0 R2. Разрешить пакеты от сервера S1, идущие к хостам в подсети A. Запретить пакетам с сервера S1 идти к хостам в подсети C. Разрешить пакетам с сервера S2 идти к хостам в подсети C. Запретить пакетам с сервера S2 идти к хостам в подсети A. Не было комментариев о том, что делать по умолчанию; используйте подразумеваемое отклонение всего по умолчанию. Как оказалось, вы не можете сделать все, что просил ваш начальник, с помощью стандартного ACL. Например, рассмотрим очевидную команду для требования номер 2: access-list 2 permit 10.2.2.1. Это разрешает весь трафик с исходным IP-адресом 10.2.2.1 (сервер S1). Следующее требование просит вас фильтровать (отклонять) пакеты, полученные с того же IP-адреса! Даже если вы добавите другую команду, которая проверяет исходный IP-адрес 10.2.2.1, маршрутизатор никогда не доберется до него, потому что маршрутизаторы используют логику первого совпадения при поиске в ACL. Вы не можете проверить и IP-адрес назначения, и исходный IP-адрес, потому что стандартные ACL не могут проверить IP-адрес назначения. Чтобы решить эту проблему, вам следует переосмыслить проблему и изменить правила. В реальной жизни вы, вероятно, вместо этого использовали бы расширенный ACL, который позволяет вам проверять как исходный, так и целевой IP-адрес. Представьте себе, что ваш начальник позволяет вам изменять требования, чтобы попрактиковаться в другом стандартном ACL. Во-первых, вы будете использовать два исходящих ACL, оба на маршрутизаторе R1. Каждый ACL разрешает пересылку трафика с одного сервера в эту подключенную локальную сеть со следующими измененными требованиями: Используя исходящий ACL на интерфейсе F0 / 0 маршрутизатора R1, разрешите пакеты с сервера S1 и запретите все остальные пакеты. Используя исходящий ACL на интерфейсе F0 / 1 маршрутизатора R1, разрешите пакеты с сервера S2 и запретите все остальные пакеты. Пример 3 показывает конфигурацию, которая удовлетворяет этим требованиям. access-list 2 remark This ACL permits server S1 traffic to host A's subnet access-list 2 permit 10.2.2.1 ! access-list 3 remark This ACL permits server S2 traffic to host C's subnet access-list 3 permit 10.2.2.2 ! interface F0/0 ip access-group 2 out ! interface F0/1 ip access-group 3 out Как показано в примере, решение с номером ACL 2 разрешает весь трафик с сервера S1, при этом эта логика включена для пакетов, выходящих из интерфейса F0/0 маршрутизатора R1. Весь другой трафик будет отброшен из-за подразумеваемого запрета all в конце ACL. Кроме того, ACL 3 разрешает трафик от сервера S2, которому затем разрешается выходить из интерфейса F0/1 маршрутизатора R1. Также обратите внимание, что решение показывает использование параметра примечания списка доступа, который позволяет оставить текстовую документацию, которая остается в ACL. Когда маршрутизаторы применяют ACL для фильтрации пакетов в исходящем направлении, как показано в Примере 2, маршрутизатор проверяет пакеты, которые он направляет, по списку ACL. Однако маршрутизатор не фильтрует пакеты, которые сам маршрутизатор создает с помощью исходящего ACL. Примеры таких пакетов включают сообщения протокола маршрутизации и пакеты, отправленные командами ping и traceroute на этом маршрутизаторе. Советы по устранению неполадок и проверке Устранение неполадок в списках ACL IPv4 требует внимания к деталям. В частности, вы должны быть готовы посмотреть адрес и обратную маску и с уверенностью предсказать адреса, соответствующие этим двум комбинированным параметрам. Во-первых, вы можете определить, соответствует ли маршрутизатор пакетам или нет, с помощью пары инструментов. Пример 2 уже показал, что IOS хранит статистику о пакетах, соответствующих каждой строке ACL. Вдобавок, если вы добавите ключевое слово log в конец команды access-list, IOS затем выдает сообщения журнала со случайной статистикой совпадений с этой конкретной строкой ACL. И статистика, и сообщения журнала могут помочь решить, какая строка в ACL соответствует пакету. Например, в примере 4 показана обновленная версия ACL 2 из примера 3, на этот раз с добавленным ключевым словом log. Внизу примера затем показано типичное сообщение журнала, в котором показано результирующее совпадение на основе пакета с исходным IP-адресом 10.2.2.1 (в соответствии с ACL) с адресом назначения 10.1.1.1. R1# show running-config ! lines removed for brevity access-list 2 remark This ACL permits server S1 traffic to host A's subnet access-list 2 permit 10.2.2.1 log ! interface F0/0 ip access-group 2 out R1# Feb 4 18:30:24.082: %SEC-6-IPACCESSLOGNP: list 2 permitted 0 10.2.2.1 -> 10.1.1.1, 1 Packet Когда вы впервые устраняете неисправности на ACL, прежде чем вдаваться в подробности логики сопоставления, подумайте, как об интерфейсе, на котором включен ACL, так и о направлении потока пакетов. Иногда логика сопоставления идеальна, но ACL был включен на неправильном интерфейсе или в неправильном направлении, чтобы соответствовать пакетам, настроенным для ACL. Например, на рисунке 9 повторяется тот же ACL, показанный ранее на рисунке 7. Первая строка этого ACL соответствует конкретному адресу хоста 10.1.1.1. Если этот ACL существует на маршрутизаторе R2, размещение этого ACL в качестве входящего ACL на интерфейсе S0/0/1 R2 может работать, потому что пакеты, отправленные хостом 10.1.1.1 - в левой части рисунка - могут входить в интерфейс S0/0/1 маршрутизатора R2. Однако, если R2 включает ACL 1 на своем интерфейсе F0/0 для входящих пакетов, ACL никогда не будет соответствовать пакету с исходным IP-адресом 10.1.1.1, потому что пакеты, отправленные хостом 10.1.1.1, никогда не войдут в этот интерфейс. Пакеты, отправленные 10.1.1.1, будут выходить из интерфейса R2 F0/0, но никогда не попадут в него только из-за топологии сети.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59