Email OAuth2 Proxy

Microsoft Screws Their Users… Again…

 

Desktop Outlook Banned From Outlook.com and Hotmail.com POP3

Microsoft had stopped allowing users of their premium Outlook desktop product (versus the useless, neutered “Outlook” wannabe bloatware “Outlook for Windows” included force installed in Windows 11) to access their “free” @hotmail.com and @outlook.com emails via POP3 and SMTP (secured or not), forcing everyone to use effectively use IMAP mode (links here and here, backup here).

Leaving discussions over any reasons (e.g. financial greed trying to force clueless desktop Outlook + “free” MS email-using people to pay for more storage) and the sheer stupidity of forcing this down Outlook users’ throats (against, say, everyone else like those using Thunderbird or other third-party email clients) aside, I had simply left this aside, relying on my trusty K-9 Mail on Android to access any emails on these “throw-away” accounts…

Unfortunately, there were a few emails (mainly shopping-related receipts) that I wanted to keep – so once again, I had to roll-up my sleeves and fix shit Microsoft breaks get things working…

Google search basically found me Email OAUTH2 Proxy nearly immediately… Attempts at simply using the Docker image did not go so smoothly, so I ended up using pipx and did a “bare metal” install..

 

Trying To Understand/Explain Things

Furthermore, I found the author’s README.md hard to understand, so I decided to whip up my “own” documentation, based more around an intended outcome (that may require multiple switches/options used together), than say, explaining individual switches.

Since some explanation sections covers multiple points, I have used separate multiple sub-section headers denoting what/which point/s a singular section would resolve/be relevant to/answer.

 

OAUTH2 Client_ID and Microsoft

For the “free” @outlook.com and @hotmail.com services (it’s never free – you pay with your information), the bastards people at Microsoft have disabled the use of custom clients (unless you jump through a lot of hoops and/or pay a lot of money). Therefore, this configuration uses Thunderbird’s public client_id (i.e. the proxy is identifying itself, during OAUTH2 token generation, that it is “a Thunderbird email client”).

 

Headless Mode

This configuration runs “headless” (i.e. --no-gui) and as a background service (i.e. no manual input interaction) with all console output pushed to a log file. There are considerations to be aware of due to the latter point – refer to the section “New Accounts and OAUTH2 Token Generation“.

Refer to * footnote.

 

Single Domain Configuration

Wildcard Mode

Adding Users Semi-Automatically

To prevent me from having to manually create and repeat configuration snippets for every account, and also minimise the ports count (i.e. one port per domain and service vs. one for each account and service), I configured emailproxy to use wildcards per domain (i.e. allow_catch_all_accounts), allowing me to configure each server type (and service port) once, where any attempts to log in with a here-to-fore unknown email address (on said domain) or unknown password (refer to ‘How EmailProxy Determines An Account as “New”‘) would trigger the OAUTH2 token generation ceremony.

Refer to * footnote.

 

New Accounts and OAUTH2 Token Generation

Disabling “ANY” User Creation

Any manual actions required of the OAUTH2 token generation ceremony (like copying the temporary authentication URL for actual browser-based authentication then “pasting” the token as input) has to be done only in interactive mode (i.e. run the email-oauth2-proxy-manual.sh script). By virtue of this point, not just anyone, because of your use of “wildcard” domain, can use/abuse your proxy.

  • stop  the service
    • systemctl stop emailoauth2proxy
  • run the script interactively in the foreground
    • /opt/emailproxy/email-oauth2-proxy-manual.sh
  • run the email client with the “new” account, using a complex password (that has to be re-used for this account henceforth)
    • copy the authentication URL and access using standard browser with no existing logged in sessions for said OAUTH2 domain (e.g. use “incognito mode”)
    • run through the authentication process
      • it will end in a redirect to “http://localhost:8080” with a 404 – this is expected
      • copy the entire URL and paste it back (as input) to the running emailproxy process (which will be waiting for the input on the console)
    • force a check again (e.g. using Outlook’s “Send/Receive Groups” pull-down and selecting the correct Hotmail.com/Outlook.com account to “pull” the “Inbox”)
  • stop (CTRL-C) the emailproxy process/thread and (re)start the service
    • systemctl start emailoauth2proxy

* Because of the out-of-band authentication and no HTTP interface of emailproxy, the process can only be, at best, semi-automated. i.e. You will need to execute any new OAUTH2 token generation process from the server directly.

 

Disabling Auto Force New Token Generation

Separating Credentials Best Practice

Enforcing “Basic/Simple” Authentication

How EmailProxy Determines An Account Is “New”

Since --cache-store specifies a separate file, any actual accounts’ tokens and other (copied) settings (from the “wildcard” source service) will be stored in said separate file, encrypted by the initial password used during OAUTH2 token generation.

I consider this “best practice” as I only need to review said file for changes.

By default (i.e. “delete_account_token_on_password_error = True“), emailproxy assumes any failure to decrypt any existing data (or finds missing data) from individual account sections means (re-)triggering a new OAUTH2 token generation ceremony/process.

By using “delete_account_token_on_password_error = False“, any failure in decrypting encrypted data of the account would not (re-)trigger a new OAUTH2 token generation ceremony/process.

Although if missing data, or if the account section was completely missing (i.e. new), the OAUTH2 token generation ceremony/process would still be triggered (and correctly so).

This acts as a sort of “basic/simple” security check – not anyone can just attempt to use your generated token and get access to your email – only when attempting to authenticate with the same password used during the initial OAUTH2 token generation ceremony/process will the client be successful.

 

Continue reading

Customising CyberChef…

So, in the need to run some Base64 encoding + decoding using local HTML files and modern browser-based JS, I came across CyberChef

Asking Google’s “AI Mode” (even the “Pro” version) to provide instructions to strip the files down to the basic (e.g. no bloat from Tesseract OCR files or other operations/modules not needed excepting “To Base64” and “From Base64” operations) was an exercise in frustration… With “instructions” from deleting .mjs operation files from source tree, to editing the src/core/config/scripts/generateConfig.mjs (in truth, only one or the other was required – along with some other steps), to attempting hard-code edits on webpack.config.js.

None of that worked correctly – No HTML was produced at the end due to some compilation error.

Fortunately, it pointed me in the right direction, and I finally managed to “shrink” my build for easy transfer, down from the hefty 70+MB .zip file…

Continue reading

“Unrooting” WSL…

WSL starts as root user be default.

Here’s how to ensure it runs as a “non-root user” (assumedly already created), which you then have to su and/or sudo <something> to act as root:

  • either/and:
    • modify a shortcut or change Windows Terminal’s Profile to set the distribution (if required) and the user name, and starting in the user’s home directory:
      • wsl -d <distro> -u <user> -cd ~
    • edit /etc/wsl.conf to always start with a specific user:
      • [user]
        default=<user>

Simple! (Not!)

Unifi Controller

I had a docker container of the jacobalberty/unifi “all-in-one” Unifi Network Application, and I somehow garbled the password…

The fix?

  • enter the container:
    • docker exec -it <container_name> /bin/bash
  • run MongoDB CLI:
    • mongo --port 27117
  • find the administrator user name/s:
    • use ace;
    • db.admin.find().forEach(printjson);
  • you should see one or more name entry/entries:
    • "name" : "<user_name>"
  • set/reset the password (to “password“):
    • db.admin.update( { "name" : "<user_name>" }, { $set : { "x_shadow" : "$6$ybLXKYjTNj9vv$dgGRjoXYFkw33OFZtBsp1flbCpoFQR7ac8O0FrZixHG.sw2AQmA5PuUbQC/e5.Zu.f7pGuF7qBKAfT/JRZFk8/" } } )

You should be able to log right back in with the reset password.

LAGGing pfSense… Manually…

Throughput through my KVM-hosted pfSense was abysmal for a 10Gbps link – despite the Intel Core i7 155h host w/128GB 5600Mhz RAM doing nothing else but hosting the pfSense VM (replete with VFIO-passthrough)…

I could get ~8-9Gbps iperf3 performance on from my PC to the WAN interface, which was “OK”, but iperf3 from pfSense out to various 10Gbps-capable public iperf3 servers was bad, as was Ookla speedtest.net results (from my PC).

In an attempt to figure out if the virtualisation was part of the issue, I attempted to run pfSense bare metal (via dual-booting – which had a whole storied journey itself)…

First boot brought up all the interfaces (thankfully) for selection – but no way to set up LAG then choose that for my WAN/LAN interface…

Continue reading

Upgrading WSL2 Ubuntu LTS 22.04 to LTS 24.04…

After fixing WSL networking issues, I had to upgrade the Ubuntu LTS instance… The sequence should have been:

  • apt update
  • apt upgrade -y
  • apt dist-update
  • lsb_release -a   # to confirm version before upgrade
  • do-release-upgrade
  • lsb_release -a   # to confirm version after upgrade

But, as per usual, I hit another issue attempting to upgrade (i.e. while running do-release-upgrade):

error: cannot list snaps: cannot communicate with server: Get "http://localhost/v2/snaps": dial unix /run/snapd.socket: connect: no such file or directory

A quick ‘net search brought up the point that snapd was not running…

Continue reading

Windows 11 Host Network Service (HNS) and Windows Subsystem for Linux (WSL)…

For the longest time, my Ubuntu LTS 22.04 on my (forced-to-be-updated-to) Windows 11 (replete with other networking horrors) was not working properly – I could only access the Internet from within the WSL2 container when Windows Firewall was disabled.

Despite shenanigans like attempting to whitelist a whole plethora of executables:

  • C:\Windows\System32\vmcompute.exe
  • C:\Windows\System32\vmms.exe
  • C:\Windows\System32\vmwp.exe
  • C:\Windows\System32\wsl.exe
  • C:\Program Files\WSL\wsl.exe
  • C:\Program Files\WSL\wslservice.exe

Even attempting to whitelist the usual services suspects via C:\Windows\System32\svchost.exe like the following:

  • Host Network Service
  • Internet Connection Sharing (ICS)

All were to no avail. I could resolve domain names, but no traffic went out unless the host’s Windows Firewall was disabled.

I could not even see any blocked traffic from the logs, despite having the correct set up (tip: just use WFC‘s logging interface).

Searching ChatGPT and Perplexity sent me on various wild-goose chases, from changing WSL networking modes (NAT vs. “mirrored” in %USERPROFILE%/.wslconfig), to setting up dubious firewall rules referencing InterfaceAlias using New-NetFirewallRule (but which actual interface UUIDs change every boot). Continue reading

pfSense and 2FA…

I wasted quite a bit of time attempting to implement 2FA as part of user authentication on pfSense, firstly finding out that 2FA support was not intrinsic…

Next up, grappling with the FreeRADIUS extension for pfSense 2.7.x and attempting to follow everything from Reddit posts, some time-wasting video posts, to the abbreviated instructions from Google Search and some posts from different Google Search results.

Continue reading

Malwarebytes fka BiniSoft Windows Firewall Control and Windows Defender Firewall with Advanced Security Interactions…

I used to swear by the very useful, but extremely complicated (and easy to break your OS if you get it wrong, but free) Comodo Internet Security suite, which included  Comodo Firewall…

Unfortunately, having been forced to upgrade to Windows 11 a few months back, replete with feature retardation, my trusty ol’ CIS 12.x no longer worked (properly), and I had to switch to the “plain ‘ol Windows Firewall” – which works great except for the rules and rules management. Working with the Advanced Firewall console UI is a nightmare, and not being able to quickly allow something that was blocked renders the plain ‘ol Windows Firewall unusable.

I may have gotten the following versions and timelines wrong: When I initially tested Windows 7, I knew ZoneAlarm 7.x was not compatible (then), I actually looked at, and bought, BiniSoft’s WFC before finally settling on CIS… I returned to BiniSoft in 2024 only to find out that it had been bought out in 2018 by Malwarebytes…

Nevertheless, background and fuzzy memory aside, I was chugging along on Windows 11 (sans LACP’d 10Gbps NICs) with “just” Windows Firewall and WFC, when I must have changed something, because, all of a sudden:

  • attempting to pull up the connection logs through WFC resulted in a never-ending “loading” prompt
  • attempting to change any setting in the Windows Defender Firewall with Advanced Security console (i.e. running wf.msc with Administrator privileges) failed with a repeated “access denied” message

 

Checking the ‘net did not help much:

  • explicitly adding NT Service\mpssvc user and even myself to security ACL of the (default) C:\Windows\System32\LogFiles\Firewall directory and the created .log files with “Full Control” permissions did nothing
  • attempting to edit anything via the registry still worked, but the never-ending connection logs UI was still a problem

I bashed my head against this issue for the better part of some 3 hours before some memory synapses lit up…

Continue reading

pfSense OpenVPN Server IP Address Changes and DNS Forwarder…

Note to self – if attempting to change the IP address of the OpenVPN server/service, you need to disable the interface then re-enable it, otherwise the DNS Forwarder selection of active interfaces will still take the old IP address (and therefore fail to start).

You will be able to see the pfSense’s debug logs showing a failed attempt to listen on the old IP.