January 23, 2017

Let's Encrypt with Amazon Linux

For the past couple of years, I have used StartSSL to obtain free SSL certificates for 13cubed.com and other side projects. As many are aware, StartSSL's parent StartCom was acquired by Chinese CA WoSign. Apple, Google, the Mozilla Foundation, and others have revoked certificates issued by WoSign and StartCom due to several incidents involving improper issuance and back-dating of certificates to avoid the SHA-1 sunset.

I decided to give Let's Encrypt a try, but I wanted to manually handle the editing of the Apache SSL/TLS configuration (I don't trust a script to properly do this without making a mess of things). Surprisingly, as of the time of this post, Let's Encrypt does not provide configuration information for Amazon Linux. Using the information here, I was able to cobble together a short list of steps to get everything up and running:

1. Download the newest version of the Certbot Auto script:

cd /home/ec2-user
wget https://dl.eff.org/certbot-auto

2. Change permissions to make the script executable:

chmod 755 certbot-auto

The script checks for the presence of /etc/issue, and looks for the string "Amazon Linux" therein. On my instance, this file was not present. If the script doesn't find the file, you will receive the following error:
Sorry, I don't know how to bootstrap Certbot on your operating system!
You will need to bootstrap, configure virtualenv, and run pip install manually. Please see https://letsencrypt.readthedocs.org/en/latest/contributing.html#prerequisitesfor more info.
3. If "/etc/issue" is not present on your instance, create the file, adding the string "Amazon Linux" therein:

sudo echo "Amazon Linux" > /etc/issue

4. Run the script with the following parameters, replacing "13cubed.com" and "www.13cubed.com" with your domain. Note the "certonly" parameter, which instructs the script to NOT modify any configuration files. You can add as many "-d" flags as necessary, but wildcards are not supported:

sudo ./certbot-auto --debug -v --server https://acme-v01.api.letsencrypt.org/directory certonly -d www.13cubed.com -d 13cubed.com

You will likely be prompted to install several packages. In my example, I installed the following:


The script will then ask how the CA should verify ownership of the domain for which you wish to obtain the certificate. I chose the second option, which involved placing a temporary file within the web root (normally /var/www/html on a default installation).

Once the script has finished, it will have generated the following symlinks within /etc/letsencrypt/live/[DOMAIN NAME]/:


cert.pem -> ../../archive/www.13cubed.com/cert1.pem
chain.pem -> ../../archive/www.13cubed.com/chain1.pem
fullchain.pem -> ../../archive/www.13cubed.com/fullchain1.pem
privkey.pem -> ../../archive/www.13cubed.com/privkey1.pem

5. Assuming you are using Apache, edit /etc/httpd/conf.d/ssl.conf as follows, changing "www.13cubed.com" to the name of the domain for which you obtained the certificate:

vi /etc/httpd/conf.d/ssl.conf

SSLCertificateFile /etc/letsencrypt/live/www.13cubed.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.13cubed.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/www.13cubed.com/chain.pem

6. Restart Apache and verify the certificate installation was successful:

service httpd restart

7. Let's Encrypt certificates expire every 90 days, so you'll need to create a cron job under "root" to periodically check the status. As suggested in the article I referenced above, I would recommend twice per day. The following cron job checks at 1AM and 1PM:

sudo crontab -e

0 1,13 * * *    /home/ec2-user/certbot-auto renew


October 17, 2016

Arch Linux Installation Guide

I decided to give Arch Linux a try on my main desktop (Core i7-4790K, 16GB RAM, 256GB/1TB SSDs, GTX 1070). After quite a bit of research and information gleaned from multiple wikis, blog posts, and how-tos, I cobbled together a list of steps necessary to install the OS, a base set of core utilities, and the GNOME Desktop Environment (DE). I've been a Linux user since 1996, and anyone with Linux experience will likely find the steps fairly straightforward. It really isn't that difficult, but it does require a certain degree of patience.

Let's get started! Boot the Arch Linux ISO, and follow the steps below. Oh, and a side note -- stop using nano! Seriously, if you really want to learn Linux, teach yourself a real editor like Vi/VIM (or, God forbid, Emacs). If you're using iOS, check out Vimmy. It's a free Vi/VIM reference app I wrote that will be quite useful to you.

Check network connectivity and update the system clock:

ping google.com
timedatectl set-ntp true

Partition the drive with your tool of choice, normally as follows. Obviously, you may have to adjust this for your particular configuration:

- /dev/sda1  = EFI (512MB, FAT32)
- /dev/sda2  = Swap (dependent on RAM)
- /dev/sda3  = Root (remaining space, Ext4)

Format partitions and turn on swap:

mkfs.fat -F32 -nEFI /dev/sda1

mkswap /dev/sda2
swapon /dev/sda2

mkfs.ext4 –LRoot /dev/sda3

Mount partitions:

The order of these steps is critical. Mount the root file system first, then create /boot, then mount /boot.

mount /dev/sda3 /mnt
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot

Find closest mirrors:

cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
sed -i 's/^#Server/Server/' /etc/pacman.d/mirrorlist.backup
rankmirrors -n 6 /etc/pacman.d/mirrorlist.backup > /etc/pacman.d/mirrorlist

Install base packages:

pacstrap -i /mnt base base-devel

Generate fstab:

genfstab -U /mnt > /mnt/etc/fstab

Change root into new system:

arch-chroot /mnt /bin/bash

Install and configure boot loader and Intel ucode:

bootctl --path=/boot install
pacman –S intel-ucode

Obtain UUID of root file system:

blkid –s PARTUUID –o value /dev/sda3 > /boot/loader/entries/arch.conf

Now edit the new arch.conf you created above to look like this:

vi /boot/loader/entries/arch.conf

title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options root=PARTUUID=[UUID you wrote to the file in above step] rw

Set language and time zone:

vi /etc/locale.gen

Uncomment the following line:


… then run the following commands:

echo LANG=en_US.UTF-8 > /etc/locale.conf
export LANG=en_US.UTF-8

Run “tzselect” and create a symlink to the correct timezone:

ln -s /usr/share/zoneinfo/America/New_York /etc/localtime

Sync hardware clock to UTC:

hwclock --systohc –-utc

Change hostname:

echo “myhostname” > /etc/hostname

Change root password and create user accounts:

useradd -m -G wheel,users -s /bin/bash username-here
passwd username-here

Enable Multilib and AUR:

vi /etc/pacman.conf

Uncomment the lines in the [multilib] section.
Then, add the following to the bottom of the file to enable AUR:

SigLevel = Never
Server = http://repo.archlinux.fr/$arch

Run pacman –Sy to process the changes…

Install YAOURT to pull from Arch User Repository (AUR):

pacman -S yaourt

Install GNOME and GNOME Software:

pacman -S gnome gnome-extra gnome-tweak-tool gnome-software gnome-shell-extensions

Install WPA Supplicant and Network Manager:

pacman -S iw wpa_supplicant dialog network-manager-applet networkmanager

Set GNOME Display Manager (GDM) and Network Manager to start at boot:

systemctl enable gdm.service
systemctl enable NetworkManager.service

Install NVIDIA proprietary drivers (with 32-bit support):

pacman –S nvidia nvidia-utils nvidia-libgl lib32-nvidia-libgl lib32-nvidia-utils

Install Bash Completion:

pacman -S bash-completion

Configure static IP address (optional):

Copy the /etc/netctl/examples/ethernet-static example profile to /etc/netctl and modify Interface, Address, Gateway and DNS as needed.

Exit chroot, Unmount, and reboot:

umount -R /mnt

Once the system is up, you'll notice the default fonts and font rendering are pretty poor. You can use the steps below to install additional recommended fonts, as well as the Infinality font rendering engine.

Add additional fonts:

pacman -S ttf-bitstream-vera ttf-inconsolata ttf-ubuntu-font-family ttf-dejavu ttf-freefont ttf-linux-libertine ttf-liberation

Disable bitmap fonts used as fallback:

ln -s /etc/fonts/conf.avail/70-no-bitmaps.conf /etc/fonts/conf.d

Install Infinality to improve font rendering:

vi /etc/pacman.conf

Server = http://bohoomil.com/repo/$arch

Server = http://bohoomil.com/repo/multilib/$arch

Server = http://bohoomil.com/repo/fonts

pacman-key -r 962DDE58
pacman-key --lsign-key 962DDE58

pacman -Syy infinality-bundle infinality-bundle-multilib


At this point, the basic install of the OS is complete. The steps below involve installation of additional recommended packages from AUR, but they are completely optional.

[Optional AUR Packages]

Install Numix Circle Icons and Adapta Theme:

yaourt numix-circle-icon-theme-git
yaourt adapta-gtk-theme

Install Google Chrome, Dropbox, and Sublime Text 3:

yaourt google-chrome
yaourt dropbox
yaourt nautilus-dropbox
yaourt sublime-text-dev

To update all packages, including AUR:

yaourt -Syua

To update all packages, excluding AUR:

pacman –Syu

October 3, 2016

GNS3 Launcher

Installing GNS3 on Ubuntu-based distros is easy:

sudo add-apt-repository ppa:gns3/ppa
sudo apt update
sudo apt install gns3-gui

After installation you can easily launch GNS3 from the Terminal, but if you were expecting a nice icon you could add to a dock or other location, you'll notice there isn't one.

To create a launcher for GNS3:

sudo vi /usr/share/applications/gns3.desktop

Insert the following lines:

[Desktop Entry]
Comment=Network Simulation Software

I use Numix Circle Icons on my system, so in place of the standard GNS3 icon specified above within the "Icon=" line, I use the following:


When done, ensure that user/group is root:root and that the permissions are 644, and that's it. GNS3 should now show up when you search your applications. If you want to add the launcher to your desktop, simply copy gns3.desktop to ~/Desktop.

October 2, 2016

Correct HDMI Audio Issues with PulseAudio

I recently encountered an issue that caused my default audio output to revert to S/PDIF instead of HDMI audio every time I would wake or reboot the system. After a bit of research, I determined that it was likely that PulseAudio, the sound system used by Ubuntu and many other Linux distros, was attempting to reconnect the last used output, HDMI in my case, prior to the video card bringing up the HDMI interfaces. As such, PulseAudio would revert to a fallback audio output, which in my case was S/PDIF. This meant that each time I resumed from suspend or rebooted the system, I had to manually change the audio output back to HDMI.

To solve the issue, edit /etc/pulse/default.pa and make the following changes:

Find this line:
load-module module-stream-restore

Modify the line as follows:
load-module module-stream-restore restore_device=false

Comment out or remove this line:
#load-module module-switch-on-port-available

Select the desired audio output device within Settings and reboot. The output device should no longer change.

October 1, 2016

Move GNOME Login Window to Primary Display

If you have two or more monitors (or a laptop with an external display) and are using GNOME 3 as your desktop environment, you may encounter an issue where the GNOME Display Manager (GDM) does not place the login window on the correct monitor.

To correct this problem, first make sure your display settings are correct once you've logged in. Then, copy ~/.config/monitors.xml to /var/lib/gdm3/.config and reboot:

cp ~/.config/monitors.xml /var/lib/gdm3/.config 

The file you've just copied contains your customized display settings. Placing a copy of the file in this location instructs GDM to use the same settings and should correct this problem.

Correct Printing Issues in Ubuntu or Linux Mint

Within most Debian operating systems, including Ubuntu and Linux Mint, you may have noticed that the operating system automatically discovers and adds printers. I have an HP LaserJet P1102w, and while it seems convenient that the printer is automatically installed for me, it simply doesn't work out of the box. If you attempt to delete the printer, it will automatically reappear.

To correct this problem, edit /etc/cups/cups-browsed.conf as shown below.

At the top of the file, add:
BrowseRemoteProtocols none

Reboot, and you'll notice that the printer is not present. Now, add a new printer and the operating system will automatically use HP's Linux Imaging and Printing software (HPLIP), and within seconds you'll be up and running.

Resolve ".local" Domains

The default configuration within /etc/nsswitch.conf tells the resolver to use mDNS (Multicast DNS) to resolve .local domains. If you have a home lab, run a DNS server, and use .local domains as I do, this can present a problem.

To correct this problem, edit /etc/nsswitch.conf as shown below.

hosts:        files mdns4_minimal [NOTFOUND=return] dns myhostname

hosts:        files dns mdns4_minimal [NOTFOUND=return] myhostname

Restart the network stack or reboot for the changes to take effect.

June 1, 2016

Apache SSL/TLS Strong Encryption

If you’ve been keeping up with the numerous changes from Google and the Mozilla Foundation regarding SSL/TLS support, vulnerabilities such as Logjam, BEAST, FREAK, and POODLE, the deprecation of SSL 3.0, RC4, and SHA-1, and Firefox 37’s deprecation of TLS 1.0, you may be wondering what cipher suites you should support in Apache to ensure strong encryption. From the Guide to Deploying Diffie-Hellman for TLS, the following configuration will likely provide you with an A rating using Qualys SSL Server Test:

SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
Remember, you should use an all-SHA-2 certificate chain (the intermediate and the issued certificate should not be signed with SHA-1) when you renew your certs.

Recommended Reading:
SSL/TLS Deployment Best Practices, Ivan Ristic, Qualys SSL Labs

Custom Crons

Suppose you needed to run a cron job that ran only on the first x-day of the month. It’s easy to create a cron that runs every x-day, but how would you specify the first? The solution is pretty nifty. Simply create a cron that would run a job every x-day, but then have that cron execute a script that evaluates whether it is indeed the first occurrence of that day in a given month. If yes, it will execute your script. If no, it will do nothing.

Example for running a cron the first Wednesday of every month at midnight:
0 0 * * 3 [ “$(date ‘+\%d’)” -le 7 ] && /usr/local/bin/myscript.sh > /dev/null

The cron will indeed run every Wednesday, but the conditional statement will only execute myscript.sh if the current day of the month is less than or equal to seven. Perfect!