278 lines
20 KiB
Markdown
278 lines
20 KiB
Markdown
<!-- lead -->
|
||
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.
|
||
|
||
```bash
|
||
[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
|
||
```
|
||
|
||
[![screenshot](https://git.ssh.surf/snxraven/p2ns/raw/branch/main/images/sc.webp)](https://git.ssh.surf/snxraven/p2ns/raw/branch/main/images/sc.webp)
|
||
|
||
# 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.
|
||
|
||
## Code Walkthrough
|
||
|
||
This implementation consists of multiple components, from peer discovery to DNS handling and HTTP proxying. Let’s explore each section in detail.
|
||
|
||
### Environment Variables and Dependencies
|
||
|
||
The code starts by loading environment variables and initializing necessary dependencies. The environment variable `masterNetworkDiscoveryKey` allows for creating isolated DNS networks, where only peers with the same key can discover each other.
|
||
|
||
```javascript
|
||
require('dotenv').config(); // Load environment variables
|
||
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 b4a = require('b4a');
|
||
const { createHash } = require('crypto');
|
||
const net = require('net');
|
||
```
|
||
|
||
### Corestore and Hyperswarm Setup for P2P Synchronization
|
||
|
||
The P2P DNS system uses **Corestore** for decentralized data storage and **Hyperswarm** for peer discovery and connectivity. These allow peers to sync domain records in a distributed network.
|
||
|
||
- **Corestore** is used to manage DNS data in a decentralized way. Each domain and its hash are stored in `dnsCore`, a key-value store that synchronizes records across peers.
|
||
- **Hyperswarm** creates a P2P network where peers with the same discovery key (generated from `masterNetworkDiscoveryKey` or `dnsCore.discoveryKey`) can connect and sync their data.
|
||
|
||
```javascript
|
||
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' });
|
||
|
||
console.log(`Loaded masterNetworkDiscoveryKey: ${masterNetworkDiscoveryKey ? masterNetworkDiscoveryKey.toString('hex') : 'None'}`);
|
||
```
|
||
|
||
### Virtual Interface Creation and IP Mapping
|
||
|
||
To handle P2P domains locally, the system creates virtual network interfaces (on macOS) and assigns IPs in the range `192.168.100.x`. Each domain is mapped to a unique IP, allowing it to be isolated within the local subnet.
|
||
|
||
The function `createVirtualInterface` uses `ifconfig` to create a network interface alias for each domain.
|
||
|
||
```javascript
|
||
async function createVirtualInterface(subnetName, subnetCIDR) {
|
||
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);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
```
|
||
|
||
The `createInterfaceForDomain` function manages the automatic IP assignment by creating virtual interfaces for each domain and incrementing the IP range.
|
||
|
||
```javascript
|
||
async function createInterfaceForDomain(domain) {
|
||
const subnetID = currentIP;
|
||
const subnetName = `lo0`;
|
||
const subnetCIDR = `192.168.100.${subnetID}/24`;
|
||
|
||
await createVirtualInterface(subnetName, subnetCIDR);
|
||
domainToIPMap[domain] = `192.168.100.${subnetID}`;
|
||
currentIP++;
|
||
return domainToIPMap[domain];
|
||
}
|
||
```
|
||
|
||
### DNS Server and Query Handling
|
||
|
||
The DNS server uses `dgram` to listen on UDP port 53, processing incoming DNS requests. It checks whether the requested domain exists in the P2P DNS core or falls back on a public DNS lookup.
|
||
|
||
```javascript
|
||
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);
|
||
}
|
||
});
|
||
```
|
||
|
||
The function `checkPublicDNS` queries Cloudflare's 1.1.1.1 DNS server to resolve domains not available in the P2P DNS.
|
||
|
||
### Holesail Client for P2P Tunneling and Connection Management
|
||
|
||
Holesail provides the essential P2P tunneling required to maintain decentralized DNS connections across peers. Each domain is associated with a unique `hash`, which Holesail uses to establish a tunnel between peers. Connections are automatically restarted if they become unresponsive.
|
||
|
||
```javascript
|
||
async function restartHolesailClient(domain, hash, ip, port) {
|
||
if (!await checkPortResponsive(ip, port)) {
|
||
logDebug(`Port ${port} on ${ip} is unresponsive; restarting Holesail client`);
|
||
if (activeConnections[domain]) {
|
||
activeConnections[domain].destroy();
|
||
delete activeConnections[domain];
|
||
}
|
||
await createInterfaceForDomain(domain);
|
||
startHolesailClient(domain, hash, ip, port);
|
||
}
|
||
}
|
||
```
|
||
|
||
### HTTP Proxy for Accessing P2P Domains
|
||
|
||
The HTTP proxy listens on port 80 and routes traffic to domains in the P2P network. It uses the Holesail tunnel to establish connections and proxy HTTP requests to the correct IP.
|
||
|
||
```javascript
|
||
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');
|
||
```
|
||
|
||
### Syncing TLDs and Hashes Across Peers
|
||
|
||
The `addDomain` function is used to append new domains and their associated hashes to the `dnsCore`. This ensures the domain records are accessible and synchronized across all peers in the P2P network.
|
||
|
||
```javascript
|
||
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 and DNS Core Synchronization
|
||
|
||
Upon startup, the system joins the Hyperswarm network with a unique topic derived from either the `masterNetworkDiscoveryKey` or `dnsCore.discoveryKey`. This allows only peers with the same discovery key to join the same network, effectively isolating private networks.
|
||
|
||
```javascript
|
||
(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);
|
||
});
|
||
})();
|
||
```
|
||
|
||
This configuration ensures that only peers with matching keys or topics can access and replicate DNS data, allowing for both public and private P2P DNS networks.
|
||
|
||
## 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. |