Installing TLS certificates on HP printers automatically

Installing a TLS (SSL) certificate on an HP LaserJet printer automatically isn’t as difficult as you might think

I wrote an article about installing a Let’s Encrypt TLS certificate on an HP LaserJet printer a while ago.  Since then, I’ve been annoyed by having to install updated certificates manually, so I decided to look at how I could automate it.

HP LaserJet printer control panel
Photo by Alex Furr from FreeImages

TechRadar has a great article on securing printers, but how do you automate it? Well, with a certificate authority like Let’s Encrypt for starters, but there’s no mechanism for the printer to automatically update its certificate after it expires.

I’ve set my desktop machine to certbot and renew the certificate automatically. An evening’s hacking around the web interface showed it’s really easy to install a certificate automatically.

This is the magic command to install the certificate:

curl -v --insecure https://HOSTNAME/hp/device/Certificate.pfx --form upload=@/tmp/cert.pfx --form Password=password

Replace HOSTNAME with the hostname of your printer and change /tmp/cert.pfx as required. If you want to know how to create the PFX file, see my original post.

Has anyone else found out how to do this? If they have, they’ve not posted about it!

Running Postgres as a normal user

Whilst testing out some PostgreSQL replication scenarios, I needed to have multiple instances of Postgres running under my user. I could have used multiple Docker machines with ports exposed, but I opted for another solution. Here’s how I did it.

First, I created /home/user/pgdata to hold the data directories, and /tmp/postgres to hold the UNIX socket files.

Then, it’s just a case of running /usr/lib/postgresql/12/bin/initdb /home/user/pgdata/1 -E UTF-8 to create a data directory, then editing postgresql.conf and changing the TCP port from 5432 to, say, 50432, and unix_socket_directories to /tmp/postgresql.

To start the server, run /usr/lib/postgresql/12/bin/pg_ctl -D /home/user/pgdata/1 -l logfile start, and to stop it, replace "start" with "stop". The final step is to create a postgres user with /usr/lib/postgresql/12/bin/createuser -drs postgres -h localhost -p 50432 and you’re away.

Some use cases I can think of for this are:

  • An isolated Postgres instance for integration testing
  • Trying out a new version of Postgres in parallel with your existing version
  • Verifying your disaster recovery procedures

There are probably more.

Hue-ge pain in the butt

I have a Philips Hue bridge which lets me control the lights in my flat in a variety of useful ways. It’s a good bit of kit, but with one major problem – it assumes you’re running PAT (Port Address Translation), and that your Hue bridge and the device you access https://account.meethue.com/bridge both access the Internet from the same source IP address. If not, even though the devices may be in the same broadcast domain and the same IPv4 subnet, you won’t be able to link your Hue to your account.

Despite tweeting for assistance, I ended up crying shibboleet and reverse-engineering the method of linking they’re using. Here’s what I found out, in the hope it’ll save somebody else a lot of time.

My Internet services are through the excellent A&A, and I can’t recommend them highly enough. I have a public IPv4 subnet, and each of my devices accesses the Internet without any address translation. Inbound connectivity is restricted – there are only a few things I need accessible from the Internet. (As an aside, I have two DSL lines, with my IPv4 subnet routed down each – load balancing and resilience)

My Hue bridge connects to https://discovery.meethue.com/, and that service makes a note of an inventory that the bridge sends to it. Here’s where the problem is – visiting discovery.meethue.com only returns the devices that registered from the IP address you’re connecting from. That’s fine if all your devices go through address translation and appear to come from a single external IP address, but useless for me – my mobile device uses an entirely different IPv4 address, as does my desktop and laptop. The Hue app reports that no devices were found.

After some frustrating interactions on Twitter, I solved the problem myself. I set up IP Masquerade – essentially port address translation behind the router’s external IPv4 address – for my Hue bridge and my mobile device, so they’d appear to be coming from the router’s external IP address. Rebooting the Hue, disabling one of the PPP connections on my router (necessary since they both have an IP address assigned, and my outbound traffic is load-balanced per TCP connection) and linking the device from my mobile phone then worked. Rolling it all back and rebooting the Hue again leaves the device linked to my account.

What a mess. Adding a “Enter the IP address of your Hue then when prompted, press the button” on the device linking page would have been a whole load easier. Not everyone’s Internet connection is the same, nor is everyone as experienced in network engineering as I am… yet still it took me three days to work out a fix.

In summary: buy Hue devices – they’re good, but beware if you’re doing anything that possibly deviates from the common case.

Integration and Unit Tests with IntelliJ IDEA and JUnit 5

When working on a project in Java, I like to name my integration and unit tests separately. Integration tests end ‘-IT’, and unit tests don’t.

This makes it really easy to run just unit or integration tests in IntelliJ by using one of these two patterns:

  • Integration tests – ^(.*IT.*).*$
  • Unit tests – ^(?!.*IT.*).*$

Make sure the Run configuration has the Test Kind set to Pattern, and searches for tests in the whole project.

OpenLDAP with TLS and LetsEncrypt on Ubuntu 16.04

Using TLS (SSL) certificiates with OpenLDAP

Every time we added this, an error cropped up:

A project I’m working on requires a Kerberos and LDAP infrastructure. Most technology projects are easy to do badly, and more difficult to do well – and documented.

We use LetsEncrypt to issue a certificate to each server, and OpenLDAP can take the certificate and use it to encrypt and authenticate connections from other LDAP servers.

One of the problems I encountered was when setting up replication between servers. We use SaltStack to build and maintain our server estate, so deployment and configuration needs to be automated. This normally means spending a week automating a process which you’ll only do twice – once when you install it, and once again when you’re rebuilding the server and have forgotten everything you’ve done.

To secure OpenSSL, add this LDIF file to your directory:

dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/letsencrypt/live/ldap1.example.com/fullchain.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/letsencrypt/live/ldap1.example.com/cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/letsencrypt/live/ldap1.example.com/privkey.pem

Every time we did this, a vague error popped up:

$ sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f ./ssl.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0 modifying entry "cn=config"
ldap_modify: Other (e.g., implementation specific) error (80)

Restarting slapd, the LDAP daemon, with full debugging showed nothing, neither did running the daemon through strace.

Several days of painful troubleshooting followed. We eventually found the issue – the LDAP daemon wasn’t able to access the TLS certificates! AppArmor was blocking access to the files under /etc/letsencrypt, and so we did two simple things.

First, we used setfacl to give the openldap user ‘rx’ permissions on /etc/letsencrypt/live and /etc/letsencrypt/archive:

$ sudo setfacl -m user:openldap:r-x /etc/letsencrypt/live
$ sudo setfacl -m user:openldap:r-x /etc/letsencrypt/archive

This lets the LDAP daemon read and following the symbolic links in the live directory to the actual files.

Next, we needed to tell AppArmor to let the LDAP daemon, slapd, access the files themselves. It’s as easy as creating a file called /etc/apparmor.d/local/usr.sbin.slapd with the following:

/etc/letsencrypt/live/{{ grains.id }} r,
/etc/letsencrypt/archive/{{ grains.id }} r,
/etc/letsencrypt/archive/{{ grains.id }}/** r,

The trailing comma on the last line isn’t a mistake – if you don’t include it, AppArmor won’t install the rule. I won’t admit how long it took us to realise this!

Turning off SSID broadcast for HP LaserJet printers

How do you turn off your HP LaserJet printer’s built-in WiFi Direct SSID?

A new HP LaserJet printer arrived in the office recently. After plugging it on to the office network, the setup was easy, but I couldn’t find a way to stop the printer broadcasting a wireless network name.

Photo by Rybson from FreeImages

Several hours of testing, failing, resetting and re-testing led me to HP’s Support Forum.  I found some instructions from a user who worked out how to disable the network.  It’s not logical or obvious.

First, make sure you don’t have a USB cable attached to the printer. Go to the web configuration page and select Networking > Wi-Fi Direct Setup, and turn WiFi Direct on.

Then, set the connection method to Advanced, and check “Do not broadcast the Wi-Fi Direct Name”. Click Apply, restart the printer, then go back in to the configuration page and turn Wi-Fi Direct off.

I don’t know why this isn’t an obvious option, but HP might fix it in a later release of the printer’s firmware.

Converting from assert() to assertEquals() in Java

When I was inexperienced in Java, I wrote a lot of tests using assert(), rather than using assertEquals().
Revisiting code today, I wanted to update many test suites to use assertEquals(), which requires I flip the expected and actual values around. Too difficult to do quickly by hand, so I used the following regular expression:
Find: assert \((.+)\)\.equals\((.+)\)\);
Replace: assertEquals($2, $1));
It worked like a treat.

Securing an HP LaserJet printer with LetsEncrypt

Installing a TLS (or SSL) certificate on a HP LaserJet printer

The fantastic and free Let’s Encrypt service lets you issue TLS (SSL) certificates to as many devices as you want. It’s perfect for a home or small office environment.

The Let’s Encrypt service needs to validate that you are in control of the device you’ve requested a certificate for. Most of the time, it’s fine to serve up a single file from your server. What if you can’t actually serve arbitrary files from your device?

There is a way around this – you can use a TXT (text) record in DNS to authenticate the device, and that’s what I did.

Photo by Alex Furr from FreeImages

I’ve used certbot to generate my certificate:

certbot -d host.example.com --manual --preferred-challenges dns certonly

Note down the TXT record that appears and add it to your DNS server, and you’re done.

My printer wants the certificate and private key in a PKCS#12 bundle, a bit like a ‘zip’ or ‘tar’ archive. This isn’t obvious, but it can be done with this command:

openssl pkcs12 -export -out certificate.pfx -inkey config/live/host.example.com/privkey.pem -in config/live/host.example.com/cert.pem

You’ll be asked for a passphrase, and the key and certificate will be in certificiate.pfx.  You can load this in to the printer by hand, or automatically with a single command.

Ubuntu 16.04LTS

I will freely admit that I’ve been putting off upgrading my Ubuntu 14.04LTS boxes to 16.04LTS. In a previous post, I wrote about my battle with getting the Ubuntu desktop to be usable in the way I wanted it. Having tried this out on 16.04LTS, I realised that I’d have to change the way I work.
I am two weeks in to running the new upgraded system and I wish I’d gone through the pain earlier. Making the Unity Launcher smaller, getting used to the menu bar in the top row of windows, and the close, minimise and maximise buttons landing in the top left of the screen when maximised – none of those took particularly long to get past.
On previous installs, I’ve wanted shortcuts to the common applications at the top of the screen by the clock, but I’ve locked these in to the Unity Launcher – and there’s more space for them.
The only irritation that’s still there is resizing terminal windows. It takes a while to re-learn that I don’t have to be precise with the cursor positioning to change the window size. And that’s it.
Ubuntu 16.04LTS, you are forgiven – I thought you were going to be a nightmare, but you’re lovely. And when I unplug one of my monitors from the graphics card, you put everything back on the screen still plugged in. That’s awesome!

Citrix Receiver and CA support

On installing an Ubuntu 16.04 desktop from scratch and putting Citrix Receiver on it, I found I couldn’t connect to one of the servers that I need to for work. The strange error suggested that the Citrix client doesn’t trust the VeriSign Class 3 Public Primary Certification Authority – G5.
This seemed confusing at first – I have the CA certificate in /usr/share/ca-certificates/mozilla. A quick look at where Citrix Receiver installed itself quickly found what was going on.
Citrix Receiver only has a handful of CA certificates installed in /opt/Citrix/ICAClient/keystore/cacerts, so if you’re connecting to a server with an SSL certificate other than the dozen or so in here, simply copy the .crt or .pem file and you’re sorted.