Docs/docs/services/lxc201-gateway/Coredns.md

11 KiB
Raw Blame History

Руководство по настройке локального DNS-сервера на CoreDNS

Версия: 1.0 Дата: 28.05.2026 Цель: Настройка сервера имен для локальных сервисов (домен .zailon.ru) с возможностью работы при отсутствии интернета.

Введение

CoreDNS — это гибкий DNS-сервер, написанный на Go. В данной инструкции мы настраиваем его как Docker-контейнер. Он будет выполнять две функции:

  1. Отдавать локальные IP-адреса для сервисов внутри домена zailon.ru.
  2. Перенаправлять (форвардить) все остальные запросы (например, google.com) на публичные DNS.

Требования

  • Сервер Ubuntu 24.04 (или аналогичный Linux).
  • Установленный Docker и Docker Compose.
  • Статический IP-адрес сервера (в примере: 192.168.1.201).
  • Права пользователя root.

Шаг 1: Подготовка файловой структуры

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

mkdir -p /opt/coredns/zones

Шаг 2: Освобождение порта 53 на хосте

По умолчанию в Ubuntu сервис systemd-resolved "слушает" порт 53 на локальном интерфейсе. Это не даст CoreDNS запуститься. Нужно отключить встроенный DNS-слушатель.

  1. Открываем конфигурационный файл:
sudo nano /etc/systemd/resolved.conf
  1. Находим строку #DNSStubListener=yes, раскомментируем её (убираем решетку) и меняем значение на no:
DNSStubListener=no
  1. Перезапускаем сервис сети для применения изменений:
sudo systemctl restart systemd-resolved
  1. Проверяем, что порт 53 освободился (вывод должен быть пустым):
sudo ss -tulpn | grep :53

Шаг 3: Создание конфигурации CoreDNS (Corefile)

Создаем файл Corefile, который говорит серверу, как обрабатывать запросы. Важно использовать плагин file для BIND-зоны.

nano /opt/coredns/Corefile

Содержимое файла:

zailon.ru:53 {
    file /etc/coredns/zones/zailon.ru.zone zailon.ru
    forward . 1.1.1.1 8.8.8.8
    cache 30
    reload
    log
    errors
}

.:53 {
    forward . 1.1.1.1 8.8.8.8
    cache 30
    reload
    log
    errors
}

Разбор плагинов:

  • file: Читает текстовый файл зоны и отдает локальные IP.
  • forward: Если домен не zailon.ru, шлет запрос в Cloudflare/Google.
  • cache: Запоминает ответы на 30 секунд для скорости.
  • reload: Автоматически перечитывает конфиг при изменениях.

Шаг 4: Создание DNS-зоны

Создаем файл с записями ваших сервисов. Формат: имя IN A ip-адрес.

nano /opt/coredns/zones/zailon.ru.zone

Содержимое файла:

$TTL 3600
@ IN SOA ns1.zailon.ru. admin.zailon.ru. (
    2026052801 ; Serial
    3600       ; Refresh
    600        ; Retry
    604800     ; Expire
    86400      ; Minimum TTL
)

@ IN NS ns1.zailon.ru.

ab IN A 192.168.1.203
book IN A 192.168.1.203
bw IN A 192.168.1.202
cerberus IN A 192.168.1.208
chat IN A 192.168.1.206
cloud IN A 192.168.1.213
git IN A 192.168.1.209
jellyfin IN A 192.168.1.203
mail IN A 192.168.1.212
music IN A 192.168.1.203
nc IN A 192.168.1.205
olimp IN A 192.168.1.201
wiki IN A 192.168.1.202

Примечание: Список можно дополнять. Обязательно оставьте пустую строку в конце файла.


Шаг 5: Docker Compose

Создаем файл запуска контейнера. Мы явно привязываем порты к интерфейсам 127.0.0.1 (для локальных проверок) и 192.168.1.201 (для сети).

nano /opt/coredns/docker-compose.yml

Содержимое:

services:
  coredns:
    image: coredns/coredns:latest
    container_name: coredns
    restart: unless-stopped
    ports:
      - "127.0.0.1:53:53/tcp"
      - "127.0.0.1:53:53/udp"
      - "192.168.1.201:53:53/tcp"
      - "192.168.1.201:53:53/udp"
    volumes:
      - /opt/coredns/Corefile:/Corefile:ro
      - /opt/coredns/zones:/etc/coredns/zones:ro
    dns:
      - 1.1.1.1
      - 8.8.8.8
    cap_add:
      - NET_BIND_SERVICE

Шаг 6: Запуск и Проверка

  1. Запускаем контейнер:
cd /opt/coredns
docker compose up -d
  1. Проверяем логи (должно быть сообщение о загрузке конфигурации):
docker logs coredns
  1. Проверяем локальные записи (должен вернуть внутренний IP):
dig @192.168.1.201 book.zailon.ru +short
  1. Проверяем внешние записи (должен вернуть публичный IP):
dig @192.168.1.201 google.com +short

Полезные команды

  • Перезагрузка конфига без рестарта контейнера (сработает плагин reload):
docker restart coredns
  • Проверка синтаксиса Corefile перед запуском:
docker run --rm -v /opt/coredns/Corefile:/Corefile coredns/coredns -conf /Corefile
  • Трассировка DNS-запроса для отладки:
dig @192.168.1.201 book.zailon.ru +trace

Решение проблем (Troubleshooting)

1. Ошибка: bind: address already in use

Причина: Порт 53 занят systemd-resolved. Решение: Выполнить Шаг 2 (отключить DNSStubListener).

2. Dig возвращает внешний IP вместо локального

Причина: CoreDNS не нашел запись в локальной зоне. Проверка:

  • Убедитесь, что в Corefile используется плагин file, а не hosts.
  • Проверьте права на файл зоны: chmod 644.
  • Проверьте пути монтирования в docker-compose.yml (должны быть абсолютными).

3. Контейнер не видит файлы зоны

Причина: Ошибка монтирования томов (volumes). Решение: В docker-compose.yml используйте абсолютные пути (/opt/coredns/...), избегайте относительных (./).

4. Ошибка парсинга зоны

Причина: Синтаксическая ошибка в файле zailon.ru.zone. Решение: Проверьте логи docker logs coredns. Убедитесь, что файл заканчивается пустой строкой.


Безопасность

  1. Ограничение доступа: В данном конфиге порт 53 открыт только для локальной подсети через привязку к интерфейсу 192.168.1.201. Внешний интерфейс (WAN) не слушает этот порт.
  2. Режим Read-Only: Файлы конфигурации смонтированы с флагом :ro (Read Only), что предотвращает случайную модификацию конфигов изнутри контейнера.
  3. Обновления: Регулярно выполняйте docker compose pull и docker compose up -d для обновления образа CoreDNS.
  4. Резервное копирование: Сохраняйте копии Corefile и zailon.ru.zone в отдельное хранилище. Потеря этих файлов потребует ручного восстановления записей.

🤖 AI Контекст для аварийного восстановления

Скопируйте этот блок и сохраните в отдельный файл ai_emergency_context.txt. При аварии отправьте его нейросети целиком. Она мгновенно восстановит состояние системы.

[AI EMERGENCY CONTEXT - COREDNS SETUP]
DATE: 28.05.2026
HOST_OS: Ubuntu 24.04
SERVER_IP: 192.168.1.201
CONTAINER_NAME: coredns
IMAGE: coredns/coredns:latest
PROJECT_PATH: /opt/coredns/

FILE: /opt/coredns/Corefile
---
zailon.ru:53 {
    file /etc/coredns/zones/zailon.ru.zone zailon.ru
    forward . 1.1.1.1 8.8.8.8
    cache 30
    reload
    log
    errors
}

.:53 {
    forward . 1.1.1.1 8.8.8.8
    cache 30
    reload
    log
    errors
}
---

FILE: /opt/coredns/zones/zailon.ru.zone
---
$TTL 3600
@ IN SOA ns1.zailon.ru. admin.zailon.ru. (
    2026052801 ; Serial
    3600       ; Refresh
    600        ; Retry
    604800     ; Expire
    86400      ; Minimum TTL
)

@ IN NS ns1.zailon.ru.

ab IN A 192.168.1.203
book IN A 192.168.1.203
bw IN A 192.168.1.202
cerberus IN A 192.168.1.208
chat IN A 192.168.1.206
cloud IN A 192.168.1.213
git IN A 192.168.1.209
jellyfin IN A 192.168.1.203
mail IN A 192.168.1.212
music IN A 192.168.1.203
nc IN A 192.168.1.205
olimp IN A 192.168.1.201
wiki IN A 192.168.1.202
---

FILE: /opt/coredns/docker-compose.yml
---
services:
  coredns:
    image: coredns/coredns:latest
    container_name: coredns
    restart: unless-stopped
    ports:
      - "127.0.0.1:53:53/tcp"
      - "127.0.0.1:53:53/udp"
      - "192.168.1.201:53:53/tcp"
      - "192.168.1.201:53:53/udp"
    volumes:
      - /opt/coredns/Corefile:/Corefile:ro
      - /opt/coredns/zones:/etc/coredns/zones:ro
    dns:
      - 1.1.1.1
      - 8.8.8.8
    cap_add:
      - NET_BIND_SERVICE
---

SYSTEM_STATE:
- systemd-resolved DNSStubListener = no
- Port 53 bound to 127.0.0.1 and 192.168.1.201 only
- All paths are ABSOLUTE
- Plugin used: file (NOT hosts)
- Serial: 2026052801
- Fallback DNS: 1.1.1.1, 8.8.8.8

RECOVERY COMMANDS:
1. cd /opt/coredns && docker compose down && docker compose up -d
2. dig @192.168.1.201 book.zailon.ru +short
3. docker logs coredns --tail 20
4. ss -tulpn | grep :53
---