docs(learnings): record YubiKey + Dell E7250 air-gapped keygen host setup
Session record 2026-06-24: YubiKey inventory, GPG commit-signing plan, reusable SPECCOL inventory/provisioning stick (dock-aware), and full hardening + provisioning of the Dell Latitude E7250 as the dedicated air-gapped keygen/forensic host (BIOS A24, Secure Boot, AMT off, radios off, dist-upgraded, Phase-2 tooling installed). TPM 1.2-only (hardware limit). Captures key gotchas (yubikey-manager package name, FAT32 +x, TXT-before-TPM-clear, E7250 not on LVFS) and the refined architecture.
This commit is contained in:
@@ -0,0 +1,135 @@
|
|||||||
|
---
|
||||||
|
description: >-
|
||||||
|
Session record (2026-06-24) of detecting the YubiKey, planning GPG commit
|
||||||
|
signing, building a reusable SPECCOL inventory/provisioning stick, and
|
||||||
|
hardening + provisioning a Dell Latitude E7250 as a dedicated air-gapped
|
||||||
|
keygen/forensic host.
|
||||||
|
tags:
|
||||||
|
- learning
|
||||||
|
- yubikey
|
||||||
|
- gpg
|
||||||
|
- security
|
||||||
|
- air-gap
|
||||||
|
- latitude-e7250
|
||||||
|
last_updated: '2026-06-24'
|
||||||
|
---
|
||||||
|
|
||||||
|
# YubiKey + Dell E7250 air-gapped keygen host - 2026-06-24
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Detected and inventoried the attached YubiKey; researched 2026 best practice
|
||||||
|
for hardware-backed Git commit signing; wrote a baby-step plan; then procured,
|
||||||
|
hardened, and provisioned a dedicated Dell Latitude E7250 as the permanent
|
||||||
|
air-gapped keygen/forensic host. Built a reusable `SPECCOL` USB toolkit
|
||||||
|
(inventory + provisioning scripts, verified BIOS, checklist) along the way.
|
||||||
|
|
||||||
|
**Outcome:** E7250 is fully hardened + provisioned and ready to go offline for
|
||||||
|
PGP key generation. The YubiKey remains the daily-carry signer; the Type-C USB
|
||||||
|
will hold the LUKS-encrypted key recovery backup (pending keygen).
|
||||||
|
|
||||||
|
## Decisions (with rationale)
|
||||||
|
|
||||||
|
| Decision | Choice | Why |
|
||||||
|
|----------|--------|-----|
|
||||||
|
| Signing approach | **GPG/OpenPGP on YubiKey** (not SSH `ed25519-sk`) | Secret keys are exportable -> a true LUKS recovery backup on USB is possible (requirement #3). |
|
||||||
|
| Keygen environment | **Dedicated air-gapped host** (Dell E7250) instead of a re-booted live USB | Reproducible; Certify key never touches a networked machine; reusable for forensic work. |
|
||||||
|
| Key identity | `Michael Wegener <mw@satware.com>`; subkeys ed25519(S)/cv25519(E)/ed25519(A); 2y expiry; touch required | 2026 modern; avoids RSA-deprecation for SSH auth. |
|
||||||
|
| Push transport | HTTPS + GPG-sign (unchanged) | Lowest risk; signing is transport-independent. |
|
||||||
|
|
||||||
|
## Components & final state
|
||||||
|
|
||||||
|
### 1. YubiKey (serial 30836069, FW 5.7.1, USB-A)
|
||||||
|
- OTP: slot 1 programmed, slot 2 empty.
|
||||||
|
- FIDO2: PIN set (8 tries left), 4 credentials - `google.com` (Jane Alesi),
|
||||||
|
`auth.satware.ai`, `git.g-b-c.de`, `github.com` (satwareAG-ironMike).
|
||||||
|
- OATH: empty. PIV: factory-defaults/empty. OpenPGP: **empty, sign-PIN was blocked**.
|
||||||
|
- Note: existing GPG keyring has 3 **expired** ed25519 keys tied to a *different*
|
||||||
|
card serial (24530904) - stale references, not on this key.
|
||||||
|
|
||||||
|
### 2. Plan (committed)
|
||||||
|
- `docs/plans/2026-06-24-yubikey-gpg-github-signing.md` (commit `5a714e6`).
|
||||||
|
- 9 phases (0-9): remediate -> air-gapped keygen -> LUKS backup -> transfer to
|
||||||
|
YubiKey -> configure workstation -> register with GitHub -> Ansible -> recovery
|
||||||
|
-> 2nd YubiKey.
|
||||||
|
|
||||||
|
### 3. Boot stick (Type-C USB, 29 GB)
|
||||||
|
- Debian Live **13.5.0 Trixie XFCE** ISO, verified (SHA512 + Dell... Debian CD
|
||||||
|
OpenPGP signature), `dd`'d clean at ~40 MB/s.
|
||||||
|
|
||||||
|
### 4. SPECCOL toolkit stick (FAT32, label `SPECCOL`, ~1.9 GB) - reusable
|
||||||
|
```
|
||||||
|
toolkit/collect-specs.sh dock-aware inventory (TPM version, radios,
|
||||||
|
TB dock nvm/serial, fwupd, robust tooling check)
|
||||||
|
devices/latitude-e7250/provision.sh apt update + full-upgrade + tooling + autoremove
|
||||||
|
+ logging + re-inventory (idempotent)
|
||||||
|
devices/latitude-e7250/checklist.md hardening + provisioning checklist
|
||||||
|
devices/latitude-e7250/bios/ E7250A24.exe (verified) + flash instructions
|
||||||
|
devices/latitude-e7250/logs/ one provision log per run
|
||||||
|
inventory/<hostname>/ collected hw-specs baselines
|
||||||
|
README.txt incl. FAT32 "+x" rule (run via `bash`)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Dell Latitude E7250 (Service Tag JQN3P32) - the air-gapped host
|
||||||
|
- i7-5600U (vPro), 16 GB RAM, SK hynix SC210 mSATA 256 GB SSD (TRIM), Intel HD 5500.
|
||||||
|
- Debian 13 Trixie, kernel **6.12.94** (dist-upgraded), LUKS on root+swap.
|
||||||
|
- **Hardened:** BIOS **A24**; Secure Boot **enabled** (+ kernel lockdown); AMT/vPro
|
||||||
|
**disabled** (MEBx); Wi-Fi **off** (gone from bus); Bluetooth **hard-blocked**;
|
||||||
|
WWAN (Dell Gobi 5809e 4G LTE) **off**; TPM **cleared -> 1.2-only** (hardware
|
||||||
|
limit - no 2.0 option in BIOS A24; non-blocking).
|
||||||
|
- **Provisioned:** full dist-upgrade applied; 20/20 Phase-2 tools installed
|
||||||
|
(scdaemon, pcscd, pcsc-tools, yubikey-manager/ykman, yubikey-personalization,
|
||||||
|
cryptsetup, parted, fdisk, dosfstools, e2fsprogs, paperkey, tpm2-tools, fwupd,
|
||||||
|
hdparm, smartmontools, nvme-cli, usbutils, pciutils, rfkill). 0 packages pending.
|
||||||
|
- **Dock:** Dell E-Port Replicator (legacy bottom-connector; SMSC USB hubs only;
|
||||||
|
no Thunderbolt, no serial, no updatable firmware).
|
||||||
|
|
||||||
|
## Architecture (refined)
|
||||||
|
- **E7250** (offline, LUKS) = keygen + recovery host; holds the Certify key.
|
||||||
|
- **YubiKey** = daily-carry commit/tag signer on the workstation.
|
||||||
|
- **Type-C USB** = offline LUKS-encrypted recovery backup of the keys (pending Phase 3).
|
||||||
|
|
||||||
|
## Key learnings / gotchas
|
||||||
|
- **LVFS:** the E7250 is **NOT** on the LVFS - no `fwupd`/`.cab` BIOS path; Dell
|
||||||
|
dock also not updatable. BIOS update only via the Dell `.exe` (F12 BIOS Flash
|
||||||
|
Update or FreeDOS).
|
||||||
|
- **Dell package naming:** the YubiKey Manager CLI is Debian package
|
||||||
|
**`yubikey-manager`** (provides the `ykman` binary), **not** `ykman`. One invalid
|
||||||
|
name aborts the entire `apt-get install`. Fixed in `provision.sh`.
|
||||||
|
- **FAT32 +x:** the SPECCOL stick can't store the executable bit - scripts must be
|
||||||
|
invoked as `bash <script>` (the toolkit scripts chain each other via `bash`).
|
||||||
|
- **TXT vs TPM:** Intel TXT must be **disabled before clearing the TPM** ("TXT must
|
||||||
|
be disabled before clearing"). TXT is not needed for this host - left disabled.
|
||||||
|
- **TPM version:** `/sys/class/tpm/tpm0/tpm_version_major` (kernel) is the reliable
|
||||||
|
TPM 1.2-vs-2.0 indicator; `/dev/tpmrm0` presence also signals TPM 2.0.
|
||||||
|
- **OpenPGP sign-PIN block** was pre-existing; a `ykman openpgp reset` will clear it
|
||||||
|
before key transfer (Phase 4).
|
||||||
|
- **gh auth** token for satwareAG-ironMike is invalid on the workstation; git
|
||||||
|
protocol is HTTPS. (Re-auth when starting workstation-side setup.)
|
||||||
|
- **Plaintext secrets exposure:** a `yubikey-provision-…` folder with unencrypted
|
||||||
|
GnuPG + SSH private keys was on the Type-C USB ("safety net"). It gets destroyed
|
||||||
|
when that stick is repartitioned for the LUKS backup (Phase 3) - same keys exist
|
||||||
|
on the workstation `~/.gnupg`/`~/.ssh`, so nothing is lost.
|
||||||
|
|
||||||
|
## Verification baselines captured (on the SPECCOL stick)
|
||||||
|
`inventory/michael-latitudee7250/hw-specs-*.txt` across: pre-flash (A19) ->
|
||||||
|
post-flash (A24) -> post-provision -> post-TPM-clear. Tooling-detection bugs
|
||||||
|
(scdaemon/pcsc-tools/yubikey-personalization binary-name mismatches; ambiguous
|
||||||
|
lsusb messages; ANSI codes from fwupd) were fixed in `collect-specs.sh`.
|
||||||
|
|
||||||
|
## Open items / next steps
|
||||||
|
1. On the E7250: (optional) set a BIOS/Setup admin password; **unplug Ethernet
|
||||||
|
permanently**.
|
||||||
|
2. **Phase 2 - keygen** on the E7250 (tmpfs GNUPGHOME): Certify key + S/E/A
|
||||||
|
subkeys. Then Phase 3 (LUKS backup to Type-C USB `sdc3`) and Phase 4 (transfer
|
||||||
|
to YubiKey; reset OpenPGP app first to clear the blocked sign-PIN).
|
||||||
|
3. Workstation side: `gh auth login`, import public key, configure `git` signing
|
||||||
|
(Phases 5-6), fold non-secret config into `ansible/` (Phase 7).
|
||||||
|
4. Procure a 2nd YubiKey for redundancy (Phase 9).
|
||||||
|
|
||||||
|
## Artifacts produced today
|
||||||
|
- `docs/plans/2026-06-24-yubikey-gpg-github-signing.md` (commit `5a714e6`)
|
||||||
|
- `docs/learnings/2026-06-24-yubikey-e7250-airgap-setup.md` (this file)
|
||||||
|
- SPECCOL toolkit stick (toolkit + devices/latitude-e7250/* + verified BIOS A24)
|
||||||
|
- Type-C USB = current Debian-Live boot stick (29 GB; to be repurposed as the
|
||||||
|
LUKS recovery backup in Phase 3)
|
||||||
Reference in New Issue
Block a user