16 марта 2013

Повышаем безопасность SSH-доступа на маршрутизаторах Juniper SRX

Системное администрированиеСетевые технологии
В этой статье я расскажу, как настроить действительно безопасный SSH-доступ к устройствам Juniper серии SRX, т.е. сделать взлом нашего маршрутизатора гиблым априори занятием. Я опишу две вещи:
  • Как сделать вход по SSH возможным только по ssh-ключу.
  • Как ограничить список IP-адресов, которые смогут пользоваться ssh-доступом к Джуниперу.

В свое время я честно убил целый день, чтобы дорубиться, как реализовать такие простые вещи в Джуниперах. Надеюсь, моя статья поможет вам сэкономить время.

Давайте реализуем первый пункт. И сразу пара ложек дегтя для затравки:
  • На Джуниперах НЕЛЬЗЯ сменить порт SSH! Будем всю жизнь коннектиться на 22-ой! Ладно. Это еще одна причина сделать вход по ключам. Надеюсь в будущих прошивках как-то пофиксят это…
  • Данная процедура никак не влияет на доступ к веб-интерфейсу. Это с одной стороны плохо, т.к. любой, кто поломает пароль к веб-морде, сможет изменить конфигу как хочет, а с другой стороны хорошо, т.к. заставляет нас задуматься, а кто вообще может зайти на нашу веб-морду и можно ли ему это делать? Ограничить доступ к веб-интерфейсу можно как по интерфейсу, так и по айпи. Но об этом позже.

Итак, приступим. Для начала надо сгенерировать пару SSH-ключей. Для этого прекрасно подходит утилита PuTTygen из стандартного набора утилит PuTTy. Запускаем ее и видим вот такое окошечко:

image

Выбираем SSH2-RSA, длину ключа 1024 бит (выше Джуниперы не поддерживают). Нажимаем «Генерировать», шевелим мышкой пока идет генерация. Когда закончит, обязательно вводим два раза стойкий пароль в соответствующих полях и нажимаем кнопку «Личный ключ» для сохранения закрытого ключа. Я думаю, не нужно напоминать, что закрытый ключ на то и назван закрытым, что хранить его стоит в очень надежном месте? Я, например, не храню его в открытом виде, а пользуюсь утилитой KeePass2. Ну, это уже кому как удобнее!
Также желательно не потерять этот ключ, т.к. дальше мы настроим Джунипер так, что он без него просто не пустит в консоль. Придется заходить в веб-морду и удалять ту часть конфига, которая отвечает за данную настройку. Ну, или проводить тоскливую процедуру сброса рутового пароля к девайсу.
Затем, копируем в блокнот содержимое окна «Открытый ключ… ». Нам надо будет кое-что поправить перед вставкой открытого ключа в конфиг Джунипера. Сначала удаляем с конца фразу «rsa-key-…», затем приводим ключ к виду:
«ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQBfkD3juKaLXqNKJfhUMIwt4Ro/aF38WDi7XlALiSYDYY8GZuhcAMJHL0FKJRTI07Qcr
Kfev4nFm2HbeSFkaI96l4TSKlqS90goemrbTkNTes/2F9VBzRjogYcEfr57bgUQ+DVmnSMWiLeWwFwT79pctJR1dJZbSuQf2jgmrqPpTfJ235u+8+V4O2KPmIbrjHaWg9MZQcu2pdDfLBFaLgkgh9wPlToKtaCk0577DN6OImhOpL+xoyIOzg3JFlCwTNIYSvGX8sdnJaJkt0IOWf+KJrGQSXfc68Zw0hhakBojfotyFklGO390KxO
wVecS35kMuHjSRmhaGqf03yG1sQWt= root@juniper»
Внимание! Тут важно не ошибиться, иначе Джунипер не примет ключ! Ключ должен быть обязательно целиком заключен в кавычки. В конце должен стоять знак «=», после него пробел, а дальше – root@имя_вашего_Джунипера. То бишь точь в точь, как приглашение командной строки вашего девайса! Имя Джунипера, напомню, задается командой set system host-name в конфигурационном режиме. Если вы в дальнейшем смените это имя, то придется поправлять и сам ключ.
Теперь, когда закрытый ключ запаролен и сохранен в надежном месте, а открытый готов для вставки в конфиг, утилиту PuTTygen можно закрыть и зайти в консоль. Пишем:
root@juniper# set system root-authentication ssh-rsa открытый_ключ (вставляем копи-пастом)
Если все сделали верно, то Джунипер запишет наш ключ в свой конфиг.
Теперь делаем вход только по ключу:
root@juniper# set system services ssh root-login deny-password
Ну и само собой:
root@juniper# commit check
root@juniper# commit
Теперь чтобы войти по SSH нам надо предварительно указать файл нашего закрытого ключа в Путти в разделе «Соединение – SSH — Аутентификация». При входе мы увидим примерно такую картинку:

image

Здесь вводим пароль, который задали при генерации закрытого ключа. После этого нас великодушно пускает! Интересно, что если кто-то теперь попытается войти без ключа, то Джунипер все равно послушно будет спрашивать у него логин-пароль, но аутентификация каждый раз будет проваливаться.

Теперь поговорим о том, как ограничить вход по SSH на уровне сетевого доступа. Для этого есть два взаимодополняющих метода. Первый: директива host-inbound-traffic в разделе edit security zones. Пример:
root@juniper# show security zones security-zone untrust
    screen untrust-screen;
    interfaces {
        fe-0/0/0.0 {
            host-inbound-traffic {
                system-services {
                    ping;
                    ssh;
                }
            }
        }
Данная директива регулирует, по каким протоколам для данной зоны/интерфейса будет доступен сам Джунипер. Например, ssh, ping, https, https, dhcp, tftp и т.д. Если мы указываем в разделе host-inbound-traffic system-services протокол ssh, то Джунипер будет слушать ssh-запросы на данной зоне/интерфейсе.
Хорошо. Но если у нас ssh открыт на интерфейсе для локалки, то все пользователи локалки могут потенциально обратиться к Джуниперу по ssh. Это в большинстве случаев не есть гуд, поэтому необходимо воспользоваться файрволл-фильтрами, чтобы дать доступ только определенным айпишникам.
Допустим нам надо разрешить доступ только для айпи 192.168.10.10, а всем остальным – запретить. Пишем такую конструкцию:
root@juniper# edit firewall filter deny-ssh
(вошли в режим редактирования фильтра)
root@juniper# set term 1 from source-address 0/0
(указываем совпадение с любым адресом источника…)
root@juniper# set term 1 from source-address 192.168.10.10 except
(… кроме нужного нам)
root@juniper# set term 1 from destination-port ssh
root@juniper# set term 1 then log discard
(запрещаем доступ по ssh. Discard – означает молча убить пакет. Можно написать reject – тоже запрет, но с отсылкой icmp port unreachable. Log – означает логирование неудачных попыток стукнуться по ssh. В принципе, можно и не писать).
root@juniper# set term 2 then accept
(не забываем разрешить все остальное, иначе будет очень плохо и нам и роутеру)

Применяем данный фильтр к loopback-интерфейсу роутера (т.к. именно он ведет в routing-engine, т.е. к ядру системы, где живет демон sshd).
root@juniper# set interfaces lo0 unit 0 family inet filter input deny-ssh
Вышеописанный способ является довольно жестким и требует аккуратного применения, т.к. регулирует доступ по ssh к Джуниперу с ЛЮБЫХ ИНТЕРФЕЙСОВ. Если нам не нужен такой серьезный уровень безопасности, то можно этот же фильтр аналогичным образом применить к интерфейсу локальной сети. Только в этом случае нужно учесть, что интерфейс локалки является транзитным по определению, и поэтому нужно добавить в правила фильтра destination-address самого Джунипера, иначе у нас волшебным образом не будет работать в целом ssh-протокол в данной сети. Для loopback-интерфейса указывать destination-address не нужно, т.к. он не является транзитным.
Понятное дело, что совсем необязательно, например, писать в source-address все нули. Можно указать какие-то конкретные подсети и даже интерфейсы. Иначе говоря, настроить доступ можно очень гибко.

Кстати, аналогичной процедурой мы можем ограничить доступ и к веб-интерфейсу Джунипера!

Вот и все! Таким простым способом мы значительно увеличили безопасность наших ssh-сессий!
Теги:juniperjuniper networkssshбезопасность в сети
Хабы: Системное администрирование Сетевые технологии
+1
19,5k 37
Комментарии 10
Лучшие публикации за сутки

Партнерские материалы

Разместить