Facebook account locked…

I spent my birthday on a trip to Europe. It’s a combo trip, Jay’s moving on from college to his job and I turned 61. If you know me you know that means we took a cruise. I like cruising. I get to meet lots of interesting people and get a taste of lot’s of interesting places. Ask me about the Mosque in Casablanca if you want to hear me gush. Part of the way through the cruise I checked into my Facebook account. I’m very leery of Facebook. Their function is to reconnect you with your friends but the way you pay for it is by sacrificing a large amount of your privacy. For most, the tradeoff is worth the sacrifice. That includes me but I like to hedge a little by only using Facebook from a privacy/incognito mode browser. I never consume www.facebook.com either on a device or through an app. This keeps their tracking information to a minimum. I had assumed that this behavior poisoned the relationship to the point where Facebook could live without me. That may be true but I don’t think that they would be so overt. The saying goes: Never blame malice for an action that’s adequately explained by incompetence. I tried using the process for unlocking the account unsuccessfully for three days. The process includes:

  • Upload a picture of your driver’s license that just so, at least 1500×1000 pixels, on a dark background,
  • Appeal to the Facebook security people for a code, write that code on a piece of paper by hand and make a video of yourself holding the paper. Make sure to move your head and the paper.

This morning I got up, very early because I’m still a little jet lagged, and decided to do what all good computer scientists do. I looked at the logs because sometimes the emails from Facebook would reach me but most o the time I just got what I though was very frustrating radio silence. It turns out that like Microsoft in January, facebook has found their way into an email DNS based realtime blocklist, or DNSRBL. And I happen to use that block list in my email server so Facebook emails were getting dropped on the floor. This is probably the root cause of the problem. Each time you log into Facebook, it tries to put a piece of information in your browser, app, or device that says: “Facebook, you can trust this because it’s really Chris”. If you do this in an incognito mode browser, that token gets deleted when you close the browser window or tab. Thus, people like me don’t have a place that facebook can say it’s really me. Lacking that they assume the worst. If I keep logging in from someplace near my house, it’s all good. But if I’m on a cruise ship in the harbor of Casablanca, that could be a hacking attempt. I’ll write a different post about 2FA and how it applies here later. When they assume the worst, they send you an email which saying: “Hey, someone logged into your Facebook account using your password and your 2FA token but they are in Morocco. Was this really you?” Now, if you receive that email and respond, yes, I’m on vacation” the gears keep turning. But if that email gets dropped on the floor, you know the rest of the story.

So what can one do to fix this. I still want to hedge my bets but Facebook has become a little too sensitive to the stream of brand new logins that they saw from me each time I fired up a new private tab and logged in. If you’re like me, you’ll still only consume www.facebook.com from a browser tab but the next best thing to private mode is a separate profile. Profile’s are supported in both Chrome and Safari. A profile is essentially domain under which browser information, cookies etc, are stored. In Chrome each profile is a separate space. Tracking information that you generate by browsing in one profile won’t cross into another one. I’m not happy to recommend Chrome but in this case, it gets the job done. I will note that profiles work under Chrome. I implemented by creating a separate “social media” profile for twitter / X and Facebook. Facebook just goes into a login loop when I try to do it from a profile in Safari.

Pip + git for development

I’m working on what should be a simple raspberry pi display project and I came up with the need for a set of ad-hoc python modules that were installable from my gitlab server. It was a bit of a journey. Here are the broad steps:

  • Create a gitlabs project for your python module. Since will probably have a few of these, it might be good to make a group for them right now.
  • I think that you can use git+ssh://git@gitlabs.example.com... for this but I chose to use a gitlabs impersonation token for this since ssh isn’t installed everywhere and sometimes the installation needs a bunch of hints in ~/.ssh/config.
  • A standard install will be done with pip as follows pip install git+https://{user}:{password}@git.example.com/example-group/example-project.git. If you created a gitlabs impersonation token about, you can substitute it for password here.

Sometimes I need to edit the installed package that I’m working on. The way to do this is to use the –editable flag to pip. To do that you need to specify some extra information to git when checking out the project. I found that this command line:

pip install --editable git+https://{user}:{token}@gitlabs.example.com/example-group/example-project.git#egg={module_name}

I think that the #egg={module_name} piece provides pip with name of the module as installed. I found the documentation that explains this here: “https://pip.pypa.io/en/stable/topics/vcs-support/”. Assuming that you are doing this in a venv, and it doesn’t make sense not to, you’ll get a new directory called venv/src/{module_name} which has a git checkout of your module so you can edit it to your needs for this particular project.

Nuke and Pave

I recently reinstalled MacOS on my work and home laptops and then brough back my working state using Time Machine on both. I’m always impressed by how much faster and better a computer is after you do this. My friend Matt Zagaja: https://zagaja.com calls this a “Nuke and Pave” from here: https://www.macsparky.com/blog/2016/3/t0kcqkdxmkapwyo9eno0hv98ojd2kx and I love the term. In my opinion, one of the bad side effects of MacOS’ success is that you don’t have to *Nuke and Pave* very often. I think I’d been carrying my working environment forward for better than 10 years without a refresh and moving from High Sierra to Catalina added a bunch of unwanted quirkiness. This was probably because Apple is deprecating a bunch of the tools that I used in 2012 and while I don’t use them today, they were still installing kernel extensions and other stuff that was making my machine a little unstable. If you want to do your own *Nuke and Pave* on mac, you’ll need the following:

  1. The operating system you want to install. I used Big Sur 11.6. I find that for MacOS you want to download the OS and then use instructions like these: https://support.apple.com/en-us/HT201372 to create usb install media.
  2. If you use MacPorts see the notes at the end to save a list of the ports that your run. You’ll need it when you rebuild.
  3. Backup media: If it’s important you should have one or two backups of it . In this case you want a Time Machine backup. Disk Clone style backups would normally be quicker but don’t give you the granularity you need here. I use a USB-C to NVMe drive enclosure for speed here. My second backup is on rotating rust.

The operation is pretty simple. You want to:

  1. Boot your Mac from the USB installer by shutting down completely and then booting and pressing *Option* and holding it until your Mac presents you with a choice of boot media. It’s handy that newer Macs will boot on a keypress so you can start this process by simply pressing and holding *Option* If you are on Catalina or later you have to boot to _recovery mode_ first by shutting down your mac completely and using the utilities menu to enable booting from other media. If you have a firmware password on your Mac, you’ll need that to change this setting.
  2. Once you’ve booted from your install media, you need to erase and repartition the hard drive on your Mac. This is the point of no return so don’t take this step unless you trust your backups.
  3. Follow the install media instructions to reinstall MacOS on your computer. It will pause and ask you how to build users. What’s going on behind the scenes is the mac is using Migration Assistant to populate your home directory. Choose Time Machine backup and go into the menus and trim all of Applications, Settings, etc. You really only want to carry over data at this point. If you don’t migrate enough information, you can use Migration Assistant or Time Machine to catch anything that you missed.
  4. Reinstall your apps using the App Store, and whatever other sources you have. As a developer I have a bunch of software installed that requires me to Control-Click on the Application and then give permission to run one time.
  5. Restore security permissions as needed. App Store packages generally won’t have this problem. Other packages will. I use Emacs as my main editor because I’ve been doing this for a while. That requires me to go into the System Preferences -> Security & Privacy -> Privacy pane and grant Emacs permission to read files from my specified locations.

That’s most of what you need. I did the operation overnight. I handled steps 1 ~ 3 and then went to sleep. When I woke up I finished up 4 and 5.

A side note here for MacPorts or Homebrew users. You’ll want to restore your MacPorts/Homebrew environment also. For MacPorts this isn’t hard. Basically run sudo port list requested > ~/Desktop/ports-requested.txt This will leave a copy of the ports you installed by hand in a text file. When you are rebuilding your machine, you’ll need to perform the prerequisites needed to run MacPorts. Then you can use this output to install the packages that you used. I don’t use HomeBrew but I’ imagine that there must be something similar to this in HomeBrew.

Mutt account passwords

First, to give credit where it’s due, I started here. That said, here’s how I store and access account passwords in mutt on Linux.

## -- Passwords: encrypted by gpg --------------------------------------------------------------

source “/bin/gpg -d ~/.keychain/mutt.password.neopost.gpg 2>/dev/null |”

The source line in gpg tells mutt to decrypt a file at startup. The file .keychain/mutt… contains two mutt configuration lines:

set imap_pass = "<my_email_password>"
set smtp_pass = "<my_email_password>"

I created it as follows:

$ cat <<EOF | gpg -r <my_gpg_id> ~/.keychain/mutt.password.neopost.gpg
set imap_pass = "<my_email_password>"
set smtp_pass = "<my_email_password>"
EOF
$

Gpg knows how to decrypt this file and retrieve the plain text configuration. Note well that I used a “Here” document to create the file. This keeps mail password out of the filesystem. Simple stuff, at mutt startup the first time I use it, gpg-agent asks for my gpg key and unlocks the configuration snippet.

Of IPv6, and unhappy eyeballs

I’m a dinosaur. I still bring a little Soekris Net5501 configured as a NAT gateway with IPsec back home when on vacation. This solution works best in hotels that still offer Wired internet. I do this because:

  • Majorly, In many cases a hotel’s WiFi is a great example of the worst case engineering solution with wifi tuned just well enough that web browsing doesn’t suck but nothing else is considered.
  • Minorly, Hotel’s in the United States will probably be the last places on Earth to get IPv6.

The other advantages should be obvious. By bringing a router I can control or at least police my DNS.

My Soekris is tiny. It takes up about as much space as three tee shirts in my packed bag including an Ancient Apple Airport Express that can be tuned to run on 5GHz only. Off hand I want to mention that configuring 5GHz WiFi in each hotel room might bring the best improvement to WiFi overall but hoteliers can’t do this because lots of people have old devices that don’t do 5GHz or don’t do it well. No one wants to be the guy trying to explain to a customer that the problem isn’t the WiFi, it’s the customer’s 2007 vintage MacBook Pro that can’t use channel 149.

So, note my surprise when I find that things aren’t working better on my custom wifi, homed to the edge router over ethernet, during my latest hotel stay. What happened? I think this…

My router connects the internet and establishes a tuned IPSec tunnel back home. Once that works, it advertises IPv6 addresses from my /48 which route back to my house and then out to the internet. If the latency for all of that is 10ms no one would notice the difference. If it goes greater than 30ms things start getting funky. We’ve crossed into a time where if you have a dual stack machine, one with both IPv4 and IPv6, you’ll try to use IPv6 for outbound work first and revert to IPv4 only when v6 has too much latency. Well, folks, when you have just enough latency, this doesn’t look pretty.

No solution yet and possibly not ever. The problem with latency issues like this is that you can’t easily fix them. That’s why tuning latency out is so important. I’ll post more when I know more.

Emacs use tabs rather than spaces.

Today, about the only place you should see an ascii TAB in a file is in a Makefile. In a world where memory is metered as gigabytes of RAM and terabytes of storage on fast SSDs there is absolutely no need to save space in a source code or configuration file by using a tab rather than two or four or eight spaces. Note well that I may be talking to your editor configuration and not you. But when you write code you should say what you mean and mean what you say unequivocally. I say this because I have been looking at a whitespace difference in my puppet checks for better than a month now. This is because my file has in production has tabs and my file in the puppet/git repository has spaces.

To that end, I’m linking this bit of Emacs magic for readers and my future self.

Submission brutes

Brush aside vandals attacking my submission daemon with a little sed:


submission_brutes=$(bzcat /var/log/maillog.0.bz2 | \
cat - /var/log/maillog | \
sed -Ene '/postfix\/submission\/smtpd.*errors after AUTH/s/^.*[^0-9]+(([0-9]+\.){3}[0-9]*).*$/\1/p' | sort -u)
[[ ! -z "${submission_brutes}" ]] && pfctl -t blackhole -T add ${submission_brutes}

pf required: pass proto ipv6-frag all

FreeBSD’s pf has serious problems with ipv6 fragment handling. The problems cascade into other issues like named axfr time outs.  Add this, “pass proto ipv6-frag all”, to your ruleset somewhere near your antispoof rules to fix this.

Much of the issue is that the FreeBSD team has diverged their version of the pf firewall so far from the OpenBSD version that they cannot incorporate upstream fixes. I’m not making my situation any better by sticking with FreeBSD 9. Some of this is probably addressed in FreeBSD 10.

While this persists the best course of action is probably to make sure it works on OpenBSD first, then figure out how to deal with any FreeBSD issues.