Featured image of post Установка сервера Headscale для построения виртуальной сети

Установка сервера Headscale для построения виртуальной сети

С помощью Docker будем устанавливать Headscale, Headscale-admin(панель управления) и Caddy (обратный прокси-сервер)

Проект Headscale реализует открытый серверный компонент виртуальной сети Tailscale, который позволяет создавать сети, схожие с Tailscale, без привязки к сторонним сервисам. Код Headscale написан на языке Go и распространяется под лицензией BSD.

Tailscale позволяет объединить любое количество территориально разнесённых хостов в одну сеть, построенную по образу mesh-сети, в которой каждый узел взаимодействует с другими узлами напрямую (P2P) или через соседние узлы, без передачи трафика через централизованные внешние серверы VPN-провайдера. Поддерживается управление доступом и маршрутами на основе ACL. Для установки каналов связи в условиях применения трансляторов адресов (NAT) предоставляется поддержка механизмов STUN, ICE и DERP (аналог TURN, но на базе HTTPS). В случае блокировки канала связи между определёнными узлами сеть может перестраивать маршрутизацию для направления трафика через другие узлы.

Схема работы Tailscale(Headscale)

Список задач которые я хочу закрыть с помощью Headscale и Caddy:

  1. Объединение нескольких локальных сетей в разных городах и возможность подключения к виртуальной сети из интернета
  2. Подключение “Exit Node” позволяет перенаправлять трафик клиента через этот узел, что дает возможность получить доступ к заблокированным ресурсам, таким как YouTube, сайты торрентов и другие
  3. С помощью Caddy будет возможность публиковать свои сервисы из локальной сети в интернет

Для установки Headscale нам понадобится сервер с белым IP (я использую бесплатный сервер от Cloud.ru тариф Free tier, бесплатный с оговоркой :grin: за белый IP нужно будет платить 150р/м) и доменное имя (в моём случае test-headscale.31bel.ru).

Сервер с белым IP нам нужен для построения связей между нодами в разных (локальных) сетях как показано на схеме работы Tailscale(Headscale) выше :point_up:

Пишем файл Docker Compose

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

docker --version
docker compose version

Если не установлен то его необходимо установить. Docker желательно устанавливать всегда по официальной документации из Docker.Docs. Так же устанавливаем Docker Compose командой:

sudo apt install docker-compose

И не забываем после установки настроить управление Docker от имени пользователя без полномочий root.

Нам нужно создать каталог, в котором будут храниться конфигурации и данные Headscale и Caddy.

mkdir -p docker/caddy/config docker/headscale/config

Переходим в наш каталог docker и создаём новый файл с именем docker-compose.yml

cd docker
nano docker-compose.yml

Вставляем и сохраняем приведенное ниже содержимое:

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: always
    stdin_open: true
    tty: true
    volumes:
      - ./caddy/data:/data
      - ./caddy/config:/config
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 80:80
      - 443:443
    entrypoint: /usr/bin/caddy run --adapter caddyfile --config /config/Caddyfile
    networks:
      - headscale-nw

  headscale:
    image: headscale/headscale:latest
    restart: unless-stopped
    container_name: headscale
    volumes:
      - ./headscale/config:/etc/headscale
      - ./headscale/data:/var/lib/headscale
    command: serve
    depends_on:
      - caddy
    networks:
      - headscale-nw

  headscale-admin:
    image: goodieshq/headscale-admin:latest
    container_name: headscale-admin
    restart: unless-stopped
    depends_on:
      - caddy
    networks:
      - headscale-nw

networks:
  headscale-nw:
    external: true

В файле docker-compose.yml мы определили сеть в docker, внутри которой будут доступны друг для друга наши контейнеры, и для её создания необходимо выполнить команду

docker network create headscale-nw

название сети headscale-nw и проверить что она создалась

docker network create ls

Давайте создадим файлы с настройками для каждого из контейнеров.

Caddy

На данный момент мы находимся в каталоге ~/docker/ и нам нужно создать файл Caddyfile в каталоге ./caddy/config

nano ./caddy/config/Caddyfile

Вставляем и сохраняем приведенное ниже содержимое:

https://test-headscale.31bel.ru {
    reverse_proxy /admin* headscale-admin:80
    reverse_proxy * headscale:8080
}
  • Первая строка файла это адрес нашего доменного имени.

Для того что бы наш домен третьего уровня (в нашем случае) понимал на какой сервер ему нужно ссылаться нам необходимо добавить A-запись в DNS у регистратора нашего домена, нужно выполнить следующие шаги:

  1. Войдите в панель управления вашим регистратором доменов.
  2. Найдите раздел “DNS” или “Домены”.
  3. Выберите домен, для которого вы хотите добавить A-запись.
  4. Нажмите на кнопку “Добавить запись”.
  5. Введите тип записи “A” и введите IP-адрес сервера, который вы хотите связать с этим доменным именем.
  6. Введите имя для этой записи (например, “@”, “www”, “mail” и т.д.).
  7. Нажмите на кнопку “Сохранить” или “Применить”. После выполнения этих шагов, ваша A-запись будет добавлена в DNS вашего регистратора доменов.

Пример как это выглядит у меня:

Добавление А-записи в DNS

  • Вторая строка будет редиректить все запросы test-headscale.31bel.ru/admin* в наш контейнер с панелью управления по адресу headscale-admin:80
  • Третья строка так де как и вторая редиректит все запросы test-headscale.31bel.ru/* в наш контейнер с приложение headscale по адресу headscale:8080

Настройку Caddy закончили. В Caddy можно ещё настроить basic_auth как дополнительную защиту для панель управления.

Пример Caddyfile c basic_auth:

https://test-headscale.31bel.ru {
   reverse_proxy /admin* headscale-admin:80
   basic_auth /admin/* {
               # Username "Bob", password "hiccup"
               Bob $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR7hx4IjWJPDhjvG
       }
   reverse_proxy * headscale:8080
}

Пример был взят с официальной документации Caddy. В комьюнити находил информацию что можно привязать двухфакторную аутентификацию (two-factor, 2FA), если у меня получится то обязательно опишу как это сделать.

Headscale

Нам понадобится шаблон конфигурационного файла Headscale который мы скачаем с официального репозитория

wget https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml -O headscale/config/config.yaml

Теперь нам необходимо его отредактировать:

nano headscale/config/config.yaml

Для базовой настройки и запуска нам необходимо привести несколько строк к виду:

  1. В параметр server_url вписать адрес нашего доменного имени
#server_url: http://127.0.0.1:8080
server_url: https://test-headscale.31bel.ru
  1. Параметр listen_addr отвечает на то с каких адресов будет доступ за пределами контейнера (0.0.0.0 это все IP-адреса)
# For production:
listen_addr: 0.0.0.0:8080
#listen_addr: 127.0.0.1:8080

Headscale готов к работе, настроек для headscale-admin делать не нужно.

Запускаем файл Docker Compose

С помощью pwd проверяем что мы находимся в каталоге ~/docker и запускает

docker compose up -d

Ключ -d в команде отвечает за запуск контейнеров в фоновом режиме.

Проверяем состояние созданных контейнеров:

docker compose ps

Docker ps

Если STATUS равен UP на всех контейнерах то всё хорошо. Так же можно посмотреть логи по каждому контейнеру в реальном времени с помощью команды:

docker logs --follow headscale
docker logs --follow caddy

Для проверки работоспособности можно в браузере открыть страницу https://test-headscale.31bel.ru/windows

headscale: Windows configuration

Ну или сразу открыть панель управления по адресу https://test-headscale.31bel.ru/admin/

Headscale-admin - Панель управления

Страница открывается по https с действующим сертификатом от Let’s Encrypt благодаря Caddy.

Работа с Headscale-admin

Для входа в панель управления нам нужен API ключ, возвращаемся в консоль и вводим команду:

docker exec headscale headscale apikeys create

Но желательно использовать команду :point_up: с дополнительным ключом –expiration 30d который ограничит действие ключа по времени (для безопасности).

Получаем ключ копируем его и вводим в поле API Key нашей панели управления и кнопку Save.

Headscale-admin - Панель управления

Теперь нам необходимо создать пользователя, переходим в раздел Users, нажимаем кнопку Create, вводим имя пользователя user1 и нажимаем Enter.

Но все это можно сделать через консоль с помощью команды:

docker exec headscale headscale users create user2

Headscale-admin - Панель управления - Users

Пользователь у нас есть теперь нам нужно сгенерировать ключ для регистрации новых нод, в разделе Users нажимаем на нашего пользователя и в поле PreAuth Keys нажимаем кнопку Create, ставим галки Ephemeral и Reusable, в поле с датой выбираем сколько наш ключ будет действовать и нажимаем на кнопку галки в кружке.

Headscale-admin - Панель управления - PreAuth Keys

Headscale-admin - Панель управления - PreAuth Keys

Это так же можно сделать командой:

docker exec headscale headscale --user user1 preauthkeys create --reusable --expiration 24h

Headscale-admin - Панель управления - PreAuth Keys

Теперь нам нужно собрать команду для регистрации новой ноды, переходим в раздел Deploy, ставил галку на PreAuth Key, выбираем пользователя user1 и выбираем созданный ранее ключ и получаем команду

tailscale up --login-server=https://test-headscale.31bel.ru --authkey=cfffb6dcc4e16ed6a5c41946c25ba1f9b65da15e5fbcbeb9 --accept-dns=false

Переходим к установки и настройке клиента.

Установка клиента Tailscale на MacOS

Скачиваем клиент с сайта Tailscale, устанавливаем, запускаем и в настройках даём разрешения для приложения в системе. В трее появилась иконка приложения Tailscale нажимаем на неё правой кнопкой и выбираем Settings… переходим в раздел Settings, находим пункт CLI integration, нажимаем на кнопку Show me how и нажимаем кнопку Install.

Клиент Tailscale для MacOS

Далее открываем терминал и вводим нашу заготовленную команду.

Клиент Tailscale для MacOS Готово.

Установка клиента Tailscale на Android

Приложение устанавливаем через Google Play название Tailscale, запускаем, в верхнем правом углу нажимаем на шестеренку, выбираем Accounts, в верхнем правом углу нажимаем три точки, выбираем пункт Use an alternate server, вводим на адрес сервера Headscale и нажимаем кнопку Add account.

Клиент Tailscale для Android

Открывается страница с командой для регистрации.

Клиент Tailscale для Android

Набираем эту команду в консоли сервера Headscale:

docker exec headscale headscale nodes register --user user1 --key mkey:b3e480a96dc88d2fe3a765514535eaf4df6ee31e633c1839613fc635c6c47977

Клиент Tailscale для Android

Exit Node

Имеется VPS за пределами, на нём Ubuntu, для установки клиента Tailscale на VPS вводим команды:

curl -fsSL https://tailscale.com/install.sh | sh

После установки нужно включить IP forwarding.

Если в вашей системе Linux есть /etc/sysctl.d каталог, используйте:

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

В противном случае используйте:

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf

В панели управления headscale подготавливаем команду для регистрации нового клиента. Выбираем пункты: PreAuth Key (Пользователя, Ключ), Advertise Exit Node (Говорим что этот клиент будет выступать в роли Exit Node), Accept DNS(Применять настройки DNS, предоставленные headscale).

Копируем получившеюся команду на наш VPS:

tailscale up --login-server=https://test-headscale.31bel.ru --authkey=362fefafd382f2f0b9d5f752f8dc110ef88062034c95124f --advertise-exit-node --accept-dns

Регистрация клиента на VPS

Теперь нам нужно вернуться в консоль нашего сервера где установлен headscale и включить Exit Node, необходимо посмотреть routes list командой:

docker exec headscale headscale routes list

routes list

Видим что зарегистрированный VPS появился в списке но Enabled = false, нужно это исправить.

docker exec headscale headscale routes enable -r 1
docker exec headscale headscale routes enable -r 2

routes list

Теперь возвращаемся в клиент который на Android или Mac, в списке Exit node видим наш VPS, если мы его выберем то наш трафик пойдет через VPS, наш ip сменится и заработаю нужные сайты.

Готово.

DNS

Из последних скриншотов в macos и android видим домен example.com, это внутренний домен который можно изменить на свой например home.local в конфигурационном файле (headscale/config/config.yaml) headscale, параметр base_domain в разделе DNS.

Параметр base_domain в разделе DNS

Так же в разделе DNS есть параметр extra_records с помощью которого можно записывать свои записи A для использовании их внутри сети, пример:

Параметр extra_records в разделе DNS

Изучайте официальную документацию на сайте headscale и создавайте свою виртуальную сеть, удачи.

Built with Hugo
Theme Stack designed by Jimmy