−25%

на годовую оплату Windows, до 31.10. К тарифам

EQVPS
Начать

Как настроить VPS на Alpine Linux: apk, doas, OpenRC и файрвол

Первые шаги на свежем VPS с Alpine Linux 3.21: обновиться и перезагрузиться, создать пользователя с doas, который действительно сможет войти, отключить вход root и по паролю, поставить ufw, включить cron и ежедневные обновления. Плюс порт Docker, который ufw не закрывает.

Alpine Linux — самый компактный образ из тех, что мы предлагаем. На наших серверах свежий Alpine 3.21 в простое занимал 55 МБ памяти и 153 МБ диска, а Ubuntu 24.04 — 313 МБ и 2,7 ГБ. Платить за это приходится привычными инструментами. В Alpine apk вместо apt, doas вместо sudo, OpenRC вместо systemd и musl вместо glibc.

Шаги ниже — те же первые десять минут, что на Debian или Ubuntu, только переложенные на Alpine. Мы выполнили каждую команду на нашем образе Alpine 3.21 перед публикацией, и на двух из них с первого раза споткнулись. Войдите как root с паролем из кабинета.

1. Обновитесь и один раз перезагрузитесь

apk update && apk upgrade
uname -r
ls /lib/modules

Сервер уже поставил доступные обновления при первой загрузке, поэтому apk upgrade обычно почти ничего не делает. Смотрите на две последние строки. Если то первое обновление принесло новое ядро, у работающего ядра (uname -r) больше нет модулей на диске. Всё, что загружает модуль, будет падать до перезагрузки. На нашем тестовом сервере установка файрвола выдала ERROR: Couldn't determine iptables version. Если версии различаются, перезагрузитесь сейчас:

reboot

Наш тестовый сервер вернулся меньше чем через минуту.

2. Создайте пользователя, который сможет войти

adduser -D deploy
passwd deploy
adduser deploy wheel

Не пропускайте passwd. adduser -D создаёт учётную запись без пароля, Alpine помечает её как заблокированную, и sshd отказывает заблокированной записи даже с правильным ключом. В нашем тесте единственной подсказкой была эта строка в /var/log/messages:

User deploy not allowed because account is locked

Пароль понадобится и дальше: его будет спрашивать doas.

Если при заказе сервера вы добавили SSH-ключ, он лежит в authorized_keys пользователя root. Скопируйте его новому пользователю:

install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys

Ключа ещё нет? Создайте его на своём компьютере и вставьте публичную часть в /home/deploy/.ssh/authorized_keys.

3. Пусть doas спрашивает пароль

В Alpine вместо sudo используется doas, и в нашем образе группе wheel он уже разрешён. Правило в /etc/doas.d/wheel.conf — permit nopass :wheel, то есть любой участник wheel становится root, ничего не вводя. Пусть он спрашивает пароль и потом помнит его несколько минут:

echo 'permit persist :wheel' > /etc/doas.d/wheel.conf

Теперь doas apk add nano работает так же, как sudo apt install nano в Ubuntu.

4. SSH: только ключи, без root

sshd читает файлы из /etc/ssh/sshd_config.d/ по порядку имён и для каждой настройки берёт первое найденное значение. В нашем образе первый файл — 00-eqvps.conf, он разрешает вход root и по паролю, чтобы в первый день вы могли попасть на сервер. Замените его содержимое:

cat > /etc/ssh/sshd_config.d/00-eqvps.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
EOF
sshd -t && rc-service sshd restart
sshd -T | grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication) '

Третья строка на Alpine важна. В образе стоит сборка OpenSSH с PAM, и только с двумя первыми строками наш тестовый сервер по-прежнему предлагал вход через keyboard-interactive. Со всеми тремя попытка входа без ключа получает:

Permission denied (publickey).

Не закрывайте сессию root. Во втором терминале проверьте, что работает ssh deploy@YOUR.SERVER.IP (на тарифе с NAT добавьте -p и персональный порт из кабинета) и что doas id принимает пароль.

5. Файрвол: ufw

ufw лежит в репозитории community, который в нашем образе уже включён:

apk add ufw
ufw limit 22/tcp
ufw --force enable
rc-update add ufw default
ufw status

limit пропускает SSH, но притормаживает того, кто открывает много соединений подряд. rc-update здесь обязателен: OpenRC не запустит файрвол после перезагрузки, если не добавить его в runlevel. После перезагрузки наш сервер поднялся со Status: active. На тарифе с NAT оставьте SSH на порту 22: ваш персональный внешний порт проброшен на 22 внутри сервера. На тарифе с собственным IPv4 открывайте веб-порты, когда они понадобятся (ufw allow 80/tcp, ufw allow 443/tcp). Остальное есть в руководстве по ufw.

6. Включите cron и ежедневные обновления

На свежем Alpine cron вообще не запущен. Включите его:

rc-update add crond default
rc-service crond start

crontab root в Alpine уже запускает всё из /etc/periodic/daily в 02:00. Положите туда скрипт обновления:

cat > /etc/periodic/daily/apk-upgrade <<'EOF'
#!/bin/sh
apk upgrade --update-cache --no-progress >> /var/log/apk-auto.log 2>&1
EOF
chmod +x /etc/periodic/daily/apk-upgrade
run-parts --test /etc/periodic/daily

Последняя команда показывает скрипты, которые запустит cron, и ваш должен быть в списке. Так вы получаете исправления для ветки 3.21. Переход на следующий релиз Alpine — отдельный ручной шаг. Обновления ядра по-прежнему требуют перезагрузки: время от времени повторяйте проверку uname -r / ls /lib/modules из шага 1.

7. OpenRC в одной таблице

Если вы знаете systemd, вот почти всё, что меняется:

ЗадачаsystemdAlpine (OpenRC)
Запустить сервисsystemctl start nginxrc-service nginx start
Автозапуск при загрузкеsystemctl enable nginxrc-update add nginx default
Статусsystemctl status nginxrc-service nginx status
Что запущеноsystemctl list-unitsrc-status
Системный журналjournalctl/var/log/messages

8. Docker и порт, который ufw не закрывает

Alpine — хороший хост для Docker: сама система почти не мешает:

apk add docker docker-cli-compose
rc-update add docker default
rc-service docker start
docker run --rm hello-world

На нашем сервере это заняло 12 секунд вместе со скачиванием. С запущенным демоном Docker занятая память выросла с 57 МБ до 124 МБ.

Одна ловушка, которая не связана именно с Alpine: Docker пишет собственные правила файрвола. Когда ufw разрешал только SSH, мы запустили nginx с -p 8080:80 и открыли его снаружи сервера на порту 8080. ufw его не закрыл. Если контейнер должен быть доступен только через обратный прокси на том же сервере, публикуйте его на localhost:

docker run -d -p 127.0.0.1:8080:80 nginx:alpine

Какой тариф

Alpine оставляет почти всю память вашим программам. Тарифа Nano (2 vCPU, 1 ГБ, 15 ГБ, $3/мес) хватит для небольшого сервиса или нескольких контейнеров. Это тариф с NAT, поэтому SSH приходит через персональный порт. Если нужны открытые в интернет порты 80 и 443, у Nano-IP есть собственный IPv4 за $8/мес. Для более тяжёлых стеков Docker Micro даёт 2 ГБ за $5/мес.

Alpine 3.21 есть на странице Alpine VPS и доступен на всех Linux-тарифах в разделе VPS. Оплата в USDT, USDC или ETH в сетях Base, Ethereum или Polygon, без документов и карты.

Частые вопросы

Почему Alpine намного меньше Ubuntu и Debian?

В нём musl вместо glibc, BusyBox для базовых команд и OpenRC вместо systemd. На наших серверах свежий Alpine 3.21 в простое занимал 55 МБ памяти и 153 МБ диска. Ubuntu 24.04 занимал 313 МБ и 2,7 ГБ.

Почему новый пользователь получает «account is locked», хотя ключ правильный?

adduser -D создаёт учётную запись без пароля, Alpine помечает её как заблокированную, и sshd отказывает такому пользователю даже с верным ключом. В журнале появляется строка «User deploy not allowed because account is locked». Задайте пользователю пароль командой passwd, и вход по ключу заработает.

Почему на Alpine не работает SSH-туннель?

В стандартном /etc/ssh/sshd_config Alpine стоит AllowTcpForwarding no, поэтому пробросы ssh -L отклоняются. Если туннели нужны, поменяйте значение на yes в этом файле и выполните rc-service sshd restart.

Запустится ли моя программа на Alpine?

Всё из репозиториев Alpine запустится, как и контейнеры Docker на любом базовом образе. Готовые бинарники Linux, собранные под glibc, на musl часто не стартуют. Ищите сборку для Alpine или musl либо запускайте программу в Docker. Пакет gcompat помогает с некоторыми простыми glibc-бинарниками.

Какого тарифа хватит для Alpine?

Тарифа Nano на 1 ГБ за $3 в месяц хватает с запасом: сама система занимает около 55 МБ. Если нужны открытые в интернет порты 80 и 443, берите Nano-IP за $8 в месяц, у него собственный IPv4.

Комментарии

Пока нет комментариев. Будьте первым.

Оставить комментарий

Комментарии проходят модерацию перед публикацией.