Настройка SSH, VNC и Fail2ban на Raspberry Pi

Disclaimer: данные инструкции не претендуют на истину в последней инстанции. Более того, наверняка в этих инструкциях есть не оптимальные или «костыльные» решения. Я пытался решать возникающие вопросы теми способами, которые нашёл. Если у вас есть замечания и дополнения — ниже есть блок для комментариев.

Быстрый переход:

SSH

VNC

Fail2ban

SSH

Итак, первое, что понадобилось мне после установки Raspbian на Raspberry Pi 3 (и после смены стандартного пароля) — это организовать удалённый доступ, и желательно через интернет. Не настраивать же плату непосредственно подключая к ней клавиатуру и монитор.

Тут на выручку, очевидно, приходит SSH. Благо в Raspberry Pi удобный конфигуратор прямо в GUI, то можно прямо в нём выбрать SSH (И, заранее, VNC).
Всё то же самое можно настроить и из консоли:

sudo raspi-config

На самом деле это всё. Теперь можно соединяться с платой по SSH используя 22 порт. А если пробросить этот порт во внешку, то и из внешки подключаться.

Правда есть один момент: логин-пароль это, конечно, хорошо, но не очень правильно при открытом 22 порте в интернет. На плату, закономерно, станут стучаться боты с попытками авторизоваться с помощью словарных баз с логинами-паролями.
Поэтому, логичный шаг для увеличения безопасности — запретить доступ по связке логин-пароль и использовать авторизацию с помощью RSA ключей.

Начнем с генерации ключей. В RSA-шифровании используются 2 ключа, открытый и закрытый. Открытый (Public) ключ будет находиться на Pi, а закрытый (Private) на всех тех устройствах, с которых вы захотите подключаться.

В Linux генерация связки ключей делается командой

ssh-keygen

После выбора имени файла в домашней директории будут сохранены 2 файла, файл с расширением .pub — открытый ключ и второй, соответственно, закрытый ключ.  Например pikeyLin и pikeyLin.pub.

В Windows связку можно сгенерировать через PuTTYGen, который входит в состав PuTTY.
Тут всё просто, нажать Generate и поводить мышкой поверх окна для генерации. После этого, соответственно:
  • Скачать Private key (назвав, например, pikey.ppk);
  • Скопировать весь текст из окна «Public key for pasting into OpenSSH authorized_keys» (например в open_ssh.txt);
  • Дополнительно выполнить Conversions -> Export OpenSSH key, и сохранить этот файл (например pOSHH.pem). Это понадобится, например, для устройств на macOS или Android.


Итого:

open_ssh.txt (или pikeyLin.pub) — ключ, который будет находится на Raspberry Pi.
pikey.ppk — ключ для подключения с Windows через PuTTY.
pOSHH.pem (или pikeyLin) — ключ для подключения с macOS или Android.

Теперь переходим к Pi.
Дадим знать плате об открытом ключе. Положим файл open_ssh.txt в корень директории пользователя (pi), откроем терминал и скопируем его содержимое в новый файл:

cat open_ssh.txt >> ~/.ssh/authorized_keys

или, если связка ключей была создана на этой же Pi:

cat pikeyLin.pub >> ~/.ssh/authorized_keys

И дадим необходимые права этому файлу

sudo chmod 644 ~/.ssh/authorized_keys

Теперь перенастроим SSH — запретим доступ по паролю и разрешим по ключу:

sudo nano /etc/ssh/sshd_config

Нас интересуют следующие строчки, они должны быть раскоментированы (Без знака # в начале) и иметь соответствующие значения:

ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2

После замены выходим и сохраняемся (Ctrl+X -> Yes -> Enter).
Всё, плата настроена на использование SSH с RSA-ключами. Осталось только перезапустить SSH следующей командой:

sudo service ssh reload

Переходим к клиентам:

Windows: через Putty для использования ключа перед соединением нужно зайти в Connections -> SSH -> Auth и выбрать файл pikey.ppk
Android: всё также, надо найти клиент с поддержкой SSH с ключами. Я пользуюсь ConnectBot. В настройках сначала нужно выбрать «Управление открытыми ключами» и загрузить туда pem файл, а потом в настройках соединения уже выбрать его.


macOS: 
в терминале выполнить команду со своим расположением файла и адресом платы:

ssh -i Documents/pikey.pem pi@IP_Rasberry_Pi

VNC

Дальше — VNC, иногда же хочется и доступ к графической оболочке иметь.
В конфигураторе Pi мы уже включили VNC (самое начало статьи), поэтому теперь нам надо установить VNC-сервер.

В терминале:

sudo apt-get update
sudo apt-get install realvnc-vnc-server

Подключаться можно через VNC-клиент по IP адресу и порту (обычно) 5900.

В RealVNC для домашнего использования можно использовать облачное подключение (VNC Connect). Оно зашифровано, поэтому в теории через интернет можно пользоваться и им, но мне всё равно захотелось сделать более интересное решение: VNC через SSH-туннель.
Собственно большую часть для этого мы уже сделали при настройке SHH, осталось только пробросить порт через SSH подключение.

На Windows в PuTTY дополнительно в Connections -> SSH -> Tunnels нужно добавить какой-нибудь неиспользуемый порт на машине-клиенте (В моём случае я выбрал 5999) и “направить” его на желаемый нам порт у Pi (127.0.0.1:5900)
После этого нужно соединиться с такими настройками по SSH, открыть VNC-клиент и инициализировать подключение с адресом 127.0.0.1:5999. Таким образом через SSH-туннель мы добираемся до нашего VNC-сервера на Pi. И наружу у нас открыт только 22 порт.

Такой же фокус работает и на Android. В SSH клиенте (В моём случае ConnectBot) инициализируется соединение, дальше в настройках открывается «Перенаправление портов» и выполняется то же самое.
Оставляя на фоне открытое SSH соединение можно подключаться через VNC-клиент.


И на macOS это всё делается из терминала:

sh -L 5999:127.0.0.1:5900 -N -i Documents/pikey.pem pi@IP_Rasberry_Pi

Fail2ban

Отлично, удалённый доступ из внешки есть, и используется только 22 порт. К сожалению, это не отменяет ботнеты направленные на этот порт. Поэтому можно немного и ограничить их активность.
Тут поможет написанный на Python сканер Fail2ban. Он сканирует лог-файлы на подозрительную активность вроде брут-форса и банит IP адреса.

Устанавливается он следующей командой в терминале:

sudo apt-get install fail2ban

После установки, Fail2ban создаёт папку /etc/fail2ban в которой расположен конфигурационный файл jail.conf. Его содержимое должно быть скопировано в файл  jail.local. Внутри файла расположились подборки общих настроек и отдельных опций для конкретных сервисов. Нужно сделать следующее: 

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Тут нас интересует настройка bantime в разделе [DEFAULTS]. Время в секундах, на которое будут баниться IP-адреса. Я поставил 6000. И настройка maxretry — количество повторов с одного адреса, после которых будет установлен бан. Я выставил 5.
И дальше секция JAILS и блок [sshd]. Её надо «включить», добавив enabled = true. Остальные настройки и сервисы я не трогал.


Сохраняем файл и перезапускаем fail2ban

sudo service fail2ban restart

Отчёты о его работе находятся в /var/log/fail2ban.log