Введение
В этом руководстве мы оснастим недавно созданный сервер с Debian (Debian 9 Stretch) безопасной базовой конфигурацией и установим Docker.
Вот что мы сделаем ...
- создадим непривилегированного пользователя Sudo
- запретим вход по паролю
- заблокируем пользователя root
- сменим порт SSH
- настроим межсетевой экран
- установим Docker и docker-compose
- настроим доступ к Docker
Если Docker на сервере не нужен, этот шаг, конечно же, можно опустить.
Я также создал конфигурацию Cloud-Init, которая позволяет при создании сервера автоматически применять все шаги, описанные в этом руководстве.
Шаг 1 — Создание пользователя Sudo
Поскольку один из следующих шагов предотвращает вход на сервер от пользователя с именем root, нам сначала нужен новый пользователь, с которым мы можем войти и администрировать сервер.
Создадим пользователя holu
с помощью следующей команды:
adduser --disabled-password holu
Так как мы хотим деактивировать возможность входа по паролям, нового пользователя создали сразу без пароля, указав для этого параметр --disabled-password
.
Вновь созданный пользователь «holu» в настоящее время не имеет специальных прав. Однако, поскольку мы хотим использовать пользователя в качестве замены пользователю «root», мы дадим ему возможность использовать Sudo для запуска команд от пользователя root.
Для этого надо создать файл /etc/sudoers.d/90-holu
следующего содержания:
holu ALL=(ALL) NOPASSWD:ALL
Шаг 2 — Настройка SSH
Шаг 2.1 — Настройка SSH-сервера
Для дополнительной безопасности надо изменить настройки SSH-сервера. Для этого откройте файл /etc/ssh/sshd_config
с помощью текстового редактора по нашему выбору (который, конечно же, должен попадать на vim), удалите содержимое файла и вставьте конфигурацию ниже. Наиболее важные параметры описаны ниже.
Protocol 2
Port 44933
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
SyslogFacility AUTH
LogLevel INFO
PermitRootLogin no
StrictModes yes
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
AllowUsers holu
Protocol 2
Гарантирует, что сервер принимает соединения только по защищенному протоколу версии 2.
Port 44933
Изменение порта не повышает безопасность, но мы можем обойти большинство автоматических попыток входа, поскольку они обычно используют только порт по умолчанию.
PermitRootLogin no
Запрещает пользователю root вход по SSH.
PasswordAuthentication no
Запрещает вход по паролю. Мы установили эту опцию, потому что вход по ключу является более безопасным.
PubkeyAuthentication yes
Включает аутентификацию с использованием пар SSH-ключей.
StrictModes yes
Предотвращает запуск SSH-сервера, если некоторые файлы имеют разрешения сверх необходимого.
AllowUsers holu
Эта опция предоставляет белый список для всех пользователей, которым разрешено входить через SSH. В нашем случае это только один пользователь «holu».
Важно: сервер или служба SSH не должны быть перезапущены до завершения следующих шагов, в противном случае новая конфигурация станет активной, что заблокирует нас от сервера.
Шаг 2.2 — создание пары SSH-ключей
На предыдущем шаге мы отключили вход по паролю, поэтому теперь мы должны использовать единственный оставшийся вариант — аутентификацию с помощью пары SSH-ключей.
Во-первых, нам нужно создать пару ключей на нашей локальной машине. Если ключ уже существует, этот шаг можно пропустить.
Пользователи Windows могут, например, использовать PuTTYgen для создания пары ключей.
Под GNU/Linux создать пару ключей можно при помощи следующей команды.
ssh-keygen \
-o \
-a 100 \
-t ed25519 \
-f ~/.ssh/id_ed25519 \
-C "$(whoami)@$(hostname)"
Пара ключей (состоящая из файлов id_ed25519
и id_ed25519.pub
) теперь должна быть расположена в домашнем каталоге локального пользователя ~/.ssh
. Закрытый ключ (файл без .pub) должен храниться в безопасности, подобно паролю, и не передаваться.
Шаг 2.3 — Размещение открытого ключа
Чтобы иметь возможность аутентифицировать себя с помощью своего закрытого ключа, соответствующий открытый ключ должен быть размещен на сервере. Поэтому в каталоге SSH пользователя «holu» мы создаем файл authorized_keys
и добавляем в него открытый ключ (содержимое id_ed25519.pub). Мы также настраиваем права доступа к файлу, чтобы никто, кроме пользователя «holu», не мог получить доступ к этому файлу (в противном случае StrictMode не позволит запустить службу ssh).
mkdir -p /home/holu/.ssh
vim /home/holu/.ssh/authorized_keys
chmod 600 /home/holu/.ssh/authorized_keys
chown holu:holu /home/holu/.ssh/authorized_keys
Шаг 2.4 — Применение новых настроек
Теперь, когда ключ хранится на сервере, мы можем применить новые настройки SSH-сервера просто перезапустив SSH-сервер.
systemctl restart sshd
Теперь мы должны иметь возможность подключиться к серверу пользователем «holu» через новый SSH-порт и аутентифицироваться с помощью нашей пары SSH-ключей.
ssh -p 44933 holu@<your_host>
Все дальнейшие шаги выполняются от пользователя с именем «holu».
Шаг 3 — Настройка межсетевого экрана
Для настройки межсетевого экрана мы будем использовать программу «ufw» (абстракция над iptables), потому что правилами можно управлять намного проще и комфортнее, чем напрямую с iptables.
Пакет «ufw» не входит в установку Debian по умолчанию и может быть установлен при помощи менеджера пакетов.
sudo apt install ufw
Создадим правило, которое блокирует все входящие соединения, которые не были явно разрешены.
sudo ufw default deny incoming
Прежде чем активировать межсетевой экран, нужно разрешить доступ к нашему SSH-порту, иначе мы потеряем связь с сервером и не сможем к нему подключиться.
sudo ufw allow 44933/tcp
Теперь мы можем активировать межсетевой экран с помощью следующей команды.
sudo ufw enable
С помощью команды ufw status
можно вывести на экран все созданные правила. Она тоже должна быть выполнена от пользователя root.
Шаг 4 — Установка Docker (необязательно)
Шаг 4.1 — Добавление репозитория
Поскольку Debian не предоставляет последнюю версию Docker в официальных репозиториях, репозитории Docker необходимо загружать через менеджер пакетов. В официальной документации описано как это сделать.
Шаг 4.2 — Установка
Если включены источники пакетов, Docker можно установить обычным образом через менеджер пакетов.
sudo apt install \
docker-ce \
docker-ce-cli \
containerd.io \
docker-compose
Шаг 4.3 — Доступ к Docker
По умолчанию Docker можно использовать только как root. Для использования Docker (без Sudo) пользователь «holu» должен быть членом группы «docker».
sudo usermod -aG docker holu
Примечание: пользователи в группе «docker» имеют привилегии root. Более подробную информацию можно найти здесь: Docker security | Docker Documentation.
Шаг 5 — Cloud Init
Некоторые поставщики, включая Hetzner Cloud, поддерживают Cloud-Init для настройки серверов непосредственно после создания. Следующая конфигурация Cloud-Init автоматически выполнит все шаги, показанные в этой статье.
Переменные (помеченные <>
) должны быть заменены перед использованием конфигурации.
#cloud-config
users:
- name: <имя пользователя>
ssh-authorized_keys:
- <публичный ssh-ключ>
sudo: ['ALL=(ALL) NOPASSWD:ALL']
groups:
- sudo
- docker
shell: /bin/bash
package_upgrade: true
packages:
- ufw
- vim
- apt-transport-https
- ca-certificates
- curl
- gnupg2
- software-properties-common
runcmd:
- curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
- add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
- apt-get update -y
- apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose
- ufw default deny incoming
- ufw allow <SSH-порт>/tcp
- echo "y" | ufw enable
write_files:
- path: /etc/ssh/sshd_config
content: |
Protocol 2
Port <SSH-порт>
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
SyslogFacility AUTH
LogLevel INFO
PermitRootLogin no
StrictModes yes
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
AllowUsers <имя пользователя>
Вывод
Готов! Теперь у нас есть сервер Debian с надежной базовой конфигурацией.