Thursday, March 21, 2024

Reinstalling grub on my Debian 12 LVM LuksCrypt dual-boot laptop

So, Microsoft's latest Windows 11 update decided to blow away my dual-boot config because Microsoft apparently hasn't been involved in an antitrust lawsuit recently enough.  (Seriously, I liken this to buying a Ford vehicle and then discovering that it actively disables any non-Ford vehicles also parked in your driveway.  Not cool, Microsoft.)

Anyhow, since I run Debian 12 with LVM and an encrypted root filesystem, recovering the grub bootloader was a very manual process.  I'm adding the steps I used here for my own future reference.  Yours will probably be different.  This assumes you know your way around Linux, hardware device mappings, &etc.  Please don't ask me for help recovering your own system unless you're also offering me $200/hr for my time.

1. Boot Debian 12 install media, Advanced Options, "Rescue Mode"

2. Follow the prompts but then "continue with no root filesystem", drop to an installer shell

3. The encrypted LVM logical volume should already be in /dev/mapper.  Open it with 

    cryptsetup luksOpen /dev/mapper/$LVNAME $LVNAME_crypt

4. mount /dev/mapper/$LVNAME_crypt /mnt

5. Double check /mnt/etc/fstab to make sure the root fs name you used in cryptsetup is the one also here.  If not, unmount /mnt, close the luksCrypt mapping, and go back to step 3 but use the correct root mount point name for the mapping.

6. fdisk -l /dev/nvme0n1  (or whatever your drive is) to find the /boot and /boot/EFI partitions

7. mount them under the new rootfs:

        mount /dev/nvme0n1p4 /mnt/boot

        mount /dev/nvme0n1p1 /mnt/boot/efi

8. Attach all the virtual filesystems needed to make everything function:

        mount --bind /proc /mnt/proc

        mount --bind /dev /mnt/dev

        mount --bind /dev/pts /mnt/dev/pts

        mount --bind /sys /mnt/sys

9. chroot /mnt

10. Mount efivarfs under efivars 

        mount -t efivarfs none /sys/firmware/efi/efivars

11. Reinstall grub on the drive (not on one of the partitions)

        grub-install /dev/nvme0n1  # or whatever drive is appropriate

12. exit chroot and reboot to get back into your orphaned Debian OS.

Note:  I wasn't able to get grub-prober to find the Windows boot manager in rescue mode, so this returns the system to being able to boot Debian but not to the original multiboot. 

13. Boot into Debian 12

14. Re-enable os-prober in /etc/default/grub

15. grub-mkconfig >/boot/grub/grub.cfg

16. grub-install

Now everything should be back to the way it was.  Bill, I'll send you an invoice for the two hours of my morning you just stole from me.

Saturday, January 13, 2024

That 1981 KROQ Doodle

Someone posted this notebook doodle in a Facebook group that I'm in.  It appears to be a transcription of the playlist on Los Angeles' famous KROQ station overnight from 10:15pm - 04:15am, one random night, long ago.  It's kind of captivating.  I set out to decode it and recreate it on a playlist, with pretty good success.

First - the doodle itself.  (Click for the original version as I found it.)

I don't know who created this, but I kind of love it.  It's like a time capsule into the broadcast FM punk & new wave scene of Los Angeles at the beginning of the 1980s.  Most of it was pretty straightforward, but there are some errors in it and some oddities.

First, though, here's the playlist as best I could recreate it.  Then I'll go into the challenges, guesses, and 
errors I came across trying to reconstruct it (noted as orange highlights below).

Youtube Music playlist:  KROQ Doodle

I don't have spotify, but if you recreate this playlist on Spotify (or other services) feel free to shoot me a link and I'll add it.)

Monday, January 17, 2022

HowTo: GeoIP restrictions for Amazon Linux 2

pew pew pew


I have a few Amazon Linux 2 EC2 instances that I run for personal use.  Generally, I restrict "important" / remote access services to my home egress IPs, but for services that I expect to be generally available I cannot do that.

Anyone who has hosted a service on the public Internet knows that it's a matter of minutes after the service comes online before it starts being probed by all manner of scanners, exploit scripts, curious hackers, botnets, &etc.  No big deal, just build secure services, right?

Naturally.  But "defense in depth" dictates that if you can filter out a large percentage of these requests, you should.  As doing so not only reduces the load on your service, but also reduces the likelihood of your service being tagged by some unforeseen exploit.

Enter:  Maxmind's GeoIP database and the xtables-addons GeoIP filter.  With the geoip module you can easily use iptables to restrict traffic to only those countries you know your service will be accessed from.  Useful if you're building, say, a game server or similar for only a small group of friends and you know where they all are!

Note:  I'm mostly documenting this so that I can repeat it again later without having to rediscover the dependencies / steps.  No warranties, support, or promises.  You are responsible for your own systems.  But I thought someone else might find it useful.


- I'm using Amazon Linux 2 on EC2, but the steps are probably similar for any CentOS / RHEL based Linux distribution.  If using something Debian / Ubuntu based, your package management commands will differ (e.g. apt instead of yum) but you can probably muddle through it.

- A Maxmind account with which to download the "GeoIP Countries CSV" database.  For non-commercial use, the free account tier works fine for this.  Of course, you have options if you want to expand from there.


(Note: since we're installing and configuring kernel modules, I did all this as root by running "sudo -i" first.  You can split it into download / install steps and use sudo on the individual commands if you wish.  YMMV)

1. Set up the build environment 

# yum install gcc gcc-c++ make automake unzip zip xz kernel-devel-`uname -r` iptables-devel cpan

(Yes, this requires CPAN.  Blast from the past!  The geoip build scripts are written in Perl.)

2. Set up CPAN.  I just took all the default options:

# cpan install

3. Install the required CPAN modules for the xt_geoip_build script:

# cpan Text::CSV Text::CSV_XS Net::CIDR::Lite

4. Download and extract the latest xtables-addons build (3.18 at the time of this writing.  Update the following commands for the version you download.)

# wget
# tar -xvf xtables-addons-3.18.tar.xz
# cd xtables-addons-3.18

5. Edit the "mconfig" file and comment out the modules you don't need.  I commented out everything except "build_geoip=m" to build only the geoip module.

6. Build and install the selected xtables-addon modules.

# ./configure && make && make install

7. If that went well, go into the "geoip" subdirectory under the xtables-addons build directory:

# cd geoip

8. Sign in to your Maxmind account, go to the "GeoIP Downloads" page, and find the link for the GeoLite2 Country: CSV Format database.  (Note, you want the CSV format in particular.)  I got this onto the server by copying the "Download ZIP Format" link and fetching it into the geoip directory with wget and extracting it:

# wget 'MAXMIND_URL' -O
# unzip

9. Now you should have a GeoLite2-Country-CSV_YYYYMMDD folder (name will vary based on the age of the database.  Substitute yours for YYYYMMDD.)  You need to run the "xt_geoip_build_maxmind" perl script from inside that folder, with the destination set for where the iptables module will look for the output:

# cd GeoLite2-Country-CSV_YYYYMMDD
# mkdir /usr/share/xt_geoip 
# ../xt_geoip_build_maxmind -D /usr/share/xt_geoip

10. If this went well, the script should build a series of files in /usr/share/xt_geoip and then show you a table of how many addresses are allocated to each country/region.  Congrats! 

Using this in IPTABLES: 

The iptables command to drop traffic from, say, non-US addresses is:

# iptables -A $CHAIN -m geoip ! --source-country US -j DROP

I maintain a "blocklist" chain specifically for things I want to drop, but put it AFTER the "RELATED,ESTABLISHED" state rules.  That way I can still initiate connections to foreign services, but clients outside the US can't initiate connections to my services.  An example configuration to do that looks like this:

# iptables -N blocklist
# iptables -A INPUT -m state --state INVALID -j DROP
# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -j blocklist
# iptables -A blocklist -m geoip ! --source-country US -j DROP
[... your additional rules / policy here ...]

You can manage these with your own script, or do "iptables-save >/etc/sysconfig/iptables" to write the configuration to the sysconfig service that sets up iptables on boot. 

If this works, you should be able to do an "iptables -L -n -v" and see a count of packets that have been dropped from other countries.

# iptables -L -n -v
Chain blocklist (1 references)
 pkts bytes target     prot opt in     out     source               destination
  704 40777 DROP       all  --  *      *              -m geoip ! --source-country US

 LPT:  If you mess up iptables in such a way that you can't ssh into your host anymore, you can always log into the "serial console" via the AWS -> EC2 console -> Instance -> Actions -> Monitor & Troubleshoot -> Serial Console (It might make you enable it first, but that's a one step process.)


To UPDATE the Geo_IP tables, just repeat steps 8 and 9 above (without the mkdir /usr/share/xt_geoip).  The xt_geoip_build_maxmind script will replace the GEOIP databases.   Note you probably need to reboot (or remove / reload the geoip module?) to refresh the iptables data.  I haven't explored how persistent it is in memory.

IF your distro updates the kernel (or you install a new kernel for some reason) you have to rebuild and re-install the xtables-addon geoip module!  If you reboot one day, and your iptables rules don't load, you probably updated the kernel and didn't build the new module.

Just repeat yum install kernel-devel-`uname -r`and then repeat step 6 above to build and re-install the module for the new kernel.

Good luck and have fun!

Monday, December 21, 2020

Wiring Diagram for Whirlpool / Maytag Dryer MEDC200XW1

 Wiring Diagram / Schematic for Whirlpool / Maytag Dryer model # MEDC200XW1
Drawing listed as Part No W10185989 REV L

Friday, April 3, 2020


I made a "DayClock" to remind me what day it is.   You can find the details on my GitHub page:

Wednesday, April 17, 2019

Flight to Death Valley

And a video of the landing:

Tuesday, March 12, 2019

OpenSCAD Module for Rounded Boxes

I got kind of tired of rewriting the same OpenSCAD code to build rounded boxes for things and messing up the minkowski sum math in the process, so I built a simple module to do it for me. 

Usage is simple:
include <rounded_case.scad>
rounded_case(25, 25, 10, 2);

The paramaters are:
rounded_case(X, Y, Z, T, LID, LID_OFFSET)

X, Y, Z : Inside dimensions of box
T : Thickness of walls
LID : optional, bool : true to also make a lid
LID_OFFSET : optional :  how much smaller to make the "lip" of the lid that fits inside the top of the box

The outside dimensions of the box will be the inside dimensions + 2 x T.   E.g. if the X dimension is 20mm, and T is 2mm, then the width of the box will be 24mm (20 + 2 + 2).   The example above will make a box that is 29mm x 29mm x 14mm (with the lid on) on the outside, and 25 x 25 x 10 on the inside.

Get it here: rounded_case.scad