Skip to content

# AdGuard DNS Rewrite Opportunities

## Overview

AdGuard DNS at `192.168.1.2` can handle internal domain resolution, eliminating need for external DNS or hosts file entries.

## Current Setup

- AdGuard URL: `http://192.168.1.2`
- Status: Running on Proxmox LXC 102 (`dns`, 192.168.1.2)
- Homepage widget: Configured

## AI Service DNS Entries

### Recommended DNS Rewrites

Add these static DNS entries in AdGuard to resolve AI services locally:

Domain | IP Address | TTL | Purpose
--- | --- | --- | ---
`ai.nuclide.systems` | `192.168.1.40` | 300 | LiteLLM gateway
`chat.nuclide.systems` | `192.168.1.40` | 300 | LobeHub chat
`mcp.nuclide.systems` | `192.168.1.40` | 300 | MCP servers
`litellm.nuclide.systems` | `192.168.1.40` | 300 | LiteLLM API
`s3.nuclide.systems` | `192.168.1.40` | 300 | Garage S3 (Zoraxy proxy)

### Benefits

1. No external DNS needed - All AI services resolve internally
2. Failover protection - Works even if external DNS is unreachable
3. Faster resolution - Local DNS vs external lookup
4. Simplified client config - Services can use domain names directly

## How to Add

### Method 1: Web UI (Recommended)

1. Open AdGuard: `http://192.168.1.2` (or via Zone: `http://192.168.1.2:3000`)
2. Navigate to DNS Settings → Static DNS Entries
3. Click Add for each service:

       Domain: ai.nuclide.systems
       IP Address: 192.168.1.40
       TTL: 300

4. Click Save

### Method 2: API

    # Get session token first
    curl -c /tmp/cookies.txt -k -X POST http://192.168.1.2:3000/ \
      -H "Content-Type: application/json" \
      -d "{\"username\": \"root\", \"password\": \"${ADGUARD_PASSWORD}\"}"
    # Export ADGUARD_PASSWORD from your shell env or a `.env` file — never hardcode.

    # Add static DNS entry
    curl -s -k -c /tmp/cookies.txt -b /tmp/cookies.txt \
      -X POST http://192.168.1.2:3000/admin/api/staticDNS \
      -H "Content-Type: application/json" \
      -d '{
        "domain": "ai.nuclide.systems",
        "ip": "192.168.1.40",
        "ttl": 300
      }'

### Method 3: Auto-configure (Script)

Create `/opt/stacks/scripts/configure_adguard_dns.sh`:

    #!/bin/bash
    # Configure AdGuard DNS for AI stack

    ADGUARD_HOST="192.168.1.2"
    ADGUARD_PORT="3000"
    TARGET_IP="192.168.1.40"

    # AI service domains to add
    DOMAINS=(
        "ai.nuclide.systems"
        "chat.nuclide.systems"
        "mcp.nuclide.systems"
        "litellm.nuclide.systems"
        "s3.nuclide.systems"
    )

    echo "🔧 Adding DNS entries to AdGuard..."

    for domain in "${DOMAINS[@]}"; do
        echo "  → $domain → $TARGET_IP"
        # Note: This is a placeholder - actual API call needed
    done

    echo "✅ Done! Add these in AdGuard UI manually."

## `*.nuclide.lan` zone (LAN-only aliases, added 2026-05-24)

30 A-records mapping stable names to host IPs. Use cases: (a) bypass Zoraxy for direct LAN access (Immich app on home Wi-Fi `nuclide`, NAS browsers, infra admin UIs), (b) decouple client config from IPs so when a service moves CT only the AdGuard rewrite changes.

Naming convention: - Per-host (one per CT/VM/device): `unifi`, `dlink`, `pve`, `adguard`, `backrest`, `zoraxy`, `id`, `db`, `secrets`, `ops`, `nas`, `docker`, `nextcloud`, `dev`, `shepard`, `ha`, `mainsail` - Per-service (alias when only port differs from the host): `immich`, `vault`, `karakeep`, `memos`, `abs`, `gotify`, `n8n`, `chat`, `ai`, `mcp`, `grafana`, `prometheus`

Full list in `/opt/AdGuardHome/AdGuardHome.yaml` under `dns.rewrites:`. Auto-pushed nightly to `fkrebs/adguard-conf`.

Adding a new service alias: 1. Append a `- {domain: <new>.nuclide.lan, answer: 192.168.x.y, enabled: true}` line 2. `systemctl restart AdGuardHome` on CT 102 (AdGuard doesn't support `reload` for rewrites) 3. Verify: `dig +short @192.168.1.2 <new>.nuclide.lan`

When a service moves CT (changes IP): edit only the AdGuard rewrite → restart. No client app needs an update — this is the whole point of the alias zone.

## Alternative Useful DNS Entries

### NextCloud & Sync

- `nc.nuclide.systems` → `192.168.1.40` (NextCloud web)
- `sync.nuclide.systems` → Internal IP of Sync client

### Garage S3

- `storage.nuclide.systems` → `192.168.1.40` (Garage internal, port 3900)
- `s3-local.nuclide.systems` → `192.168.1.40` (S3 API for local only)

### Service Discovery

- `api.nuclide.systems` → `192.168.1.40` (future API gateway)
- `web.nuclide.systems` → `192.168.1.40` (general web services)

### Immich

- `immich.nuclide.systems` → `192.168.1.40` (Immich web & API)
- `immich-api.nuclide.systems` → `192.168.1.40:2283` (Immich API only)

### Paperless-ngx

- `pp.nuclide.systems` → `192.168.1.40` (Paperless web)
- `pp-api.nuclide.systems` → `192.168.1.40:8000` (Paperless API)

### Home Assistant

- `ha.nuclide.systems` → `192.168.1.60` (Home Assistant OS VM 100)
- `homeassistant.local` → `192.168.1.60` (mDNS fallback)

## Internal DNS Server Setup

### Option A: Use AdGuard as Forwarding DNS

Configure clients to use `192.168.1.2` as their DNS server:

1. Proxmox Host: Edit `/etc/resolv.conf`
2. Docker containers: Add DNS in docker-compose.yml
3. VMs/PFs: Configure network settings

### Option B: Create Custom Zone in AdGuard

1. AdGuard → DNS Settings → Zone Management
2. Add zone: `nuclide.systems`
3. Add A records for all subdomains with proper IPs
4. Zone file format:

       @       IN SOA ns1.nuclide.systems. admin.nuclide.systems. (
                     1   ; Serial
                     3600  ; Refresh
                     1800  ; Retry
                     604800  ; Expire
                     86400 ) ; Minimum TTL

       @       IN NS   ns1.nuclide.systems.
       @       IN A    192.168.1.40
       ai      IN A    192.168.1.40
       chat    IN A    192.168.1.40
       mcp     IN A    192.168.1.40
       l       IN A    192.168.1.40  ; LiteLLM
       s3      IN A    192.168.1.40
       nc      IN A    192.168.1.40  ; NextCloud

## Verification

After adding DNS entries:

    # Test from any machine on network
    dig ai.nuclide.systems @192.168.1.2
    dig chat.nuclide.systems @192.168.1.2

    # Should return: 192.168.1.40

## Integration with MCP/Gateway Config

Update service configs to use domain names:

### In LiteLLM Config (`/opt/stacks/ai/litellm-config/config.yaml`)

    general_settings:
      proxy_base_url: https://ai.nuclide.systems
      control_plane_url: https://ai.nuclide.systems

### In Karakeep (`.env`)

    OPENAI_BASE_URL=https://ai.nuclide.systems/v1

### In LobeHub (`.env`)

    APP_URL=https://chat.nuclide.systems
    S3_ENDPOINT=https://s3.nuclide.systems

## Migration Checklist

- [ ] Add DNS entries to AdGuard
- [ ] Verify resolution: `dig ai.nuclide.systems`
- [ ] Update service configs to use domains
- [ ] Test HTTPS connectivity
- [ ] Remove old hosts file entries (if any)
- [ ] Document for team

## Notes

- AdGuard runs on LXC 102 at `192.168.1.2`
- All AI services run on `192.168.1.40`
- Using same IP for all domains is intentional (single endpoint)
- SSL certs are issued by Zoraxy (public domain validation)
- DNS-only setup doesn't require HTTP proxy (Zoraxy still handles HTTPS)