Repository navigation
feat(posts): migrate four posts from the old blog - #6
Merged
Merged
Conversation
Ports the surviving material from teamkhunglong.github.io, a Jekyll blog dormant since 2022, translated from Vietnamese and rewritten to this repo's conventions. Each post opens with an archive note giving its original date and saying plainly that the subject matter is history. - Merklision: the SVATTT 2020 CTF writeup, a Merkle second-preimage attack composed with an odd-length padding bug to reach 2047 collisions against a requirement of 2020. - Mining ETH in a homelab: the 2021-04 GPU passthrough narrative with the 2021-09 Kubernetes how-to folded in, since the how-to was the second half of the same arc. - The arithmetic that makes cryptojacking worth it: the 2021-07 post on rented-GPU economics, reframed around what the missing cost line means defensively. Each carries one inline SVG built from the svg.dg classes, verified in both theme states. All numbers trace to the source posts; the swept facts and their verification live in homelab-platform under docs/blog/old-blog-archive.md. Dropped rather than ported: four generic DevOps and Kubernetes tutorials that were largely renderings of upstream documentation, and the 2020 post about building the old blog itself. The whoami bio is left for the about-page rewrite. Posts stay draft: true pending Minh's read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A fresh subagent read the three posts with no context and returned FIX FIRST on all three. Most of what it caught was real, and three of them were errors introduced in translation rather than inherited. Corrected against the Vietnamese sources: - The RTX 3060 needed the Windows driver unlock to *reach* 48 MH/s. The migrated text said it "only reached" that, inverting the sense. - "The mining paid for itself" was never claimed in the source, which states the goal and never reports the outcome. Removed; the posts now say plainly that no revenue figure was ever recorded. - The Chia example was offered as evidence that people rent GPUs to mine. Chia plotting is a storage and CPU workload on plain compute instances, so it evidences the instinct, not the hardware. Also fixed: the 2047 collision count is now stated as measured rather than derived, since the original author explicitly wrote that he did not know the closed form; the cap on n is stated where the challenge is described; M and H are defined before use; the Windows-guest instability and the 4U case's three stable months are separated, being claims about different things; the April/July/September timeline is made explicit, since the container insight belongs to the July post and the build instructions to September. Diagram fixes: post one's colour now encodes role consistently and says so, rather than drawing identical values in two colours; post two stops claiming the passthrough path "scales by building another machine", which contradicts its own prose, and marks IOMMU as a mapping rather than a pipeline stage; post three's first column no longer renders a verdict the prose never reaches, and no longer pairs a shared container input with "walk to the machine" recovery. The hostAliases bullet is kept and named as evasion, with a pointer to the companion post that argues the defender's side. Post three is retitled to match its slug and its content: it contains no arithmetic, and said so in its title. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ports the 2021-03-16 post from the old blog, which the first pass had misfiled with the generic DevOps tutorials. It is not a tutorial: it argues that port forwarding on the ISP modem fails by accumulation, one defensible hole per service, on hardware the owner does not administer, and that a 5 USD VPS running a VPN hub holds the count at zero however long the service list gets. This is the earliest post in the sequence and the decision the rest of the homelab grew out of, so it now sits in front of the mining post. The original carried three raster topology diagrams. They are replaced by one inline SVG contrasting the two shapes, per the repo's rule that topologies get redrawn rather than copied. The home ISP named in the third original diagram is genericised. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A cold read of the origin post returned FIX FIRST, and its central objection was correct: the post spent its length arguing against internet-facing listeners while proposing a design that has one. A VPN server on a public address is exactly the thing being condemned. The claim is now the honest one. The hub does not remove the exposure, it relocates it: four listeners on ISP firmware nobody can patch become one listener on a machine the owner administers, and that count does not move when the service list grows. The diagram says this too - red marks an internet-facing listener in both panels, so the single red arrow on the right is the admission rather than an omission. Other corrections from the same read: - The cost comparison had no billing period on the 24.90 USD figure, so it could not support "cheaper". The source never recorded the period; the post now says so and drops the claim. - Chrome Remote Desktop was described as free two bullets before the summary asserted the products cost more than a VPS. The post now admits the remote desktop was the excuse and a general-purpose machine was the reason. - "No third party in the path" was false. The rented box is in the path for every packet, and unlike a direct-routing product it always is. - The modem cannot be both unconfigurable and a viable place to run a VPN. Where the ISP locks the firmware the alternative is unavailable, which is a different objection than insecurity. - A camera appliance cannot run a VPN client, and it was the first example in the escalation. Appliances stay on the LAN; clients join the tunnel and reach them. - One reverse proxy collapses three HTTP services onto one port, so the port count grows only if you let it. That makes the two designs closer relatives than the post first implied, and it now says so. - Added what the design costs: a server that must be patched forever, a single point of failure that takes the recovery path with it, and all traffic transiting the cheapest instance available. One real drawing bug: the home-side flow line carried no marker-end while every other line did, so the direction the whole argument rests on was not drawn. All nine lines now have arrowheads. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Read the gist rather than relying on the 2020 writeup's summary of itself, and re-ran the solver. Several things the post asserted were wrong. The second-preimage rewrite does not submit the internal nodes. The implementation hashes every element before pairing any of them, so the element that reproduces a node is the concatenation of that node's two child digests - twelve bytes, not the six-byte node. The post and the first diagram both said the wrong thing; both now say M(L1, L2, L3, L4) == M(h(L1)||h(L2), h(L3)||h(L4)) which is what the solver's `hashes[i] + hashes[i+1]` actually computes, `+` on bytes being concatenation. Where 2047 comes from is now derived rather than shrugged at. The answers come out one per list length, from 2 up to the padding ceiling of 2048, so the count is 2048 - 2 + 1. It is not 2^11 - 1; the resemblance is the ceiling being a power of two. Re-running the solver reproduces 2047 with every length present exactly once. The set also includes the original tuple, so there are 2046 genuine collisions, and the post says so rather than leaving two defensible numbers implicit. Other corrections from the source: - The bound is `assert 0 <= n <= 2020`, stated exactly. - A duplicate submission trips an assertion and ends the session. The draft said repeats were silently discarded. - There is no check that a submission differs from the original, only that the 2020 are pairwise distinct, so the original is a legal answer. The draft claimed otherwise. - Submissions are base64-decoded to arbitrary bytes, so there is no alphabet restriction. The draft had invented one and built a paragraph on it about why the composition's last step mattered. - The hash is SHA-256 truncated to six bytes, which the draft never mentioned. SVATTT expands to the ASEAN Student Contest in Information Security. The draft called it a Vietnamese inter-university competition. Adds a second diagram, for the length ladder that produces 2047. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Minh supplied what the original post never recorded: the VPN was WireGuard, deployed with Algo, the Trail of Bits Ansible scripts, on a virtual machine from Viettel IDC. Both facts carry real weight in the argument, so neither is a footnote. Algo's opinions are half of why exposing this server is defensible: it refuses to install OpenVPN or Tor, drops L2TP, IKEv1 and RSA, does not rest on TLS, and builds on an Ubuntu LTS with unattended security upgrades. That last one partly answers the post's own objection about having to patch the replacement forever, so the cost section now says what it covers and what it does not - distribution packages, yes; the day the LTS goes end of life, no. WireGuard closes the harder gap. It does not reply to packets that fail authentication, so the one remaining listener does not announce itself to a port scan, which is a different exposure profile from a forwarded port where whatever sits behind it answers anyone who knocks. That is the strongest available answer to the objection the previous commit conceded, and it is now in the prose, the diagram label and the description. Viettel IDC was the hosting arm of the same carrier terminating the line at home, so tunnel traffic stayed inside one national network instead of transiting Singapore or Frankfurt. For a tunnel every interactive session crosses, that is the difference between a remote desktop feeling local and feeling remote - and it is the piece that stopped making sense when he moved to the Netherlands within the year. The disclosure rule in blog-inspirations.md is scoped to current employer material, so a personal 2021 hosting provider is nameable. The home ISP stays generic; the argument never needed it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The provider was named without context, which assumes a reader who already knows it. Both mentions now place it: a Vietnamese cloud provider whose small instances sit where an equivalent DigitalOcean droplet sits. That also repairs the cost reasoning. The post argued for buying domestically on latency grounds while leaving the impression that the price was a concession, when it was competitive on its own terms. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Flips draft to false on the material ported from the retired teamkhunglong.github.io blog, after Minh's read. Verified before flipping: hugo --minify builds with no ERROR and emits all four; content/ is ASCII throughout; no post carries a hex value, fill= or stroke=; all five inline SVGs render as markup with nothing escaped by Goldmark; and no employer name appears in the output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adopts the surviving material from
teamkhunglong.github.io, a Jekyll blog dormant since 2022, translated from Vietnamese and rewritten to this repo's conventions.Four posts, in reading order:
Each opens with an archive note giving its original date and saying plainly that the subject matter is history. Five inline SVGs replace the originals' raster diagrams, built from the
svg.dgclasses with no hex values.Dropped, not ported
Four generic DevOps and Kubernetes tutorials that were largely renderings of upstream documentation, the 2020 post about building the old blog, the 2020 V8 build note and the 2022 CPU war story. The
whoamibio is left for the about-page rewrite, which is its own branch.What changed against the sources
Cold reads returned FIX FIRST on every post, and several findings were errors introduced in translation rather than inherited. Corrected against the Vietnamese sources and, for the CTF post, against the challenge source itself:
2^11 - 1. Re-running the solver reproduces it.The origin post was rebuilt around the objection that a VPN hub is itself an internet-facing listener. The claim is now that the exposure relocates rather than disappears, with WireGuard's silence to unauthenticated packets as the reason that trade is worth making.
Verification
hugo --minifybuilds with no ERROR and emits all four postscontent/is ASCII throughoutfill=orstroke=Swept facts and per-post decisions are recorded in
homelab-platformunderdocs/blog/old-blog-archive.md.🤖 Generated with Claude Code