dcrouter/readme.plan2.md
2025-05-28 18:07:07 +00:00

6.0 KiB

DNS Server Configuration Fix Plan

First command: cat /home/centraluser/eu.central.ingress-2/CLAUDE.md

Problem Summary

The DNS server is logging "Dns Server starting on port undefined" because:

  1. The smartdns.DnsServer expects specific properties (udpPort, httpsPort, etc.) but something is trying to access port
  2. The records array we're passing isn't part of the DnsServer interface
  3. DnsServer uses a handler registration pattern, not a records array

Implementation Plan

1. Fix DnsServer Interface Usage in DcRouter

  • Update dcrouter/ts/classes.dcrouter.ts to properly handle DNS configuration
  • Remove the records property from IDnsServerOptions type extension
  • Create a new interface for DNS configuration that includes both DnsServer options and records

2. Implement DNS Record Handler Registration

  • After creating the DnsServer instance, register handlers for each DNS record
  • Create a helper method registerDnsRecords() that takes the records array and registers appropriate handlers
  • Use the DnsServer's registerHandler() method for each record type

3. Find and Fix the Logging Issue

  • Search for any logging that references dnsServerConfig.port
  • Update to use dnsServerConfig.udpPort instead
  • Check if the message is coming from within smartdns package or our code

4. Create Proper Type Definitions

  • Extend the dcrouter options to properly type DNS configuration
  • Create interface that combines DnsServer options with our custom records array:
    interface IDcRouterDnsConfig extends IDnsServerOptions {
      records?: Array<{
        name: string;
        type: string;
        value: string;
        ttl?: number;
      }>;
    }
    

5. Update DcRouter DNS Setup Logic

  • Modify setupDnsServer() method (or create if doesn't exist)
  • Separate DnsServer instantiation from record registration
  • Add proper error handling for DNS server startup

6. Test the Implementation

  • Create test file to verify DNS server starts correctly
  • Test that all DNS records are properly registered
  • Verify the port logging shows correct port number

Code Changes Required

File: dcrouter/ts/classes.dcrouter.ts

  1. Update the DNS server setup section (around line 117-122):

    // Set up DNS server if configured
    if (this.options.dnsServerConfig) {
      const { records, ...dnsServerOptions } = this.options.dnsServerConfig;
      this.dnsServer = new plugins.smartdns.DnsServer(dnsServerOptions);
    
      // Register DNS record handlers if records provided
      if (records && records.length > 0) {
        this.registerDnsRecords(records);
      }
    
      await this.dnsServer.start();
      console.log(`DNS server started on UDP port ${dnsServerOptions.udpPort}`);
    }
    
  2. Add new method for registering DNS records:

    private registerDnsRecords(records: Array<{name: string; type: string; value: string; ttl?: number}>) {
      if (!this.dnsServer) return;
    
      // Group records by domain pattern
      const recordsByDomain = new Map<string, typeof records>();
    
      for (const record of records) {
        const pattern = record.name.includes('*') ? record.name : `*.${record.name}`;
        if (!recordsByDomain.has(pattern)) {
          recordsByDomain.set(pattern, []);
        }
        recordsByDomain.get(pattern)!.push(record);
      }
    
      // Register handlers for each domain pattern
      for (const [domainPattern, domainRecords] of recordsByDomain) {
        const recordTypes = [...new Set(domainRecords.map(r => r.type))];
    
        this.dnsServer.registerHandler(domainPattern, recordTypes, (question) => {
          const matchingRecord = domainRecords.find(
            r => r.name === question.name && r.type === question.type
          );
    
          if (matchingRecord) {
            return {
              name: matchingRecord.name,
              type: matchingRecord.type,
              class: 'IN',
              ttl: matchingRecord.ttl || 300,
              data: this.parseDnsRecordData(matchingRecord.type, matchingRecord.value)
            };
          }
    
          return null;
        });
      }
    }
    
  3. Add helper method to parse DNS record data:

    private parseDnsRecordData(type: string, value: string): any {
      switch (type) {
        case 'A':
          return value; // IP address as string
        case 'MX':
          const [priority, exchange] = value.split(' ');
          return { priority: parseInt(priority), exchange };
        case 'TXT':
          return value;
        case 'NS':
          return value;
        default:
          return value;
      }
    }
    

File: dcrouter/ts/config/index.ts (if exists) or create type definition

Add proper type definition for DNS configuration:

export interface IDcRouterDnsConfig {
  // Required DnsServer options
  udpPort: number;
  httpsPort: number;
  httpsKey: string;
  httpsCert: string;
  dnssecZone: string;
  
  // Our custom records array
  records?: Array<{
    name: string;
    type: 'A' | 'AAAA' | 'MX' | 'TXT' | 'NS' | 'CNAME' | 'SOA';
    value: string;
    ttl?: number;
  }>;
}

Testing Strategy

  1. Create test file dcrouter/test/test.dns-server-config.ts
  2. Test DNS server starts without "undefined" port message
  3. Test DNS records are queryable after registration
  4. Test error handling when DNS server fails to start

Timeline

  • Step 1-3: Fix interface and logging (30 min)
  • Step 4-5: Implement proper record registration (45 min)
  • Step 6: Testing and verification (30 min)

Total estimated time: ~2 hours

Success Criteria

  • DNS server starts without "undefined" port message
  • Shows correct port number in logs (e.g., "DNS server started on UDP port 53")
  • All DNS records are properly registered and queryable
  • No type errors or runtime errors
  • Integration with DKIM auto-registration still works

COMPLETED

All tasks have been successfully implemented. The DNS server configuration is now properly handled in dcrouter.