[{"content":"Bio (Draft — short bio TBD.)\nContact Personal email: me [at] inetshell [dot] mx Work email: me [at] inet [dot] sh GPG/PGP: TBD Social Networks Icons below link to the same accounts.\n","permalink":"https://inet.sh/en/about/","summary":"Short bio, contact, and social links.","title":"About"},{"content":"Microsoft ended support for Windows XP in April 2014 and for Windows Server 2003 / 2003 R2 in July 2015. No official patches, no Schannel/TLS updates, and almost no vendor still tests software on those platforms.\nIn practice you cannot “just open Internet Explorer.” IE 8 speaks TLS 1.0 (maybe 1.2 with brittle hacks). Google Chrome dropped XP/Vista years ago; current installers will not even start. Mozilla Firefox left XP as well (only ancient ESR builds were usable). Banks, GitHub, cloud consoles, and most SaaS demand TLS 1.2+ and a recent Chromium. On a lab ProLiant still running 2003 you get blank pages, certificate errors, or “cannot display the webpage.”\nIf you still have to touch a legacy host (firmware, SCADA, a license server, a lab box), you need a modern browser that still builds for old Win32. The option that works in the lab: Supermium.\nWhat Supermium is A Chromium fork aimed at Windows XP SP3, Server 2003 SP2, Vista, 7, 8.x, and newer. It behaves like a Chrome drop-in (extensions, chrome://flags, sandbox) but still ships 32-bit SSE2 builds for CPUs from that era.\nOfficial requirements (short):\nWindows XP SP3 or Server 2003 SP2 (or later) An SSE2-capable CPU (Pentium 4 or newer; dual-core recommended) ≥ 768 MB RAM (2 GB+ if you want it usable) Downloads: win32subsystem.live/supermium — 32-bit and 64-bit setups.\nQuick install On a machine with a modern browser, download the 32-bit Setup (most lab XP/2003 is x86) or 64-bit if the OS is x64. Copy the installer to the legacy host (USB, SMB, iLO virtual media). Install as Administrator. Open Supermium and hit https://example.com plus the site you actually need. If the installer will not run: confirm SP3/SP2, SSE2, and that you are not on Windows 2000 / XP RTM without a service pack.\nExtensions and privacy Unlike current Chrome, Supermium is not killing Manifest V2 on a schedule. You can sideload uBlock Origin from GitHub and keep ads out on an OS that should not be on the public Internet.\nIt also carries ungoogled-chromium-style flags and classic UI options (Aero, old tabs). Nice; do not treat that as OS hardening.\nWarnings (read them) The OS is still unpatched. A new browser does not fix SMB1, old RDP, or kernel bugs. Keep the host on an isolated VLAN, VPN, or jump box; do not expose it to the Internet. Supermium fixes sites broken by TLS; it does not make XP/2003 a safe daily driver. Download only from the official site. Random “Chrome for XP” forum builds are a malware classic. For real work the goal is still migration (new VM, container, or move the service to a supported OS). This is a bridge, not a strategy. When it is worth it Opening an iLO / iDRAC / appliance UI you only documented on a 2003 lab box. Grabbing a driver or EULA from a portal that rejects IE8. Reproducing a compatibility failure without spinning up Windows 10 for one click. Download and docs: Supermium.\n","permalink":"https://inet.sh/en/posts/windows/modern-browser-xp-2003/","summary":"XP and 2003 are EOL. Chrome and Firefox will not run. Supermium will.","title":"Browse the modern web on Windows XP and Server 2003"},{"content":"k3s keeps state on the system disk. When / fills up or you want faster storage, the short path is: stop → mv → symlink → start.\nThe destination (/datadrive here) must exist and be mounted first. Root or sudo.\n1 2 3 sudo systemctl stop k3s sudo systemctl stop k3s-agent # only if this node is an agent sudo /usr/local/bin/k3s-killall.sh 1 2 3 sudo mv /run/k3s/ /datadrive/k3s/ sudo mv /var/lib/kubelet/pods/ /datadrive/k3s-pods/ sudo mv /var/lib/rancher/ /datadrive/k3s-rancher/ 1 2 3 sudo ln -s /datadrive/k3s/ /run/k3s sudo ln -s /datadrive/k3s-pods/ /var/lib/kubelet/pods sudo ln -s /datadrive/k3s-rancher/ /var/lib/rancher 1 2 sudo systemctl start k3s sudo systemctl start k3s-agent # agents only 1 2 kubectl get nodes kubectl get pods -A What moves Source Example destination /run/k3s/ /datadrive/k3s/ /var/lib/kubelet/pods/ /datadrive/k3s-pods/ /var/lib/rancher/ /datadrive/k3s-rancher/ Working state lives there: containerd, manifests, pods. A half-finished mv or a start against empty paths breaks the cluster.\nTraps /run is tmpfs. After a reboot the /run/k3s symlink is gone. Recreate it from a unit After=local-fs.target, or leave /run/k3s on RAM and do not move it.\nk3s-agent does not exist on a server-only node. systemctl stop k3s-agent failing is not a migration failure.\nCreate the destination parent (mkdir -p /datadrive) and confirm the mount (findmnt /datadrive) before mv. A mv onto an unmounted path leaves the data on the old disk under a new name.\ncontainerd and kubelet sometimes reject a symlink. If the node never goes Ready, switch to a bind mount in /etc/fstab:\n1 /datadrive/k3s-rancher /var/lib/rancher none bind 0 0 Cleaner alternative: --data-dir The official k3s path is --data-dir (default /var/lib/rancher/k3s). On a new node, install with the data-dir already on the large disk. On an existing node, mv + symlink (or bind) of /var/lib/rancher is the shortcut; do not rewrite the unit mid-cluster without a plan.\nWrite-up of this mv + symlink sequence: How to Move K3s Data to a New Location.\n","permalink":"https://inet.sh/en/posts/k3s/migrate-data/","summary":"Root disk is full. Stop k3s, move the directories, leave a symlink, start again.","title":"Move k3s data to another disk"},{"content":"On Linux the reflex for “is 1433 open?” is:\n1 nc -v 10.1.1.1 1433 Windows does not ship nc. The closest PowerShell equivalent is a TCP connect test:\n1 Test-NetConnection -ComputerName 10.1.1.1 -Port 1433 Short alias:\n1 tnc 10.1.1.1 -Port 1433 What to look at TcpTestSucceeded:\nValue Meaning True Port is open and answering (same as nc connecting) False No connection (firewall, dead service, unreachable IP) More detail, closer to nc -v:\n1 Test-NetConnection -ComputerName 10.1.1.1 -Port 1433 -InformationLevel Detailed Port only, no ping Test-NetConnection also pings by default. TCP only:\n1 2 Test-NetConnection -ComputerName 10.254.3.2 -Port 1433 -WarningAction SilentlyContinue | Select-Object ComputerName, RemoteAddress, RemotePort, TcpTestSucceeded Very old PowerShell If Test-NetConnection is missing, use the .NET TCP client:\n1 2 3 4 5 6 7 8 9 $tcp = New-Object System.Net.Sockets.TcpClient try { $tcp.Connect(\u0026#34;10.254.3.2\u0026#34;, 1433) Write-Host \u0026#34;Connected to 10.254.3.2:1433\u0026#34; } catch { Write-Host \u0026#34;Failed: $($_.Exception.Message)\u0026#34; } finally { $tcp.Close() } ","permalink":"https://inet.sh/en/posts/windows/netcat-equivalent/","summary":"Windows has no nc. Test-NetConnection -Port is the port check.","title":"Netcat equivalent on Windows: Test-NetConnection"},{"content":"Skills Kubernetes Linux AWS GCP ","permalink":"https://inet.sh/en/resume/","summary":"Skills draft.","title":"Resume"},{"content":"Windows Server 2003 / 2003 R2 does not ship an SSH server. Microsoft never shipped OpenSSH for Windows for that generation either (that arrived much later on Windows 10 / Server 2019+). PowerShell Remoting / WinRM is not the answer on 2003 either: the usable remote stack is RDP, SMB, and Telnet if you enabled it.\nIf you need ssh user@2003-box from a modern jump host (scripts, scp, legacy Ansible, pull logs without RDP), install a third-party SSH server. In the lab I use Bitvise SSH Server; 7.x is the line validated on Server 2003.\nBitvise still lists XP SP3 and Server 2003 in its compatibility matrix. On a host unpatched since 2015, stick to an installer you have already validated (7.x if that is your golden image) or try current only on a clone — not blind on production.\nWhy not the alternatives Option On Server 2003 OpenSSH (Win32-OpenSSH / Windows feature) No Cygwin sshd Possible, brittle and heavy FreeSSHd / abandoned forks Avoid (unmaintained, attack surface) RDP only Fine for GUI; useless for SSH automation Bitvise SSH Server Yes — shell + SFTP on old Win32 Install (short) On a machine with a modern browser, download the installer from bitvise.com/ssh-server-download (or the 7.x package you keep for the lab). Check the digital signature on the .exe (Properties → Digital Signatures → Bitvise). Copy the installer to the 2003 box (USB, SMB, iLO virtual media). Do not fetch it with IE8 from a random mirror. Run the installer as Administrator. Reboot when Bitvise asks (recommended after first install, especially for key auth). Open the Bitvise SSH Server Control Panel and start the service if it is not set to Automatic. Official install notes: Installing Bitvise SSH Server.\nMinimum config you should not skip Accounts: allow only the Windows user(s) you need (or Bitvise virtual accounts). Do not leave “any local account.” Port: 22 by default. On a management VLAN that is fine; otherwise change it and restrict with the host firewall / switch ACL. Windows 2003 firewall: open TCP/22 (or your chosen port) for the management network only. Key auth: import the jump-host pubkey; turn off password auth once keys work. SFTP root: mount only the path you need (e.g. D:\\logs), not C:\\. From the client:\n1 2 3 ssh Administrator@192.168.x.x # or whichever account you enabled scp logfile.log Administrator@192.168.x.x:D:/logs/ A modern OpenSSH client talks to Bitvise fine; you do not need the Bitvise client unless you want its GUI.\nSecurity (legacy context) The OS is still without Microsoft patches. Adding SSH improves operations; it increases network surface if the port is reachable beyond the jump host.\nVLAN / firewall: bastion IP only. Do not put the 2003 box on the Internet “because it has SSH now.” Licensing: Personal Edition is free for non-commercial use; Standard is eval / paid. Respect that in lab vs work. Real goal: migrate the workload. SSH is the bridge to pull data and retire the box. Related To open a modern HTTPS portal from the same host (IE8 will not cut it): modern browser on XP/2003 with Supermium.\nVendor docs and downloads: Bitvise SSH Server.\n","permalink":"https://inet.sh/en/posts/windows/ssh-server-2003-bitvise/","summary":"2003 has no SSH. Windows OpenSSH does not apply. Bitvise does.","title":"SSH into Windows Server 2003 with Bitvise"},{"content":"Topics are the site folders (ZFS, iLO, …). They are not the same as tags: a tag is a detail (encryption, bitvise); a topic is the whole family.\nTopics ZFS — pools, snapshots, encryption, send/recv HP iLO — CLI, firmware, license key Proxmox — cloud-init templates and VMs Windows — legacy XP/2003, disk, SSH k3s — lightweight cluster, data-dir, disk moves Tags For a loose keyword (extension, tool, symptom): all tags.\n","permalink":"https://inet.sh/en/topics/","summary":"The big site buckets. Fine-grained tags (encryption, firmware…) live elsewhere.","title":"Topics"},{"content":"On Linux, when a disk fills up, the reflex is:\n1 2 du -xh --max-depth=1 / | sort -h # or ncdu / On Windows there is no decent du in the box. Explorer → Properties is slow and opaque. The tool I use in the lab and on desktops: WinDirStat — free, open source, interactive treemap.\nThink of it as du on steroids: scan a drive or folder and see where the space went, not only how many GB.\nWhat it does (beyond summing bytes) View Use Directory list Sort by size, like du | sort -h Extension stats See whether .iso, .vmdk, .log, or .bak dominate Treemap Each rectangle is a file; area is size; color is type Largest files / duplicates Obvious delete-or-move candidates The project site documents multithreaded scans, direct NTFS scanning when available, dark mode, and Explorer integration.\nQuick use Download the installer (or portable build) from windirstat.net / the project\u0026rsquo;s GitHub releases. Run as Administrator if you are scanning all of C:\\ (permissions on Windows, other user profiles, etc.). Pick a volume or a specific folder (D:\\VMs, C:\\Users\\…\\AppData). Wait for the scan. Large disks take time; this is not du on a tmpfs. In the treemap, zoom into the fat block. Open the folder in Explorer, or delete from the UI only when you know what it is. When to use it Disk is “full” and you do not know whether it is Downloads, hibernation, pagefile, ISOs, or VM snapshots. Before/after cleanup of a profile or a share. Showing a non-CLI person what owns the space (the treemap sells itself). What it is not It does not replace du/ncdu on Linux or on a NAS over SSH. It is not a magic cleaner: deleting System Volume Information, WinSxS, or “big” databases because they look large will break the host. A full C:\\ scan on a file server with millions of files can take a long time; narrow the root. Mental map World Tool Linux CLI du, ncdu Windows GUI WinDirStat macOS DaisyDisk / OmniDiskSweeper (another family) Download and docs: https://windirstat.net/.\n","permalink":"https://inet.sh/en/posts/windows/windirstat-disk-usage/","summary":"du gives numbers. WinDirStat gives the map: which folder and which extension own the disk.","title":"WinDirStat: see what is eating the disk on Windows"},{"content":"On Proxmox a VM disk on ZFS is a ZVOL (rpool/data/vm-101-disk-0), not a file. To copy it to another hypervisor or a USB stick, dump a RAW.\nThread: Import/convert/export RAW images to ZFS volume.\nSnapshot and dd If the VM is running, freeze the disk with a snapshot and read the snap (the @snap ZVOL shows up under /dev/zvol/…):\n1 2 3 zfs snapshot rpool/data/vm-101-disk-0@export dd if=/dev/zvol/rpool/data/vm-101-disk-0@export of=/mnt/backup/vm-101.raw bs=1M status=progress zfs destroy rpool/data/vm-101-disk-0@export VM off, you can read the live zvol:\n1 dd if=/dev/zvol/rpool/data/vm-101-disk-0 of=/mnt/backup/vm-101.raw bs=1M status=progress bs=1M matters: the 512 B default takes forever.\nqemu-img (qcow2 / vmdk) 1 qemu-img convert -p -f raw -O qcow2 /mnt/backup/vm-101.raw /mnt/backup/vm-101.qcow2 Or straight from the zvol:\n1 qemu-img convert -p -f raw -O qcow2 /dev/zvol/rpool/data/vm-101-disk-0 vm-101.qcow2 The other way (RAW → ZVOL) 1 2 zfs create -s -V 32G rpool/data/vm-101-disk-0 dd if=file.raw of=/dev/zvol/rpool/data/vm-101-disk-0 bs=1M status=progress -s = sparse. The RAW must not be larger than the zvol.\nSee also: basic commands.\n","permalink":"https://inet.sh/en/posts/zfs/zvol-raw-image/","summary":"A ZVOL is a block device. dd (or qemu-img convert) to .raw. Snapshot first if the VM is up.","title":"Export a ZFS ZVOL to a RAW image"},{"content":"If you have SSH to iLO and do not want the web UI, the shell is SMASH CLP (/map1, oemhp_*). This is the iLO 2/3/4 dialect, not Redfish.\nConnect 1 ssh Administrator@\u0026lt;ilo-ip\u0026gt; Old firmware often needs a legacy cipher:\n1 ssh -c aes256-cbc Administrator@\u0026lt;ilo-ip\u0026gt; Accounts Create a user with the usual admin groups (network changes reset iLO; accounts persist):\n1 create /map1/accounts1 username=ops password=\u0026#39;\u0026lt;password\u0026gt;\u0026#39; group=admin,config,oemhp_vm,oemhp_rc,oemhp_power Change the Administrator password on first boot (Administrator / hpinvent is the HP default):\n1 set /map1/accounts1/Administrator password=\u0026#39;\u0026lt;new-password\u0026gt;\u0026#39; Network (iLO reboots) 1 2 3 set map1/dhcpendpt1 EnabledState=no set map1/enetport1/lanendpt1/ipendpt1 IPv4Address=192.168.1.213 SubnetMask=255.255.255.0 set map1/enetport1 SystemName=merlin After each network set, wait for iLO to come back and SSH to the new address.\nMount an HTTP ISO and boot once The ISO must be HTTP-reachable from iLO, not from your laptop.\n1 2 3 set /map1/oemhp_vm1/cddr1 oemhp_image=http://10.254.0.50/ssp2017.iso set /map1/oemhp_vm1/cddr1 oemhp_boot=Once show /map1/oemhp_vm1/cddr1 Power 1 2 3 4 show /system1 start /system1 stop /system1 reset /system1 Ping from iLO Useful to see whether iLO can reach the management network:\n1 oemhp_ping /map1 10.1.1.50 Manual HP\u0026rsquo;s CLP tree: iLO scripting and command line.\nSee also: upgrade firmware over SSH, read the license key.\n","permalink":"https://inet.sh/en/posts/ilo/cli-commands/","summary":"iLO CLP cheat sheet: accounts, network, virtual media, and power.","title":"HP iLO CLI: users, network, ISO, and power"},{"content":"After a power cut the pool is often still on the disks but zpool status is empty: it was left dirty-exported, or the host booted without it. Do not zpool create on those disks.\nSee what is there 1 zpool import Lists importable pools by name (VOL1 below) and whether they are FAULTED / UNAVAIL.\nImport 1 zpool import -f VOL1 -f means “I know it might still look imported elsewhere”. That is the usual crash case: ZFS thinks the other side still holds it.\nIf -f is not enough because the last txgs were half-written:\n1 zpool import -F VOL1 -F rewinds to an earlier consistent txg. You can lose the last seconds of writes. That is better than a pool that will not mount.\nDry-run:\n1 zpool import -F -n VOL1 Afterwards: scrub 1 2 zpool scrub VOL1 zpool status VOL1 Scrub confirms the rewind did not leave checksum errors. Let it finish before you delete “just in case” snapshots.\nDo not zpool create on the same sdX devices wipes the labels. -F is not the first knob: try -f first. If the pool is the root (rpool / Proxmox bpool), import from live media, not from the system that will not boot. See also: replacing disks, basic commands.\n","permalink":"https://inet.sh/en/posts/zfs/import-after-power-outage/","summary":"Pool will not import. -f force, -F rewind txgs, then scrub.","title":"Import a ZFS pool after a power outage"},{"content":"OpenZFS encrypts datasets, not the whole pool. Pool labels and metaslabs stay visible; tank/secret contents do not. This is the TrueNAS / Proxmox / Linux path.\nBackground: Ars native encryption, ZFS encrypted backups.\nCreate 1 2 zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt tank/encrypted zfs create tank/encrypted/child1 child1 inherits encryption. Do not set encryption=off on a child: OpenZFS will not let you punch a plaintext hole under an encrypted parent.\nKeyfile instead of prompt:\n1 2 zfs create -o encryption=on -o keyformat=passphrase \\ -o keylocation=file:///root/zfs.key tank/encrypted The key file does not live on the encrypted dataset. USB, TPM, or a path on another pool.\nLoad the key at boot 1 2 zfs load-key tank/encrypted zfs mount tank/encrypted Without load-key the dataset exists and zfs list shows it, but it will not mount.\nReceive plaintext as encrypted On the first recv you can set encryption properties:\n1 2 3 zfs send tank/test@snap1 \\ | zfs recv -o encryption=on -o keyformat=passphrase \\ -o keylocation=file:///path/to/keyfile tank/encrypted That receive is without -w. Raw -w copies the source wrapping key: only valid if the source was already encrypted. Details: unencrypted send into encrypted.\nRotate the passphrase (OpenZFS) On Solaris the command was zfs key -c. On OpenZFS / Linux / TrueNAS:\n1 2 zfs change-key tank/encrypted zfs get keyformat,keylocation,keystatus tank/encrypted New keyfile:\n1 zfs change-key -o keylocation=file:///media/stick/key tank/encrypted Wrapping-key rekey (does not rewrite every block; rotates the key that wraps master keys) is zfs change-key -i depending on version — read your zfs change-key man page before production.\nSee also: snapshot holds, off-host backups.\n","permalink":"https://inet.sh/en/posts/zfs/encryption/","summary":"encryption=on at create. Children inherit. On Linux, rotate with zfs change-key.","title":"Native ZFS encryption (OpenZFS): create, inherit, change-key"},{"content":"Retention scripts (zfs destroy -r …@auto-…) do not ask. A hold is a named lock on a snapshot: destroy fails until you drop the tag.\nUse it on the snapshot you are zfs sending, or on the only known-good rollback after an upgrade.\nTake the hold 1 zfs hold keep tank/home/cindys@snap1 Recursive on a whole tree (snapshot first, then hold):\n1 2 zfs snapshot -r tank/home@now zfs hold -r keep tank/home@now The tag (keep) is yours, but unique per snapshot. You can have both keep and offsite on the same @now.\nWhat destroy does 1 2 zfs destroy tank/home/cindys@snap1 # cannot destroy \u0026#39;tank/home/cindys@snap1\u0026#39;: dataset is busy That is the hold, not a mounted filesystem. zfs destroy -d defers deletion until holds are gone; it does not override them.\nList 1 2 zfs holds tank/home@now zfs holds -r tank/home@now 1 2 3 NAME TAG TIMESTAMP tank/home@now keep Thu Jul 15 11:25:39 2010 tank/home/cindys@now keep Thu Jul 15 11:25:39 2010 Release, then destroy 1 2 zfs release -r keep tank/home@now zfs destroy -r tank/home@now If a long send is still running, wait: the hold exists so prune cannot eat your incremental cursor.\nOracle\u0026rsquo;s description (same mechanism on OpenZFS): Holding ZFS snapshots.\nSee also: send into an encrypted dataset.\n","permalink":"https://inet.sh/en/posts/zfs/hold-protect-snapshot/","summary":"zfs destroy says dataset is busy. That is a hold. How to set one and drop it.","title":"Protect ZFS snapshots from destroy with hold"},{"content":"You do not need an installer ISO if you just want Linux that boots with a user, an SSH key, and DHCP. Distros ship a GenericCloud / cloudimg (qcow2): import it, attach a cloud-init drive, turn it into a template.\nTested on Proxmox 8.0.4. The flow is this gist (fork of zidenis). Fedora 38 / Ubuntu 23.04 URLs go stale: point wget at the distro’s current cloud image.\n1. Download the image On the node, as root, on a storage with space (NFS, local, whatever you use):\n1 2 3 4 5 6 export IMAGES_PATH=\u0026#34;/mnt/pve/nfs-data/images/\u0026#34; cd \u0026#34;${IMAGES_PATH}\u0026#34; wget https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2 wget https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/CHECKSUM -O SHA256SUMS sha256sum -c SHA256SUMS --ignore-missing Other distros (uncomment one):\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # Amazon Linux 2 — https://cdn.amazonlinux.com/os-images/latest/ # wget https://cdn.amazonlinux.com/os-images/2.0.20230727.0/kvm/amzn2-kvm-2.0.20230727.0-x86_64.xfs.gpt.qcow2 # CentOS Stream 9 # wget https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2 # Fedora (bump the version) # wget https://download.fedoraproject.org/pub/fedora/linux/releases/38/Cloud/x86_64/images/Fedora-Cloud-Base-38-1.6.x86_64.qcow2 # Oracle Linux 9 — the .qcow is not qcow2; convert it # wget https://yum.oracle.com/templates/OracleLinux/OL9/u2/x86_64/OL9U2_x86_64-kvm-b197.qcow # qemu-img convert -O qcow2 -o compat=0.10 OL9U2_x86_64-kvm-b197.qcow OL9U2_x86_64-kvm-b197.qcow2 # RHEL 9 — needs a logged-in download from access.redhat.com # Rocky 9 # wget https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2 # Ubuntu cloudimg # wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img 2. VM and cloud-init variables 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 export QEMU_CPU_MODEL=\u0026#34;host\u0026#34; export VM_CPU_SOCKETS=1 export VM_CPU_CORES=2 export VM_MEMORY=4098 export VM_RESOURCE_POOL=\u0026#34;CustomResourcePool\u0026#34; export CLOUD_INIT_USER=\u0026#34;user\u0026#34; export CLOUD_INIT_SSHKEY=\u0026#34;/home/user/.ssh/id_rsa.pub\u0026#34; export CLOUD_INIT_IP=\u0026#34;dhcp\u0026#34; export CLOUD_INIT_NAMESERVER=\u0026#34;1.1.1.1\u0026#34; export CLOUD_INIT_SEARCHDOMAIN=\u0026#34;example.com\u0026#34; export TEMPLATE_ID=1001 export VM_NAME=\u0026#34;alma9\u0026#34; export VM_DISK_IMAGE=\u0026#34;${IMAGES_PATH}/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2\u0026#34; --cpu host passes through the node CPU flags (faster; the template is not portable across CPU vendors). VM_MEMORY=4098 is the gist value; 4096 is fine.\nThe cloud-init user is not root. The key must be the .pub you will use from your laptop.\n3. Create the base VM and import the disk Swap local-lvm and vmbr0 for your real storage and bridge.\n1 2 3 4 5 6 7 8 9 10 11 qm create ${TEMPLATE_ID} --name ${VM_NAME} --cpu ${QEMU_CPU_MODEL} \\ --sockets ${VM_CPU_SOCKETS} --cores ${VM_CPU_CORES} --memory ${VM_MEMORY} \\ --numa 1 --net0 virtio,bridge=vmbr0 --ostype l26 --agent 1 \\ --pool ${VM_RESOURCE_POOL} --scsihw virtio-scsi-single qm set ${TEMPLATE_ID} --scsi0 local-lvm:0,import-from=${VM_DISK_IMAGE} qm set ${TEMPLATE_ID} --ide2 local-lvm:cloudinit --boot order=scsi0 qm set ${TEMPLATE_ID} --ipconfig0 ip=${CLOUD_INIT_IP} \\ --nameserver ${CLOUD_INIT_NAMESERVER} --searchdomain ${CLOUD_INIT_SEARCHDOMAIN} qm set ${TEMPLATE_ID} --ciupgrade 1 --ciuser ${CLOUD_INIT_USER} --sshkeys ${CLOUD_INIT_SSHKEY} qm cloudinit update ${TEMPLATE_ID} --agent 1 asks for qemu-guest-agent. Alma/Rocky/Fedora ship it or cloud-init installs it (ciupgrade). Amazon Linux 2 and some Ubuntu cloudimgs will not show the guest IP in the Proxmox GUI until you install the agent yourself.\n4. Convert to a template 1 2 qm set ${TEMPLATE_ID} --name \u0026#34;${VM_NAME}-Template\u0026#34; qm template ${TEMPLATE_ID} Do not start that VM again: clone it.\n5. Clone and boot 1 2 3 export VM_ID=$(pvesh get /cluster/nextid) qm clone ${TEMPLATE_ID} ${VM_ID} --name ${VM_NAME} qm start ${VM_ID} SSH with the private key that matches the .pub you fed cloud-init:\n1 ssh user@192.168.0.123 -i ~/.ssh/id_rsa If Proxmox does not show an IP: serial console, ip neigh on the bridge, or the router’s DHCP leases.\nSource: gist inetshell/f1d0206d5319c11062845901e4f3d06b.\n","permalink":"https://inet.sh/en/posts/proxmox/cloud-image-templates/","summary":"Five steps: download the cloud image, qm create, import the disk, qm template, clone.","title":"Proxmox templates from Linux cloud images (qm + cloud-init)"},{"content":"iLO Advanced is licensed by key. If you inherited a ProLiant and the UI will not open (cert, Java, firmware), the BMC still publishes an inventory XML.\nThe endpoint 1 curl -sk \u0026#34;https://\u0026lt;ilo-ip\u0026gt;/xmldata?item=CpqKey\u0026#34; In a browser: https://\u0026lt;ilo-ip\u0026gt;/xmldata?item=CpqKey.\nThe body is XML with the product and the key (or an unlicensed state). This is not Redfish; it is iLO\u0026rsquo;s xmldata interface, the one old HP SIM scripts used.\nNotes -k because the iLO certificate is almost never from a public CA. Some iLOs still serve this over HTTP (http://\u0026lt;ilo-ip\u0026gt;/xmldata?item=CpqKey) if HTTPS will not negotiate. Treat the key as a secret. Do not commit it or paste it. Reading it does not activate anything: it only reads what is already stored on the BMC. Applying a different key is still license in CLP or the UI. See also: iLO CLI commands.\n","permalink":"https://inet.sh/en/posts/ilo/get-license-key/","summary":"GET https://\u003c!-- raw HTML omitted --\u003e/xmldata?item=CpqKey and pull the key out of the XML.","title":"Read an HP iLO license key without the web UI"},{"content":"Proxmox documents the case: ZFS on Linux — change a failed device. The symptom is an OFFLINE / FAULTED vdev and a long number instead of sde.\nStatus 1 zpool status vol1 The dead member often shows up as a GUID:\n1 1894156996840098641 OFFLINE That happens when the kernel no longer has a /dev/sdX for that disk (you yanked it, it died, or the letter moved).\nReplace 1 zpool replace -f vol1 1894156996840098641 /dev/disk/by-id/ata-NEWDISK -f forces if ZFS still “remembers” the old disk. The replacement must be at least the same size (prefer by-id, not sde).\nIf the new disk is in the same slot and ZFS sees it:\n1 zpool replace vol1 /dev/disk/by-id/ata-OLDDISK /dev/disk/by-id/ata-NEWDISK or auto-detect a replacement in-place:\n1 zpool replace vol1 /dev/disk/by-id/ata-OLDDISK Wait for resilver 1 2 zpool status vol1 watch -n 5 zpool status vol1 Do not reboot, export, or start another replace on the same vdev until resilvered. On RAIDZ1 you are one disk down: a second failure in that window is data loss.\nAfterwards 1 2 zpool detach vol1 1894156996840098641 # only if status still shows it as spare/old zpool labelclear /dev/sdOLD # if you reuse the old disk elsewhere See also: import after a power outage.\n","permalink":"https://inet.sh/en/posts/zfs/replace-disks/","summary":"zpool status gives you a GUID, not /dev/sde. replace -f GUID /dev/disk/by-id/…","title":"Replace a disk in a ZFS pool"},{"content":"zfs send emits a replicable stream, not a directory. The natural sink is another pool (zfs recv). S3 is a second hop: store the stream as an object, or use something like z3.\nIncremental to another host (the command I actually run) 1 2 zfs send -w -R -v -i vol1/secure/backups@initial vol1/secure/backups@new \\ | ssh root@10.0.0.1 zfs recv -s vol1/secure/backups Flag Meaning -w raw: send the dataset encrypted as-is. The receiver does not need the key to recv. -R replicate properties and child snapshots -i @initial @new incremental from @initial (must exist on both sides) -v progress recv -s resumable if SSH drops (recv -s again) Hold @initial and @new while the send runs, or prune will break the chain.\nThe first full (no -i) is mandatory once:\n1 2 zfs send -w -R -v vol1/secure/backups@initial \\ | ssh root@10.0.0.1 zfs recv -s vol1/secure/backups Land it in S3 Same stream, other side of the pipe:\n1 2 3 zfs send -w -R vol1/secure/backups@new \\ | gzip -1 \\ | aws s3 cp - s3://my-bucket/zfs/backups@new.zfs.gz Restore:\n1 2 3 aws s3 cp s3://my-bucket/zfs/backups@new.zfs.gz - \\ | gunzip \\ | zfs recv -s vol1/secure/backups This is not a file sync. It is an opaque blob: you restore the whole stream (or the incremental on top of the full), or you restore nothing. Name @initial / @new and do not delete the full.\nFor incrementals in S3, tools like z3 keep a catalog of what already landed. A raw aws s3 cp - does not.\n-w into S3 is correct if the dataset is already encrypted: AWS never sees plaintext. If the source is not encrypted, either encrypt on recv (post) or encrypt the object (KMS / client) — a cleartext stream in a bucket is a cleartext backup.\nSee also: native encryption.\n","permalink":"https://inet.sh/en/posts/zfs/backups-to-s3/","summary":"A zfs send stream is not a tarball. Another pool first, S3 object if you need it.","title":"Send ZFS snapshots to another host (and on to S3)"},{"content":"When iLO firmware is old enough that browsers refuse its TLS, SSH plus HTTP still works.\n1. Serve the .bin over HTTP iLO pulls the firmware; you do not SCP it in. python3 -m http.server on the management network is enough, or nginx. Use the official HPE ilo*.bin.\n2. Log in and load 1 2 3 4 ssh -c aes256-cbc Administrator@\u0026lt;ilo-ip\u0026gt; show /map1/firmware1 cd /map1/firmware1 load -source http://\u0026lt;http-server\u0026gt;/ilofirmware.bin -c aes256-cbc is the iLO 2/3 trick: modern OpenSSH will not offer the BMC\u0026rsquo;s ciphers unless you ask.\nshow /map1/firmware1 prints the current version before you touch anything. Keep it.\nWhat to expect load takes minutes. Do not kill the session. iLO reboots itself. The host does not power off (firmware lives on the BMC). If HTTP is not reachable from the iLO NIC, load fails with a useless error: oemhp_ping the HTTP server. After reboot, show /map1/firmware1 again and confirm the version string.\nWrite-up this is based on: Upgrade HP iLO via SSH.\nSee also: iLO CLI commands.\n","permalink":"https://inet.sh/en/posts/ilo/upgrade-firmware-ssh/","summary":"iLO web UI is dead. Serve the .bin over HTTP and load it from the SSH session.","title":"Upgrade HP iLO firmware over SSH"},{"content":"Short reference. Longer procedures are linked at the bottom.\nPool 1 2 3 4 5 6 zpool create vol1 raidz sda sdb sdc zpool status vol1 zpool export vol1 zpool import -f vol1 zpool destroy tank # irreversible zpool labelclear ada0 # wipe ZFS labels from a spare disk raidz here is RAIDZ1 (one parity). For two, raidz2. Address disks as /dev/disk/by-id/…, not sdX, which reorder.\nMountpoint 1 2 3 zfs unmount vol1 zfs set mountpoint=/mnt/vol1 vol1 zfs mount vol1 L2ARC (cache) and SLOG (ZIL) 1 2 3 4 zpool add vol1 cache \u0026lt;disk-id\u0026gt; zpool add vol1 log \u0026lt;disk-id\u0026gt; zpool add vol1 log mirror \u0026lt;disk-id-a\u0026gt; \u0026lt;disk-id-b\u0026gt; zpool remove vol1 \u0026lt;device\u0026gt; Cache = hot reads. Log = sync writes (NFS, VMs). A “fast” USB SLOG is worse than no SLOG: if it dies mid-txg, you feel it. Mirror the log.\nCompression 1 2 3 zfs set compression=lz4 newvol zfs set compression=off newvol zfs get compressratio newvol lz4 is the sane default on modern OpenZFS. zstd compresses more and costs CPU. The property inherits to child datasets that do not override it.\nSee also Import after a power outage Replace disks Native encryption ","permalink":"https://inet.sh/en/posts/zfs/basic-commands/","summary":"The 2 a.m. commands to create, mount, compress, and not destroy the wrong pool.","title":"ZFS command cheat sheet (pool, compression, cache, log)"},{"content":"Same bytes, new key. Source stays plaintext; destination is born encrypted. OpenZFS allows this only on the initial receive (dataset that does not exist yet).\nSource thread: r/zfs.\nCommand 1 2 3 4 5 6 zfs snapshot tank/test@snap1 zfs send tank/test@snap1 \\ | zfs recv -o encryption=on \\ -o keyformat=passphrase \\ -o keylocation=file:///path/to/keyfile \\ tank/encrypted Things that silently break the send:\nDo not use -w. Raw send replicates the source encryption state. Plaintext in → plaintext out, and -o encryption=… is ignored or errors. Name the destination dataset (tank/encrypted). A recv with no target does not create it. Passphrase vs file: keylocation=prompt is a bad fit across a non-interactive pipe. Use a keyfile. Later incrementals (-i) inherit encryption. Do not pass -o encryption=on again. Check 1 2 zfs get encryption,keystatus,keyformat tank/encrypted zfs load-key tank/encrypted # if keystatus=unavailable The other direction Encrypted → encrypted with the same wrapping key: zfs send -w. Encrypted → new wrapping key: send without -w (ZFS decrypts on send; recv encrypts). That needs load-key on the source and is slower.\nSee also: native encryption.\n","permalink":"https://inet.sh/en/posts/zfs/send-unencrypted-to-encrypted/","summary":"No -w. -o encryption=on only on the first recv. The destination dataset name is required.","title":"zfs send/recv from an unencrypted dataset into an encrypted one"}]