Initial commit: DDNS service with NIC V2 protocol support

Features:
- Token-based subdomain claiming
- NIC V2 (DynDNS2) protocol implementation
- Technitium DNS integration
- Rate limiting (10 req/min IP, 1 req/min token)
- Web UI for space claiming
- Docker/Docker Compose support
- Compatible with UniFi, pfSense, EdgeRouter

Module: git.dws.rip/DWS/dyn
This commit is contained in:
2026-02-01 16:37:09 -05:00
commit 2470f121e2
16 changed files with 1835 additions and 0 deletions

118
web/templates/index.html Normal file
View File

@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DWS Dynamic DNS</title>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="container">
<header>
<h1>🌐 DWS Dynamic DNS</h1>
<p>Claim your space under {{.zone}}</p>
</header>
<main>
<section id="claim-section" class="card">
<h2>Claim Your Space</h2>
<form id="claim-form">
<div class="input-group">
<input type="text"
id="subdomain"
name="subdomain"
placeholder="your-name"
maxlength="63"
autocomplete="off"
pattern="[a-z0-9-]+"
required>
<span class="domain-suffix">.{{.zone}}</span>
</div>
<div id="availability-status" class="status"></div>
<button type="submit" id="claim-btn" disabled>Claim Space</button>
</form>
</section>
<section id="success-section" class="card hidden">
<h2>✅ Space Claimed!</h2>
<div class="token-display">
<p><strong>Your Token (save this!):</strong></p>
<code id="token-value" class="token"></code>
<button id="copy-token" class="btn-secondary">Copy Token</button>
</div>
<div class="fqdn-display">
<p>Your hostname:</p>
<code id="fqdn-value"></code>
</div>
</section>
<section id="router-config" class="card hidden">
<h2>Router Configuration</h2>
<p>Use these settings in your router's Dynamic DNS configuration:</p>
<div class="config-grid">
<div class="config-item">
<label>Service:</label>
<code>Custom</code>
</div>
<div class="config-item">
<label>Update URL:</label>
<code id="update-url"></code>
</div>
<div class="config-item">
<label>Username:</label>
<code>none</code>
</div>
<div class="config-item">
<label>Password:</label>
<code id="password-value">(your token above)</code>
</div>
</div>
<div class="examples">
<h3>Example Configurations</h3>
<div class="example">
<h4>UniFi / UDM</h4>
<ul>
<li><strong>Service:</strong> dyndns</li>
<li><strong>Hostname:</strong> <span class="hostname-placeholder"></span></li>
<li><strong>Username:</strong> none</li>
<li><strong>Password:</strong> <em>your token</em></li>
<li><strong>Server:</strong> dyn.{{.baseDomain}}/api/nic/update</li>
</ul>
</div>
<div class="example">
<h4>pfSense / OPNsense</h4>
<ul>
<li><strong>Service Type:</strong> Custom</li>
<li><strong>Update URL:</strong> <span class="update-url-placeholder"></span></li>
<li><strong>Username:</strong> none</li>
<li><strong>Password:</strong> <em>your token</em></li>
</ul>
</div>
<div class="example">
<h4>cURL Test</h4>
<pre><code id="curl-example"></code></pre>
<button id="copy-curl" class="btn-secondary">Copy</button>
</div>
</div>
</section>
<section id="error-section" class="card hidden error">
<h2>❌ Error</h2>
<p id="error-message"></p>
<button id="try-again" class="btn-secondary">Try Again</button>
</section>
</main>
<footer>
<p>DWS Dynamic DNS Service</p>
</footer>
</div>
<script src="/static/js/app.js"></script>
</body>
</html>