В последнее время разрабатывать код стало не так безопасно как раньше. Некоторые критичные сервисы перестают работать или изгоняют пользователей по какому-то признаку. В статье постараюсь рассказать как сделать свою разработку максимально автономной и при этом не потерять в комфорте. Сразу отмечу, что не разделяю идею поднять все-все на локалхосте, хотя в мире с dockerом, это вполне реально.

Для доступа к своим данным «откуда угодно» предлагаю поднять VPS. Хостингов много, но я остановился на reg.ru. Если кому-то нужна машина за пределами РФ, то рекомендую посмотреть в сторону Inferno Solutions, оплату Миром принимают.

Чеклист

После того как оператор передаст управление, нужно пройти следующий чеклист:

  • Сменить пароль на root
  • Добавить обычного юзера (не админа)
  • Перенести ssh на другой порт с 22 (например 224). Это резко сократит попытки залогиниться со стороны какого-нибудь China-net и соотвественно уменьшит ненужную нагрузку на тачку
  • Сделать логин для юзера только по публичному ключу
  • Отобрать возможность логиниться у рута
  • Установить утилиту sudo
  • Добавить юзера в группу wheel, где кроме него никого не должно быть
  • Заблокировать любой входящий трафик кроме ssh (224), http(80) и https (443)

Генерация стойкого пароля

Для генерации пароля прям в консоли в linux есть утилита pwgen. Например, для генерации 24-х символьного пароля нужно выполнить

pwgen -s -1 24

Так же, нельзя использовать слишком короткий пароль или пароль состоящий только из симфолов. Для наглядного объяснения как быстро такие пароли могут быть взломаны, сотрудники Hive Systems сделали табличку: Password Cracking Time

Разделение прав

По-умолчанию, в свежей VPS присутствует только один пользователь - root - категорически не рекомендуется его использовать для решения всех задач!
Для повышения безопасноти необходимо создать хотя бы двух пользователей с ограниченными правами, в идеале, отдельный пользователь должен быть под каждый сервис запущенный на машине.
Чтобы создать пользователя с домашним каталогом надо выполнить

useradd -m owner
useradd -m services

где ключ m отвечает за создание домашнего каталога, а services/owner - имя нового пользователя. Соотвественно, пользователь owner будет отвечать за взаимодействие с системой через sudo, а от пользователя services будут запускаться (микро)сервисы. Пароль необходимо задать только для owner так же как и создавали пароль для root.

Настройка SSH

Перед тем как начинать конфигурировать сервер, нужно создать пару ключей для доступа через ssh с локальной машины

ssh-keygen -t rsa -b 4096

После выполнения этой команды в каталоге пользователя появятся два файла: id_rsa и id_rsa.pub, это секретный и публичные ключи соответственно. Для логина пользователя owner надо скопировать содержимое id_rsa.pub на локальной машине в файл /home/owner/.ssh/authorized_keys. После этого следует проверить, что все работает правильно командой

ssh owner@<server-ip>

Если ключ применился, то ssh-сервер сразу залогинит пользователя без запроса пароля. Настройки ssh которые предоставляются по-умолчанию тоже не являются достаточно безопасными, так например множество сканеров (как известных, так и самописных) проверяют наличие открытого tcp порта 22 и если такой действительно открыт, то вход идут всякие переборщики паролей и прочие утилиты для эксплуатации известных ssh-уязвимостей.
Чтобы снизить вредоносную активность необходимо в файле настроек демона ssh (/etc/ssh/sshd_config) изменить значение переменной Port с 22 на любое другое которое не используется системой (проверить можно командой netstat -napt, которая выведет все активные соединения и открытые порты), например 225.

Port 225

Далее, в этом же файле надо прописать пользователей которым разрешен доступ по ssh и запретить логин для root

AllowUsers      owner
PermitRootLogin no

После этого надо разрешить аутентификацию только по публичным ключам

PubkeyAuthentication    yes
PasswordAuthentication  no
PermitEmptyPasswords    no

После того как конфиг-файл был исправлен, необходимо перезапустить демон ssh (например командой: systemctl restart sshd) и снова попробовать зайти под пользователем owner. Так же можно проверить, что логин под пользователем root невозможен и система сразу прерывает попытку входа не предлагая ввести пароль.

Использование sudo вместо root

Так как теперь мы не можем через ssh сразу залогиниться в администратора(root), то нам может пригодиться утилита которая сделает взаимодействие с системой более комфортной, но не менее безопасной - sudo. Для разрешения доступа к ней от пользователя надо выполнить команду, которая добавит текущего пользователя owner в группу wheel

su -c "usermod -a -G wheel owner"

после этого необходимо разлогинить из системы(exit) и выполнить команду

sudo su

если появился запрос пользовательского пароля после ввода которого получается консоль администратора(#), значит все настроено и работает. Но в некоторых случаях надо разрешать доступ для группы wheel к привилегиям sudo. Для этого надо запустить консоль администратора su и размаскировать строчку

%sudo   ALL=(ALL:ALL) AL

сохранить файл, перезапустить демон sudo (systemctl restart sshd), выйти из консоли администратора и снова запустить sudo su для проверки работоспособности.

Блокировка входящего трафика

Простой способ избежать тривиальных DDoS-атак и случайных раскрытий данных, когда сервис оказывает доступен из инетернета, это превентивно закрыть все порты для входящего трафика, за исключением необходимых (ssh, web-сервер). Для реализации этой задачи используем утилиту iptables. Пример конфигурации который надо скопировать в /etc/iptables_rules.conf на удаленной машине

*filter
:INPUT DROP [1379:71727]
:OUTPUT ACCEPT [1985:127314]
:FORWARD DROP [0:0]
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 225 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
COMMIT

загрузить конфиг можно командой iptables-restore < /etc/iptables_rules.conf. Чтобы правила поднимались автоматически нужно добавить хук на подъем интерфейса в /etc/network/interfaces

...
iface eth0 inet static
   pre-up iptables-restore < /etc/iptables_rules.conf
...

в таком случае, всегда при включении интерфейса eth0 будут загружаться правила iptables из файла /etc/iptables_rules.conf.

Ну вот и все! Машинка готова к работе, в следующей части я расписал безопасные варианты хранение паролей т.к. это очень важно.

Подпишись на мой канал в Телеграм!