Compare commits
8 Commits
57930abc00
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
11792cba26
|
|||
|
901ea165e5
|
|||
|
1621d82c56
|
|||
|
a4e058fe53
|
|||
|
aadfc83e9d
|
|||
|
142b3f014b
|
|||
|
aa6431e6e7
|
|||
|
77293ba260
|
30
README.md
Normal file
30
README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# DNSControl Configuration
|
||||
|
||||
## Overview
|
||||
|
||||
| Domain | Purpose |
|
||||
|----------------|--------------------------------|
|
||||
| `arirex.me` | Primary domain |
|
||||
| `achl.fr` | Legacy domain |
|
||||
| `arirex.email` | Email proxy for primary domain |
|
||||
| `achlfr.email` | Email proxy for legacy domain |
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Unlock credentials
|
||||
git-crypt unlock
|
||||
|
||||
# Check planned changes
|
||||
dnscontrol preview
|
||||
|
||||
# Apply DNS changes
|
||||
dnscontrol push
|
||||
```
|
||||
|
||||
## Update
|
||||
|
||||
```bash
|
||||
nix flake update
|
||||
dnscontrol write-types
|
||||
```
|
||||
163
dnsconfig.js
163
dnsconfig.js
@@ -9,15 +9,24 @@ var DNS_CLOUDFLARE = NewDnsProvider("cloudflare");
|
||||
\* ****************************************************************************************************************** */
|
||||
var rexbox = "rexbox.prm.achl.fr.";
|
||||
var rexcloud = "rexcloud.cld.achl.fr.";
|
||||
var reportEmail = "0acbbb8a-1558-419a-ab2d-3f2773a1247d@arirex.email";
|
||||
var dmarcPolicy = "v=DMARC1; p=quarantine; adkim=s; aspf=s; rua=mailto:" + reportEmail + "; ruf=mailto:" + reportEmail + "; pct=100; fo=1";
|
||||
var reportEmail = "mailto:0acbbb8a-1558-419a-ab2d-3f2773a1247d@arirex.email";
|
||||
var dmarcRecord = DMARC_BUILDER({
|
||||
policy: "reject",
|
||||
subdomainPolicy: "reject",
|
||||
alignmentDKIM: "strict",
|
||||
alignmentSPF: "strict",
|
||||
rua: [reportEmail],
|
||||
ruf: [reportEmail],
|
||||
percent: 100,
|
||||
failureOptions: "1",
|
||||
});
|
||||
|
||||
DEFAULTS(
|
||||
DnsProvider(DNS_CLOUDFLARE),
|
||||
DefaultTTL(1),
|
||||
CF_MANAGE_COMMENTS, // opt into comments syncing
|
||||
CAA_BUILDER({
|
||||
iodef: "mailto:" + reportEmail,
|
||||
iodef: reportEmail,
|
||||
iodef_critical: true,
|
||||
issue: ["letsencrypt.org"],
|
||||
issue_critical: true,
|
||||
@@ -31,17 +40,26 @@ DEFAULTS(
|
||||
);
|
||||
|
||||
/* ****************************************************************************************************************** *\
|
||||
Primary Domains
|
||||
Managed Domains
|
||||
\* ****************************************************************************************************************** */
|
||||
|
||||
/* -------------------------------------------------------------------------- *\
|
||||
Primary Domains
|
||||
\* -------------------------------------------------------------------------- */
|
||||
D("arirex.me", REG_101DOMAIN,
|
||||
ALIAS("@", rexbox),
|
||||
protonmail("6fd60590dc31588ca5a85c7e311649ff5f93cab2", "dodai2qaszneyk5jeyfloq24ttjcqfer2gdopw3nfmxn3bugtw2hq"),
|
||||
|
||||
// Verifications
|
||||
TXT("@", "oa1:xmr recipient_address=89dQNyY3E9gJGYrEeRw4EFAdezWQg7BBbHJdBpLRwrjH52ngNfAYRcEhAHQotCswGxTeSoFi5nQ7Gf86kySmXzuQE9CXjUH; recipient_name=AriRexouium;", CF_COMMENT("OpenAlias > XMR > Kraken")),
|
||||
TXT("_discord", "dh=1c93b7effbe0bf428cb55d33175c2721ef715bb6", CF_COMMENT("Discord Verify")),
|
||||
TXT("_atproto", "did=did:plc:53kf45pcsqgayjmoau42lhsk", CF_COMMENT("BlueSky Verify")),
|
||||
TXT("_github-pages-challenge-arirexouium", "0b62c2fb7a8422145d5b5e6637257d", CF_COMMENT("GitHub Pages Verify")),
|
||||
|
||||
// OpenAlias
|
||||
openalias("xmr", "89dQNyY3E9gJGYrEeRw4EFAdezWQg7BBbHJdBpLRwrjH52ngNfAYRcEhAHQotCswGxTeSoFi5nQ7Gf86kySmXzuQE9CXjUH", {
|
||||
name: "AriRexouium",
|
||||
checksum: true,
|
||||
}),
|
||||
);
|
||||
|
||||
D("achl.fr", REG_101DOMAIN,
|
||||
@@ -56,12 +74,11 @@ D("achl.fr", REG_101DOMAIN,
|
||||
// Verifications
|
||||
TXT("_discord", "dh=d041188169640d1f23c6b379d97935981a7a07da", CF_COMMENT("Discord Verify")),
|
||||
TXT("_github-pages-challenge-arirexouium", "134234f292827135d74e0637efc575", CF_COMMENT("GitHub Pages Verify")),
|
||||
|
||||
);
|
||||
|
||||
/* ****************************************************************************************************************** *\
|
||||
/* -------------------------------------------------------------------------- *\
|
||||
Email Proxy Domains
|
||||
\* ****************************************************************************************************************** */
|
||||
\* -------------------------------------------------------------------------- */
|
||||
D("arirex.email", REG_101DOMAIN,
|
||||
simplelogin("ngmfowygibangqmiobjznfmjhxniyi"),
|
||||
);
|
||||
@@ -82,32 +99,32 @@ cnames("arirex.me", rexbox, [
|
||||
"Enclosed@bin",
|
||||
"IT Tools@it",
|
||||
"Karakeep@karakeep",
|
||||
"Matrix / Client@chat",
|
||||
"Matrix / Server@matrix",
|
||||
"Minecraft@mc",
|
||||
"Matrix > Client@chat",
|
||||
"Matrix > Server@matrix",
|
||||
"Ntfy@ntfy",
|
||||
"OpenWebUI@ai",
|
||||
"Pocket ID@id",
|
||||
// "Prompts@prompts",
|
||||
"Traefik@traefik",
|
||||
"Traefik Forward Auth@auth",
|
||||
]);
|
||||
|
||||
cnames("achl.fr", rexbox, [
|
||||
"Matrix / Client@chat",
|
||||
"Matrix / Server@matrix",
|
||||
"Matrix > Client@chat",
|
||||
"Matrix > Server@matrix",
|
||||
]);
|
||||
|
||||
minecraft("Frantic", "frantic.mc", "arirex.me", 63548);
|
||||
minecraft("The Furry Cult", "thefurrycult.mc", "arirex.me", 54924);
|
||||
|
||||
/* -------------------------------------------------------------------------- *\
|
||||
RexCloud Services
|
||||
\* -------------------------------------------------------------------------- */
|
||||
cnames("arirex.me", rexcloud, [
|
||||
"Beszel@beszel",
|
||||
"Gitea@git",
|
||||
"IPFS Subdomain Gateway@*.ipfs.gw",
|
||||
"IPFS Subdomain Gateway@*.ipns.gw",
|
||||
"IPFS Path Gateway@gw",
|
||||
// "LibreSpeed@speedtest",
|
||||
// "IPFS Subdomain Gateway@*.ipfs.gw",
|
||||
// "IPFS Subdomain Gateway@*.ipns.gw",
|
||||
// "IPFS Path Gateway@gw",
|
||||
"SearXNG@search",
|
||||
]);
|
||||
|
||||
@@ -129,6 +146,9 @@ cnames("arirex.me", rexcloud, [
|
||||
Helper Functions
|
||||
\* ****************************************************************************************************************** */
|
||||
|
||||
/* -------------------------------------------------------------------------- *\
|
||||
Basic Builders
|
||||
\* -------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Create CNAME records from "comment@subdomain" strings
|
||||
* @param {string} domain - Domain to extend
|
||||
@@ -136,12 +156,30 @@ cnames("arirex.me", rexcloud, [
|
||||
* @param {string[]} records - Array of "comment@subdomain" strings
|
||||
*/
|
||||
function cnames(domain, target, records) {
|
||||
records.forEach(function(r) {
|
||||
var parts = r.split("@");
|
||||
D_EXTEND(domain, CNAME(parts[1], target, CF_COMMENT(parts[0])));
|
||||
records.forEach(function(rec) {
|
||||
var part = rec.split("@");
|
||||
D_EXTEND(domain, CNAME(part[1], target, CF_COMMENT(part[0])));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Minecraft server subdomain with CNAME and SRV records
|
||||
* @param {string} comment - Human-readable server name
|
||||
* @param {string} subdomain - Subdomain for the server
|
||||
* @param {string} domain - Domain to extend
|
||||
* @param {number} port - Port the server listens on
|
||||
*/
|
||||
function minecraft(comment, subdomain, domain, port) {
|
||||
var fqdn = subdomain + "." + domain + ".";
|
||||
D_EXTEND(domain,
|
||||
CNAME(subdomain, rexbox, CF_COMMENT("Minecraft > " + comment)),
|
||||
SRV("_minecraft._tcp." + subdomain, 0, 0, port, fqdn, CF_COMMENT("Minecraft > " + comment)),
|
||||
);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- *\
|
||||
Email Builders
|
||||
\* -------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Generate ProtonMail DNS records (MX, SPF, DMARC, verification, DKIM)
|
||||
* @param {string} verification - ProtonMail verification token
|
||||
@@ -150,14 +188,19 @@ function cnames(domain, target, records) {
|
||||
*/
|
||||
function protonmail(verification, dkimKey) {
|
||||
return [
|
||||
// Stage 1: Verify
|
||||
TXT("@", "protonmail-verification=" + verification, CF_COMMENT("ProtonMail Verify")),
|
||||
// Stage 2: MX
|
||||
MX("@", 10, "mail.protonmail.ch.", CF_COMMENT("ProtonMail MX")),
|
||||
MX("@", 20, "mailsec.protonmail.ch.", CF_COMMENT("ProtonMail MX")),
|
||||
// Stage 3: SPF
|
||||
TXT("@", "v=spf1 include:_spf.protonmail.ch mx ~all", CF_COMMENT("ProtonMail SPF")),
|
||||
TXT("@", "protonmail-verification=" + verification, CF_COMMENT("ProtonMail Verify")),
|
||||
TXT("_dmarc", dmarcPolicy, CF_COMMENT("ProtonMail DMARC")),
|
||||
// Stage 3: DKIM
|
||||
CNAME("protonmail._domainkey", "protonmail.domainkey." + dkimKey + ".domains.proton.ch.", CF_COMMENT("ProtonMail DKIM")),
|
||||
CNAME("protonmail2._domainkey", "protonmail2.domainkey." + dkimKey + ".domains.proton.ch.", CF_COMMENT("ProtonMail DKIM")),
|
||||
CNAME("protonmail3._domainkey", "protonmail3.domainkey." + dkimKey + ".domains.proton.ch.", CF_COMMENT("ProtonMail DKIM")),
|
||||
// Stage 4: DMARC
|
||||
dmarcRecord,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -168,13 +211,83 @@ function protonmail(verification, dkimKey) {
|
||||
*/
|
||||
function simplelogin(verification) {
|
||||
return [
|
||||
// Stage 1: Verify
|
||||
TXT("@", "sl-verification=" + verification, CF_COMMENT("SimpleLogin Verify")),
|
||||
// Stage 2: MX
|
||||
MX("@", 10, "mx1.simplelogin.co.", CF_COMMENT("SimpleLogin MX")),
|
||||
MX("@", 20, "mx2.simplelogin.co.", CF_COMMENT("SimpleLogin MX")),
|
||||
// Stage 3: SPF
|
||||
TXT("@", "v=spf1 include:simplelogin.co ~all", CF_COMMENT("SimpleLogin SPF")),
|
||||
TXT("@", "sl-verification=" + verification, CF_COMMENT("SimpleLogin Verify")),
|
||||
TXT("_dmarc", dmarcPolicy, CF_COMMENT("SimpleLogin DMARC")),
|
||||
// Stage 4: DKIM
|
||||
CNAME("dkim._domainkey", "dkim._domainkey.simplelogin.co.", CF_COMMENT("SimpleLogin DKIM")),
|
||||
CNAME("dkim02._domainkey", "dkim02._domainkey.simplelogin.co.", CF_COMMENT("SimpleLogin DKIM")),
|
||||
CNAME("dkim03._domainkey", "dkim03._domainkey.simplelogin.co.", CF_COMMENT("SimpleLogin DKIM")),
|
||||
// Stage 5: DMARC
|
||||
dmarcRecord,
|
||||
];
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- *\
|
||||
Open Alias Builder
|
||||
\* -------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Generate OpenAlias TXT record
|
||||
* @param {string} prefix - Application prefix (e.g., "xmr", "btc")
|
||||
* @param {string} address - Recipient address
|
||||
* @param {object} [opts] - Optional key-value pairs
|
||||
* @param {string} [opts.name] - Recipient name
|
||||
* @param {string} [opts.description] - Transaction description
|
||||
* @param {string} [opts.amount] - Transaction amount
|
||||
* @param {string} [opts.paymentId] - Payment ID (e.g., for Monero)
|
||||
* @param {string} [opts.signature] - Address signature
|
||||
* @param {boolean} [opts.checksum] - Optional CRC-32 checksum
|
||||
* @returns {DomainModifier} TXT record
|
||||
*/
|
||||
function openalias(prefix, address, opts) {
|
||||
// Prefix and address are minimum requirement.
|
||||
// Everything else is optional.
|
||||
|
||||
opts = opts || {};
|
||||
var record = "oa1:" + prefix + " recipient_address=" + address + ";";
|
||||
|
||||
if (opts.name) { record += " recipient_name=" + opts.name + ";"; }
|
||||
if (opts.description) { record += " tx_description=" + opts.description + ";"; }
|
||||
if (opts.amount) { record += " tx_amount=" + opts.amount + ";"; }
|
||||
if (opts.paymentId) { record += " tx_payment_id=" + opts.paymentId + ";"; }
|
||||
if (opts.signature) { record += " address_signature=" + opts.signature + ";"; }
|
||||
if (opts.checksum) { record += " checksum=" + crc32(record.trim()).toString(16).toUpperCase() + ";"; }
|
||||
// Checksum must be last: CRC-32 of the record trimmed of surrounding spaces.
|
||||
|
||||
return TXT("@", record, CF_COMMENT("OpenAlias > " + prefix.toUpperCase() + (opts.name ? " > " + opts.name : "")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate CRC-32 checksum of a string
|
||||
* Handles UTF-8 strings correctly for use with DNSControl.
|
||||
* @param {string} str - Input string
|
||||
* @returns {number} CRC-32 value
|
||||
* @see https://github.com/nabijaczleweli/openalias.rs/blob/master/src/crypto_addr.rs
|
||||
*/
|
||||
function crc32(str) {
|
||||
// 1. Generate the CRC Table
|
||||
var table = [];
|
||||
for (var i = 0; i < 256; i++) {
|
||||
var c = i;
|
||||
for (var j = 0; j < 8; j++) {
|
||||
c = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);
|
||||
}
|
||||
table[i] = c;
|
||||
}
|
||||
|
||||
// 2. Convert string to UTF-8 "binary" string
|
||||
// This ensures characters like '€' are treated as 3 bytes, not 1.
|
||||
var utf8Str = unescape(encodeURIComponent(str));
|
||||
|
||||
// 3. Calculate CRC
|
||||
var crc = 0xFFFFFFFF;
|
||||
for (var k = 0; k < utf8Str.length; k++) {
|
||||
crc = table[(crc ^ utf8Str.charCodeAt(k)) & 0xFF] ^ (crc >>> 8);
|
||||
}
|
||||
|
||||
return (crc ^ 0xFFFFFFFF) >>> 0;
|
||||
}
|
||||
|
||||
6
flake.lock
generated
6
flake.lock
generated
@@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1772773019,
|
||||
"narHash": "sha256-E1bxHxNKfDoQUuvriG71+f+s/NT0qWkImXsYZNFFfCs=",
|
||||
"lastModified": 1773821835,
|
||||
"narHash": "sha256-TJ3lSQtW0E2JrznGVm8hOQGVpXjJyXY2guAxku2O9A4=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "aca4d95fce4914b3892661bcb80b8087293536c6",
|
||||
"rev": "b40629efe5d6ec48dd1efba650c797ddbd39ace0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
2
types-dnscontrol.d.ts
vendored
2
types-dnscontrol.d.ts
vendored
@@ -1,7 +1,7 @@
|
||||
// This file was automatically generated by DNSControl. Do not edit it directly.
|
||||
// To update it, run `dnscontrol write-types`.
|
||||
|
||||
// 4.35.0
|
||||
// 4.36.1
|
||||
// WARNING: These type definitions are experimental and subject to change in future releases.
|
||||
|
||||
interface Domain {
|
||||
|
||||
Reference in New Issue
Block a user