How to compile the ngx_pagespeed (Nginx Pagespeed) module for ARM architecture on the Raspberry Pi 4, or any other aarch64 devices, running Ubuntu Server 20.04

If you are using a Raspberry Pi as a LEMP (Linux, Nginx, MariaDB, PHP) server to host your website, you may want to consider speeding up your site on the server level by using the pagespeed module for Nginx. In this tutorial, we are going to learn how to compile (build) and install google’s ngx_pagespeed module for the Nginx Mainline Version 1.21.6, on a Raspberry Pi 3, Raspberry Pi 4, or any 64 bit ARM (aarch64) Device.

Natively, the ngx_pagespeed module does not support ARM device, nor do they have ARM support in their development roadmap. This poses a problem for users running a web server on aarch64 devices such as the Raspberry Pi 3 and above. This is mostly due to the fact that the PSOL binaries required to compile the pagespeed module are not 64-bit ARM or armv7l compatable. Fortunately, a developer by the name of Mogwai (@gusco) on gitlab, has solved this issue by patching the PSOL Binaries to make them compatible with aarch64/armv7l operating systems and their respective devices. This in turn, makes compiling the Nginx pagespeed module now possible for ARM devices.

As a reference note, This tutorial was created by merging/modifying three different tutorials and sets of instructions into one clean ARM versioned tutorial. You can find the original sources/tutorials/content on Linuxbabe’s page, on the Mogwai Gitlab page and on the official google pagespeed documentation page. Keep in mind, this has only been tested by me on Ubuntu Server (64-bit) 20.04 for the Raspberry Pi 4. However, it should also work on any 64 bit ARM device running Ubuntu 20.04, or any 64-bit version of Rasperry Pi OS. So, without further ado, lets begin:

Before you begin: You should do this on a machine (or seperate SD card) that IS NOT your real production web server or LEMP server! This will prevent code litter scattered throughout your server. Just be sure to use the same OS, Same Architecture, and Same Nginx version.

Step 1) Install the Nginx Mainline repository and corresponding signing keys

sudo nano /etc/apt/apt/sources.list.d/Nginx.list

Then copy and paste the following text into the file.

# Nginx Official Repositories for Ubuntu 20.04 Focal

# Official Nginx Stable Repository for Ubuntu 20.04 Raspi
# Stable Nginx and Nginx source repositories
#deb [arch=arm64] https://nginx.org/packages/ubuntu focal nginx
#deb-src [arch=arm64] https://nginx.org/packages/ubuntu focal nginx

# Official Nginx Mainline Repository for Ubuntu 20.04 Raspi
deb [arch=arm64] https://nginx.org/packages/mainline/ubuntu focal nginx
deb-src [arch=arm64] https://nginx.org/packages/mainline/ubuntu focal nginx

Then update or add the Official Nginx Signing Key to your GPG Keyring.

cd ~/ && curl -O https://nginx.org/keys/nginx_signing.key && sudo apt-key add ./nginx_signing.key

Then type:

apt-key list

and you should see the following text appear.

pub   rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
      573B FD6B 3D8F BC64 1079  A6AB ABF5 BD82 7BD9 BF62
uid           [ unknown] nginx signing key <signing-key@nginx.com>

/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-archive.gpg

Be sure the fingerprints (573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62) match. Then proceed to update, upgrade, and finally install nginx.

sudo apt update && sudo apt upgrade && sudo apt install nginx

Once installed you can check and be sure your version of nginx is 1.21.6 with nginx -v. Then proceed to the next step, which is taken almost directly from linuxbabe.com.

STEP 2) Download nginx source package

Modify this line by changing “yourusername” to your real Ubuntu login user name. Then copy the rest of the line and paste it in your linux terminal.

sudo chown yourusername:yourusername -R /usr/local/src/ && sudod mkdir -p /usr/local/src/nginx && cd /usr/local/src/nginx/ && sudo apt install dpkg-dev && sudo apt source nginx && ls

The final “ls” command should show the following output:

nginx-1.21.6
nginx_1.21.6-1~focal.debian.tar.xz
nginx_1.21.6-1~focal.dsc
nginx_1.21.6.orig.tar.gz

STEP 3) Download the Pagespeed source package

Here is where we do something different for ARM devices. The PSOL (pagespeed optimization Libraries) provided by google are not compatable with ARM devices. Therefore, we are going to use a patched version of the PSOL. Paste this entire one liner to clone the pagespeed module from github, convert it to the stable branch, and then download and extract the aarch64 patched version of the PSOL into the proper directory.

cd /usr/local/src && git clone https://github.com/apache/incubator-pagespeed-ngx.git && cd incubator-pagespeed-ngx/ && git checkout latest-stable && wget https://gitlab.com/gusco/ngx_pagespeed_arm/-/raw/master/psol-1.15.0.0-aarch64.tar.gz && tar xvf psol-1.15.0.0-aarch64.tar.gz && sed -i 's/x86_64/aarch64/' config && sed -i 's/x64/aarch64/' config && sed -i 's/-luuid/-l:libuuid.so.1/' config

STEP 4) Configure the Pagespeed module.

CD into the Nginx directory and install the build dependancies.

cd /usr/local/src/nginx/nginx-1.21.6 && sudo apt build-dep nginx && sudo apt install uuid-dev

Finally, we need to configure the environment with the exact same arguments that are already in your currently installed Nginx. To do that, you have to first check your nginx arguments with the following command:

nginx -V

Should return:

configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.21.6/debian/debuild-base/nginx-1.21.6=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

If the “--with-compat” and “--with-cc-opt='-DNGX_HTTP_HEADERS'” arguments are not in there, then you must be sure to them to the next command or your module won’t be compatable with your Nginx. If “--with-compat” is in the above set of arguments, then just continue to copy and paste the above arguments in the next command along with “--with-cc-opt='-DNGX_HTTP_HEADERS'“. Either way, the arguments”--with-compat” and “--with-cc-opt='-DNGX_HTTP_HEADERS'” MUST be in the next command. Lastly, since we are compiling pagespeed as a dynamic argument, we must also include “--add-dynamic-module=/usr/local/src/incubator-pagespeed-ngx” argument. To summarize, the new arguments look like this:

--add-dynamic-module=/usr/local/src/incubator-pagespeed-ngx --with-compat --with-cc-opt='-DNGX_HTTP_HEADERS'

RUNNING MY FINAL ./CONFIGURE COMMAND LOOKS LIKE THIS (adjust according your output of the nginx -V command):

./configure --add-dynamic-module=/usr/local/src/incubator-pagespeed-ngx --with-compat --with-cc-opt='-DNGX_HTTP_HEADERS'

So in my case, since I am compiling for the latest Mainline version of Nginx v1.21.6, my entire configure command, including arguments (with the NEW Additional Arguments first) would be as follows:

./configure --add-dynamic-module=/usr/local/src/incubator-pagespeed-ngx --with-cc-opt='-DNGX_HTTP_HEADERS' --with-compat --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.21.6/debian/debuild-base/nginx-1.21.6=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

So to complete this step, just copy and paste:

./configure --add-dynamic-module=/usr/local/src/incubator-pagespeed-ngx --with-cc-opt='-DNGX_HTTP_HEADERS' --with-compat

before the rest of the output of nginx -V and then hit enter to start configuring! Don’t forget to check for an already existing --with-compat argument before you paste the above line.

STEP 5) Make the Pagecache module!

cd /usr/local/src/nginx/nginx-1.21.6/ && make modules

Then copy your newly created module to the Nginx modules directory.

cd objs && sudo cp ngx_pagespeed.so /etc/nginx/modules/

STEP 6) Load the module

sudo nano /etc/nginx/nginx.conf

Then add the following line to the beginning of the file:

load_module modules/ngx_pagespeed.so;

Underneath the lines…

user www-data;
worker_processes auto;
pid /run/nginx.pid;
load_module modules/ngx_pagespeed.so;

Now it’s your job to set up and configure the Nginx Filter settings. You can find the list of filters here.

Congrats, you can STOP because you are all done! Now you have a working pagespeed module for your 64 bit ARM Raspberry Pi 4!

References:

https://gitlab.com/gusco/ngx_pagespeed_arm

https://www.modpagespeed.com/doc/build_ngx_pagespeed_from_source

https://github.com/apache/incubator-pagespeed-ngx

How to install OpenVPN 3 client on Ubuntu 20.04

Today we are going to learn how to install openvpn3 client on Ubuntu 20.04 using the command line. For those who don’t know, the client is what connects to your openvpn service provider and tunnels its connection out to your openvpn service provider.

In this tutorial we will take the following steps to complete this task:

  1. Add openvpn3 repository to your apt sources.list to get automatic updates.
  2. Install the OpenVPN3 repository signing key
  3. Install OpenVPN3
  4. Download and modify your my-openvpn-client-config-file.ovpn to work with openvpn3
  5. Create a simple yet secure and useful my-openvpn3-client-config-file.autoload file to automatically load openvpn3 at boot time and start up.
  6. Create a simple yet secure and useful my-openvpn3-client-config.file.autoload file to automatically reconnect openvpn after it unexpectedly disconnects.
  7. Enable openvpn3 permanantely to connect on boot and after any unexpected disconnects.

Lets begin.

1st,

Open open up your terminal and run the following command to add openvpn3 to your apt repository…

sudo nano /etc/apt/sources.list.d/openvpn3.list

Your nano text editor will open up and your terminal should be blank. Then you must copy and paste the following lines into your nano editor:

# OpenVPN3 Official Apt Repository for openvpn3.
deb https://swupdate.openvpn.net/community/openvpn3/repos focal main

Once you have pasted the text into your nano text editor (using the terminal), you can save and exit by typing “Control-X“, then hit “y” for the save option, then hit “Enter” to save and exit nano.

2nd,

Ensure your apt supports the https transport by installing apt-transport-https. Then install the OpenVPN3 repository signing key used by the openVPN 3 Linux packages. You can do all of this by running the following commands:

cd ~/
sudo apt install apt-transport-https && wget https://swupdate.openvpn.net/repos/openvpn-repo-pkg-key.pub && sudo apt-key add openvpn-repo-pkg-key.pub
rm ~/openvpn-repo-pkg-key.pub

Now, you can install your openvpn3 package with the following command:

sudo apt update && sudo apt install openvpn3

Now, navigate to /etc/openvpn3/autoload.

cd /etc/openvpn3/autoload/

Download your openvpn.ovpn configuration file from your vpn service provider and open it with a text editor. Then add the following to its configuration with each option on its own seperate line:

auth-user-pass
push-peer-info
resolv-retry infinite
persist-key
persist-tun
keepalive 10 120

Now, copy all of the text in your openvpn.ovpn file that you downloaded and edited, and paste it into a new file called “myvpn3client.conf” located in the /etc/openvpn3/autoload directory, using nano.

sudo nano /etc/openvpn3/autoload/myvpn3client.conf

Type ctrl+x, y, then Enter, to save your file.

Now, create your autoload file by openining up your nano editor with the following command:

cd /etc/openvpn3/autoload && sudo nano myvpn3client.autoload

Copy and paste the following text into the currently opened “myvpn3client.autoload” file with your nano editor.

{
   "autostart": true,
    "name": "myvpnclient",
    "acl": {
        "set-owner": "my_ubuntu_username"
    },
    "tunnel": {
        "ipv6": "no",
        "persist": true,
        "dns-fallback": "google",
        "dns-setup-disabled": false
    },
    "user-auth": {
        "username": "my_vpn_username",
        "password": "my_vpn_password"
    }
}

Fill in “my_ubuntu_username” “my_vpn_username” and “my_vpn_password” with your corresponding information. DO NOT DELETE THE QUOTES! Leave them. Your username should be the name that you registered when you set up your ubuntu installation. It should also be noted in your terminal on the left next to your computer’s hostname i.e. mrubuntu@mrubuntusdesktop.

Once you have finished filling in the blanks inside the quotes, press “control-X“, then “y” to save, and hit “Enter” to exit out of nano with a newly saved .autoload file.

Now, lets secure the permissions for your myopenvpn.conf and myopenvpn.autoload files.

sudo chmod 644 /etc/openvpn3/autoload/myvpn3client.conf && sudo chmod 644 /etc/openvpn3/autoload/myvpn3client.autoload

Now we’re ready to start your VPN. The following command will automatically connect your VPN on boot, as well as reconnect it if your internet connection drops, and restarts again. In other words, this will keep you connected to your vpn after reboot or connection failure.

Run this last command to do so:

sudo systemctl enable openvpn3-autoload.service

Now reboot and check to see if your vpn is connected by running the following command:

curl https://ipinfo.io/ip

It should show the IP Address of your vpn provider.

Next,

lets test to see if your DNS is leaking or not.

Download the dns command line dns leak test from github, and make it executable by your user by running the following command:

cd ~/ && curl https://raw.githubusercontent.com/macvk/dnsleaktest/master/dnsleaktest.sh -o dnsleaktest.sh && chmod +x dnsleaktest.sh

Run your dnsleaktest!

./dnsleaktest.sh

After a minute or so, it should show the IP addresses of your VPN provider. If it does not, then your dns may be leaking, and the leaktest will tell you that.

THE END