<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Daniel Magyar</title><description>Cloud &amp; GenAI engineer</description><link>https://danielmagyar.com/</link><language>en</language><item><title>Rebuilding danielmagyar.com: the parts that broke</title><link>https://danielmagyar.com/posts/rebuilding-danielmagyar-com/</link><guid isPermaLink="true">https://danielmagyar.com/posts/rebuilding-danielmagyar-com/</guid><description>Moving a domain to Cloudflare, email to Google Workspace, and a personal site off a template, and the things that went wrong on the way.</description><pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For about two years danielmagyar.com pointed at a single static page on GitHub Pages. It had my
name, a job title, and three links. It was fine in the way that a placeholder is fine.&lt;/p&gt;
&lt;p&gt;This is what replacing it actually involved, mostly the parts that didn&apos;t go to plan, because those
are the parts worth writing down.&lt;/p&gt;
&lt;h2&gt;Starting with DNS, not the site&lt;/h2&gt;
&lt;p&gt;The obvious first move is to build the site. It&apos;s the wrong one. The site is the easy part; the
domain and email underneath it are what everything else depends on, and they&apos;re what you don&apos;t want
to touch twice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So&lt;/strong&gt;: nameservers from Namecheap to Cloudflare first, site later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The trap&lt;/strong&gt;: DNSSEC ordering. If your domain has DNSSEC enabled at the registrar and you point the
nameservers somewhere new, the DS record still published at the registry no longer matches what the
new nameservers are signing. Validating resolvers don&apos;t fall back gracefully. They return SERVFAIL.
Your domain goes dark for a large share of the internet, and you can&apos;t fix it quickly because the DS
record has its own TTL to wait out.&lt;/p&gt;
&lt;p&gt;The order is non-negotiable:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Disable DNSSEC at the registrar&lt;/li&gt;
&lt;li&gt;Wait for the DS record to clear&lt;/li&gt;
&lt;li&gt;Change nameservers&lt;/li&gt;
&lt;li&gt;Wait for the new zone to go active&lt;/li&gt;
&lt;li&gt;Re-enable DNSSEC at the new provider&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;The misconception&lt;/strong&gt;: TTLs. Every migration guide tells you to lower your record TTLs before cutting
over, and that&apos;s good advice, but it doesn&apos;t do what people think for a nameserver change. Record
TTLs govern records. The nameserver delegation is governed by the NS TTL at the TLD registry, which
for .com is cached at 48 hours and isn&apos;t yours to change.&lt;/p&gt;
&lt;p&gt;For most of two days, some resolvers asked Namecheap and some asked Cloudflare. Nothing broke, and
not because of TTLs: both sets of nameservers answered identically. Record parity across the overlap
window is the actual safety net. Don&apos;t delete anything at the old provider until you&apos;ve verified the
new one.&lt;/p&gt;
&lt;h2&gt;Email, which is where it got interesting&lt;/h2&gt;
&lt;p&gt;The domain had been on Namecheap&apos;s Private Email. The plan was Google Workspace, partly for the
mailbox and partly because I wanted an identity provider to wire into AWS later.&lt;/p&gt;
&lt;p&gt;Two things went wrong immediately.&lt;/p&gt;
&lt;p&gt;Signup was blocked by an account I&apos;d forgotten creating. Workspace refused the address I wanted:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;this email address is associated with another Google service&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At some point I&apos;d used that address to sign into something Google-adjacent, and Google had quietly
created a consumer account around it. You can&apos;t create a managed Workspace account at an address a
consumer account already occupies.&lt;/p&gt;
&lt;p&gt;The fix isn&apos;t obvious: you add Gmail to the existing consumer account. Doing so permanently changes
that account&apos;s primary username to the new @gmail.com address and demotes the original to an
alternate.&lt;/p&gt;
&lt;p&gt;That matters, because Google&apos;s transfer tooling for conflicting accounts only handles conflicts on a
primary address; an alternate simply gets released when you create the managed user. So the
awkward-sounding fix is the one that unblocks you.&lt;/p&gt;
&lt;p&gt;Everything inside the old account survives. Nothing is lost.&lt;/p&gt;
&lt;p&gt;The IMAP migration failed on credentials that looked correct. Google&apos;s data import tool kept
rejecting the connection to mail.privateemail.com. The server and port were right. The password
wasn&apos;t, because the mailbox password is separate from the Namecheap account password, and I&apos;d only
ever reached webmail through the dashboard&apos;s single-sign-on button. I had never set the mailbox
password. There was nothing to be wrong.&lt;/p&gt;
&lt;p&gt;If you&apos;re migrating off a hosted mailbox and the credentials fail, test them independently at the
provider&apos;s own webmail login before assuming the migration tool is at fault. It&apos;s a thirty-second
check that isolates the problem completely.&lt;/p&gt;
&lt;h2&gt;SPF, DKIM and DMARC: the bit nobody explains&lt;/h2&gt;
&lt;p&gt;Everyone tells you to set all three. Fewer explain why three exist.&lt;/p&gt;
&lt;p&gt;SMTP has no authentication. Anyone who can open a socket to a mail server can claim to be sending
from your domain. The three protocols each close a different gap:&lt;/p&gt;
&lt;p&gt;SPF answers &quot;is this IP allowed to send for this domain?&quot; It&apos;s a DNS record listing authorized
senders.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The subtlety&lt;/strong&gt;: SPF validates the envelope sender (the MAIL FROM that becomes Return-Path), not
the From: header a human reads. Those are different fields and frequently different values. SPF
alone does nothing to stop someone spoofing your visible address. It also breaks on forwarding,
since the forwarding server&apos;s IP isn&apos;t on your list.&lt;/p&gt;
&lt;p&gt;DKIM answers &quot;was this signed by the domain, and is it unaltered?&quot; The sending server signs a hash
of selected headers plus the body with a private key; the public key lives in DNS under a selector.
Because the signature travels with the message rather than depending on the connecting IP, DKIM
survives forwarding, unless a mailing list rewrites the subject or appends a footer, which
invalidates it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc7489&quot;&gt;DMARC&lt;/a&gt; ties them together with the concept that makes them
useful: alignment. It requires that at least one of SPF or DKIM both passes and matches the domain
in the visible From: header. That&apos;s the check that finally protects the address people actually
see, and it&apos;s the reason neither of the other two is sufficient alone.&lt;/p&gt;
&lt;p&gt;Start DMARC at p=none with an aggregate reporting address. It changes nothing about delivery. It
just tells you which senders are using your domain, including the ones you forgot about. Thirty
clean days later you move to quarantine, then reject. Jumping straight to enforcement is how people
discover their invoicing tool was sending as them, in the worst possible way.&lt;/p&gt;
&lt;h2&gt;The registrar transfer I nearly got wrong&lt;/h2&gt;
&lt;p&gt;I had planned to move the registration to Cloudflare at the November renewal, on the assumption that
transferring earlier would waste the time I&apos;d already paid for.&lt;/p&gt;
&lt;p&gt;That&apos;s backwards. A transfer adds a year to the existing expiry, so you lose nothing by doing it
early.&lt;/p&gt;
&lt;p&gt;Waiting is what actually costs you: if the old registrar&apos;s auto-renewal fires first, the registry
still adds the transfer year on top, but the old registrar is the one who gets refunded the
auto-renewal charge, not you, unless it chooses to pass that back. &lt;a href=&quot;https://www.icann.org/en/announcements/details/registrar-advisory-concerning-registration-transfers-within-the-auto-renew-grace-period-6-6-2002-en&quot;&gt;ICANN&apos;s own advisory on
this&lt;/a&gt;
says registrars aren&apos;t required to, and most don&apos;t ask first.&lt;/p&gt;
&lt;p&gt;Transfer inside that 45-day window and you can end up paying two registrars for one extra year of
registration.&lt;/p&gt;
&lt;p&gt;The right time to transfer is as soon as the new provider is authoritative for DNS.&lt;/p&gt;
&lt;h2&gt;The site itself&lt;/h2&gt;
&lt;p&gt;Astro, built on the Fuwari theme and restyled until it stopped looking like a template.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Static output&lt;/strong&gt;: no server, no database, nothing to keep patched.&lt;/p&gt;
&lt;p&gt;The hosting went through some of its own trouble. It&apos;s now S3 behind CloudFront, provisioned with
Terraform: a private bucket with no public access, reached only through CloudFront&apos;s Origin Access
Control. The certificate has to be issued in us-east-1, which is a CloudFront requirement rather than
a preference, and it validates through a DNS record at Cloudflare the same way the mail records above
proved ownership.&lt;/p&gt;
&lt;p&gt;Two things needed fixing before it worked properly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The 403&lt;/strong&gt;: with Origin Access Control and no list permission on the bucket, S3 can&apos;t distinguish a
missing object from an unauthorized listing request, so it answers both with a 403, not a 404.
CloudFront needs an explicit rule mapping that 403 to the same error page, or the plan output looks
clean while the live site serves the wrong status code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The leftovers&lt;/strong&gt;: the apex still carried DNS records from the old GitHub Pages placeholder, which
had to be found and cleared before the new ones could go in. Easy to miss if you assume DNS above an
unchanged site is also unchanged.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Same rule as the mail records&lt;/strong&gt;: one entry per resource, never a whole-zone import that would put
unrelated records like DKIM keys under a tool that has no reason to know they exist.&lt;/p&gt;
&lt;p&gt;Deploy is manual right now: one command builds the site, syncs it to the bucket, and invalidates the
CloudFront cache. Wiring that into CI with short-lived credentials is next.&lt;/p&gt;
&lt;h2&gt;What I&apos;d tell myself at the start&lt;/h2&gt;
&lt;p&gt;Do the infrastructure before the interesting part. DNS, email and identity are unglamorous, they&apos;re
what everything else sits on, and they&apos;re the things you genuinely don&apos;t want to migrate twice.&lt;/p&gt;
&lt;p&gt;And write down the failures while they&apos;re fresh. The DNS and email problems above cost me maybe
three hours combined, and every one of them is the kind of thing you&apos;d otherwise solve, forget, and
solve again next year.&lt;/p&gt;
&lt;p&gt;The site is live. There will be more here: mostly Bedrock architecture, LLMOps, and the question of
where AI workloads are legally allowed to run. More on what that work actually looks like is on the
&lt;a href=&quot;/about/&quot;&gt;about page&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item></channel></rss>