Decrypting Password Protected PDF Files

Receiving password protected PDF files? If you get annoyed to type the password every time, decrypt and save into a new file:

$ qpdf --password=secret --decrypt infile.pdf outfile.pdf

QPDF is a command-line tools and library for transforming PDF files, an alternative to pdftk.


qpdf 7.1.1

Using Two Different Phones for 2FA

When setting up two-factor authentication (2FA), there is always an option to print backup codes in case you lose your phone. But if you have a spare phone, you can use it as the backup authenticator device.

During the 2FA setup process, scan the QR code on two different phones. Both phones will show the identical codes. This is because of time-based OTP (One-Time Password) implementation. Time-based OTP establishes authentication by an Unix time to start counting and an interval for computing the next set of codes (usually 30 seconds).

In fact, you can use three, four, or as many devices you want. When done, set a strong password for the phone, turn it off, store somewhere safe. It’s better than a piece of paper, because when your safe was broken into, there’s another layer of protection.

BTW, when Google asks you “What kind of phone do you have?”, you can pick Android and still use the authenticator app from the iPhone.

Get codes from the Authenticator app

Therefore, 2FA, two different phones, two locations, no LastPass, no Authy, no cloud based backup.

Resetting GitLab User Password with a Simple Shell Script


Resetting password is one of the most common requests virtually in any system. In GitLab, user password can be updated by visiting the /admin/users page. But if you forgot the password for the root user or the admin user. You need another method to reset it.


The goal is to simplify the process of resetting GitLab user password by using CLI, so next time when encountering the same problem again, it will be quick and easy.


Self-hosted GitLab, installed in a Docker container.


Step by step procedure to reset the root password is already provided by this GitLab documentation. By converting it into a Bash shell script and placing it in user’s home bin directory as an executable ~/bin/gitlab-password-reset file, we will have created a simple command to be run repeatedly:

#!/usr/bin/env bash
echo -n "Email: "; read MAIL
echo -n "Password: "; read -s PASS
echo # Ensure a new line
docker exec gitlab gitlab-rails runner -e production " \
user = User.find_by(email: '$MAIL'); \
user.password = user.password_confirmation = '$PASS'; \!"

We could simply run the long docker command instead of shell script. But since we’re dealing with password, it’s a good practice to avoid placing sensitive information on command line history log.

No trailing spaces are allowed on the password field, by the way.

Another solution is turning the Ruby evaluation into a script and save into somewhere like /srv/gitlab/config directory. Then, we can just run:

$ docker exec gitlab gitlab-rails runner -e production /etc/gitlab/scripts/password-reset.rb

Because we are using Docker to run GitLab, and the following directories are mapped from the host to the guest:


Therefore, when executing the Ruby script, it’s /etc/gitlab instead of /srv/gitlab. However, you will need to figure out how to get the email and password into the script. That’s for you to answer.