Гайд на виртуальный частный сервер (VPS) с нуля

от автора

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

— Сервер Linux Debian 11
— Виртуальная частная сеть Wireguard
— Мониторинг Grafana
— Спасательный круг: backups & snapshots
— Базовая защита от взлома перебором fali2ban
— Фильтр нежелательного контента, приоритезация трафика QoS

Шаг 1: Выбрать хостинг

Воспользоваться поисковым запросом «список самых дешёвых VPS хостингов» и выбрать, какой больше нравится. Конфигурации и цены бывают разные, самые дешёвые начинаются от двух евро в месяц. Например — hip.hosting

Шаг 2: Выбрать локацию, операционную систему и оплатить аренду сервера

Локацию сервера выбираем из доступных, исходя из своих предпочтений. Обычно — чем ближе локация, тем ниже задержка. Операционную систему я советую Debian.

Шаг 3: Настройка операционной системы

Используя программу Putty и предоставленные IP адрес и пароль, нужно войти на сервер и обновиться:

sudo apt update && apt upgrade -y

sudo apt-get install iptables net-tools vim rsync parted -y

В файле системной конфигурации нужно убрать знак комментария «#» в начале строки «net.ipv4.ip_forward=1«, чтобы разрешить нашему серверу выполнять роль прокси:

vim /etc/sysctl.conf

vim, vi — самый распространённый текстовый редактор linux. Режим редактирования включается кнопкой i, выход из редактирования кнопка esc. Чтобы выйти без сохранения надо ввести «:q!» (без кавычек), выход с сохранением — «:wq!»

Установим бесплатный клиент с открытым исходным кодом Wireguard:
sudo apt install wireguard -y

Переходим в папку приложения:
cd /etc/wireguard/

Генерируем и записываем ключи:
wg genkey | tee privatekey | wg pubkey | tee publickey

Приватный ключ надо записать в конфиг Wireguard; здесь Address = это адрес сервера в виртуальной сети, а ListenPort = порт, по которому будут подключаться клиенты (адрес и порт можно задать произвольно):

echo "[Interface]
PrivateKey = $(cat privatekey)
Address = 10.0.0.1/24
ListenPort = 51820" > wg0.conf

в Putty текст вставляется правой кнопкой мыши. В vim через Putty — клавиша shift+правая кнопка мыши. А для переноса больших объёмов текста в веб-консоль, у меня есть пара удобных инструментов — typewriter и infill.

Далее — надо добавить в этот файл информацию о сетевом адаптере:
INTERFACE=$(ip route | grep default | awk '{print $5}' | head -n1); sudo tee -a wg0.conf <<EOF
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o $INTERFACE -j MASQUERADE
EOF

После этого, в конфигурационный файл добавляются клиенты:
[Peer]
PublicKey = uJWPI0zpKSB7C4G9LLdy4VMX2bPXs33g7nfdo2CVanw=
AllowedIPs = 10.10.10.30/32

PublicKey — публичный ключ клиента, которому принадлежит виртуальный адрес AllowedIPs, а маска /32 говорит о том, что это одиночный адрес хоста.

В итоге, конфигурационный файл wg0.conf должен иметь вид типа такого:

[Interface]
Address = 10.10.10.1/24

ListenPort = 21212

PrivateKey = qPSUFPcGiHUQkOo2RHPGWeb3XmSjfiSWqSMuPd3SnCs=

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE

[Peer]
PublicKey = uJWPI0zpKSB7C4G9LLdy4VMX2bPXs33g7nfdo2CVanw=
AllowedIPs = 10.10.10.30/32

[Peer]
PublicKey = YXnyogyq5930eFdueaFivCqpJCRMEmawJrpP1lcGEDc=
AllowedIPs = 10.10.10.20/32

где
PrivateKey — приватный ключ сервера
Address — виртуальный адрес сервера
ListenPort — порт сервера
PublicKey — публичный ключ клиента, которому принадлежит виртуальный адрес AllowedIPs из его секции [Peer]

Публичный ключ клиента можно получить в приложении клиента (например, Wireguard для Windows), где он будет случайно сгенерирован при добавлении нового «пустого» туннеля.

Добавляем туннель в автозагрузку и перезагружаемся:
sudo systemctl enable wg-quick@wg0

sudo reboot

Готово! Минимальная настройка завершена,

теперь введя в клиент публичный ключ сервера, внутренний IP-адрес клиента и внешний IP=адрес сервера с портом — можно пользоваться сетью. Теперь установим и настроим мониторинг Grafana для отслеживания сетевой активности по клиентам:

sudo tee /etc/apt/sources.list.d/grafana.list <<'EOF' deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main EOF

sudo mkdir -p /etc/apt/keyrings/

apt-get install gpg

wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null

sudo apt install -y prometheus grafana

sudo iptables -A INPUT -i wg0 -j ACCEPT

sudo iptables -A OUTPUT -o wg0 -j ACCEPT

curl https://sh.rustup.rs -sSf | sh

source $HOME/.cargo/env

sudo apt install cargo build-essential -y

cargo install clap --version 4.0.26

exec bash

cargo install prometheus_wireguard_exporter

vim /etc/prometheus/prometheus.yml

Заполнить файл следующим содержанием, строгое количество пробелов в началах строк!
scrape_configs:
- job_name: 'wireguard'
scrape_interval: 10s
static_configs:
- targets: ['localhost:9586']

Чтобы мониторинг запускался со стартом системы, создадим systemd-сервис:
vim /etc/systemd/system/wireguard-exporter.service

[Unit]
Description=Prometheus WireGuard Exporter
After=network-online.target

[Service]
ExecStart=/usr/bin/prometheus_wireguard_exporter —interfaces wg0
Restart=on-failure

[Install]
WantedBy=multi-user.target

sudo systemctl daemon-reload

sudo systemctl enable --now grafana-server

sudo systemctl enable --now wireguard-exporter.service

prometheus_wireguard_exporter --interfaces wg0 &>> /var/log/wireguard-exporter.log &

Проверка что всё работает:
jobs -l

Теперь можно зайти на веб-панель мониторинга, используя адрес своего сервера и порт 3000: http://your-server-ip:3000

Для первого входа используются стандартные логин и пароль admin

Мониторинг можно настроить в разделе «Dashboards». В режиме «edit» — включается сверху справа — выбираем Add — visualisation. Выбираем prometheus, адрес сервера вставляем дефолтный (http://localhost:9090) и save. Сохраняем дашборд под каким-нибудь названием и заходим в него через меню Dashboards. Удаляем все query и создаём новую, по кнопке + Add query. В поле Data source должен быть выбран prometheus. Справа — переключаемся в режим Code, если вдруг выбран Builder. Далее — в поле «Enter a PromQL query…» вставляем следующий запрос:
rate(wireguard_received_bytes_total[1m])

Нажимаем кнопку Run queries и сверху должен появиться график. Сохраняем дашборд справа сверху. Дальнейшая настройка вполне интуитивна. Чтобы переименовать графики — нужно прокрутить Panel options вниз до кнопки + Add field override, нажав на неё выбрать нужный график и переименовать его.

Для базовой защиты сервера от взлома — рекомендую утилиту fail2ban:
sudo apt install fail2ban -y

vim /etc/fail2ban/jail.local

Пример настройки файла конфигурации /etc/fail2ban/jail.local:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 7
bantime = 1h

sudo systemctl start fail2ban

sudo systemctl enable fail2ban

Далее — продвинутая конфигурация: переход на другую файловую систему, резервное копирование и моментальные снимки, восстановление из резервной копии, фильтрация нежелательного контента и правила для разных типов трафика.

Этап 1: Смена файловой системы и резервное копирование

Иногда случаются различные казусы, после которых возникает острое желание откатиться на некоторое время назад. В большинстве приложений — такой откат на одно последнее действие происходит комбинацией клавиш CTRL+Z, однако не всегда и не везде. В некоторых случаях — полезно иметь полную резервную копию всех данных. Лучше, когда она есть и не нужна, чем когда нужна и её нет.

Базовая файловая система Linux, EXT4 — не обладает функционалом снимков файловой системы — поэтому в первую очередь мы выполним переход на более продвинутую BTRFS

  1. Смотрим сколько есть места на сервере командой df -h. В моём примере сервер с 10ГБ диском.

  2. Свободное место делим чуть меньше чем пополам и с помощью parted создаём логический том под резервную копию

sudo apt install parted btrfs-progs -y

sudo parted /dev/sda

resizepart 1 → указываем новый размер: 4.8GB.

mkpart primary btrfs 4.8GB 100% → создаем /dev/sda2 из оставшегося места.

print → проверяем, что получилось.

q

sudo mkdir /mnt/btrfs_backup

sudo mount /dev/sda2 /mnt/btrfs_backup

Синхронизируем содержимое корневого раздела и резервного, без лишних каталогов (и удаляя всё лишнее в целевой директории):
sudo rsync -aAXv --delete --exclude={"/dev/","/proc/","/sys/","/tmp/","/run/","/mnt/","/media/*","/lost+found"} / /mnt/btrfs_backup/

sudo mkdir /mnt/btrfs_backup/{dev,proc,sys,tmp,run,mnt,media}

Подменяем разделы для загрузки с бэкапа — редактируем fstab:
sudo sed -i "| / |c UUID=$(sudo blkid -s UUID -o value /dev/sda2) / btrfs defaults,compress=zstd,noatime 0 1" /mnt/btrfs_backup/etc/fstab

И загрузчик grub:
sudo mount --bind /dev /mnt/btrfs_backup/dev

sudo mount --bind /proc /mnt/btrfs_backup/proc

sudo mount --bind /sys /mnt/btrfs_backup/sys

sudo chroot /mnt/btrfs_backup

update-grub

grub-install /dev/sda

exit

Теперь при следующей загрузке сервер запустится из резервной копии в разделе с файловой системой BTRFS.

sudo reboot

После перезагрузки, убедимся, что корень (/) находится на /dev/sda2 командой df -h, затем преобразуем /dev/sda1 в BTRFS:

sudo mkfs.btrfs -f /dev/sda1

sudo mkdir /mnt/sda1

sudo mount /dev/sda1 /mnt/sda1

mkfs преобразует файловую систему, не конвертируя данные, поэтому нам надо вернуть их обратно из резервной копии:
sudo rsync -aAXv --delete --exclude={"/dev/","/proc/","/sys/","/tmp/","/run/","/mnt/","/media/*","/lost+found"} / /mnt/sda1/

Снова правим GRUB, для загрузки в sda1:
sudo mount --bind /dev /mnt/sda1/dev

sudo mount --bind /proc /mnt/sda1/proc

sudo mount --bind /sys /mnt/sda1/sys

sudo chroot /mnt/sda1

update-grub

grub-install /dev/sda

exit

Перезагружаемся и актуализируем fstab
sudo reboot

sudo sed -i "s/^UUID=[^ ]* / btrfs/UUID=(blkid -s UUID -o value(findmnt -n -o SOURCE /)") / btrfs/" /etc/fstab

Восстановление из загрузочного меню GRUB RESCUE

Если по какой-то случайности система оказалась в нерабочем состоянии, разбираться в котором нет никакого желания — можно загрузиться в резервную копию через меню загрузчика GRUB.

Смотрим список доступных разделов:
ls

Проверяем список на наличие загрузочного сектора:
ls (hd0,gpt2)/boot/

Если вывод команды показывает файлы типа vmlinuz и initrd.img, значит, это корневой раздел. Для успешного восстановления — нужно выбрать корневой раздел с резервной копией.

Обычно, нумерация разделов такая же, как в операционке, а hd — это номер физического диска (нумерация с нуля)

Загрузка из этого раздела:
set root=(hd0,gpt2)

set prefix=(hd0,gpt2)/boot/grub

insmod normal

normal

После загрузки в резервный раздел — нужно вернуться к действию 5) и копировать резервную копию на основной раздел, а затем перезагрузиться в него (и fstab обновить).

Работа с моментальными снимками

Создадим первый:
sudo mkdir /snapshots

sudo btrfs subvolume snapshot / /snapshots/root_$(date +%Y-%m-%d_%H-%M)

Просмотр списка «быстрых сохранений»:
sudo btrfs subvolume list /

Откат системы к моментальному снимку

sudo btrfs subvolume set-default $(sudo btrfs subvolume list / | sort -n -k2 | tail -1 | awk '{print $2}') / && sudo reboot

— Эта команда выполняет откат к последнему снапшоту, после чего перезагружает систему.

Этап 2: Настройка конфигурации клиента и блокировка рекламы на уровне DNS

На стороне устройств, включённых в виртуальную частную сеть, (на стороне клиентов) выполняется следующая настройка конфигурации Wireguard:

  • Секция [Interface] относится к виртуальному интерфейсу клиента; ему нужно присвоить (или сгенерировать) приватный ключ подходящего формата (wireguard), публичный отпечаток которого вводится в конфигурацию на стороне сервера. Адрес — во внутренней сети, то бишь в VPN. А DNS — указываем от AdGuard, с блокировкой рекламы и вредоносных сайтов, и запасной от Google, как самый надёжный — к нему сервер будет обращаться только в случае недоступности первого (чего обычно тоже никогда не случается).

  • В секции [Peer] указывается публичный ключ нашего сервера, Endpoint — это IP-адрес сервера и его listenport; PersistentKeepalive — это время в секундах когда будет повторно выполнено рукопожатие для поддержания активного статуса подключения, а AllowedIPs — это список сетевых адресов, трафик до которых будет перенаправлен через VPN. Иными словами — если какой-то адрес не входит в диапазоны указанные в этом списке — то трафик до этого адреса не будет идти через VPN. Это может быть полезно, например, для внутренних ресурсов, доступ к которым может быть ограничен с удалённых серверов, или для минимизации задержки в онлайн-играх.

Чтобы «ограничить влияние» VPN на какие-либо сервисы, делаются три действия:

  1. определение сетевого адреса, используемого сервисом — проще всего это сделать с помощью поиска в Сети, поскольку разработчики обычно публикуют информацию о используемых адресах, либо с помощью анализаторов типа WireShark

  2. с помощью специального калькулятора (https://www.procustodibus.com/blog/2021/03/wireguard-allowedips-calculator/) нужно составить корректную строку для AllowedIPs

  3. ввести эту строку в секцию AllowedIPs в конфиге клиента (пира)

Пример конфигурации для клиента, с блокировкой рекламы и исключением сети 11.7.0.0/16:

[Interface]
PrivateKey = e3rmxdsBWO5pcHR4wRaQSiOJ9lrz7w8dALNIKeMUc0M=
Address = 10.10.10.99/24
DNS = 94.140.14.14, 8.8.8.8

[Peer]
PublicKey = Hp3gn3oQOHO2QBWSL0jlYVhrCSNh/HW3a/e+O1jR2Ts=
AllowedIPs = 0.0.0.0/5, 8.0.0.0/7, 10.0.0.0/8, 11.0.0.0/14, 11.4.0.0/15, 11.6.0.0/16, 11.8.0.0/13, 11.16.0.0/12, 11.32.0.0/11, 11.64.0.0/10, 11.128.0.0/9, 12.0.0.0/6, 16.0.0.0/4, 32.0.0.0/3, 64.0.0.0/2, 128.0.0.0/1
Endpoint = 2.21.189.131:33444
PersistentKeepalive = 60

Этап 3: фильтр HTTP рекламы Privoxy

Установим Privoxy и скачаем расширенные листы блокировок:
sudo apt update && sudo apt install privoxy -y

sudo wget -O /etc/privoxy/easylist https://easylist.to/easylist/easylist.txt && echo "filterfile easylist" | sudo tee -a /etc/privoxy/config && sudo systemctl restart privoxy && sudo systemctl enable privoxy

Для фильтрации всей остальной рекламы — рекомендую приложение uBlock в браузере клиента

Этап 4: правила для разных типов трафика (QoS)

Установим политики по умолчанию
sudo iptables -P INPUT ACCEPT

sudo iptables -P OUTPUT ACCEPT

sudo iptables -P FORWARD DROP

Разрешить форвард только для клиентов Wireguard:
sudo iptables -A FORWARD -i wg0 -o ens3 -j ACCEPT

sudo iptables -A FORWARD -i ens3 -o wg0 \ -m state --state RELATED,ESTABLISHED -j ACCEPT

Включить NAT для выхода в Интернет:
sudo iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE

Смарт-фильтр CAKE настраиваем на пропускную способность сети сервера (с указанием названия адаптера):
sudo tc qdisc replace dev ens3 root cake bandwidth 100mbit nat

Правила для игрового трафика:
sudo iptables -t mangle -A PREROUTING -i wg0 -p udp -m multiport --dports 27000:27100,3478:3479,4379:4380,3724,4000,5060:5062,6112:6119,6250,12000:64000 -j DSCP --set-dscp-class EF

sudo iptables -t mangle -A PREROUTING -i wg0 -p tcp -m multiport --dports 27015:27050,1119:1120,3074,3724,4000,6112:6120 -j DSCP --set-dscp-class EF

Голосовые и видеозвонки:
sudo iptables -t mangle -A PREROUTING -i wg0 -p udp --dport 3478:3481 -j DSCP --set-dscp-class EF

Видео-стриминг:
sudo iptables -t mangle -A PREROUTING -i wg0 -p tcp --dport 443 -m string --string "youtube" --algo bm -j DSCP --set-dscp-class AF21

Веб-трафик:
sudo iptables -t mangle -A PREROUTING -i wg0 -p tcp --dport 80,443 -j DSCP --set-dscp-class BE

Низкий приоритет для всего остального (например, торренты):
sudo iptables -t mangle -A PREROUTING -i wg0 -j DSCP --set-dscp-class CS1

команды iptables и tc не сохраняются при перезагрузке по умолчанию; чтобы конфигурация не потерялась при выключении сервера, используем дополнительные инструменты:
sudo apt-get install iptables-persistent -y

sudo iptables-save > /etc/iptables/rules.v4

vim /usr/local/bin/apply_qos.sh

sudo chmod +x /usr/local/bin/apply_qos.sh

vim /etc/systemd/system/qos.service

[Unit]
Description=Apply QoS rules
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/apply_qos.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

sudo systemctl enable qos.service

После успешной настройки — сделаем снапшот системы и выполним перезагрузку сервера, чтобы убедиться, что система устойчива к перезапускам:
sudo btrfs subvolume snapshot / /snapshots/root_$(date +%Y-%m-%d_%H-%M) && sudo reboot

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Ваше мнение о виртуальных частных сетях

88.89% Интернет — он как карнавал: выходить в Сеть без красивой маски — некультурно и небезопасно8
11.11% ВПН — как балаклава: только террорист станет прятать своё лицо1

Проголосовали 9 пользователей. Воздержавшихся нет.

ссылка на оригинал статьи https://habr.com/ru/articles/921736/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *