В этой статье я расскажу, как настроить действительно безопасный SSH-доступ к устройствам Juniper серии SRX, т.е. сделать взлом нашего маршрутизатора гиблым априори занятием. Я опишу две вещи:
- Как сделать вход по SSH возможным только по ssh-ключу.
- Как ограничить список IP-адресов, которые смогут пользоваться ssh-доступом к Джуниперу.
В свое время я честно убил целый день, чтобы дорубиться, как реализовать такие простые вещи в Джуниперах. Надеюсь, моя статья поможет вам сэкономить время.
Давайте реализуем первый пункт. И сразу пара ложек дегтя для затравки:
- На Джуниперах НЕЛЬЗЯ сменить порт SSH! Будем всю жизнь коннектиться на 22-ой! Ладно. Это еще одна причина сделать вход по ключам. Надеюсь в будущих прошивках как-то пофиксят это…
- Данная процедура никак не влияет на доступ к веб-интерфейсу. Это с одной стороны плохо, т.к. любой, кто поломает пароль к веб-морде, сможет изменить конфигу как хочет, а с другой стороны хорошо, т.к. заставляет нас задуматься, а кто вообще может зайти на нашу веб-морду и можно ли ему это делать? Ограничить доступ к веб-интерфейсу можно как по интерфейсу, так и по айпи. Но об этом позже.
Итак, приступим. Для начала надо сгенерировать пару SSH-ключей. Для этого прекрасно подходит утилита PuTTygen из стандартного набора утилит PuTTy. Запускаем ее и видим вот такое окошечко:
Выбираем SSH2-RSA, длину ключа 2048 бит. Нажимаем «Генерировать», шевелим мышкой пока идет генерация. Когда закончит, обязательно вводим два раза стойкий пароль в соответствующих полях и нажимаем кнопку «Личный ключ» для сохранения закрытого ключа. Я думаю, не нужно напоминать, что закрытый ключ на то и назван закрытым, что хранить его стоит в очень надежном месте? Я, например, не храню его в открытом виде, а пользуюсь утилитой 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 — Аутентификация». При входе мы увидим примерно такую картинку:
Здесь вводим пароль, который задали при генерации закрытого ключа. После этого нас великодушно пускает! Интересно, что если кто-то теперь попытается войти без ключа, то Джунипер все равно послушно будет спрашивать у него логин-пароль, но аутентификация каждый раз будет проваливаться.
Теперь поговорим о том, как ограничить вход по 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-сессий!
Автор: celebrate