24 KiB
Breaking Boundaries with a Decentralized, Firewall-Resistant Peer-to-Peer DNS System in Node.js
DNS is an essential service that translates human-readable domain names into IP addresses. However, it’s currently governed by centralized authorities, requiring domain registration and payments for top-level domains (TLDs). This blog post dives into a revolutionary DNS system implemented in Node.js that leverages peer-to-peer (P2P) networking and UDP hole-punching to create a decentralized, firewall-resistant DNS. This system removes the need for traditional registries and provides users with complete control over their TLDs.
[DEBUG 2024-10-14T21:04:20.875Z] Public DNS returned records for www.google.com
[DEBUG 2024-10-14T21:04:28.465Z] DNS query received: Domain = example.tld, Type = A
Virtual interface dummy2 created with CIDR 192.168.100.2.
[DEBUG 2024-10-14T21:04:28.527Z] Assigned virtual interface IP: 192.168.100.2 for domain: example.tld
[DEBUG 2024-10-14T21:04:28.528Z] Starting Holesail client for domain: example.tld, hash: 8a5b90945f8fbd5d1b620be3c888a47aaae20706a7f140be4bfa0df9e0dbcf38, IP: 192.168.100.2, Port: 80
Source:
https://git.ssh.surf/snxraven/p2ns
The Beginnings
This P2P DNS system represents a conceptual breakthrough in how DNS can operate. However, it's essential to recognize that the current code is a proof of concept and not yet fully equipped for large-scale or production use. As with any pioneering technology, there are significant challenges to address and features to refine.
One of the primary areas that require attention is ensuring unique TLD registration across peers. Currently, the system allows any peer to add a TLD and associated hash to the dnsCore
, but without a centralized authority or a consensus mechanism, there’s nothing preventing multiple users from registering the same TLD. This can lead to conflicts where different peers assign different IPs or hashes to the same TLD, creating ambiguity and potential security risks.
Another issue is data integrity and synchronization. In decentralized systems, especially those that operate asynchronously like this one, there’s always a chance that data may go out of sync. If peers don’t replicate updates promptly, they might serve outdated or conflicting DNS records. A more robust method for maintaining consistency, perhaps through periodic verification or consensus models, would enhance reliability.
Network resilience and performance also pose challenges. Although Hyperswarm facilitates P2P connectivity, peer connections can be unpredictable, particularly in large, dispersed networks. Connection stability might vary based on network conditions, and without an efficient way to verify peer connectivity, the user experience could degrade over time.
Potential Issues to Address
Other challenges that might arise in the development of a fully functional P2P DNS system include:
-
Security and Authentication: Without a centralized verification process, it’s difficult to authenticate peers and ensure only authorized peers participate in a private DNS network. A secure authentication layer or peer verification process would be necessary to prevent unauthorized access.
-
Redundancy and Conflict Resolution: In cases where the same TLD exists with different hashes, a conflict-resolution mechanism would be necessary to determine which entry is legitimate. This might involve a voting system or trust-based model where peers agree on the correct record.
-
Network Performance Overhead: As the network grows, synchronizing large amounts of data could impact performance, especially for peers with limited bandwidth. Optimizations around data storage, compression, and bandwidth management would be needed to handle network scalability.
-
Handling Malicious Peers: In a decentralized network, there’s always the risk of malicious actors attempting to flood the network with junk records or hijacking TLDs. Implementing trust models, perhaps reputation-based or verified peers, could mitigate this risk.
The current code lays the foundation for a decentralized DNS system that could, in time, replace the need for centralized registries. However, for it to become a robust, production-ready solution, these challenges must be overcome through further research, testing, and community collaboration. As this concept evolves, it has the potential to redefine digital identity, providing a truly autonomous DNS model that’s both resilient and accessible.
The Concept: Decentralized DNS with UDP Hole-Punching
At the heart of this system is the integration of decentralized technologies with resilient connection strategies, primarily UDP hole-punching. This P2P DNS uses Holepunch for tunneling and Hyperswarm for establishing peer connections, creating seamless communication between peers across diverse network environments.
Handling DNS requests through a decentralized P2P framework fundamentally alters the dynamics of DNS:
- Centralized DNS servers are no longer required.
- Domain registries become irrelevant, as the system allows for self-created TLDs.
- Domain purchases and the limitations of traditional TLD structures are eliminated.
This system redefines DNS, empowering individuals and organizations alike to bypass conventional limitations and establish their own namespaces and domains without dependence on outside entities.
Technical Ramifications of a Decentralized DNS System
Enhanced resilience and uptime come from distributing DNS records across multiple peers. Traditional DNS relies on centralized servers, meaning if one server goes down or is compromised, access for large numbers of users is affected. With a decentralized model, records are distributed across many peers, creating a self-healing, resilient network with no single point of failure. An attack on one peer or group of peers has little to no effect on the network as a whole. By decentralizing the DNS infrastructure, uptime is maximized even if some peers are offline, as remaining peers continue serving the DNS records without interruption.
UDP hole-punching is a critical feature enabling P2P DNS to function effectively across restrictive networks. Firewalls, NATs, and CGNAT configurations—often found in mobile networks (4G, 5G) and satellite Internet (like Starlink)—typically prevent or limit incoming connections. UDP hole-punching establishes a direct link between peers by creating connection paths through intermediaries, allowing traffic to flow regardless of network restrictions. This makes the system an ideal DNS solution for users in restrictive environments where traditional DNS services may be blocked or monitored. The increased accessibility enables users on restricted networks to participate freely in the DNS network without needing VPNs or additional circumvention tools.
Local IP assignment offers streamlined peer-to-peer interaction, with IPs dynamically assigned to each domain in the range 192.168.100.x
. Each domain is mapped to a virtual interface within the system’s subnet, leveraging local addresses like 127.0.0.1
. This approach enhances security by isolating domain traffic within the network, preventing direct IP exposure to external sources. Local traffic stays secure and private, and DNS requests are automatically handled within the network, making the system easier to use for both technical and non-technical users.
Security and Privacy Implications
This decentralized DNS model also opens up new possibilities for security and privacy. Unlike traditional DNS, which often involves ISP-based logging, centralized tracking, and even DNS hijacking, a P2P DNS creates a privacy-centric, user-controlled environment.
Privacy becomes inherent in this model as users retain control over DNS queries, shielding themselves from ISP surveillance and bypassing centralized logging. DNS queries remain private and inaccessible to third-party trackers, thanks to Holesail’s encrypted, peer-to-peer tunneling. Traffic stays encrypted and direct between peers, making it far less vulnerable to interception or manipulation compared to conventional DNS systems.
Eliminating the need for domain ownership removes the barriers associated with central registries and domain purchasing. No longer bound by regulatory bodies or commercial interests, users can register their own TLDs and subdomains on demand, within the P2P DNS network. This opens up vast possibilities, from small-scale personal projects to enterprise-level applications, without the need to purchase domain names or navigate the policies of registries.
The structure of this DNS system brings freedom back into the hands of the user, allowing self-regulated control over DNS queries and reducing reliance on ISPs or DNS providers. Users can establish TLDs for internal use, private communication, and personal networks, expanding traditional DNS concepts into a private or exclusive P2P namespace.
Use Cases: How the P2P DNS System Can Be Applied
This system has applications that extend beyond the technical enthusiast community, with potential to transform enterprise, IoT, and digital rights domains.
In the enterprise sector, organizations often need internal DNS solutions that don’t rely on public infrastructure. This P2P DNS system allows businesses to set up secure, firewall-resistant internal DNS namespaces without involving third-party registries or external providers. Not only does this reduce costs, but it also provides a high level of control and customization for internal domains, from resource isolation to custom TLD configurations.
For IoT ecosystems, which consist of numerous connected devices often spread across restricted networks, a decentralized DNS provides an efficient, scalable solution for addressing devices without public IPs. Devices can be registered and managed within a private P2P DNS, accessible through firewall-resistant connections that work even in highly restrictive environments.
Digital rights and censorship-resistant internet advocates stand to benefit greatly from decentralized DNS. Traditional DNS servers can be targeted for censorship, either by disabling access to certain domains or by redirecting users to unwanted sites. With P2P DNS, censorship becomes practically impossible, as there is no single server to target or manipulate. This system empowers users to create and distribute content without the threat of government or corporate suppression.
How This System Redefines Freedom in the DNS Landscape
Beyond the technical benefits, the freedom this system provides to global users is unparalleled. Removing the requirement to purchase or register domains is not just a cost-saving measure—it’s a liberation of identity and accessibility in the digital world. This system enables everyone, from independent users to small organizations, to create their own namespaces without restrictions. In essence, anyone can launch a TLD or subdomain network, using their preferred naming structures with no oversight.
By establishing a framework where domain registries are optional rather than mandatory, this system bypasses the regulatory and economic gatekeepers traditionally associated with the DNS. It provides a level of freedom that is particularly empowering for communities in restrictive environments, enabling access to an open DNS system that operates independently of conventional controls.
With this P2P DNS system, the ability to create and maintain digital identities is democratized. Users around the world can reclaim control over their namespaces, creating a more open, resilient, and censorship-resistant Internet. This redefines what it means to have access to the digital world, with a new level of autonomy and security, all powered by decentralized technology.
To create a comprehensive code walkthrough for the above setup, here’s an expanded breakdown:
Code Walkthrough: Peer Discovery, DNS, and HTTP Proxying in a P2P Network
This implementation involves components for peer discovery, DNS resolution, virtual networking, and HTTP proxying, integrating Hyperswarm
and Corestore
to achieve a decentralized DNS system. Here's an in-depth analysis:
Loading Environment Variables and Dependencies
The code initializes environment variables with dotenv
, allowing flexibility in configuring settings like masterNetworkDiscoveryKey
. This key enables peers to create isolated networks, ensuring only peers with the matching key can discover each other.
Dependencies:
exec
for executing shell commands.dgram
for UDP socket communication, essential for DNS operations.dns-packet
to handle DNS packet creation and decoding.HolesailClient
to manage P2P tunneling, essential for connecting domains over a decentralized network.Corestore
for distributed storage, managing and syncing domain records among peers.Hyperswarm
for peer discovery and creating P2P connections.http
to handle HTTP requests.crypto
to manage hashing for secure key generation and identification.
require('dotenv').config();
const { exec } = require('child_process');
const dgram = require('dgram');
const dnsPacket = require('dns-packet');
const HolesailClient = require('holesail-client');
const Corestore = require('corestore');
const Hyperswarm = require('hyperswarm');
const http = require('http');
const { createHash } = require('crypto');
const net = require('net');
Corestore and Hyperswarm Configuration
Here, Corestore
and Hyperswarm
are set up to manage decentralized DNS entries and establish peer-to-peer connections, respectively.
- Corestore serves as a distributed key-value store that allows DNS records to be synchronized across peers.
- Hyperswarm is initialized for P2P discovery, using a unique topic derived from
masterNetworkDiscoveryKey
ordnsCore.discoveryKey
. Only peers with matching topics can join the same swarm, allowing for secure data replication.
const store = new Corestore('./my-storage');
const swarm = new Hyperswarm();
const masterNetworkDiscoveryKey = process.env.masterNetworkDiscoveryKey
? Buffer.from(process.env.masterNetworkDiscoveryKey, 'hex')
: null;
const dnsCore = store.get({ name: 'dns-core' });
Virtual Network Interfaces for Domain Isolation
Domains are mapped to unique local IP addresses within the 192.168.100.x
subnet. This setup isolates each domain by assigning a virtual network interface for each, thus preventing conflict across domains.
removeExistingInterface
: Removes any existing virtual interface to avoid conflicts.createVirtualInterface
: Usesifconfig
to create a local network alias, ensuring each domain has a dedicated IP.createInterfaceForDomain
: Manages the IP assignment, incrementing thecurrentIP
for each new domain.
async function createVirtualInterface(subnetName, subnetCIDR) {
await removeExistingInterface(subnetName);
return new Promise((resolve, reject) => {
exec(`sudo ifconfig ${subnetName} alias ${subnetCIDR}`, (err, stdout, stderr) => {
if (err) {
console.error(`Error creating virtual interface ${subnetName}:`, stderr);
reject(`Error creating virtual interface ${subnetName}: ${stderr}`);
} else {
console.log(`Virtual interface ${subnetName} created with CIDR ${subnetCIDR}.`);
resolve(subnetCIDR);
}
});
});
}
DNS Server and Query Handling
The DNS server listens on UDP port 53, decoding and responding to DNS requests. It checks if a domain exists in the P2P DNS core, using fallback mechanisms if needed.
fetchP2PRecord
: Retrieves the domain’s hash from the P2P DNS core.checkPublicDNS
: Resolves domains outside the P2P network by querying Cloudflare’s 1.1.1.1 DNS server.- DNS Response Logic: If the domain exists in P2P DNS, it responds with the locally mapped IP; otherwise, it uses the public DNS result.
dnsServer.on('message', async (msg, rinfo) => {
const query = dnsPacket.decode(msg);
const domain = query.questions[0].name;
const p2pRecord = await fetchP2PRecord(domain);
const publicDNSRecords = await checkPublicDNS(domain);
if (p2pRecord) {
const localIP = await createInterfaceForDomain(domain);
startHolesailClient(domain, p2pRecord.hash, localIP, 80);
sendDNSResponse(dnsServer, query, rinfo, localIP);
} else if (publicDNSRecords) {
sendDNSResponse(dnsServer, query, rinfo, publicDNSRecords);
}
});
Holesail Client for Decentralized Tunneling and Connection Management
In this implementation, the Holesail client is central to achieving decentralized, peer-to-peer (P2P) tunneling, which allows domains to be accessible across peers without relying on a traditional DNS infrastructure. Holesail is a critical component, acting as a secure bridge for domain-specific connections.
Here's a breakdown of how Holesail functions within this system:
Purpose of Holesail in P2P Networking
The Holesail client facilitates direct communication between peers, bypassing the need for centralized servers by creating tunnels that connect domains across the network. Each domain entry has a unique hash, which Holesail uses to establish a tunnel. This unique hash acts as an identifier for each domain in the P2P network, ensuring traffic is routed accurately.
Key Functions and Features of Holesail
-
Starting Tunnels for P2P Domains: Holesail uses the domain’s
hash
(generated or retrieved from the P2P DNS core) as an anchor point for the tunnel connection. By associating the domain hash with a unique local IP and port, the Holesail client can reroute incoming requests to the correct peer over the network. -
Automatic Connection Monitoring and Restarting: Connections in a P2P network can be less stable than in traditional networking. Holesail monitors each tunnel’s status and automatically restarts connections if they become unresponsive. This feature is implemented through a responsive check on each domain’s port. If Holesail detects an issue, it recreates the interface for the domain and starts a new tunnel connection, ensuring continuity of service.
-
Connection Reusability: To optimize resources, Holesail reuses existing connections when possible. Each active connection is stored in the
activeConnections
object, which allows the client to check if a tunnel for a given domain is already active. If a tunnel is found, Holesail reuses it instead of initiating a new one, improving efficiency and reducing resource usage. -
Connection Lifecycle Management: Each Holesail connection has a lifecycle. To prevent stale or unresponsive connections from lingering, the client uses a timeout mechanism to automatically destroy and remove the tunnel from
activeConnections
after five minutes (300,000 ms). This cleanup process helps conserve resources and ensures only necessary connections remain active. -
Integration with Virtual Interface Management: When a new connection is needed for a domain, Holesail works alongside the
createInterfaceForDomain
function, which assigns a unique local IP to each domain. This allows domains to be isolated within the local network and ensures that each has a dedicated path through which Holesail can route traffic. By maintaining the virtual interface alongside the tunnel, Holesail manages traffic seamlessly across peers.
Code Example of Holesail Connection Management
Here's how Holesail is used to start and manage a P2P connection:
async function startHolesailClient(domain, hash, ip, port) {
logDebug(`Attempting to start/reuse Holesail client for domain: ${domain}`);
if (activeConnections[domain]) {
logDebug(`Reusing existing Holesail client for domain: ${domain} on ${ip}:${port}`);
return activeConnections[domain];
}
logDebug(`Starting new Holesail client for domain: ${domain}, hash: ${hash}, IP: ${ip}, Port: ${port}`);
const connector = setupConnector(hash);
const holesailClient = new HolesailClient(connector);
holesailClient.connect({ port: port, address: ip, reuseAddr: true }, () => {
logDebug(`Holesail client for ${domain} connected on ${ip}:${port}`);
});
activeConnections[domain] = holesailClient;
setTimeout(() => {
logDebug(`Destroying Holesail client for domain ${domain}`);
holesailClient.destroy();
delete activeConnections[domain];
}, 300000);
return holesailClient;
}
In this function:
setupConnector(hash)
sets up the connector with the domain’s hash, allowing Holesail to identify and route traffic correctly.holesailClient.connect()
initiates the connection to the specified IP and port, handling requests sent to the domain.- Timeout for Connection Lifecycle ensures the tunnel is automatically destroyed if unused, freeing up resources.
Holesail is essential for bridging the gap between DNS resolution and accessible peer connections. By using Holesail, each domain can securely connect across peers within the P2P network, overcoming traditional DNS constraints and enabling a scalable, decentralized DNS solution.
HTTP Proxy for Routing P2P Traffic
The HTTP proxy listens on port 80 and reroutes traffic to the appropriate IP for domains within the P2P network. This enables HTTP-based access for P2P-resolved domains.
http.createServer(async (req, res) => {
const domain = req.url.replace("/", "");
const localIP = await createInterfaceForDomain(domain);
await restartHolesailClient(domain, 'master_hash', localIP, 80);
const options = { hostname: localIP, port: 80, path: req.url, method: req.method, headers: req.headers };
const proxyRequest = http.request(options, (proxyRes) => {
res.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(res);
});
proxyRequest.on('error', () => res.writeHead(500).end('Error'));
req.pipe(proxyRequest);
}).listen(80, '127.0.0.1');
Synchronizing DNS Records Across Peers
The addDomain
function enables peers to add new domains to the P2P DNS system, appending records to dnsCore
, making them accessible and synchronized across the network.
async function addDomain(domain, hash) {
await dnsCore.ready();
const record = JSON.stringify({ domain, hash });
await dnsCore.append(Buffer.from(record));
logDebug(`Domain ${domain} added to DNS core`);
}
Hyperswarm Integration for Peer Synchronization
The DNS core joins the Hyperswarm network using the configured masterNetworkDiscoveryKey
, ensuring only authorized peers connect and sync DNS data.
(async () => {
await dnsCore.ready();
const topic = masterNetworkDiscoveryKey || dnsCore.discoveryKey;
logDebug(`DNS Core ready, joining Hyperswarm with topic: ${topic.toString('hex')}`);
swarm.join(topic, { server: true, client: true });
swarm.on('connection', (conn) => {
logDebug('Peer connected, starting replication...');
dnsCore.replicate(conn);
});
})();
Security and Privacy Implications
This P2P DNS system’s architecture offers significant privacy advantages. By decentralizing DNS queries and encrypting traffic over Holesail tunnels, it:
- Prevents ISPs from logging or tracking DNS requests.
- Protects DNS data from centralized surveillance or censorship.
- Enables users to create their own namespaces without interference from external authorities.
Use Cases: Expanding Applications Beyond Traditional DNS
The applications of this P2P DNS system are vast. Beyond typical DNS, it allows users to create isolated namespaces for organizational use, IoT device management, and censorship-resistant communication. By removing centralized control, it empowers users with autonomy and flexibility over their digital presence.
New Era of DNS Freedom
This decentralized, firewall-resistant P2P DNS system implemented in Node.js offers a resilient, censorship-resistant alternative to traditional DNS. By combining Corestore, Hyperswarm, and Holesail, it provides the infrastructure needed for a free, self-governing Internet. This DNS solution enables users around the world to reclaim control over their digital identities, creating a more open, accessible, and secure online ecosystem.