Не удается получить доступ к услугам в моей локальной сети через Wireguard, используя Caddy и Docker.

Вопрос или проблема

Архитектура

Системная архитектура

Проблема

Я хочу получить доступ к своим сервисам, размещенным в моей локальной сети (192.168.1.0/24), через мой домен (example.com). В данный момент я могу получить доступ к сервису Wireguard UI, размещенному на VPS (wgui.example.com), но не могу получить доступ к ни одному из моих сервисов, находящихся в локальной сети.

Если это не обязательно, например, для Vaultwarden, я бы хотел завершить TLS на VPS и общаться по HTTP через туннель Wireguard до шлюзевой машины.

Конфигурация

Wireguard

# VPS Wireguard Server wg0.conf

[Interface]
Address = 10.1.10.1/24
ListenPort = 51820
PrivateKey = (Приватный ключ сервера)
MTU = 1450
PostUp = /opt/wireguard-ui/postup.sh
PreDown =
PostDown = /opt/wireguard-ui/postdown.sh
Table = auto

[Peer]
PublicKey = (Публичный ключ клиента)
PresharedKey = (Клиентский PSK)
AllowedIPs = 10.1.10.3/32
PersistentKeepalive = 15  
# Wireguard UI postup.sh

!/usr/bin/bash
# /opt/wireguard-ui/postup.sh
sysctl -w net.ipv4.ip_forward=1
ufw route allow in on wg0 out on enp1s0
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A FORWARD -o wg0 -j ACCEPT
iptables -t nat -I POSTROUTING -o enp1s0 -j MASQUERADE
# Wireguard UI postdown.sh

#!/usr/bin/bash
# /opt/wireguard-ui/postdown.sh
sysctl -w net.ipv4.ip_forward=0
ufw route delete allow in on wg0 out on enp1s0
iptables -D FORWARD -i wg0 -j ACCEPT
iptables -D FORWARD -o wg0 -j ACCEPT
iptables -t nat -D POSTROUTING -o enp1s0 -j MASQUERADE
# Gateway Wireguard Client wg0.conf

[Interface]
Address = 10.1.10.3/24
PrivateKey = (Приватный ключ клиента)
MTU = 1450

[Peer]
PublicKey = (Публичный ключ сервера)
PresharedKey = (Клиентский PSK)
AllowedIPs = 0.0.0.0/0
Endpoint = 123.456.7.890:51820
PersistentKeepalive = 15

Caddy

# VPS Caddyfile

example.com {

    root * /usr/share/caddy

}

import sites-enabled/*
# VPS Caddy wgui config

wgui.example.com {
        reverse_proxy :5000

        handle_errors {
                respond "{err.status_code} {err.status_text}"
        }
}

www.wgui.example.com {
        redir https://wgui.example.com{uri}
}
# VPS Caddy pihole config

pihole.example.com {
    reverse_proxy 10.1.10.3
}

www.pihole.example.com {
    redir https://pihole.example.com{uri}
}
# Gateway Caddy pihole config

pihole.example.com {
    reverse_proxy 192.168.1.20:1010
}

Sysctl

# Gateway sysctl.conf

# Раскомментируйте следующую строку, чтобы включить пересылку пакетов для IPv4
net.ipv4.ip_forward=1

Устранение неисправностей

Когда я пытаюсь получить доступ к pihole.example.com, я получаю ошибку 403 Forbidden.

Соединение Wireguard

# VPS wg show

interface: wg0
  public key: (Публичный ключ сервера)
  private key: (скрыто)
  listening port: 51820

peer: 59mOhf8SBmD3tZFDUescxXRu219NP2kkpBY92Bk/XHo=
  preshared key: (скрыто)
  endpoint: (Публичный IP клиента):7615
  allowed ips: 10.1.10.3/32
  latest handshake: 1 minute, 38 seconds ago
  transfer: 2.33 MiB received, 7.20 MiB sent
  persistent keepalive: every 15 seconds

IP Tables

# VPS iptables -L -n

цепочка INPUT (policy DROP)
target     prot opt source               destination         
ufw-before-logging-input  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-before-input  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-after-input  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-after-logging-input  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-reject-input  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-track-input  all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка FORWARD (policy DROP)
target     prot opt source               destination         
ufw-before-logging-forward  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-before-forward  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-after-forward  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-after-logging-forward  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-reject-forward  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-track-forward  all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ufw-before-logging-output  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-before-output  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-after-output  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-after-logging-output  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-reject-output  all  --  0.0.0.0/0            0.0.0.0/0           
ufw-track-output  all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-after-forward (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-after-input (1 ссылка)
target     prot opt source               destination         
ufw-skip-to-policy-input  udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:137
ufw-skip-to-policy-input  udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:138
ufw-skip-to-policy-input  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:139
ufw-skip-to-policy-input  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:445
ufw-skip-to-policy-input  udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:67
ufw-skip-to-policy-input  udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:68
ufw-skip-to-policy-input  all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type BROADCAST

Цепочка ufw-after-logging-forward (1 ссылка)
target     prot opt source               destination         
LOG        all  --  0.0.0.0/0            0.0.0.0/0            limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "

Цепочка ufw-after-logging-input (1 ссылка)
target     prot opt source               destination         
LOG        all  --  0.0.0.0/0            0.0.0.0/0            limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "

Цепочка ufw-after-logging-output (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-after-output (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-before-forward (1 ссылка)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 3
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 11
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 12
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 8
ufw-user-forward  all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-before-input (1 ссылка)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ufw-logging-deny  all  --  0.0.0.0/0            0.0.0.0/0            ctstate INVALID
DROP       all  --  0.0.0.0/0            0.0.0.0/0            ctstate INVALID
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 3
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 11
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 12
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 8
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp spt:67 dpt:68
ufw-not-local  all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     udp  --  0.0.0.0/0            224.0.0.251          udp dpt:5353
ACCEPT     udp  --  0.0.0.0/0            239.255.255.250      udp dpt:1900
ufw-user-input  all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-before-logging-forward (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-before-logging-input (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-before-logging-output (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-before-output (1 ссылка)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ufw-user-output  all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-logging-allow (0 ссылок)
target     prot opt source               destination         
LOG        all  --  0.0.0.0/0            0.0.0.0/0            limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW ALLOW] "

Цепочка ufw-logging-deny (2 ссылки)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            ctstate INVALID limit: avg 3/min burst 10
LOG        all  --  0.0.0.0/0            0.0.0.0/0            limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "

Цепочка ufw-not-local (1 ссылка)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type MULTICAST
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type BROADCAST
ufw-logging-deny  all  --  0.0.0.0/0            0.0.0.0/0            limit: avg 3/min burst 10
DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-reject-forward (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-reject-input (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-reject-output (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-skip-to-policy-forward (0 ссылок)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-skip-to-policy-input (7 ссылок)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-skip-to-policy-output (0 ссылок)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-track-forward (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-track-input (1 ссылка)
target     prot opt source               destination         

Цепочка ufw-track-output (1 ссылка)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            ctstate NEW
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            ctstate NEW

Цепочка ufw-user-forward (1 ссылка)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-user-input (1 ссылка)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:51820
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 /* 'dapp_OpenSSH' */
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:443

Цепочка ufw-user-limit (0 ссылок)
target     prot opt source               destination         
LOG        all  --  0.0.0.0/0            0.0.0.0/0            limit: avg 3/min burst 5 LOG flags 0 level 4 prefix "[UFW LIMIT BLOCK] "
REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Цепочка ufw-user-limit-accept (0 ссылок)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

Цепочка ufw-user-logging-forward (0 ссылок)
target     prot opt source               destination         

Цепочка ufw-user-logging-input (0 ссылок)
target     prot opt source               destination         

Цепочка ufw-user-logging-output (0 ссылок)
target     prot opt source               destination         

Цепочка ufw-user-output (1 ссылка)
target     prot opt source               destination   
# Gateway iptables -L -n

цепочка INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     0    --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     1    --  0.0.0.0/0            0.0.0.0/0           

Цепочка FORWARD (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     0    --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     0    --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     0    --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     1    --  0.0.0.0/0            0.0.0.0/0           

Цепочка OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Ping

  • Я могу ping 10.1.10.3 с машины VPS.
  • Я могу ping 192.168.20 на шлюзевой машине, но не с машины VPS.

Curl

Если я запускаю curl -I http://192.168.1.20/admin на шлюзевой машине, я получаю:

HTTP/1.1 308 Permanent Redirect
Connection: close
Location: https://192.168.1.20/admin
Server: Caddy
Date: Mon, 25 Nov 2024 05:55:33 GMT

Не могли бы вы помочь мне понять, где я ошибаюсь?

Во-первых, в конфигурации вашего сервера вам необходимо включить 192.168.1.0/24 дополнительно в AllowedIPs= в секции [Peer] для Pi.

Кроме того, на вашем Pi также должно быть включено перенаправление IP (sysctl) и разрешено (файрвол) соответственно.

И последнее, но не менее важное, ваши устройства в локальной сети должны иметь маршрут, который использует Pi в качестве шлюза для вашей подсети VPN (например, 10.1.10.0/24 via 192.168.1.10). В противном случае, Pi придется делать маскарад / исходный NAT для подсети VPN (так чтобы трафик оттуда выглядел так, будто он исходит от Pi к устройствам в локальной сети).

Ответ или решение

Решение проблемы доступа к локальным сервисам через Wireguard с использованием Caddy и Docker

Введение

Ваша конфигурация сети включает в себя использование Wireguard для создания защищенного VPN-туннеля между вашим VPS и локальной сетью. Ваша основная проблема заключается в невозможности доступа к локальным сервисам (192.168.1.0/24) через домен, что приводит к ошибкам, таким как 403 Forbidden. Давайте подробно рассмотрим архитектуру системы и выявим возможные недостатки в конфигурации.

Архитектура

Ваше решение состоит из следующих компонентов:

  1. VPS с Wireguard и Caddy – обеспечивает проксирование запросов к локальным сервисам.
  2. Локальная сеть – включает в себя различные сервисы, такие как Pi-hole и другие, и настроена на работу по адресу 192.168.1.0/24.
  3. Клиент Wireguard на шлюзе – используется для подключения к Wireguard-серверу.

Анализ конфигурации

Подключение Wireguard

Ваши конфигурации Wireguard на VPS и локальном шлюзе могут не обеспечивать необходимую маршрутизацию:

  1. AllowedIPs в конфигурации VPS:

    • В секции [Peer], где указаны допустимые IP-адреса для клиента, вам нужно добавить диапазон 192.168.1.0/24. Это позволит маршрутизировать трафик из вашей локальной сети через VPN:
      AllowedIPs = 10.1.10.3/32, 192.168.1.0/24
  2. Включение перенаправления IP:

    • Убедитесь, что в ваших системных настройках (sysctl) на шлюзе разрешено перенаправление IP:
      net.ipv4.ip_forward=1
    • На VPS это уже настроено в скрипте postup.sh.
  3. Фильтрация и маскарад:

    • Убедитесь, что маскарад (source NAT) настроен правильно. Это позволит трафику из вашего VPN выглядеть так, как будто он идет с IP-адреса вашего шлюза. В вашем iptables правилах на VPS вы уже добавили маскарад, но следует проверить, правильно ли он подходит для ожидаемого трафика.

Настройки Caddy

Правила для Caddy на VPS и шлюзе имеют значение:

  1. Конфигурация Caddy на VPS:

    • Проверьте, что ваши блоки конфигурации содержат правильные целевые URL-адреса. Убедитесь, что адреса, на которые вы ссылаетесь, соответствуют IP-адресам, предоставляемым вашим шлюзом.
    • В секции для Pi-hole попробуйте изменить reverse_proxy 10.1.10.3 на reverse_proxy 192.168.1.20:1010, если Pi-hole развернут на этом IP-адресе.
  2. Гateway Caddy:

    • Убедитесь, что Caddy на шлюзе правильно проксирует запросы на IP адреса ваших сервисов. Например, проверьте, что прокси блок для Pi-hole правильно обрабатывает переходы на 192.168.1.20:1010.

Тестирование

  1. Проверка соединений:

    • Ваши тесты с ping и curl показывают, что соединение между VPS и шлюзом работает, но трафик между VPS и локальными сервисами не проходит. Проверьте, что локальные сервисы действительно доступны по указанным IP.
    • Выполните curl -I http://192.168.1.20/admin на шлюзе, как вы уже делали. Получение ответа 308 говорит о том, что запрос редиректится на HTTPS. Если ваше окружение не поддерживает HTTPS на этом сервисе, временно отключите его для диагностики.
  2. Маршрутизирование локальных адресов:

    • Проверьте маршруты маршрутизаторов вашей локальной сети. Если хосты в локальной сети не знают, как добраться до вашей VPN-сети, вам понадобится настроить маршрут на каждом из них, чтобы они «знали», что трафик к 10.1.10.0/24 должен проходить через адрес 192.168.1.10 (адрес шлюза).

Заключение

После внесения описанных изменений вы должны добиться улучшения доступа к услугам на локальной сети через ваш VPS. Следите за маршрутами и правилами брандмауэра, проверяйте протоколы IP и убедитесь, что ваши локальные сервисы настроены для обработки HTTPS и HTTP звонков корректно. Помните, успешная настройка требует тестирования, поэтому не стесняйтесь пробовать различные конфигурации до достижения результатов.

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

Капча загружается...