|
|
|
@ -306,6 +306,215 @@ await dnsServer.start();
|
|
|
|
|
console.log('DNS Server with Let\'s Encrypt SSL started!');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Manual Socket Handling
|
|
|
|
|
|
|
|
|
|
The DNS server supports manual socket handling for advanced use cases like clustering, load balancing, and custom transport implementations. You can control UDP and HTTPS socket handling independently.
|
|
|
|
|
|
|
|
|
|
#### Configuration Options
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
export interface IDnsServerOptions {
|
|
|
|
|
// ... standard options ...
|
|
|
|
|
manualUdpMode?: boolean; // Handle UDP sockets manually
|
|
|
|
|
manualHttpsMode?: boolean; // Handle HTTPS sockets manually
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### Basic Manual Socket Usage
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import { DnsServer } from '@push.rocks/smartdns/server';
|
|
|
|
|
import * as dgram from 'dgram';
|
|
|
|
|
import * as net from 'net';
|
|
|
|
|
|
|
|
|
|
// Create server with manual UDP mode
|
|
|
|
|
const dnsServer = new DnsServer({
|
|
|
|
|
httpsKey: '...',
|
|
|
|
|
httpsCert: '...',
|
|
|
|
|
httpsPort: 853,
|
|
|
|
|
udpPort: 53,
|
|
|
|
|
dnssecZone: 'example.com',
|
|
|
|
|
manualUdpMode: true // UDP manual, HTTPS automatic
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await dnsServer.start(); // HTTPS binds, UDP doesn't
|
|
|
|
|
|
|
|
|
|
// Create your own UDP socket
|
|
|
|
|
const udpSocket = dgram.createSocket('udp4');
|
|
|
|
|
|
|
|
|
|
// Handle incoming UDP messages
|
|
|
|
|
udpSocket.on('message', (msg, rinfo) => {
|
|
|
|
|
dnsServer.handleUdpMessage(msg, rinfo, (response, responseRinfo) => {
|
|
|
|
|
// Send response using your socket
|
|
|
|
|
udpSocket.send(response, responseRinfo.port, responseRinfo.address);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Bind to custom port or multiple interfaces
|
|
|
|
|
udpSocket.bind(5353, '0.0.0.0');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### Manual HTTPS Socket Handling
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
// Create server with manual HTTPS mode
|
|
|
|
|
const dnsServer = new DnsServer({
|
|
|
|
|
httpsKey: '...',
|
|
|
|
|
httpsCert: '...',
|
|
|
|
|
httpsPort: 853,
|
|
|
|
|
udpPort: 53,
|
|
|
|
|
dnssecZone: 'example.com',
|
|
|
|
|
manualHttpsMode: true // HTTPS manual, UDP automatic
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await dnsServer.start(); // UDP binds, HTTPS doesn't
|
|
|
|
|
|
|
|
|
|
// Create your own TCP server
|
|
|
|
|
const tcpServer = net.createServer((socket) => {
|
|
|
|
|
// Pass TCP sockets to DNS server
|
|
|
|
|
dnsServer.handleHttpsSocket(socket);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tcpServer.listen(8853, '0.0.0.0');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### Full Manual Mode
|
|
|
|
|
|
|
|
|
|
Control both protocols manually for complete flexibility:
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
const dnsServer = new DnsServer({
|
|
|
|
|
httpsKey: '...',
|
|
|
|
|
httpsCert: '...',
|
|
|
|
|
httpsPort: 853,
|
|
|
|
|
udpPort: 53,
|
|
|
|
|
dnssecZone: 'example.com',
|
|
|
|
|
manualUdpMode: true,
|
|
|
|
|
manualHttpsMode: true
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await dnsServer.start(); // Neither protocol binds
|
|
|
|
|
|
|
|
|
|
// Set up your own socket handling for both protocols
|
|
|
|
|
// Perfect for custom routing, load balancing, or clustering
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### Advanced Use Cases
|
|
|
|
|
|
|
|
|
|
##### Load Balancing Across Multiple UDP Sockets
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
// Create multiple UDP sockets for different CPU cores
|
|
|
|
|
const sockets = [];
|
|
|
|
|
const numCPUs = require('os').cpus().length;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < numCPUs; i++) {
|
|
|
|
|
const socket = dgram.createSocket({
|
|
|
|
|
type: 'udp4',
|
|
|
|
|
reuseAddr: true // Allow multiple sockets on same port
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
socket.on('message', (msg, rinfo) => {
|
|
|
|
|
dnsServer.handleUdpMessage(msg, rinfo, (response, rinfo) => {
|
|
|
|
|
socket.send(response, rinfo.port, rinfo.address);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
socket.bind(53);
|
|
|
|
|
sockets.push(socket);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### Clustering with Worker Processes
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
import cluster from 'cluster';
|
|
|
|
|
import { DnsServer } from '@push.rocks/smartdns/server';
|
|
|
|
|
|
|
|
|
|
if (cluster.isPrimary) {
|
|
|
|
|
// Master process accepts connections
|
|
|
|
|
const server = net.createServer({ pauseOnConnect: true });
|
|
|
|
|
|
|
|
|
|
// Distribute connections to workers
|
|
|
|
|
server.on('connection', (socket) => {
|
|
|
|
|
const worker = getNextWorker(); // Round-robin or custom logic
|
|
|
|
|
worker.send('socket', socket);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
server.listen(853);
|
|
|
|
|
} else {
|
|
|
|
|
// Worker process handles DNS
|
|
|
|
|
const dnsServer = new DnsServer({
|
|
|
|
|
httpsKey: '...',
|
|
|
|
|
httpsCert: '...',
|
|
|
|
|
httpsPort: 853,
|
|
|
|
|
udpPort: 53,
|
|
|
|
|
dnssecZone: 'example.com',
|
|
|
|
|
manualHttpsMode: true
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
process.on('message', (msg, socket) => {
|
|
|
|
|
if (msg === 'socket') {
|
|
|
|
|
dnsServer.handleHttpsSocket(socket);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await dnsServer.start();
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### Custom Transport Protocol
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
// Use DNS server with custom transport (e.g., WebSocket)
|
|
|
|
|
import WebSocket from 'ws';
|
|
|
|
|
|
|
|
|
|
const wss = new WebSocket.Server({ port: 8080 });
|
|
|
|
|
const dnsServer = new DnsServer({
|
|
|
|
|
httpsKey: '...',
|
|
|
|
|
httpsCert: '...',
|
|
|
|
|
httpsPort: 853,
|
|
|
|
|
udpPort: 53,
|
|
|
|
|
dnssecZone: 'example.com',
|
|
|
|
|
manualUdpMode: true,
|
|
|
|
|
manualHttpsMode: true
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await dnsServer.start();
|
|
|
|
|
|
|
|
|
|
wss.on('connection', (ws) => {
|
|
|
|
|
ws.on('message', (data) => {
|
|
|
|
|
// Process DNS query from WebSocket
|
|
|
|
|
const response = dnsServer.processRawDnsPacket(Buffer.from(data));
|
|
|
|
|
ws.send(response);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
##### Multi-Interface Binding
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
// Bind to multiple network interfaces manually
|
|
|
|
|
const interfaces = [
|
|
|
|
|
{ address: '192.168.1.100', type: 'udp4' },
|
|
|
|
|
{ address: '10.0.0.50', type: 'udp4' },
|
|
|
|
|
{ address: '::1', type: 'udp6' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
interfaces.forEach(({ address, type }) => {
|
|
|
|
|
const socket = dgram.createSocket(type);
|
|
|
|
|
|
|
|
|
|
socket.on('message', (msg, rinfo) => {
|
|
|
|
|
console.log(`Query received on ${address}`);
|
|
|
|
|
dnsServer.handleUdpMessage(msg, rinfo, (response, rinfo) => {
|
|
|
|
|
socket.send(response, rinfo.port, rinfo.address);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
socket.bind(53, address);
|
|
|
|
|
});
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Handling Different Protocols
|
|
|
|
|
|
|
|
|
|
#### UDP DNS Server
|
|
|
|
@ -573,6 +782,7 @@ await tap.start();
|
|
|
|
|
5. **Monitoring**: Log DNS queries for debugging and analytics
|
|
|
|
|
6. **Rate Limiting**: Implement rate limiting for public DNS servers
|
|
|
|
|
7. **Caching**: Respect TTL values and implement proper caching
|
|
|
|
|
8. **Manual Sockets**: Use manual socket handling for clustering and load balancing
|
|
|
|
|
|
|
|
|
|
### Performance Considerations
|
|
|
|
|
|
|
|
|
@ -580,6 +790,7 @@ await tap.start();
|
|
|
|
|
- The DNS server handles concurrent UDP and HTTPS requests efficiently
|
|
|
|
|
- DNSSEC signatures are generated on-demand to reduce memory usage
|
|
|
|
|
- Pattern matching uses caching for improved performance
|
|
|
|
|
- Manual socket handling enables horizontal scaling across CPU cores
|
|
|
|
|
|
|
|
|
|
### Security Considerations
|
|
|
|
|
|
|
|
|
@ -589,6 +800,8 @@ await tap.start();
|
|
|
|
|
- Implement access controls for DNS server handlers
|
|
|
|
|
- Use Let's Encrypt for automatic SSL certificate management
|
|
|
|
|
- Never expose internal network information through DNS
|
|
|
|
|
- Bind to specific interfaces in production environments
|
|
|
|
|
- Use manual socket handling for custom security layers
|
|
|
|
|
|
|
|
|
|
This comprehensive library provides everything needed for both DNS client operations and running production-grade DNS servers with modern security features in TypeScript.
|
|
|
|
|
|
|
|
|
|