Blog
Welcome to the Blog.
RISC-V on a 10-Cent Chip
2026-01-30
The WCH CH32V003 costs less than a stamp and runs a 32-bit RISC-V core at 48 MHz. It has 2 KB of RAM, 16 KB of flash, and a surprisingly complete peripheral set: USART, SPI, I²C, ADC, timers.
We set up the open-source MounRiver toolchain, flash a UART echo program over the single-wire debug interface, and measure current consumption in sleep mode: 8 µA. For battery-powered sensors, this chip is hard to beat.
The interesting part is not only the price. It is what this device teaches about writing firmware with hard limits. With 2 KB RAM, every buffer is a design decision. With 16 KB flash, libraries have to justify their existence. That pressure tends to produce cleaner code than “just add another package.”
My shortest path to first success:
Most early failures are clock, pin mux, or toolchain path problems, not “mystical hardware bugs.” If serial output is dead, confirm GPIO mode and baud assumptions before rewriting half the project. ... continue
Nmap Beyond the Basics
2026-01-08
Everyone knows nmap -sV target. But Nmap’s scripting engine (NSE) turns a
port scanner into a full reconnaissance framework.
We look at three scripts that changed how I approach engagements:
http-enum for directory brute-forcing, ssl-heartbleed for quick Heartbleed
checks, and smb-vuln-ms17-010 for EternalBlue detection. Combining these
with --script-args and custom output formats (XML piped into xsltproc)
creates repeatable, auditable scan reports.
The key upgrade is moving from “one clever command” to a staged workflow. I run discovery, service fingerprinting, and targeted scripts as separate passes with saved outputs. That keeps scans explainable and prevents noisy false conclusions from a single overloaded run.
For real operations, reproducibility beats heroics. If results cannot be replayed or audited, they are weak evidence.
NSE is powerful, but script selection should follow scope and authorization. Many scripts are intrusive. Treat them like controlled tests, not default checkboxes. I keep a small approved script set per engagement type, then expand only with explicit reason. ... continue
Format String Attacks
2025-12-14
Format string vulnerabilities happen when user-controlled input ends up as the
first argument to printf(). Instead of printing text, the attacker reads or
writes arbitrary memory.
We demonstrate reading the stack with %08x specifiers, then escalate to an
arbitrary write using %n. The write-what-where primitive turns a seemingly
harmless logging call into full code execution.
The fix is trivial: always pass a format string literal. printf("%s", buf)
instead of printf(buf). Yet this class of bug resurfaces in embedded firmware
to this day.
Why does this still happen? Because logging code is often treated as harmless, copied fast, and reviewed late. In small C projects, developers optimize for speed of implementation and forget that formatting functions are tiny parsers with side effects.
Typical progression in a lab binary: ... continue
Turbo Pascal in 2025
2025-10-19
Turbo Pascal 7.0 still compiles in under a second on a 486. On DOSBox-X running on modern hardware, it’s instantaneous. The IDE — blue background, yellow text, pull-down menus — is the direct ancestor of the Turbo Vision library that inspired this site’s theme.
I wrote a small unit that reads the RTC via INT 1Ah and formats it as ISO 8601. The entire program, compiled, is 3,248 bytes. Try getting that from a modern toolchain.
What surprised me was not just speed, but focus. Turbo Pascal’s workflow is so tight that experimentation becomes natural: edit, compile, run, inspect, repeat. No dependency resolver, no plugin lifecycle, no hidden build graph. You can reason about the whole stack while staying in flow.
Turbo Pascal remains one of the best environments for learning low-level software discipline without drowning in tooling:
If you want to sharpen systems instincts, this is still high-return practice. ... continue
Linux Networking 7: nftables in Production
2024-10-09
Ten years after nftables entered the Linux landscape, we can finally evaluate it as operators, not just early adopters.
In 2024, nftables has enough production mileage for operator-grade evaluation: distributions default toward nft-based stacks, migration projects have real scar tissue, and incident history is deep enough to separate marketing claims from operational truth.
By 2024, in many production environments, nftables has effectively displaced direct iptables administration. Compatibility layers still exist, legacy scripts still survive, but the center of gravity changed.
The important question now is not “is nftables new?”
The important question is “did the move improve real operations?”
For teams that completed migration well, the practical improvements are clear: ... continue
Linux Networking 6: BPF and eBPF
2015-11-19
A decade of Linux networking work with ipchains, iptables, and iproute2 teaches a useful discipline: express policy explicitly, validate behavior with packets, and automate what humans consistently get wrong at 02:00.
By 2015, another shift is clearly visible at the horizon: BPF lineage maturing into eBPF capabilities that promise more programmable networking, richer observability, and tighter integration between policy and runtime behavior.
This article is not a final verdict. It is an in-time outlook from the moment where the tools are just mature enough to be taken seriously in production pilots, while broad operational experience is still being collected.
Before discussing eBPF, an important reminder:
New programmability does not erase fundamentals. It amplifies consequences. ... continue
Storage on Budget Linux
2011-11-08
If there is one topic that separates “it works in the lab” from “it survives in production,” it is storage reliability.
In the 2000s, many of us ran important services on hardware that was affordable, not luxurious. IDE disks, then SATA, mixed controller quality, inconsistent cooling, tight budgets, and growth curves that never respected procurement cycles. The internet was becoming mandatory for daily work, but infrastructure budgets often still assumed occasional downtime was acceptable.
Reality did not agree.
This article is the field manual I wish I had taped to every rack in 2006: what actually made budget Linux storage reliable, what failed repeatedly, and how to build recovery confidence without enterprise magic.
We lose time when we treat disk failure as exceptional. In practice, component failure is normal; surprise is the failure mode. ... continue
Mailboxes to Internet 4: Perimeter and Proxies
2010-05-21
The final phase of the migration story starts when internet access stops being “useful” and becomes “required for normal business.”
That is the moment architecture changes character. You are no longer adding online capabilities to an offline-first world. You are operating an internet-dependent environment where outages hurt immediately, security posture matters daily, and latency becomes political.
If Part 1 taught us gateways, Part 2 taught policy discipline, and Part 3 taught identity realism, Part 4 teaches operational maturity: perimeter control, proxy strategy, and observability that is good enough to act on.
In the late 90s and early 2000s, many of us moved through the same progression:
Tool names changed over time. The operating truth stayed constant: ... continue
VMware on a Pentium II
2009-04-03
Some technical memories do not fade because they were elegant. They stay because they felt impossible at the time.
For me, one of those moments happened on a trusty Intel Pentium II at 350 MHz: early VMware beta builds on SuSE Linux, with Windows NT running inside a window. Today this sounds normal enough that younger admins shrug. Back then it felt like seeing tomorrow leak through a crack in the wall.
This is not a benchmark article. This is a field note from the era when virtualization moved from “weird demo trick” to “serious operational tool,” one late-night experiment at a time.
In the 90s and very early 2000s, common service strategy for small teams was straightforward:
Hardware was expensive relative to team budgets, and machine diversity created endless compatibility work. If you needed a Windows-specific utility and your core ops stack was Linux, you either kept a separate Windows machine around or you dual-booted and lost rhythm every time. ... continue
Mailboxes to Internet 3: Identity and File Services
2008-09-18
By the time mail became stable, the next migration pressure arrived exactly where everyone knew it would: file shares, printers, and user identity.
In theory this is straightforward. In reality, this is where organizations discover the true complexity of their own history. Shared drives are business process. Printer queues are department politics. User accounts are unwritten social contracts. You are not migrating servers. You are migrating habits.
In the 1995-2010 arc, Linux earned trust in this space because it solved practical problems at sane cost. But it only worked when we treated mixed environments as first-class architecture, not temporary embarrassment.
Our baseline looked familiar to many geeks in 2008:
No greenfield, no clean slate. ... continue