psj-notes
~/home ~/series ~/archive

Часть 02. SSH-ключи, безопасность, Zsh

29.07.2026 Серия: Руководство по настройке srv02-Helsinki 'ssh' 'ed25519' 'zsh' 'motd'

Часть 02. SSH-ключи, безопасность и Zsh

«Ключи — единственный способ доказать, что вы — хозяин, а не случайный прохожий, подглядывающий в щель забора.» — Воланд


Глава 1. Генерация SSH-ключа на рабочей станции

Пароль — это зло. Вместо него используем SSH-ключи. Генерируем на своём локальном компьютере (не на сервере!) пару ключей по алгоритму Ed25519:

ssh-keygen -t ed25519 -C "user01@srv02-Helsinki"

Флаги команды:

  • -t ed25519 — тип ключа (Ed25519 — современный и безопасный)
  • -C "user01@srv02-Helsinki" — комментарий, чтобы не забыть, к какому серверу ключ

Ожидаемый вывод:

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user01/.ssh/id_ed25519):

Жмём Enter, чтобы сохранить в стандартный путь.

Enter passphrase (empty for no passphrase):
Enter same passphrase again:

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

После успешного создания:

Your identification has been saved in /home/user01/.ssh/id_ed25519
Your public key has been saved in /home/user01/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx user01@srv02-Helsinki
The key's randomart image is:
+--[ED25519 256]--+
|    .o.          |
|   o  . .        |
|    .   .       |
...
+----[SHA256]-----+

Созданы два файла:

  • id_ed25519закрытый ключ (никому не показывать!)
  • id_ed25519.pubоткрытый ключ (копируем на сервер)

Проверяем, что ключи действительно создались:

ls -la ~/.ssh/

Ожидаемый вывод:

total 24
drwx------  2 user01 user01 4096 Jan 14 12:05 .
drwxr-xr-x 28 user01 user01 4096 Jan 14 12:05 ..
-rw-------  1 user01 user01  464 Jan 14 12:05 id_ed25519
-rw-r--r--  1 user01 user01  101 Jan 14 12:05 id_ed25519.pub

Права доступа:

  • Закрытый ключ id_ed25519-rw------- (только владелец)
  • Открытый ключ id_ed25519.pub-rw-r--r-- (можно показывать)

Глава 2. Копирование ключа на сервер

Копируем открытый ключ на сервер с помощью ssh-copy-id:

ssh-copy-id -i ~/.ssh/id_ed25519.pub user01@XX.XX.XX.XX

Флаги команды:

  • -i ~/.ssh/id_ed25519.pub — путь к открытому ключу
  • user01@XX.XX.XX.XX — пользователь и адрес сервера

Ожидаемый вывод:

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user01/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is the user's password
user01@XX.XX.XX.XX's password:

Вводим пароль пользователя user01. После успешной установки:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'user01@XX.XX.XX.XX'"
and check to make sure only the key(s) you wanted were added.

Проверяем, что ключ работает — теперь пароль не запрашивается:

ssh user01@XX.XX.XX.XX

Ожидаемый вывод — сразу приглашение, без запроса пароля:

Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.8.0-xx-generic x86_64)
...
user01@srv02-Helsinki:~$

Глава 3. Отключение входа по паролю

Возвращаемся на сервер (или открываем вторую сессию под root, если первая ещё active). Редактируем конфигурацию SSH.

Создаём файл /etc/ssh/sshd_config.d/99-security.conf:

sudo tee /etc/ssh/sshd_config.d/99-security.conf > /dev/null <<EOF
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
UsePAM yes
MaxAuthTries 3
EOF

Пояснение параметров:

  • PasswordAuthentication no — запретить вход по паролю
  • PubkeyAuthentication yes — разрешить вход по ключам
  • KbdInteractiveAuthentication no — отключить интерактивную аутентификацию (ещё один способ ввода пароля)
  • UsePAM yes — оставить PAM (нужно для sudo)
  • MaxAuthTries 3 — максимум 3 попытки аутентификации

Проверяем конфигурацию на корректность:

sudo sshd -t

При успехе команда не выводит ничего. Если есть ошибки — будет сообщение.

Перечитываем конфигурацию SSH без разрыва текущих соединений:

sudo systemctl reload ssh

reload в отличие от restart не обрывает активные сессии — применяет настройки только для новых подключений.

Не закрывая текущую сессию, открываем второе окно терминала и пробуем войти по ключу:

ssh user01@XX.XX.XX.XX

Если ключ настроен правильно — пароль не запрашивается, мы сразу попадаем на сервер.

Ожидаемый вывод:

Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.8.0-xx-generic x86_64)
...
user01@srv02-Helsinki:~$

Только после успешной проверки можно закрыть старую сессию.

Воланд, с удовлетворением наблюдая за запертой дверью:
«Пароли изгнаны обратно в преисподнюю! Теперь ни один бот в интернете не сможет подобрать отмычку к нашей системе.»


Глава 4. Смена порта SSH на 22022

Стандартный 22-й порт — первое, что сканируют боты. Меняем его на нестандартный 22022.

Создаём файл /etc/ssh/sshd_config.d/99-port.conf:

echo 'Port 22022' | sudo tee /etc/ssh/sshd_config.d/99-port.conf

Проверяем конфигурацию:

sudo sshd -t

Если ошибок нет — команда не выводит ничего.

Перечитываем конфигурацию SSH:

sudo systemctl reload ssh

Проверяем, что SSH теперь слушает новый порт:

ss -tlnp | grep :22022

Ожидаемый вывод:

LISTEN 0      128        0.0.0.0:22022      0.0.0.0:*    users:(("sshd",pid=1234,fd=3))
LISTEN 0      128           [::]:22022         [::]:*    users:(("sshd",pid=1234,fd=4))

Важно: пока не закрывайте текущую сессию! Сначала откройте новое окно терминала и проверьте подключение на новом порту:

ssh -p 22022 user01@XX.XX.XX.XX

Флаг -p 22022 — указывает порт подключения.

После успешной проверки можно закрывать старую сессию на порту 22.

Чтобы не вводить порт каждый раз, создаём на локальном компьютере файл ~/.ssh/config:

cat >> ~/.ssh/config << EOF

Host srv02
    HostName XX.XX.XX.XX
    Port 22022
    User user01
    IdentityFile ~/.ssh/id_ed25519
EOF

Теперь можно подключаться просто:

ssh srv02

Воланд, пряча ключи в карман сюртука:
«Порт изменён. 22-й забыт, как старый чемодан на вокзале. Если боты ищут нас на 22-м — они будут ждать вечно.»


Глава 5. Установка Zsh и Oh My Zsh

Bash — это рабочие штаны. Zsh — смокинг. Настраиваем красивую и удобную оболочку.

Устанавливаем пакеты:

sudo apt update && sudo apt install -y zsh git curl unzip fontconfig

Ожидаемый вывод (сокращён):

Reading package lists... Done
Building dependency tree... Done
...
Setting up zsh (5.9-6ubuntu2) ...

Устанавливаем Oh My Zsh:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended

Флаг --unattended — без интерактивных вопросов.

Ожидаемый вывод (сокращён):

Cloning Oh My Zsh...
Cloning into '/root/.oh-my-zsh'...
...
Looking for an existing zsh config...
Using the Oh My Zsh template file and adding it to /root/.zshrc

Меняем оболочку по умолчанию для пользователя user01:

sudo chsh -s $(which zsh) user01

Команда выполняется без вывода.

Устанавливаем тему Powerlevel10k. Сначала клонируем репозиторий в каталог тем Oh My Zsh от имени пользователя user01:

sudo -u user01 git clone --depth=1 https://github.com/romkatv/powerlevel10k.git /home/user01/.oh-my-zsh/custom/themes/powerlevel10k

Ожидаемый вывод:

Cloning into '/home/user01/.oh-my-zsh/custom/themes/powerlevel10k'...
remote: Enumerating objects: 107, done.
remote: Counting objects: 100% (107/107), done.
...
Receiving objects: 100% (107/107), 1.23 MiB | 1.5 MiB/s, done.

Устанавливаем плагины:

sudo -u user01 git clone https://github.com/zsh-users/zsh-autosuggestions /home/user01/.oh-my-zsh/custom/plugins/zsh-autosuggestions
sudo -u user01 git clone https://github.com/zsh-users/zsh-syntax-highlighting /home/user01/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting
sudo -u user01 git clone --depth 1 https://github.com/marlonrichert/zsh-autocomplete /home/user01/.oh-my-zsh/custom/plugins/zsh-autocomplete

Все три клонируются без ошибок.

Редактируем конфигурацию Zsh пользователя user01. Открываем /home/user01/.zshrc:

sudo -u user01 sed -i 's/ZSH_THEME="robbyrussell"/ZSH_THEME="powerlevel10k\/powerlevel10k"/' /home/user01/.zshrc
sudo -u user01 sed -i 's/plugins=(git)/plugins=(git zsh-autosuggestions zsh-syntax-highlighting zsh-autocomplete)/' /home/user01/.zshrc

Проверяем результат:

sudo -u user01 grep -E '^ZSH_THEME=|^plugins=' /home/user01/.zshrc

Ожидаемый вывод:

ZSH_THEME="powerlevel10k/powerlevel10k"
plugins=(git zsh-autosuggestions zsh-syntax-highlighting zsh-autocomplete)

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

Воланд, глядя на цветной промпт с иконками:
«Администратор должен работать с комфортом. Качественный командный промпт с подсветкой подсказывает ошибки до того, как они успеют совершиться.»


Глава 6. Кастомный баннер приветствия (MOTD)

Создаём приветственный баннер, который будет встречать при каждом входе на сервер.

Редактируем /etc/update-motd.d/00-voland-banner:

sudo tee /etc/update-motd.d/00-voland-banner > /dev/null << 'BANNER'
#!/bin/bash
cat << "MOTD"
┌──────────────────────────────────────────────────────────────────┐
│                                                                  │
│   Добро пожаловать, дорогой гость.                               │
│                                                                  │
│   Хоть Хельсинки и Хельсинки, а Воланд — он и в Финляндии        │
│   Воланд. Квартирный вопрос, как известно, испортил не только    │
│   москвичей, но и многих, кто пытался зайти на srv02-Helsinki    │
│   без приглашения.                                               │
│                                                                  │
│   У вас есть ключ? Отлично. Вы — свой.                           │
│   А если нет — Аннушка масло уже разлила,                        │
│   и вам лучше не скользить.                                      │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘
MOTD
BANNER

Делаем скрипт исполняемым:

sudo chmod +x /etc/update-motd.d/00-voland-banner

Отключаем стандартные баннеры, которые не нужны:

sudo chmod -x /etc/update-motd.d/10-help-text /etc/update-motd.d/50-motd-news 2>/dev/null

Проверяем результат — выходим и заходим заново или запускаем вручную:

sudo run-parts /etc/update-motd.d/

Ожидаемый вывод:

┌──────────────────────────────────────────────────────────────────┐
│                                                                  │
│   Добро пожаловать, дорогой гость.                               │
│                                                                  │
│   Хоть Хельсинки и Хельсинки, а Воланд — он и в Финляндии        │
│   Воланд. Квартирный вопрос, как известно, испортил не только    │
│   москвичей, но и многих, кто пытался зайти на srv02-Helsinki    │
│   без приглашения.                                               │
│                                                                  │
│   У вас есть ключ? Отлично. Вы — свой.                           │
│   А если нет — Аннушка масло уже разлила,                        │
│   и вам лучше не скользить.                                      │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘

Воланд, оценивая выравнивание рамки:
«Псевдографика должна быть безупречной. Ровная рамка при входе сразу даёт понять входящему, что здесь царит порядок и строгость.»


Финал части: Резюме Воланда

Воланд подводит итог второй части:
«Пароли отключены, вход только по ключам, оболочка Zsh настроена, а приветственный баннер напоминает входящим про разлитое масло. Переходим к настройке самой системы!»

Комментарии

Комментарии пока не подключены.