Списки контроля доступа (ACL, Access Control List) — это базовый инструмент фильтрации трафика в Cisco IOS. С их помощью можно разрешить или запретить трафик по источнику, назначению, протоколу и порту — например, пустить пользователей VLAN 10 к веб-серверу в VLAN 20, но закрыть им доступ к базе данных на том же сервере. В этой статье разберём стандартные и расширенные ACL, wildcard-маски и применение списков на интерфейсах маршрутизатора rtr-edge01 в сети 192.168.10.0/24, домен itpages.lab.local.

ACL в IOS — это упорядоченный список правил, которые проверяются последовательно сверху вниз. Как только пакет совпадает с каким-то правилом, проверка останавливается и применяется решение этого правила (permit или deny) — остальные правила ниже уже не смотрятся. В конце каждого ACL есть неявный deny any, которого не видно в конфигурации, но который действует всегда.

Wildcard-маски: как они работают

В отличие от обычных масок подсети, ACL используют wildcard-маски — они инвертированы: 0 означает «бит должен совпадать», 1 означает «бит не важен». Маска подсети 255.255.255.0 превращается в wildcard 0.0.0.255.

! Маска подсети 255.255.255.0 -> wildcard 0.0.0.255
! Один хост -> wildcard 0.0.0.0 (или ключевое слово host)
! Любой адрес -> wildcard 255.255.255.255 (или ключевое слово any)

Это самая частая причина путаницы у тех, кто только начинает работать с ACL: логика обратная привычной маске подсети. Проще всего запомнить так — wildcard показывает, сколько «свободы» разрешено в адресе, а не сколько зафиксировано.

Стандартный ACL

Стандартные ACL фильтруют трафик только по адресу источника — ни адрес назначения, ни порт они не учитывают. Их применение ограничено, но для простых задач (например, ограничение доступа к management-линиям, как в статье про начальную настройку коммутатора) их достаточно.

rtr-edge01# configure terminal
rtr-edge01(config)# ip access-list standard MGMT-ACCESS
rtr-edge01(config-std-nacl)# permit host 192.168.10.5
rtr-edge01(config-std-nacl)# permit 192.168.10.0 0.0.0.255
rtr-edge01(config-std-nacl)# deny any log
rtr-edge01(config-std-nacl)# exit

Именованные ACL (с ключевым словом вместо номера) удобнее нумерованных — из названия сразу видно назначение списка, а редактировать их можно построчно, не пересоздавая весь список заново.

Расширенный ACL

Расширенные ACL — рабочая лошадка практической фильтрации: они учитывают адрес источника, адрес назначения, протокол и порт. Настроим правило, которое пускает VLAN 10 (192.168.10.0/24) к веб-серверу 192.168.20.10 только по HTTP и HTTPS, а остальной трафик к этому серверу запрещает.

rtr-edge01(config)# ip access-list extended USERS-TO-WEB
rtr-edge01(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 host 192.168.20.10 eq 80
rtr-edge01(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 host 192.168.20.10 eq 443
rtr-edge01(config-ext-nacl)# deny ip any host 192.168.20.10
rtr-edge01(config-ext-nacl)# permit ip any any
rtr-edge01(config-ext-nacl)# exit

Обрати внимание на порядок: сначала разрешающие правила для конкретных портов, потом запрет всего остального трафика именно к этому серверу, и только в конце общий permit для остального трафика сети. Если бы deny ip any host 192.168.20.10 стоял выше правил permit, разрешающие строки никогда бы не сработали — ACL останавливается на первом совпадении.

Применение ACL на интерфейсе

rtr-edge01(config)# interface gigabitEthernet 0/0.10
rtr-edge01(config-subif)# ip access-group USERS-TO-WEB in
rtr-edge01(config-subif)# exit

Направление in означает, что список проверяет трафик, входящий в интерфейс со стороны VLAN 10 — то есть от пользователей. Направление out проверяло бы трафик, покидающий интерфейс в сторону VLAN 10. Выбор направления — это не техническая мелочь, а половина логики всего правила: перепутав in и out, можно заблокировать совершенно не тот трафик, который планировалось.

Ограничение по конкретным портам служб

Частая практическая задача — закрыть доступ к административным портам сервера (например, RDP или SSH) для всех, кроме конкретной подсети управления.

rtr-edge01(config)# ip access-list extended PROTECT-ADMIN-PORTS
rtr-edge01(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 any eq 22
rtr-edge01(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 any eq 3389
rtr-edge01(config-ext-nacl)# deny tcp any any eq 22
rtr-edge01(config-ext-nacl)# deny tcp any any eq 3389
rtr-edge01(config-ext-nacl)# permit ip any any
rtr-edge01(config-ext-nacl)# exit

Здесь SSH (22) и RDP (3389) разрешены только из подсети управления 192.168.10.0/24, а из любых других источников — заблокированы. Остальной трафик (не связанный с этими портами) явно разрешён последней строкой.

Именованные ACL с редактированием по номерам строк

Именованные ACL в современных версиях IOS можно редактировать точечно, вставляя и удаляя отдельные строки по их порядковому номеру, без пересоздания всего списка с нуля. Это особенно полезно, когда нужное правило должно сработать раньше уже существующего deny.

rtr-edge01(config)# ip access-list extended USERS-TO-WEB
rtr-edge01(config-ext-nacl)# show
  10 permit tcp 192.168.10.0 0.0.0.255 host 192.168.20.10 eq 80
  20 permit tcp 192.168.10.0 0.0.0.255 host 192.168.20.10 eq 443
  30 deny ip any host 192.168.20.10
  40 permit ip any any
rtr-edge01(config-ext-nacl)# 15 permit tcp 192.168.10.0 0.0.0.255 host 192.168.20.10 eq 8443
rtr-edge01(config-ext-nacl)# exit

IOS автоматически нумерует строки с шагом 10, что специально оставляет пространство для вставки новых правил между существующими — как в примере выше, где новое правило для порта 8443 вставлено между строками 10 и 20 без переписывания всего списка.

Reflexive ACL: разрешить ответный трафик автоматически

Обычный ACL статичен — если разрешить исходящий трафик наружу, ответный трафик от внешнего сервера всё равно нужно пропускать отдельным правилом, и получается либо слишком широкое разрешение, либо ручная поддержка списка портов. Reflexive ACL решает эту проблему, динамически создавая временное правило для ответного трафика на основе исходящего запроса — похоже на упрощённый stateful firewall.

rtr-edge01(config)# ip access-list extended OUTBOUND
rtr-edge01(config-ext-nacl)# permit tcp 192.168.10.0 0.0.0.255 any reflect USERS-SESSIONS
rtr-edge01(config-ext-nacl)# exit

rtr-edge01(config)# ip access-list extended INBOUND
rtr-edge01(config-ext-nacl)# evaluate USERS-SESSIONS
rtr-edge01(config-ext-nacl)# deny ip any any
rtr-edge01(config-ext-nacl)# exit

Когда пользователь из VLAN 10 инициирует соединение наружу, правило с reflect автоматически создаёт временную запись во временном списке USERS-SESSIONS, разрешающую именно этот обратный поток данных. Список INBOUND, применённый на внешнем интерфейсе, через evaluate подхватывает эти временные записи — легитимный ответный трафик проходит, а любой новый, неинициированный изнутри трафик снаружи отбрасывается финальным deny.

Проверка и отладка ACL

rtr-edge01# show access-lists
rtr-edge01# show ip interface gigabitEthernet 0/0.10
rtr-edge01# show access-lists USERS-TO-WEB

show access-lists показывает не только сами правила, но и счётчик совпадений (match count) напротив каждой строки — это лучший способ понять, действительно ли трафик проходит проверку так, как задумано, или правило вообще никогда не срабатывает. Если счётчик у permit-строки не растёт при генерации тестового трафика — скорее всего, ACL применён не на том интерфейсе или не в том направлении.

Ограничение по времени суток

Иногда доступ нужно разрешать не постоянно, а только в определённые часы — например, гостевому Wi-Fi разрешить выход в интернет только в рабочее время офиса. Time-based ACL добавляют это условие через объект time-range.

rtr-edge01(config)# time-range WORK-HOURS
rtr-edge01(config-time-range)# periodic weekdays 8:00 to 19:00
rtr-edge01(config-time-range)# exit

rtr-edge01(config)# ip access-list extended GUEST-HOURS
rtr-edge01(config-ext-nacl)# permit tcp 192.168.30.0 0.0.0.255 any eq 80 time-range WORK-HOURS
rtr-edge01(config-ext-nacl)# permit tcp 192.168.30.0 0.0.0.255 any eq 443 time-range WORK-HOURS
rtr-edge01(config-ext-nacl)# deny ip any any
rtr-edge01(config-ext-nacl)# exit

Вне заданного диапазона времени правило с time-range просто не действует, как будто его нет в списке — трафик упадёт на следующее правило, в данном случае на финальный deny. Это удобно для гостевых сетей и переговорных комнат, но полагаться на time-based ACL как на единственный механизм безопасности не стоит — часы на маршрутизаторе должны быть синхронизированы через NTP, иначе расписание сработает не тогда, когда ожидается.

Логирование срабатывания правил

Ключевое слово log в конце правила ACL заставляет IOS писать в лог каждое совпадение с этой строкой — не просто счётчик, а конкретные пакеты с адресами источника и назначения. Это незаменимо при разборе инцидентов: например, когда нужно понять, кто и когда пытался достучаться до закрытого административного порта.

rtr-edge01(config)# ip access-list extended PROTECT-ADMIN-PORTS
rtr-edge01(config-ext-nacl)# no deny tcp any any eq 22
rtr-edge01(config-ext-nacl)# deny tcp any any eq 22 log
rtr-edge01(config-ext-nacl)# exit

Стоит использовать log избирательно, а не на каждой строке подряд: при высокой интенсивности совпадений (например, на широком правиле, которое матчит много трафика) логирование создаёт заметную нагрузку на процессор маршрутизатора и быстро забивает буфер логов малополезными записями. Логировать имеет смысл именно запрещающие правила на чувствительных портах — там, где каждое совпадение потенциально важно.

Частые ошибки и как их избежать

  • Неявный deny any в конце. Если список содержит только разрешающие правила для конкретных случаев и не заканчивается явным permit ip any any, весь остальной трафик, не подошедший ни под одно правило, будет молча отброшен. Это самая частая причина, когда после настройки ACL «всё сломалось» — забыли, что список не пропускает по умолчанию.
  • Неправильная wildcard-маска. Спутать 0.0.0.255 с 255.255.255.0 — классическая ошибка новичков. Результат — правило либо не совпадает ни с чем, либо совпадает вообще со всей сетью интернета. Всегда проверяй маску через show access-lists перед применением на боевом интерфейсе.
  • Правила добавляются в конец, а не в нужное место. В именованных ACL новые строки без указания номера добавляются в конец списка. Если нужное правило должно сработать раньше существующего deny, придётся использовать порядковые номера строк (ip access-list extended NAME → 10 permit ...) или пересоздавать список с нуля, иначе более общее правило сработает первым и до нужной строки очередь просто не дойдёт.
  • ACL применён не на том интерфейсе. Правило, рассчитанное на фильтрацию трафика VLAN 10, случайно применённое на интерфейсе VLAN 20, просто не увидит нужный трафик — счётчики совпадений останутся на нуле, а пользователи будут жаловаться на проблему, которую по описанию невозможно связать с ACL. Всегда сверяй, на каком именно интерфейсе и в каком направлении висит команда ip access-group, через show ip interface.

Что дальше

Продолжить тему сетевого оборудования Cisco можно так: