HomeLab как хобби

Содержание


  1. Введение
  2. Технологический стек
  3. Реализация
    1. Настройка Сервера Виртуализации
    2. Настройка VPS
    3. Настройка s_proxy2204
  4. Итоговая схема

1. Введение

Так уж получилось что современныве технологии несутся вперёд с огромной скоростью и постоянно предлагают нам, что то всё более новое и новое, в том числе что то, что можно в общем то использовать в быту и в повседневной жизни. Хорошим катализатором послужили технологии контейнеризации, в частности Docker, который можно сказать открыл ящик пандоры и сотни, тысячи энтузиастов, начали выкладывать сборки своих пет проектов или же серьёзных больших проектов, в виде Docker контейнеров. Эти контейнеры мог скачать себе любой желающий или же собрать на их основе свой контейнер и запустить без привязки к окружению, буквально несколькими командами.

На этой волне и я заинтересовался как это все работает и как сделать так что бы у меня то же был свой «сервер». Сначала это были арендованные VPS у разных поставщиков услуг, постепенно апетиты росли, сервисов становилось больше, необходимые ресурсы для работы всего и вся, так же увеличивались. Далее был арендован простенький выделенный сервер у одного известного хостера, тут уже можно было разгулятся «на все деньги», но это то же была временная схема, в планах уже маячил план по реализации «хоумлабы», домашнего сервера, который так же будет являтся стендом для опытов.

2. Технологический стек

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

Итак, у нас есть комплект:

Материнская плата Atermiter X79 Intel LGA 2011+ Xeon E5 2650 V2 (8 ядер/16 потока) +DDR3 16GB (2X8GB) 1600МГц REG ECC, какая-то чуда юдо затычка-видеокарта:

На данном этапе наш сервер уже запускается и проходит POST. Идём далее, корпус+старый(но надёжный БП)+SSD:

Наш сервер почти готов, далее нужно накатить туда ОС, я выбрал Ubuntu Server 22.04.03 LTS. Далее помещаем всё в нашу серверную:

Немного пожарной (паранои) безопасности:

Да над кабель менеджментом необходимо будет поработать. Далее я определил что буду использовать виртуализацию kvm+qemu. Мой сервер будет разбит на 5 виртуальных машин:

  1. s_proxy2204 — сервер, задача которого проксировать http\https запросы по назначению.
  2. s_web_app2204 — сервер с Apache web сервером на борту, обслуживает простенькие сайты и приложения, работающие без контйенеризации.
  3. s_docker2204 — сервер на котором будут крутится все Docker сервисы.
  4. s_k3s_master и s_k3s_node01 — два сервера, представляющих из себя кластер kubernetes, в данный момент вытсупают в качестве стенда для изучения kubernetes.

Для доступа к своему серверу из интернета, я буду использовать арендованную VPS, которая будет выполнять функции маршрутизатора, т.е. ретранслировать все запросы на 80 и 443 порты к моему серверу, а он в свою очередь будет маршрутизировать эти пакеты на прокси сервер s_proxy2204 с nginx на борту и только nginx будет знать куда слать пакеты дальше. Так же VPS будет маршрутизировать все пакеты для SSH сессий, с каждым из серверов, можно будет подключаться к каждому серверу извне.

Все SSH соединекния будут доступны только по сгенерированным RSA ключам. Авторизация по паролю будет отключена.

Соединять VPS и Сервер дома, будем через zerotier, сервис прост как в установке так и в использовании, пока что не был замечен в каких либо блокировках и ограничений, как со стороны владельцев сервиса так и со стороны различных регуляторов.

Звучит сложно! Так и есть. Сейчас попробуем разобраться.

3. Реализация

Настройка Сервера Виртуализации

Первым делом обновляем систему, ставим минимально необходимые пакеты, настраиваем SSH:

# apt update
# apt upgrade
# apt install mc
# nano /etc/ssh/sshd_config

# здесь мы включаем авторизацию по ключам и выключаем парольную авторизацию#

PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2
PasswordAuthentication no

# nano /etc/ssh/sshd_config.d/50-cloud-init.conf
PasswordAuthentication no

# генериуем ключевую пару#

# ssh-keygen -t rsa
# cd .ssh/
# cat id_rsa.pub >> ~/.ssh/authorized_keys
# chmod 600 ~/.ssh/authorized_keys
# cat id_rsa

#вывод последней комманды необходимо сохранить себе#

Установим kvm+qemu:

# apt install qemu-kvm virtinst libvirt-clients bridge-utils libvirt-daemon-system

Создадим каталог, где будут хранится диски наших VM, туда же положим скачанный образ из которого будут ставится все виртуалки:

# mkdir -p /vm-ssd/s_image/

Установим первую VM:

virt-install \
  --virt-type=kvm \
  --name s_proxy2204\
  --ram 2048 \
  --vcpus=2 \
  --os-variant=ubuntu22.04 \
  --hvm \
  --cdrom=/vm-ssd/ubuntu-22.04.3-live-server-amd64.iso \
  --network network=default,model=virtio \
  --graphics vnc \
  --disk path=/vm-ssd/s_images/s_proxy2204.qcow2,size=40,bus=virtio

Разбирать параметры установки мы не будем, во первых они легко гуглятся, во вторых на мой взгляд там всё понятно, далее нам нужно посмотреть на каком порту пошла установка ОС:

# virsh dumpxml s_proxy2204

<graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1'>
      <listen type='address' address='127.0.0.1'/>
    </graphics>

Порт — 5900. Этот же порт указываем при настройке VNC тунеля:

После запуска установки, подключаемся через VNC, предварительно подняв VNC over SSH тунель, не забываем добавить RSA ключ:

Я использую MobaXterm для подключения к серверам. Запускаем тунель, идём «Session» — «VNC», указываем Remote hostname 127.0.0.1 port 8888, подключаемся. Продолжаем установку машины в VNC сессии.

У меня уже была сохраненная конфигурация сети с предыдущего сервера, и здесь я применил её, в обычной ситуации ваша виртуальная машина получит адрес автоматически, единственное что нужно изменить forward mode=’route’ — должно быть так. Вам кроме forward mode ничего менять не нужно.

# virsh net-edit default
<network connections='5'>
  <name>default</name>
  <uuid>72019e0a-e92b-4f77-af2e-1b9f736596f8</uuid>
  <forward mode='route'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:89:80:fd'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
      <host mac='52:54:00:46:05:e7' name='s_proxy2204' ip='192.168.122.3'/>
      <host mac='52:54:00:d4:02:6b' name='s_docker2204' ip='192.168.122.5'/>
      <host mac='52:54:00:40:fe:b1' name='s_web_app2204' ip='192.168.122.6'/>
      <host mac='52:54:00:d4:e8:27' name='s_k3s_master' ip='192.168.122.7'/>
      <host mac='52:54:00:f7:56:d0' name='s_k3s_node01' ip='192.168.122.8'/>
    </dhcp>
  </ip>
</network>

После установки VM, применяем настройки сети, настраиваем автозапуск вм при старте хоста, запускаем вм:

# virsh net-destroy default
# virsh net-start default
# virsh shutdown s_proxy2204
# virsh autostart s_proxy2204
# virsh start s_proxy2204

Ставим и настраиваем zerotier:

# curl -s https://install.zerotier.com | sudo bash

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

# zerotier-cli join <номер сети zerotier>

Номер сети отображается в прфоиле в личном кабинете, далее все просто, подтверждаете в личном кабинете что этот клиент авторизован и всё, с этого момента все участники этой сети смогут обмениватсья пакетами и видеть друг друга как в локальной сети.

Далее настраиваем Форвардинг портов извне на виртуальную машину, порт 22 для подключения по SSH.

# nano /etc/ufw/before.rules

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

-A PREROUTING -i zth6rmcg4z -d 44.44.44.44 -p tcp -m tcp --dport 37023 -m comment --comment "nginx-proxy SSH" -j DNAT --to-destination 192.168.122.3:22
-A PREROUTING -i zth6rmcg4z -d 44.44.44.44 -p tcp -m tcp --dport 37025 -m comment --comment "s_docker2204 SSH" -j DNAT --to-destination 192.168.122.5:22
-A PREROUTING -i zth6rmcg4z -d 44.44.44.44 -p tcp -m tcp --dport 37026 -m comment --comment "s_web_app2204 SSH" -j DNAT --to-destination 192.168.122.6:22
-A PREROUTING -i zth6rmcg4z -d 44.44.44.44 -p tcp -m tcp --dport 37027 -m comment --comment "s_k3s_master SSH" -j DNAT --to-destination 192.168.122.7:22
-A PREROUTING -i zth6rmcg4z -d 44.44.44.44 -p tcp -m tcp --dport 37028 -m comment --comment "s_k3s_node01 SSH" -j DNAT --to-destination 192.168.122.8:22
-A PREROUTING -d 44.44.44.44/32 -p tcp -m multiport --dports 80,443 -m comment --comment "NGINX HTTP/HTTPS" -j DNAT --to-destination 192.168.122.3
-A OUTPUT -d 44.44.44.44/32 -p tcp -m tcp --dport 80 -m comment --comment "HOST to NGINX HTTP" -j DNAT --to-destination 192.168.122.3:80
-A OUTPUT -d 44.44.44.44/32 -p tcp -m tcp --dport 443 -m comment --comment "HOST to NGINX HTTPS" -j DNAT --to-destination 192.168.122.3:443
-A POSTROUTING ! -o lo -j MASQUERADE

COMMIT

Этими правилами мы сообщаем серверу что все пакеты прилетающие на указанные порты, указанного IP на интерфейсе zth6rmcg4 необходимо пересылать на такие то IP адреса, соответствубщие порты.

44.44.44.44 — это IP нашего сервера виртуализации который нам выдал zerotier, zth6rmcg4 — имя интерфейса который появится при установки zerotier. Остальное из комментариев в самих правилах должно быть понятно, пробрасываем SSH до виртуальных машин, так же пробрасываем 80,443 TCP порты.

Настроим фаервол для самого хоста:

# ufw allow 22/tcp comment 'SSH'
# nano /etc/default/ufw

DEFAULT_FORWARD_POLICY="ACCEPT"

# ufw route allow from 44.44.44.0/24 to any
# ufw route allow from any to 44.44.44.0/24
# nano /etc/sysctl.conf

net.ipv4.ip_forward=1

# ufw enable

Мы открыли порт для ssh, а так же разрешили маршрутизацию пакетов и подсети zerotier.

На этом базово настройка сервера виртуализации kvm+qemu закончена, остальные виртуальные машины ставятся аналогично. Далее настраиваются исходя из ваших потребностей.

Настройка VPS

Процесс покупки и выбора VPS, мы пропустим, открываем письмо от хостера и видим учтёные данные, заходим на VPS, сразу, обновляем систему, ставим минимально необходимые пакеты, настраиваем SSH:

# apt update
# apt upgrade
# apt install mc
# nano /etc/ssh/sshd_config

# здесь мы меняем порт SSH включаем авторизацию по ключам и выключаем парольную авторизацию#

Port 37337
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2
PasswordAuthentication no

# nano /etc/ssh/sshd_config.d/50-cloud-init.conf
PasswordAuthentication no

# генериуем ключевую пару#

# ssh-keygen -t rsa
# cd .ssh/
# cat id_rsa.pub >> ~/.ssh/authorized_keys
# chmod 600 ~/.ssh/authorized_keys
# cat id_rsa

#вывод последней комманды необходимо сохранить себе#

Моя основная рабочая система — Windows, поэтому опишу процесс создания ключа для неё, запускаем приложение PuTTYgen:

Жмём — Conversion — Import key, открываем сохраненный txt файл с содержимым команды — cat id_rsa, при необходимости можем поправить key comment, это просто комментарий для ключа, жмём — Save private key. Получим файл в формате ppk, этот файл мы будем указывать во всех менедждер ssh соединений для Windows. Теперь мы готовы, применить внесенные изменения, перезапускаем службу sshd:

# systemctl restart sshd

Указываем rsa ключ в нашем менеджере SSH (putty/moba/teraterm и т.д.) подклюаемся на новый порт по ключу и без пароля.

Ставим и настраиваем zerotier:

# curl -s https://install.zerotier.com | sudo bash

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

# zerotier-cli join <номер сети zerotier>

Номер сети отображается в прфоиле в личном кабинете, далее все просто, подтверждаете в личном кабинете что этот клиент авторизован и всё, с этого момента все участники этой сети смогут обмениватсья пакетами и видеть друг друга как в локальной сети.

Идём дальше, настраиваем в качестве маршрутизатора:

# nano /etc/ufw/before.rules

#Добавляем след строки сразу после окончания первого блока комментариев#
 
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

-A PREROUTING -i eth0 -d 111.111.111.111 -p tcp -m tcp --dport 37037 -m comment --comment "ninjalab" -j DNAT --to-destination 44.44.44.44:22

-A PREROUTING -i eth0 -d 111.111.111.111 -p tcp -m tcp --dport 37023 -m comment --comment "nginx-proxy SSH" -j DNAT --to-destination 44.44.44.44:37023
-A PREROUTING -i eth0 -d 111.111.111.111 -p tcp -m tcp --dport 37025 -m comment --comment "s_docker2204 SSH" -j DNAT --to-destination 44.44.44.44:37025
-A PREROUTING -i eth0 -d 111.111.111.111 -p tcp -m tcp --dport 37026 -m comment --comment "s_web_app2204 SSH" -j DNAT --to-destination 44.44.44.44:37026
-A PREROUTING -i eth0 -d 111.111.111.111 -p tcp -m tcp --dport 37027 -m comment --comment "s_k3s_master SSH" -j DNAT --to-destination 44.44.44.44:37027
-A PREROUTING -i eth0 -d 111.111.111.111 -p tcp -m tcp --dport 37028 -m comment --comment "s_k3s_node01 SSH" -j DNAT --to-destination 44.44.44.44:37028
-A PREROUTING -d 111.111.111.111/32 -p tcp -m multiport --dports 80,443 -m comment --comment "NGINX HTTP/HTTPS" -j DNAT --to-destination 44.44.44.44
-A POSTROUTING ! -o lo -j MASQUERADE

COMMIT

111.111.111.111 — это белый IP нашей VPS, 44.44.44.44 — это IP сервера дома который нам выдаст zerotier. Остальное из комментариев в самих правилах должно быть понятно, пробрасываем SSH до сервера дома, где аналогичная табличка будет маршрутизировать их дальше до виртуальных машин, так же пробрасываем 80,443 TCP порты.

Настроим фаервол для самого хоста:

# ufw allow 37337/tcp comment 'SSH'
# nano /etc/default/ufw

DEFAULT_FORWARD_POLICY="ACCEPT"

# ufw route allow in on zth6rmcg4z out on eth0 from 44.44.44.0/24
# ufw route allow in on eth0 out on zth6rmcg4z to 44.44.44.0/24
# nano /etc/sysctl.conf

net.ipv4.ip_forward=1

# ufw enable

Мы открыли порт для ssh, а так же разрешили маршрутизацию пакетов и подсети zerotier.

На этом базово настройка сервера VPS закончена.

Настройка s_proxy2204

Теперь у нас есть VPS с белым IP адресом на который мы сможем делегировать настройки нашего DNS и привязать свой домен. Самое время настроить обратный прокси, который сможет обрабатывать запросы и доставлять их адресатам. Этот сервер с nginx будет точкой входа ко всем нашим сервисам и приложениям.

Как и всегда, ставим обновления системы, ставим необходимые пакеты, nginx, certbot:

# apt update
# apt upgrade
# apt install nginx
# apt install python3-certbot-nginx

Настроим wildcard ssl сертификат для нашего домена — example.ru

certbot certonly --manual --preferred-challenges=dns --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d *.example.ru

certbot попросит внести txt запись в DNS зону, для подтверждение владения доменом, вносим txt запись:

Запись, обновляется не сразу, примерно за час, записи в зонах DNS обновятся, прогресс можно будет проверить в сервисах гугл, ссылка на проверку будет в выдаче certbot’а. После того как запись обновится, продолжаем генерацию SSL сертификата. Если TXT запись прошла проверку, то мы получим wildcard ssl сертификат для всех доменов 3-го уровня example.ru.

Let’s encrypt выдаёт сертификаты на 90 дней, ставим в cron автоматическое обновление сертификата, каждые 85 дней:

# crontab -e
0 0 */85 * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"

В nginx делаем конфиг файл для нашего сайта, на другом сервере, для примера сайт будет распологаться на домене 3-го уровня:

# nano /etc/nginx/sites-available/sample.example.ru.conf
server {
        listen      80;
        server_name sample.example.ru;

        return 301 https://$host$request_uri;
}

server {
        listen      443 ssl http2;
        server_name sample.example.ru;

        access_log  /var/log/sample.example.ru.ssl.access.log;
        error_log   /var/log/sample.example.ru.ssl.error.log;

        ssl_certificate /etc/letsencrypt/live/example.ru-0001/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.ru-0001/privkey.pem;

        location / {
                proxy_pass   http://192.168.122.6;
                proxy_set_header HOST $host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_http_version      1.1;
                proxy_set_header        Upgrade $http_upgrade;
                proxy_set_header        Connection 'upgrade';
                proxy_cache_bypass      $http_upgrade;
                add_header X-Frame-Options SAMEORIGIN;
                add_header X-Content-Type-Options nosniff;
                add_header X-XSS-Protection "1; mode=block";
                add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
                add_header Referrer-Policy "strict-origin";
                add_header Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()";
                client_max_body_size 0;
                proxy_buffers  16 32k;
                proxy_buffer_size 64k;
                proxy_connect_timeout 600s;
                proxy_send_timeout    600s;
                proxy_read_timeout    600s;
                send_timeout          600s;
                server_tokens   off;
        }

}
# nginx -t
# ln -s /etc/nginx/sites-available/sample.example.ru.conf /etc/nginx/sites-enabled/sample.example.ru.conf
# systemctl restart nginx

Это базовый файл конфигурации для сайта с адресом — sample.example.ru, который распологается на сервере с адресом 192.168.122.6. От приложения к приложению конфигурация может отличать, в зависимости от требований.

4. Итоговая схема

Итак, у нас есть VPS с белым IP, есть тунель на основе zerotier который соединяет нашу VPS с сервером виртуализации, находящимся у нас в квартире, мы научили пересылать все запросы 80 и 443 TCP к белому IP VPS, на наш сервер виртуализации через сеть zerotier, а сервер виртуализации научили пересылать эти запросы дальше на виртуальный сервер с NGINX reverse proxy. Таким образом мы выставили в мир, необходимые нам приложения и сайты. Моя реальная схема выглядит следующим образом:

Здесь схема, несколько перегружена, нас интересует два блока слева — VPS Entrypoint и HomeLab, всё что мы настроили и прописывали на схеме указано и указано взаимодействие сущностей друг с другом. Вот так легко и просто можно нарисовать сову поднять свой сервер дома!

1 комментарий к “HomeLab как хобби”

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