stage-fed-b federation: dns record format
This commit is contained in:
@@ -18,6 +18,7 @@ from typing import Tuple
|
||||
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ed25519
|
||||
from pydantic import BaseModel
|
||||
|
||||
from psyc import DATA_DIR, log
|
||||
|
||||
@@ -28,6 +29,10 @@ FED_DIR = DATA_DIR / "federation"
|
||||
PRIVATE_KEY_PATH = FED_DIR / "node.key"
|
||||
PUBLIC_KEY_PATH = FED_DIR / "node.pub"
|
||||
|
||||
FEED_VERSION = "psyc1"
|
||||
FEED_ALG = "ed25519"
|
||||
FEED_PATH = "/federation/feed"
|
||||
|
||||
|
||||
# ---------- keypair persistence -----------------------------------------
|
||||
|
||||
@@ -93,3 +98,56 @@ def node_fingerprint() -> str:
|
||||
_, pub = node_keypair()
|
||||
digest = hashlib.sha256(_raw_pubkey_bytes(pub)).digest()
|
||||
return digest[:16].hex()
|
||||
|
||||
|
||||
def _fingerprint_for_pubkey_pem(pubkey_pem: str) -> str:
|
||||
pub = serialization.load_pem_public_key(pubkey_pem.encode("ascii"))
|
||||
if not isinstance(pub, ed25519.Ed25519PublicKey):
|
||||
raise ValueError("not an Ed25519 public key")
|
||||
return hashlib.sha256(_raw_pubkey_bytes(pub)).digest()[:16].hex()
|
||||
|
||||
|
||||
# ---------- DNS record format -------------------------------------------
|
||||
|
||||
class DNSRecord(BaseModel):
|
||||
"""The SRV + TXT pair an admin pastes into their zone file."""
|
||||
srv_name: str
|
||||
srv_target: str
|
||||
srv_port: int
|
||||
srv_priority: int = 10
|
||||
srv_weight: int = 10
|
||||
txt_name: str
|
||||
txt_value: str
|
||||
human_instructions: str
|
||||
|
||||
|
||||
def dns_record(domain: str, port: int = 443) -> DNSRecord:
|
||||
"""Build the DNS-SD-style records that advertise this node at `domain`."""
|
||||
fp = node_fingerprint()
|
||||
srv_name = f"_psyc._tcp.{domain}"
|
||||
srv_target = f"{domain}."
|
||||
txt_name = srv_name
|
||||
txt_value = f"v={FEED_VERSION} fp={fp} alg={FEED_ALG} path={FEED_PATH}"
|
||||
instructions = (
|
||||
f"; psyc federation records for {domain}\n"
|
||||
f"; ----------------------------------------------------------\n"
|
||||
f"; 1) SRV record — locates this psyc node (host + port).\n"
|
||||
f'{srv_name}. 3600 IN SRV 10 10 {port} {srv_target}\n'
|
||||
f";\n"
|
||||
f"; 2) TXT record — declares protocol version, key fingerprint,\n"
|
||||
f"; signature algorithm, and the feed endpoint path.\n"
|
||||
f'{txt_name}. 3600 IN TXT "{txt_value}"\n'
|
||||
f"; ----------------------------------------------------------\n"
|
||||
f"; Once these are live, federation peers can fetch:\n"
|
||||
f"; https://{domain}{FEED_PATH} (signed feed JSON)\n"
|
||||
f"; https://{domain}/federation/key (public key PEM)\n"
|
||||
f"; https://{domain}/federation/info (capabilities)\n"
|
||||
)
|
||||
return DNSRecord(
|
||||
srv_name=srv_name,
|
||||
srv_target=srv_target,
|
||||
srv_port=port,
|
||||
txt_name=txt_name,
|
||||
txt_value=txt_value,
|
||||
human_instructions=instructions,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user