Updating Or Upgrading When /boot Is 100% Full

I recently ran into an issue on a test server with a particularly small /boot partition. I attempted to run the typical sudo apt update && sudo apt upgrade and it failed. This was part of the error:

Preparing to unpack .../linux-image-4.4.0-112-generic_4.4.0-112.135_amd64.deb ...
Done.
Unpacking linux-image-4.4.0-112-generic (4.4.0-112.135) ...
dpkg: error processing archive /var/cache/apt/archives/linux-image-4.4.0-112-generic_4.4.0-112.135_amd64.deb (--unp ack):
 cannot copy extracted data for './boot/vmlinuz-4.4.0-112-generic' to '/boot/vmlinuz-4.4.0-112-generic.dpkg-new': failed to write (No space left on device)
No apport report written because the error message indicates a disk full error

I tried running sudo apt autoremove as suggested to clear out the old Linux files. This ran into an error which looked like so:

cole@ubuntu-docker:~$ sudo apt autoremove
Reading package lists... Done
Building dependency tree
Reading state information... Done
You might want to run 'apt-get -f install' to correct these.
The following packages have unmet dependencies:
 libstdc++-5-dev : Depends: libstdc++6 (>= 5.4.0-6ubuntu1~16.04.6) but 5.4.0-6ubuntu1~16.04.5 is installed
 libstdc++6 : Depends: gcc-5-base (= 5.4.0-6ubuntu1~16.04.5) but 5.4.0-6ubuntu1~16.04.6 is installed
 linux-image-extra-4.4.0-112-generic : Depends: linux-image-4.4.0-112-generic but it is not installed
 linux-image-generic : Depends: linux-image-4.4.0-112-generic but it is not installed
 Recommends: thermald but it is not installed
E: Unmet dependencies. Try using -f.

Running sudo apt -f install as suggested left me with:

cole@ubuntu-docker:~$ sudo apt -f install
Reading package lists... Done
Building dependency tree
Reading state information... Done
Correcting dependencies... Done
The following packages were automatically installed and are no longer required:
 libzip4 linux-headers-4.4.0-101 linux-headers-4.4.0-101-generic linux-headers-4.4.0-87
 linux-headers-4.4.0-87-generic linux-headers-4.4.0-91 linux-headers-4.4.0-91-generic linux-headers-4.4.0-92
 linux-headers-4.4.0-92-generic linux-headers-4.4.0-93 linux-headers-4.4.0-93-generic linux-headers-4.4.0-96
 linux-headers-4.4.0-96-generic linux-headers-4.4.0-97 linux-headers-4.4.0-97-generic linux-headers-4.4.0-98
 linux-headers-4.4.0-98-generic linux-image-4.4.0-101-generic linux-image-4.4.0-87-generic
 linux-image-4.4.0-91-generic linux-image-4.4.0-92-generic linux-image-4.4.0-93-generic
 linux-image-4.4.0-96-generic linux-image-4.4.0-97-generic linux-image-4.4.0-98-generic
 linux-image-extra-4.4.0-101-generic linux-image-extra-4.4.0-87-generic linux-image-extra-4.4.0-91-generic
 linux-image-extra-4.4.0-92-generic linux-image-extra-4.4.0-93-generic linux-image-extra-4.4.0-96-generic
 linux-image-extra-4.4.0-97-generic linux-image-extra-4.4.0-98-generic
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
 libstdc++6 linux-image-4.4.0-112-generic
Suggested packages:
 fdutils linux-doc-4.4.0 | linux-source-4.4.0 linux-tools
The following NEW packages will be installed:
 linux-image-4.4.0-112-generic
The following packages will be upgraded:
 libstdc++6
1 upgraded, 1 newly installed, 0 to remove and 61 not upgraded.
33 not fully installed or removed.
Need to get 0 B/22.3 MB of archives.
After this operation, 66.9 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Setting up gcc-5-base:amd64 (5.4.0-6ubuntu1~16.04.6) ...
(Reading database ... 444689 files and directories currently installed.)
Preparing to unpack .../libstdc++6_5.4.0-6ubuntu1~16.04.6_amd64.deb ...
Unpacking libstdc++6:amd64 (5.4.0-6ubuntu1~16.04.6) over (5.4.0-6ubuntu1~16.04.5) ...
Processing triggers for libc-bin (2.23-0ubuntu10) ...
Setting up libstdc++6:amd64 (5.4.0-6ubuntu1~16.04.6) ...
Processing triggers for libc-bin (2.23-0ubuntu10) ...
(Reading database ... 444689 files and directories currently installed.)
Preparing to unpack .../linux-image-4.4.0-112-generic_4.4.0-112.135_amd64.deb ...
Done.
Unpacking linux-image-4.4.0-112-generic (4.4.0-112.135) ...
dpkg: error processing archive /var/cache/apt/archives/linux-image-4.4.0-112-generic_4.4.0-112.135_amd64.deb (--unp ack):
 cannot copy extracted data for './boot/vmlinuz-4.4.0-112-generic' to '/boot/vmlinuz-4.4.0-112-generic.dpkg-new': f ailed to write (No space left on device)
No apport report written because the error message indicates a disk full error
 dpkg-deb: error: subprocess paste was killed by signal (Broken pipe)
Examining /etc/kernel/postrm.d .
run-parts: executing /etc/kernel/postrm.d/initramfs-tools 4.4.0-112-generic /boot/vmlinuz-4.4.0-112-generic
run-parts: executing /etc/kernel/postrm.d/zz-update-grub 4.4.0-112-generic /boot/vmlinuz-4.4.0-112-generic
Errors were encountered while processing:
 /var/cache/apt/archives/linux-image-4.4.0-112-generic_4.4.0-112.135_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

I’ve clearly run into a loop that I’ll not be able to solve without removing some files from the /boot partition. I ran a simple ls -la to find the versions, and removed the oldest files. I ran the following scripts:

sudo rm *4.4.0-91-generic
sudo rm *4.4.0-92-generic
...

until I only had the most recent 6 versions. I checked df to see where I was at with disk space, and lo-and-behold I had it down to ~50%. Finally I ran the commands that were originally suggested:

sudo apt -f install
sudo apt autoremove
sudo apt update && sudo apt upgrade

Now my installation is all up to date and ready to rock and roll!

The moral of the story is: make sure to keep your Ubuntu installations up to date! Automating this process is ideal!

🙂 Cole

Install Redis Server on Ubuntu 16.04

Why would I use redis?

Redis is wonderful for many reasons. I primarily use it for caching web applications like Magento 2 and WordPress. Some other great ways to use it are as a database or a message broker. You should check it out here.

How do I install it?

The official suggestion is to build the package, but I’d much rather install applications from an official package repository (PPA). This simplifies the install, upgrade, and uninstall methods greatly.

First, you’ll need to add the PPA repository to your OS.

sudo add-apt-repository ppa:chris-lea/redis-server

Next, you’ll want to update your repositories.

sudo apt update

After that, run the installation script.

sudo apt install redis-server

Check that everything installed correctly by checking the version, starting the server, and checking the status of your newly installed server.

redis-server --version
sudo service redis-server start
sudo service redis-server status

You can run a few commands to test out your new server by jumping into the redis-cli application that was installed with your server. If not, just install redis-cli and boot it up.

$ redis-cli
127.0.0.1:6379> ping
PONG

When you get that PONG back, it’s quite satisfying. Let’s test saving and retrieving some values.

127.0.0.1:6379> set bears-eat "beets"
OK
127.0.0.1:6379> get bears-eat
"beets"

Final Notes on Web Aplications

Magento 2

You can configure Redis with Magento 2 quite easily for some really great performance benefits. There are a lot of reasons to use Redis over a few other technologies for many reasons, which are outlined quite nicely over in the Magento DevDocs.

WordPress

WordPress can easily cache with Redis with the installation of a single plugin. I love that it’s a single click away from being enabled or disabled. It’s stupid simple installation abstracts all the heavy lifting Redis does and hides the awesome power in the back-end. You’ll really love the performance boost though, and so will your visitors!

 

Installing Send Only Postfix To Ubuntu 16.04 LTS (Replace Sendmail)

Introduction

There is nothing more upsetting than email. It’s an old technology, and no one should use it. You know it, I know it, everyone knows it.

It’s just too bad the entire world practically revolves around email. So I’m going to help you with an issue I ran into recently. Hopefully this saves some hair-pulling.

Today, I’ll be explaining how to install the Sendmail like application Postfix in conjunction with Mailutils to allow you to send email from your web application. This particular guide will also solve the issue of your web application server not sending to an external mail server on the same domain.

The example I’ll be using will relate to an Amazon Web Service Elastic Cloud Compute (AWS EC2) instance sending mail to GSuite. I know that there are other (likely better) ways of sending mail like AWS SES (Simple Email Service), GSuite SMTP-Relay, Mailgun, or Mandrill. However, we’re going to go purist on this first try and have the Application Server do the entire job.

Server Setup and Installing Mailutils & Postfix

I’ll be removing Sendmail as Postfix will be replacing it. You can run sudo apt purge sendmail if you would like to remove sendmail with it’s configuration. If you only want to remove sendmail but keep its configuration run: sudo apt remove sendmail.

Next, you’ll want to specify the server hostname and change your hosts file if you haven’t yet.

sudo vim /etc/hostname

Remove the current hostname and replace with your domain. (eg. yourdomain.com)

sudo vim /etc/hosts

Change the first line in your host file to reflect the following:

127.0.0.1 yourdomain.com localhost

Once that is complete, give your instance a restart to have it reflect the changes.

Next we’ll need to make sure we have all the utilities and packages we’ll be using installed. I’m told that installing Mailutils will also install Postfix and prompt the setup steps, but in my case, it did not.

sudo apt install mailutils
sudo apt install postfix

Either mailutils will prompt you to set up postfix (a pink background fullscreen prompt) or installing postfix itself will.

You’ll want to specify the the configuration type as Internet Site. You’ll then want to set the System mail name: to yourdomain.com.

The next step will be editing your Postfix main configuration file.

sudo vim /etc/postfix/main.cf

You’ll want to change these lines:

....
mydestination = $myhostname, yourdomain.com, localhost.yourdomain.internal, localhost
....
inet_interfaces = all
....

To…

....
mydestination = 
....
inet_interfaces = loopback-only
....

Once you’re done, save your file and restart Postfix.

sudo service postfix restart

Make sure your postfix is running without errors using sudo systemctl status postfix. If you run into any errors, give your server a reboot. This is an important note. I was running into issues with port 25 having already been bound.

You can now send a test email by running:

echo "This is some email body text" | mail -s "This is a test email subject" your@email.com

Make sure to test it on your own domain, and you should be good to go!

Notes About Spam

You’ll want to make sure of a few things when sending email from multiple sources. One of the most important, and easiest spam-securing technologies available is the humble SPF record.

By adding a TXT record to your Domain Records, you can specify which servers are allowed to send mail, and what to do when something is not validated.

A simple example of this would be:

v=spf1 a mx include:_spf.example.com ip4:999.88.777.66 -all

This SPF record effectively validates A records, MX records, includes, and IP addresses to be able to send mail as an authorized domain sender. If your web application sits at your A record, you’re done. If not, add it with an ip4: tag and call it a day!

Hope you enjoyed!

Ubuntu 16.04: Changing PHP Versions

I was making some changes to a web server recently that I figured I would make a super short blog tutorial about!

Changing From PHP 5.6-7.0

The same instructions will work for pretty much any version of PHP you would like to install or change from. Just change the version of PHP in the commands and you’re good to go.

Firstly, you’ll need to add the public PHP repository. Then you’ll need to update your packages. Then you need to install PHP. I’ve included both versions in case you’re switching one way or the other. It won’t matter if you have both installed, we’ll only be referencing one by the end.

sudo apt-get-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php7.0 php5.6 php5.6-mysql php7.0-mysql php-gettext php5.6-mbstring php-mbstring php7.0-mbstring php-xdebug libapache2-mod-php5.6 libapache2-mod-php7.0

Once everything has run its course, you can start disabling and enabling which module is being used in Apache2.

sudo a2dismod php5.6; sudo a2enmod php7.0; sudo service apache2 restart

As we all know, there are two versions of PHP that run: Apache2 and CLI. To change the CLI version fo PHP, you’ll have to run the following command.

sudo update-alternatives --set php /usr/bin/php7.0

This means when you run php -v you’ll see PHP 7.0 as your PHP CLI version.

That’s it! Super simple stuff!

Let’s Encrypt The Internet! Installing Free TLS Certificates On Ubuntu 16.04

Why should we install security certificates?

I’m a big proponent of protecting data and encrypting communication on the internet regardless of the source or destination. There are just some things that shouldn’t be shared, and it’s the same reason why all envelopes aren’t made entirely of transparent plastic (recycling aside).

This doesn’t just protect your “data” but the transfer of secure information like your credit card numbers and passwords. You should always be cognoscente of the sites you’re sending your data to, and whether you would be okay sharing that information with a perfect stranger.

Note: most people still like to refer to these certificates as SSL certificates. This is referring to an old and obsolete protocol that used to be used for encryption. The new version, and widely accepted standard today is the TLS encryption protocol. At the time of writing this blog, I’ve successfully installed a TLS 1.2 certificate using Certbot with a strong key exchange (ECDHE_RS with P-256), and a strong cipher (AES_128_GCM) according to the security audit in Google Chrome. (Ctrl+Shift+I > Security tab).

Things you’ll need before moving forward.

I’m going to make the assumption that you’ve taken the time to set up your Ubuntu server and install Apache on it. Specifically that you’ve properly configured your (one or more) domains in separate Virtual host files that specify the ServerName.

Let’s get encrypting!

Firstly, you’ll want to add the Certbot repository to your list of software repositories. To do this, run the following command.

sudo add-apt-repository ppa:certbot/certbot

Once that’s finished running its course, you’ll want to pull the latest version of all of your software repositories.

sudo apt-get update

Finally, you can install the Certbot client using the following command.

sudo apt-get install python-certbot-apache

Ubuntu will then take a few moments to install the required software and the client on your system. You’re finally ready to install your TLS certificate on your server.

TLS how to install it! (hah, encryption pun)

This step is actually exceedingly easy. I was very pleased at how simple it was to install, and I think you’ll really enjoy it too.

To run the Certbot installation script and install your certificate into your Virtual Host in one shot, run the following command.

sudo certbot --apache -d yourdomain.com

You can add more domains to this single certificate by specifying multiple domains. Just flag on another -d www.yourdomain.com and you’re flying!

The installation script will walk you through a few questions regarding an administrative email address, accepting their terms of service, and whether or not all traffic will be going through HTTPS or not. It’ll look something like this:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel):support@[redacted]

-------------------------------------------------------------------
Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree in order to register with the ACME server at https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------
(A)gree/(C)ancel: a

-------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about EFF and our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------
(Y)es/(N)o: y
Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for [redacted]
Enabled Apache socache_shmcb module
Enabled Apache ssl module
Waiting for verification...
Cleaning up challenges
Created an SSL vhost at /etc/apache2/sites-available/000-default-le-ssl.conf
Enabled Apache socache_shmcb module
Enabled Apache ssl module
Deploying Certificate for [redacted] to VirtualHost /etc/apache2/sites-available/000-default-le-ssl.conf
Enabling available site: /etc/apache2/sites-available/000-default-le-ssl.conf

Please choose whether HTTPS access is required or optional.
-------------------------------------------------------------------
1: Easy - Allow both HTTP and HTTPS access to these sites
2: Secure - Make all requests redirect to secure HTTPS access
-------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1

-------------------------------------------------------------------
Congratulations! You have successfully enabled https://[redacted]

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=[redacted]
-------------------------------------------------------------------

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/[redacted]/fullchain.pem. Your cert will
   expire on [redacted]. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again with the
   "certonly" option. To non-interactively renew *all*