GoDNS is a fast, flexible experimental DNS server designed to help developers and researchers explore and experiment with various features of the DNS protocol.
- GoDNSServer
- Examples
- Constructing and Generating DNS Replies
- dns Package
- xlayers Subpackage
- xperi Subpackage
GoDNSServer
is a top-level wrapper for the DNS server, consisting of three parts:
- ServerConfig: Configuration for the DNS server.
- Netter: Packet handler that receives, parses, and sends packets while maintaining connection state.
- Responser: DNS responder that responds, parses, and constructs DNS replies.
type GoDNSServer struct {
ServerConfig DNSServerConfig
Netter Netter
Responer Responser
}
// Start the GoDNS server!
func (s *GoDNSServer) Start()
Netter
Packet Listener: Receives, parses, sends packets, and maintains connection state.
type Netter struct { // size=16 (0x10)
Config NetterConfig
}
// Send function is used to send packets
func (n *Netter) Send(connInfo ConnectionInfo, data []byte)
// Sniff function listens on a specified port and returns a channel of connection information
func (n *Netter) Sniff() chan ConnectionInfo
// handleListener function handles TCP connections
func (n *Netter) handleListener(lstr net.Listener, connChan chan ConnectionInfo)
// handlePktConn function handles packet connections
func (n *Netter) handlePktConn(pktConn net.PacketConn, connChan chan ConnectionInfo)
// handleStreamConn function handles stream connections
func (n *Netter) handleStreamConn(conn net.Conn, connChan chan ConnectionInfo)
Responser
DNS Responder: Responds to DNS queries, parses, and constructs DNS replies.
Responser
is an interface. The struct implementing this interface will generate DNS reply information based on DNS query information.
type Responser interface { // size=16 (0x10)
// Response generates DNS reply information based on DNS query data.
// Its argument is:
// - qInfo QueryInfo, DNS query information
// It returns:
// - ResponseInfo, DNS reply information
// - error, error information
Response(ConnectionInfo) (dns.DNSMessage, error)
}
With just a few lines of code, you can start a basic GoDNS server:
// Create a DNS server
server := godns.GoDNSServer{
ServerConfig: sConf,
Netter: godns.Netter{
Config: godns.NetterConfig{
Port: sConf.Port,
MTU: sConf.MTU,
},
},
Responer: &DullResponser{
ServerConf: sConf,
},
}
server.Start()
You can customize how DNS replies are generated by implementing the Responser
interface.
The responser.go
file provides several Responser
implementations and many auxiliary functions for reference.
The dns
package uses Go's built-in implementation to provide DNS message encoding and decoding capabilities, which can be used for constructing and parsing DNS messages.
DNSMessage
represents the structure of a DNS protocol message.
type DNSMessage struct {
// DNS message header
Header DNSHeader // DNS header
// Sections of the DNS message
Question DNSQuestionSection // Question section
Answer DNSResponseSection // Answer section
Authority DNSResponseSection // Authority section
Additional DNSResponseSection // Additional section
}
Each structure in the dns
package generally implements the following methods:
// Decode from buffer
func (s *struct) DecodeFromBuffer(buffer []byte, offset int) (int, error)
// Encode to byte stream
func (s *struct) Encode() []byte
// Encode to buffer
func (s *struct) EncodeToBuffer(buffer []byte) (int, error)
// Get the actual size of the structure
func (s *struct) Size() int
// Get the string representation of the structure
func (s *struct) String() string
// [Partially implemented] Check if two structures are equal
func (s *struct) Equal(other *struct) bool
These methods make it easy to encode and decode DNS messages.
The dns
package has no strict format constraints and supports encoding/decoding of unknown types of resource records, allowing it to construct and parse DNS messages as needed for experimentation.
The xperi
package implements some experimental functions, especially those related to DNSSEC, including:
ParseKeyBase64
: Parses Base64-encoded DNSKEY into byte format.CalculateKeyTag
: Calculates the Key Tag of a DNSKEY.GenerateRDATADNSKEY
: Generates DNSKEY RDATA based on parameters.GenerateRDATARRSIG
: Signs an RRSET and generates RRSIG RDATA.GenerateRDATADS
: Generates DS RDATA for a DNSKEY.GenerateRRDNSKEY
: Generates a DNSKEY RR.GenerateRRRRSIG
: Signs an RRSET and generates RRSIG RR.GenerateRRDS
: Generates DS RR for a DNSKEY.GenRandomRRSIG
: Generates a random RRSIG RDATA.GenWrongKeyWithTag
: Generates a DNSKEY RDATA with a specified incorrect KeyTag.GenKeyWithTag
: [This function is resource-intensive] Generates a DNSKEY with a specified KeyTag.
This project is licensed under the GPL-3.0 License.
For more information or support, please visit our GitHub page.