5afb9f48f5
Extends OpenAlias configuration with Bitcoin, Ethereum, and Litecoin donation addresses alongside the existing Monero entry. Also tightens the openalias() helper to use strict type checks.
294 lines
12 KiB
JavaScript
294 lines
12 KiB
JavaScript
// @ts-check
|
|
/// <reference path="types-dnscontrol.d.ts" />
|
|
|
|
var REG_101DOMAIN = NewRegistrar("none");
|
|
var DNS_CLOUDFLARE = NewDnsProvider("cloudflare");
|
|
|
|
/* ****************************************************************************************************************** *\
|
|
Defaults & Common Records
|
|
\* ****************************************************************************************************************** */
|
|
var rexbox = "rexbox.prm.achl.fr.";
|
|
var rexcloud = "rexcloud.cld.achl.fr.";
|
|
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: reportEmail,
|
|
iodef_critical: true,
|
|
issue: ["letsencrypt.org"],
|
|
issue_critical: true,
|
|
issuewild: ["letsencrypt.org"],
|
|
issuewild_critical: true,
|
|
issuevmc: "none",
|
|
issuevmc_critical: true,
|
|
issuemail: "none",
|
|
issuemail_critical: true,
|
|
}),
|
|
);
|
|
|
|
/* ****************************************************************************************************************** *\
|
|
Managed Domains
|
|
\* ****************************************************************************************************************** */
|
|
|
|
/* -------------------------------------------------------------------------- *\
|
|
Primary Domains
|
|
\* -------------------------------------------------------------------------- */
|
|
D("arirex.me", REG_101DOMAIN,
|
|
ALIAS("@", rexbox),
|
|
protonmail("6fd60590dc31588ca5a85c7e311649ff5f93cab2", "dodai2qaszneyk5jeyfloq24ttjcqfer2gdopw3nfmxn3bugtw2hq"),
|
|
|
|
// Verifications
|
|
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, }),
|
|
openalias("btc", "3DQEYUDquSvh6DX54o2Gw1TXT9ZGWWoRTh", { name: "AriRexouium", checksum: true, }),
|
|
openalias("eth", "0x3489c73A2F3DE6236624d43a3767f4dB8181d0c4", { name: "AriRexouium", checksum: true, }),
|
|
openalias("ltc", "Lg6sV5PfRrBvpQoAzsyCcWMs26aq5VBssS", { name: "AriRexouium", checksum: true, }),
|
|
);
|
|
|
|
D("achl.fr", REG_101DOMAIN,
|
|
ALIAS("@", rexbox),
|
|
protonmail("a5142b961ee71079de475ab173095ae7a8497159", "dptdmdzwbeybqhgo544aqzi6w7vqiojzxbbm6hoev3nni5kewj4ga"),
|
|
|
|
// On-prem & Cloud Servers
|
|
IGNORE("rexbox.prm", "A"), // Managed by qmcgaw/ddns-updater
|
|
A("rexcloud.cld", "5.161.231.128"),
|
|
AAAA("rexcloud.cld", "2a01:4ff:f0:e504::"),
|
|
|
|
// 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"),
|
|
);
|
|
|
|
D("achlfr.email", REG_101DOMAIN,
|
|
simplelogin("rsykypqtapcymkryscyoajdlajvqmx"),
|
|
);
|
|
|
|
/* ****************************************************************************************************************** *\
|
|
Service Records
|
|
\* ****************************************************************************************************************** */
|
|
|
|
/* -------------------------------------------------------------------------- *\
|
|
RexBox Services
|
|
\* -------------------------------------------------------------------------- */
|
|
cnames("arirex.me", rexbox, [
|
|
"Chhoto URL@l",
|
|
"Enclosed@bin",
|
|
"IT Tools@it",
|
|
"Karakeep@karakeep",
|
|
"Matrix > Client@chat",
|
|
"Matrix > Server@matrix",
|
|
"Ntfy@ntfy",
|
|
"OpenWebUI@ai",
|
|
"Pocket ID@id",
|
|
"Traefik@traefik",
|
|
"Traefik Forward Auth@auth",
|
|
]);
|
|
|
|
cnames("achl.fr", rexbox, [
|
|
"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",
|
|
"SearXNG@search",
|
|
]);
|
|
|
|
/* -------------------------------------------------------------------------- *\
|
|
Media Server
|
|
\* -------------------------------------------------------------------------- */
|
|
[
|
|
"qBittorrent", // Downloader
|
|
"Jellyfin", "Jellyseerr", // Provider & Requester
|
|
"Prowlarr", "Profilarr", // Synchronization
|
|
"Radarr", "Sonarr", "Lidarr", // Movies, Shows, Music
|
|
].forEach(function(i) {
|
|
D_EXTEND("arirex.me",
|
|
CNAME(i.toLowerCase() + ".servarr", rexbox, CF_COMMENT(i))
|
|
);
|
|
});
|
|
|
|
/* ****************************************************************************************************************** *\
|
|
Helper Functions
|
|
\* ****************************************************************************************************************** */
|
|
|
|
/* -------------------------------------------------------------------------- *\
|
|
Basic Builders
|
|
\* -------------------------------------------------------------------------- */
|
|
/**
|
|
* Create CNAME records from "comment@subdomain" strings
|
|
* @param {string} domain - Domain to extend
|
|
* @param {string} target - Server target
|
|
* @param {string[]} records - Array of "comment@subdomain" strings
|
|
*/
|
|
function cnames(domain, target, records) {
|
|
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
|
|
* @param {string} dkimKey - ProtonMail DKIM domain key
|
|
* @returns {DomainModifier[]} Array of DNS 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")),
|
|
// 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,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Generate SimpleLogin DNS records (MX, SPF, DMARC, verification, DKIM)
|
|
* @param {string} verification - SimpleLogin verification token
|
|
* @returns {DomainModifier[]} Array of DNS records
|
|
*/
|
|
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")),
|
|
// 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,
|
|
];
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- *\
|
|
OpenAlias 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 (typeof opts.name === "string") record += " recipient_name=" + opts.name + ";";
|
|
if (typeof opts.description === "string") record += " tx_description=" + opts.description + ";";
|
|
if (typeof opts.amount === "string") record += " tx_amount=" + opts.amount + ";";
|
|
if (typeof opts.paymentId === "string") record += " tx_payment_id=" + opts.paymentId + ";";
|
|
if (typeof opts.signature === "string") record += " address_signature=" + opts.signature + ";";
|
|
if (opts.checksum === true) 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;
|
|
}
|