DNS Configuration | Docs | TitaniumGuard

DNS Configuration

DNS Configuration Reference

{
  // REQUIRED: no
  // TYPE: string (host:port)
  // DEFAULT: "0.0.0.0:8080"
  // DNS UDP+TCP listener bind address.
  "listen_addr": "0.0.0.0:8080",

  // REQUIRED: no
  // TYPE: string | DEFAULT: null
  // Optional policy JSON path for DNS policy engine.
  "policy_file_path": "/etc/titaniumguard/dns-policy.json",

  // REQUIRED: no
  // TYPE: RuleEngineConfig
  // DEFAULT: { "max_trace_facts": 64, "enable_explain_logs": true }
  "rule_engine": {
    // REQUIRED: no | TYPE: u32 | DEFAULT: 64
    "max_trace_facts": 64,

    // REQUIRED: no | TYPE: bool | DEFAULT: true
    "enable_explain_logs": true
  },

  // REQUIRED: no
  // TYPE: string[] (IP addresses)
  // DEFAULT: []
  // If empty, built-in root hints are used.
  "resolvers": ["1.1.1.1", "8.8.8.8"],

  // REQUIRED: no
  // TYPE: ZoneConfig[]
  // DEFAULT: []
  "zones": [
    {
      // REQUIRED: yes
      // TYPE: string
      // Zone apex, usually FQDN with trailing dot.
      "name": "corp.internal.",

      // REQUIRED: yes
      // TYPE: ZoneSoaConfig
      "soa": {
        // REQUIRED: yes | TYPE: string | ALIAS: MNAME
        "mname": "ns1.corp.internal.",

        // REQUIRED: yes | TYPE: string | ALIAS: RNAME
        "rname": "dns-admin.corp.internal.",

        // REQUIRED: yes | TYPE: u32 | ALIAS: SERIAL
        "serial": 2026022201,

        // REQUIRED: yes | TYPE: u32 | ALIAS: REFRESH
        "refresh": 3600,

        // REQUIRED: yes | TYPE: u32 | ALIAS: RETRY
        "retry": 600,

        // REQUIRED: yes | TYPE: u32 | ALIAS: EXPIRE
        "expire": 1209600,

        // REQUIRED: yes | TYPE: u32 | ALIAS: MINIMUM
        "minimum": 300,

        // REQUIRED: no | TYPE: u32 | DEFAULT: 3600
        "ttl": 3600
      },

      // REQUIRED: no
      // TYPE: { owner_name: { record_type: ZoneRecordSetConfig } }
      // DEFAULT: {}
      "records": {
        "@": {
          // REQUIRED: no
          // TYPE: ZoneRecordSetConfig
          "A": {
            // REQUIRED: no | TYPE: u32 | DEFAULT: 300
            "ttl": 300,

            // REQUIRED: yes | TYPE: string[]
            "values": ["10.10.0.53"]
          },
          "NS": {
            "ttl": 3600,
            "values": ["ns1.corp.internal."]
          }
        }
      }
    }
  ],

  // REQUIRED: no
  // TYPE: CachingConfig
  // DEFAULT: { "type": "memory", "max_entries": 100000 }
  "caching": {
    // REQUIRED: yes
    // TYPE: enum
    // ALLOWED: "memory", "redis"
    "type": "memory",

    // REQUIRED: no (memory only) | TYPE: u64 | DEFAULT: 100000
    "max_entries": 100000,

    // REQUIRED: yes (redis only) | TYPE: string
    // "url": "redis://127.0.0.1/",

    // REQUIRED: no (redis only) | TYPE: string | DEFAULT: "dns:cache:"
    // "key_prefix": "dns:cache:"
  },

  // REQUIRED: no
  // TYPE: TransportConfig
  // DEFAULT: {}
  "transports": {
    // REQUIRED: no | TYPE: TlsTransportConfig | DEFAULT: null
    "dot": {
      // REQUIRED: yes | TYPE: string (host:port)
      "listen_addr": "0.0.0.0:853",
      // REQUIRED: yes | TYPE: string
      "cert_path": "/etc/titaniumguard/tls.crt",
      // REQUIRED: yes | TYPE: string
      "key_path": "/etc/titaniumguard/tls.key"
    },

    // REQUIRED: no | TYPE: HttpsTransportConfig | DEFAULT: null
    "doh": {
      // REQUIRED: yes | TYPE: string (host:port)
      "listen_addr": "0.0.0.0:8443",
      // REQUIRED: yes | TYPE: string
      "cert_path": "/etc/titaniumguard/tls.crt",
      // REQUIRED: yes | TYPE: string
      "key_path": "/etc/titaniumguard/tls.key",
      // REQUIRED: no | TYPE: string | DEFAULT: null
      "dns_hostname": "dns.example.com",
      // REQUIRED: no | TYPE: string | DEFAULT: "/dns-query"
      "endpoint": "/dns-query",

      // REQUIRED: no | TYPE: ODoHConfig | DEFAULT: null
      // HPKE identifiers from RFC 9180.
      "odoh": {
        // REQUIRED: yes (when odoh is set) | TYPE: string
        // ALLOWED (RFC 9180 Table 2):
        // "DHKEM(P-256, HKDF-SHA256)"
        // "DHKEM(P-384, HKDF-SHA384)"
        // "DHKEM(P-521, HKDF-SHA512)"
        // "DHKEM(X25519, HKDF-SHA256)"
        // "DHKEM(X448, HKDF-SHA512)"
        // Also accepts numeric values such as "0x0020".
        "kem_id": "DHKEM(X25519, HKDF-SHA256)",

        // REQUIRED: yes (when odoh is set) | TYPE: string
        // ALLOWED (RFC 9180 Table 3):
        // "HKDF-SHA256"
        // "HKDF-SHA384"
        // "HKDF-SHA512"
        // Also accepts numeric values such as "0x0001".
        "kdf_id": "HKDF-SHA256",

        // REQUIRED: yes (when odoh is set) | TYPE: string
        // ALLOWED (RFC 9180 Table 5):
        // "AES-128-GCM"
        // "AES-256-GCM"
        // "CHACHA20POLY1305"
        // "EXPORT-ONLY"
        // Also accepts numeric values such as "0x0001".
        "aead_id": "AES-128-GCM"
      }
    },

    // REQUIRED: no | TYPE: QuicTransportConfig | DEFAULT: null
    "doq": {
      "listen_addr": "0.0.0.0:8853",
      "cert_path": "/etc/titaniumguard/tls.crt",
      "key_path": "/etc/titaniumguard/tls.key",
      // REQUIRED: no | TYPE: string | DEFAULT: null
      "dns_hostname": "dns.example.com"
    },

    // REQUIRED: no | TYPE: QuicTransportConfig | DEFAULT: null
    "doh3": {
      "listen_addr": "0.0.0.0:8444",
      "cert_path": "/etc/titaniumguard/tls.crt",
      "key_path": "/etc/titaniumguard/tls.key",
      "dns_hostname": "dns.example.com"
    }
  },

  // REQUIRED: no
  // TYPE: LoggingConfig
  // DEFAULT: values below
  "logging": {
    // REQUIRED: no | TYPE: bool | DEFAULT: true
    "enabled": true,

    // REQUIRED: no | TYPE: enum | DEFAULT: "strict"
    // ALLOWED: "strict", "standard", "enterprise_forensics"
    "default_mode": "strict",

    // REQUIRED: no | TYPE: string | DEFAULT: "var/log/dns"
    "log_dir": "var/log/dns",

    // REQUIRED: no | TYPE: u64 | DEFAULT: 60
    "key_rotation_minutes": 60,

    // REQUIRED: no | TYPE: string | DEFAULT: "change-me"
    // Replace for production.
    "hmac_secret": "change-me",

    // REQUIRED: no | TYPE: u16 | DEFAULT: 30
    "default_retention_days": 30,

    // REQUIRED: no | TYPE: u64 | DEFAULT: 300
    "purge_interval_seconds": 300,

    // REQUIRED: no | TYPE: TenantLoggingRule[] | DEFAULT: []
    "tenants": [
      {
        // REQUIRED: yes | TYPE: string
        "tenant_id": "tenant-a",

        // REQUIRED: yes | TYPE: enum
        // ALLOWED: "strict", "standard", "enterprise_forensics"
        "mode": "enterprise_forensics",

        // REQUIRED: no | TYPE: u16 | DEFAULT: null
        "retention_days": 90,

        // REQUIRED: no | TYPE: string[] | DEFAULT: []
        "client_cidrs": ["10.0.0.0/8", "192.168.0.0/16"]
      }
    ]
  }
}

ODoH discovery endpoint

When transports.doh.odoh is configured, the DoH listener also serves:

  • GET /.well-known/odohconfigs

The response body is binary ObliviousDoHConfigs data (RFC 9230 format).