HOWTO Ubuntu 20.04 Virtual Web Hosting With Apache, PHP, vsFTPD and Let’s Encrypt

Introduction

The focus of this howto is for those users who need to host their own domains and maybe a few customer domains. This is not aimed at being used for mass web hosting.

There are many ways to do virtual websites under linux. The technique I am going to use is multiple domains on one ip address. I’m using standard linux users to log into the virtual domains.

Setting Up The Base Server

For a dedicated server start with the base server setup:

HOWTO Ubuntu 20.04 LTS Base Server Setup

Introduction All of our servers will start with this install. This base server is based on Ubuntu 20.04 LTS Server.  I don’t explain much in the howto so if you have a question leave a comment or use Google. Downloading … Continue reading

NOTE: If you don’t follow the base server setup then you may run into problems with this howto.

Install Software

We need to install an FTP server and Let’s Encrypt. So type the following:
> sudo add-apt-repository ppa:certbot/certbot
> sudo apt update
> sudo apt install vsftpd python3-certbot-apache

Setup Default User Directory

A new user’s directory needs to have some files and folders created for them.  We will modify the user skel directory so when a new user is created the required folder structure will be there.

Type the following.
> sudo mkdir -p /etc/skel/{website,logs,cgi-bin,backup}
> sudo echo “HELLO WORLD” > index.html
> sudo mv index.html /etc/skel/website/

Configuring vsftpd

Lets create the configuration file.  Replace the contents of /etc/vsftpd.conf with the text below.

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
#local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
allow_writeable_chroot=YES
pasv_enable=Yes
pasv_min_port=40000
pasv_max_port=40100

Start vsftpd.
> sudo systemctl enable vsftpd
> sudo systemctl start vsftpd.service

Configuring Apache

Most of the apache configuration is already done.  We are going to do some changes to make managing websites easier.

Create the virtual host config file. I defined macros to make virtual host creation easier.  I also turn on compression. Create /etc/apache2/conf-available/virtual.conf with the following:

# Go ahead and accept connections for these vhosts
# from non-SNI clients
SSLStrictSNIVHostCheck off

# define a macro for the virtual hosts
# the user's directory should be setup as follows:
# |- cgi-bin
# |- logs
# |- website
# |- ssl
#
LoadModule macro_module modules/mod_macro.so

<Macro virtHost $type $user $host>
    use $type $host

    ServerName $host
    ServerAlias www.$host 
    DocumentRoot /home/$user/website
    ScriptAlias "/cgi-bin/" "/home/$user/cgi-bin"
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    CustomLog /home/$user/logs/access_log common
    ErrorLog /home/$user/logs/error_log
    <Directory /home/$user/website>
      DirectoryIndex index.html index.php
      Options Indexes FollowSymLinks
      AllowOverride All
      Require all granted

      # setup file compression
      use CompressFiles

      # setup browser caching
      use BrowserCache

      # disable hotlinking for some files
      use DisableHotLink $host
    </Directory>
  </VirtualHost>
</Macro>

<Macro BrowserCache>
  # Enable expires cache
  <IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css "access 1 month"
    ExpiresByType text/html "access 1 month"
    ExpiresByType image/gif "access 1 year"
    ExpiresByType image/png "access 1 year"
    ExpiresByType image/jpg "access 1 year"
    ExpiresByType image/jpeg "access 1 year"
    ExpiresByType image/x-icon "access 1 year"
    ExpiresByType application/pdf "access 1 month"
    ExpiresByType application/javascript "access 1 month"
    ExpiresByType text/x-javascript "access 1 month"
    ExpiresDefault "access 1 month"
  </IfModule>

  # Cache-Control Headers
  <ifModule mod_headers.c>
    <filesMatch "\.(ico|jpe?g|png|gif|swf)$">
      Header set Cache-Control "public"
    </filesMatch>
    <filesMatch "\.(css)$">
      Header set Cache-Control "public"
    </filesMatch>
    <filesMatch "\.(js)$">
      Header set Cache-Control "private"
    </filesMatch>
    <filesMatch "\.(x?html?|php)$">
      Header set Cache-Control "private, must-revalidate"
    </filesMatch>
  </ifModule>
</Macro>

<Macro CompressFiles>
  # enable compression
  <IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE "application/atom+xml"
    AddOutputFilterByType DEFLATE "application/javascript"
    AddOutputFilterByType DEFLATE "application/json"
    AddOutputFilterByType DEFLATE "application/ld+json"
    AddOutputFilterByType DEFLATE "application/manifest+json"
    AddOutputFilterByType DEFLATE "application/rdf+xml"
    AddOutputFilterByType DEFLATE "application/rss+xml"
    AddOutputFilterByType DEFLATE "application/schema+json"
    AddOutputFilterByType DEFLATE "application/vnd.geo+json"
    AddOutputFilterByType DEFLATE "application/vnd.ms-fontobject"
    AddOutputFilterByType DEFLATE "application/x-font"
    AddOutputFilterByType DEFLATE "application/x-font-opentype"
    AddOutputFilterByType DEFLATE "application/x-font-otf"
    AddOutputFilterByType DEFLATE "application/x-font-truetype"
    AddOutputFilterByType DEFLATE "application/x-font-ttf"
    AddOutputFilterByType DEFLATE "application/x-javascript"
    AddOutputFilterByType DEFLATE "application/x-web-app-manifest+json"
    AddOutputFilterByType DEFLATE "application/xhtml+xml"
    AddOutputFilterByType DEFLATE "application/xml"
    AddOutputFilterByType DEFLATE "font/eot"
    AddOutputFilterByType DEFLATE "font/otf"
    AddOutputFilterByType DEFLATE "font/ttf"
    AddOutputFilterByType DEFLATE "font/opentype"
    AddOutputFilterByType DEFLATE "image/bmp"
    AddOutputFilterByType DEFLATE "image/svg+xml"
    AddOutputFilterByType DEFLATE "image/vnd.microsoft.icon"
    AddOutputFilterByType DEFLATE "image/x-icon"
    AddOutputFilterByType DEFLATE "text/cache-manifest"
    AddOutputFilterByType DEFLATE "text/css"
    AddOutputFilterByType DEFLATE "text/html"
    AddOutputFilterByType DEFLATE "text/javascript"
    AddOutputFilterByType DEFLATE "text/plain"
    AddOutputFilterByType DEFLATE "text/vcard"
    AddOutputFilterByType DEFLATE "text/vnd.rim.location.xloc"
    AddOutputFilterByType DEFLATE "text/vtt"
    AddOutputFilterByType DEFLATE "text/x-component"
    AddOutputFilterByType DEFLATE "text/x-cross-domain-policy"
    AddOutputFilterByType DEFLATE "text/xml"
  </IfModule>
</Macro>

<Macro DisableHotLink $host >
  # Disable file hotlinking - jpg jpeg png gif pdf
  <IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?$host [NC]
    RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?google.com [NC]
    RewriteRule \.(jpg|jpeg|png|gif|pdf)$ – [NC,F,L]
  </IfModule>
</macro>

<Macro VHost443 $host >
  <VirtualHost *:443>
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
    SSLCertificateFile /etc/letsencrypt/live/$host/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/$host/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/$host/fullchain.pem
</Macro>

<Macro VHost80 $host >
  <VirtualHost *:80>
</Macro>

Enable the configuration.
> sudo a2enconf virtual

Enable macros and ssl.
> sudo a2enmod macro
> sudo a2enmod ssl

Restart apache
> sudo service apache2 restart

Configuring Let’s Encrypt

Let’s Encrypt needs to be configured to auto renew certs. Lets create a daily cron job
> sudo nano -w /etc/cron.daily/letsencrypt

#!/usr/bin/bash
# letsencrypt auto renew
/usr/bin/certbot renew --no-self-upgrade >> /var/log/le-renew.log

Adding a Default Website

Now we will create a default website.  This site will be used when no other website can be found.

Setup a DNS record for the new domain. I won’t cover this here.

Add a user. This user will be associated with the new domain name. Type the following.
> sudo useradd -m -U -s /bin/bash -c “default website” defaultweb
> sudo passwd defaultweb

Add the apache user to the new user’s group.
> sudo usermod -a -G defaultweb www-data

Update directory permissions.
> sudo chmod g+rwx /home/defaultweb
> sudo chown -R defaultweb:defaultweb /home/defaultweb

Create the virtual host file.  For the default server we will use port 80. Past the text below into the file.  Type:
> sudo nano -w /etc/apache2/sites-available/00-default.conf

# Virtual host config file
#
# MACRO FORMAT
# virtHost [type] [user] [host]
#  type = VHost80 or VHost443
#  user = the username of the website
#  host = domain name or virtual host name
#
# Use the line below to configure a site on port 80
use virtHost VHost80 defaultweb myserver.mydomain.tld

# Uncomment the line below once lets encrypt is setup
# use virtHost VHost443 defaultweb myserver.mydomain.tld

Disable the old default site and enable our default site.
> sudo a2dissite 000-default
> sudo a2ensite 00-default

Reload apache config
> sudo service apache2 reload

Test out the new website.  You should get a page that says ‘Hello World’.

Now we will setup lets encrypt for the default website.  The website must be reachable from the internet.  So lets get the cert:
> sudo certbot certonly –webroot -w /home/defaultweb/website/ -d <YOUR_DOMAIN> –email <YOUR_EMAIL_ADDRESS> –agree-tos

Edit /etc/httpd/virtualHosts.d/00-default.conf
Uncomment the last line to enable ssl connections for the virtual host.

Reload apache.
> sudo service apache2 reload

Test it out.  Connect to your default host via https.

Setup Additional Virtual Hosts

Adding a new virtual host is like adding the default virtual host.  Lets go through the steps.

Be sure DNS is configured for the new virtual host.

Setup a new user. This user will be associated with the new domain name. Type the following. Change ‘NEWUSER’ to the username you want.
> sudo useradd -m -U -s /bin/bash -c “Virtual Website User” NEWUSER
> sudo passwd NEWUSER
> sudo usermod -a -G NEWUSER www-data
> sudo chmod g+rwx /home/NEWUSER
> sudo chown -R NEWUSER:NEWUSER /home/NEWUSER

Create the virtual host file.  For the virtual server we will use port 80. Past the text below into the file.  Replace ‘NEWUSER’ with your user name.  Replace NEWVHOST with your hostname.
> sudo nano -w /etc/apache2/sites-available/NEWUSER.conf

# Virtual host config file
#
# MACRO FORMAT
# virtHost [type] [user] [host]
#  type = VHost80 or VHost443
#  user = the username of the website
#  host = domain name or virtual host name
#
# Use the line below to configure a site on port 80
use virtHost VHost80 NEWUSER NEWVHOST

# Uncomment the line below once lets encrypt is setup
# use virtHost VHost443 NEWUSER NEWVHOST

Enable the new site and reload apache config
> sudo a2ensite NEWUSER
> sudo service apache2 reload

Now we will setup lets encrypt for the new website.  The website must be reachable from the internet.  Replace NEWUSER and NEWVHOST with the info you have.  So lets get the cert.
> sudo certbot certonly –webroot -w /home/NEWUSER/website/ -d NEWHOST -d www.NEWHOST –email YOUR_EMAIL_ADDRESS –agree-tos

Edit /etc/httpd/virtualHosts.d/NEWUSER.conf
Uncomment the last line to enable ssl connections for the virtual host.

Reload apache.
> sudo service apache2 reload

Test it out.  Connect to your new host via https.

Conclusion

That’s the complete setup.

Ubuntu: Disable Floppy Drive

Introduction

I was creating a new virtual machine in my development environment and was getting a kernel error complaining about the floppy drive.  Well I use VMWare Fusion and I don’t configure the virtual machine to have a floppy.  This time I configured the VM to use UEFI.  Wouldn’t you know it, UEFI creates a floppy controller.  And guess what? You can’t disable it. Follow the steps below to take care of the problem.

Steps

    1. First we need to blacklist the floppy kernel module. So type the following
      sudo echo "blacklist floppy" > /etc/modprobe.d/blacklist-floppy.conf
    2. Next we need to update the initial ramdisk. Type the follosing:
      sudo update-initramfs -u
    3. Now update grub. Type:
      sudo update-grub
    4. Time to reboot the system. Type:
      sudo reboot

Conclusion

Just a few commands and your console won’t be plastered with floppy drive errors.

Opnsense Stuck at Booting on J1900 Motherboaard

Introduction

I have an Asrock motherboard with a J1900 CPU.  I was setting up a new Opnsense firewall.  Well FreeBSD hence Opnsense has a video bug.  The firewall boots and runs.  You just don’t get the console screen. Below is a quick guide on getting the video working.

Steps

  1. Power on the firewall.
  2. Hit the spacebar at the boot screen.
  3. Choose number 3 to set boot options.
  4. Type the following:
    set kern.vty=sc
  5. Then type:
    boot
  6. Once the firewall boots login as root.
  7. Select the option to exit to a shell.
  8. Type the following:
    echo 'kern.vty="sc"' > /boot/loader.conf.local
  9. Type:
    reboot

Conclusion

Sometimes those little bugs can be a pain.

HOWTO Ubuntu 20.04 Setup An APT Caching server

Introduction

When you are running a few Ubuntu servers you may want to think about setting up an APT caching server.  Installs and upgrades will go quicker.  You might save some bandwidth on your internet connection

Setting Up The Base Server (Optional

For a dedicated server start with the base server setup:

HOWTO Ubuntu 20.04 LTS Base Server Setup

Introduction All of our servers will start with this install. This base server is based on Ubuntu 20.04 LTS Server.  I don’t explain much in the howto so if you have a question leave a comment or use Google. Downloading … Continue reading

NOTE: You can choose an existing server to use.  I chose to have a dedicated server.

Install Software

Install apt-cacher-ng
> sudo apt install apt-cacher-ng

Configure and Test the server

Apt-cacher-ng has a web interface.  To test it visit http://<your-ip-address>:3142/acng-report.html

Create /etc/apt/apt.conf.d/00aptproxy with the following
> sudo nano -w /etc/apt/apt.conf.d/00aptproxy

Acquire::http::Proxy "http://<your-ip-address>:3142";

Do a software update to test it out.
> sudo apt update
> sudo apt dist-upgrade

Now reload the server web page.  It should now show that some items have been downloaded.

Configuring Clients

On each client create /etc/apt/apt.conf.d/00aptproxy with the following
> sudo nano -w /etc/apt/apt.conf.d/00aptproxy

Acquire::http::Proxy "http://<your-ip-address>:3142";

Do a software update to test it out.
> sudo apt update
> sudo apt dist-upgrade

Conclusion

Its a nice and easy setup.  The cache will work for several distros.

Howto Ubuntu 20.04 Setting up a DNS Server

Introduction

DNS is a big player on the internet.  It gives us a way to assign names to all those IP addresses out there.  This howto is going to cover installing DNS and 3 configuration examples.  Keep in mind that one server can encompass all three configurations at the same time.

Setup New Server (Optional)

I like to have dedicated DNS servers.  So you can start with a fresh server install.  Follow the HOWTO below to setup a new server.  Otherwise move on to install software.

HOWTO Ubuntu 20.04 LTS Base Server Setup

Introduction All of our servers will start with this install. This base server is based on Ubuntu 20.04 LTS Server.  I don’t explain much in the howto so if you have a question leave a comment or use Google. Downloading … Continue reading

Install Software

We will be using BIND for our DNS server.  Software is a quick install.  Type the following.
> sudo apt-get install bind9 bind9utils bind9-doc

Three DNS Configurations

I’m going to cover 3 common DNS configurations.  They are:

Caching DNS Server:
Usually a local server.  It helps speed up the DNS lookup process by storing a local cache of frequently looked up host names by clients.

Primary DNS Server:
This type of server provides authoritative answers for domains and sub domains.  Zone files contain information about the domain.

Secondary DNS Server:
This type of server is known as a slave server.  It provides redundancy to the primary DNS server.

Caching only DNS Server

Out of the box the Bind package for Ubuntu has been configured as a caching DNS server.  We can speed up lookups by forwarding them to your ISP’s DNS servers, Googles DNS server and / or other fast DNS server.  In this example I’m going to use Google’s DNS server.  We are also going to limit the clients that can use the server.

Make a backup of /etc/bind/named.conf.options
> sudo cp /etc/bind/named.conf.options /etc/bind/named.conf.options.save

Change /etc/bind/named.conf.options to look like the text below.
> sudo nano -w /etc/bind/named.conf.options

// caching only DNS server config
//
acl localclients {
  192.168.0.0/16;
  10.0.0.0/8;
  localhost;
  localnets;
};
options {
  directory "/var/cache/bind";
  recursion yes;
  allow-query { any; };
  allow-query-cache { any; };
  allow-recursion { localclients; };
  forwarders { 
    0.0.0.0;
    8.8.4.4;
  }; 
  dnssec-validation auto;
  auth-nxdomain no; # conform to RFC1035
  listen-on-v6 { any; };
};

Restart bind
> sudo service bind9 restart

Primary DNS Server

This configuration is for providing DNS for your domain name(s).  I’m only going to cover a basic domain setup.  There are a lot of configuration options for zone files.

Make a backup of /etc/bind/named.conf.options
> sudo cp /etc/bind/named.conf.options /etc/bind/named.conf.options.save

Change /etc/bind/named.conf.options to look like the text below.
> sudo nano -w /etc/bind/named.conf.options

// caching only DNS server config
//
acl localclients {
  192.168.0.0/16;
  10.0.0.0/8;
  localhost;
  localnets;
};
options {
  directory "/var/cache/bind";
  recursion yes;
  allow-query { any; };
  allow-query-cache { any; };
  allow-recursion { localclients; };
  forwarders { 
    0.0.0.0;
    8.8.4.4;
  }; 
  dnssec-validation auto;
  auth-nxdomain no; # conform to RFC1035
  listen-on-v6 { any; };
  allow-transfer { none; };
};

Edit /etc/bind/named.conf.local and add the text below.
> sudo nano -w /etc/bind/named.conf.local

zone "example.com" {
  type master;
  file "/etc/bind/db.example.com";
};

Now create /etc/bind/db.example.com and use the text below.
> sudo nano -w /etc/bind/db.example.com

$TTL 604800
@ IN SOA dns1.example.com. admin.example.com. (
          10   ; Serial
      604800   ; Refresh
       86400   ; Retry
     2419200   ; Expire
      604800 ) ; Negative Cache TTL
;

; Name servers
example.com.    IN   NS   dns1.example.com.

; A records for name servers
dns1            IN   A    192.168.1.1

; Other A records
@               IN   A    192.168.1.2
www             IN   A    192.168.1.2

Restart bind
> sudo service bind9 restart

Secondary DNS Server

This configuration is for providing DNS for your domain name(s).  I’m only going to cover a basic domain setup.  There are a lot of configuration options for zone files.

Make a backup of /etc/bind/named.conf.options
> sudo cp /etc/bind/named.conf.options /etc/bind/named.conf.options.save

Change /etc/bind/named.conf.options to look like the text below.
> sudo nano -w /etc/bind/named.conf.options

// caching only DNS server config
//
acl localclients {
  192.168.0.0/16;
  10.0.0.0/8;
  localhost;
  localnets;
};
options {
  directory "/var/cache/bind";
  recursion yes;
  allow-query { any; };
  allow-query-cache { any; };
  allow-recursion { localclients; };
  forwarders { 
    0.0.0.0;
    8.8.4.4;
  }; 
  dnssec-validation auto;
  auth-nxdomain no; # conform to RFC1035
  listen-on-v6 { any; };
  allow-transfer { none; };
};

Edit /etc/bind/named.conf.local and add the text below.
> sudo nano -w /etc/bind/named.conf.local

zone "example.com" {
  type slave;
  file "db.example.com";
  masters { 192.168.1.1; }
};

Restart bind
> sudo service bind9 restart

Conclusion

This howto was focused on configuring Bind on Ubuntu.  You will need to do research on all the options that Bind offers.

HOWTO Ubuntu 20.04 LTS Base Server Setup

Introduction

All of our servers will start with this install. This base server is based on Ubuntu 20.04 LTS Server.  I don’t explain much in the howto so if you have a question leave a comment or use Google.

Downloading the ISO

Visit the Ubuntu website and download the ubuntu 20.04 server ISO.

Initial Install

The install screens are straight forward.  I’m not going to cover them in much detail.  Unless you need to customize a setting, just choose the default settings.  Boot the install DVD.

Click ‘Reboot’ when it appears.

First boot

Reboot the machine when the install finishes.
The OS will boot. Log in. All the commands need to be run as root so lets start a shell with root privilleges.
> sudo bash

Get everything updated and install a couple of items.
> sudo apt update
> sudo apt dist-upgrade

Install and enable ssh.
> sudo apt install ssh
> sudo systemctl enable –now ssh

WARNING: My server isn’t directly connected to the internet. The firewall is disabled to help with installation, configuration and testing easier. Once everything is working, turn on the firewall and configure it. I wil remind you to secure your server at the end of this howto.

now reboot the server.

The Second Boot – Installing Additional Packages

We need quite a few other packages. In this howto I’m installing packages regardless if they were already installed by another dependency. This guards against package changes that could cause a package to not be installed. Once again log in to your server.

We need the webmin repo. Create webmin.repo with the text below.
> sudo nano -w /etc/apt/sources.list.d/webmin.list

deb http://download.webmin.com/download/repository sarge contrib

Install the webmin key.
> wget http://www.webmin.com/jcameron-key.asc
> sudo apt-key add jcameron-key.asc

Let’s add a 3rd party repo for Apache.
> add-apt-repository ppa:ondrej/apache2

Now bring everything up to date.
> sudo apt update

Install the following packages. Multiple lines to make cut and paste easier.
> sudo apt install make screen snmp composer libcurl4 unzip net-tools
> sudo apt install apache2 libapache2-mod-php7.4 mysql-server mysql-client
> sudo apt install libapache2-mod-fcgid php-opcache php-apcu

Install some extra PHP libraries.
> sudo apt install php7.4-gd php7.4-snmp php7.4-mbstring php7.4-mysql
> sudo apt install php7.4-odbc php7.4-imap
> sudo apt install php7.4-xmlrpc php7.4-dba
> sudo apt install php7.4-soap php7.4-zip php7.4-intl php7.4-curl

Now lets install webmin.
> sudo apt install webmin
> sudo systemctl enable webmin
> sudo service webmin start

Configure Apache and PHP

Enable the rewrite module.
> sudo a2enmod rewrite actions fcgid alias proxy_fcgi expires headers

Enable Apache.
> sudo systemctl enable apache2.service

Reload apache.
> sudo systemctl restart apache2.service

Configuring MySQL

Configure mysql.
> sudo mysql_secure_installation

Installing and Configuring phpMyAdmin

I prefer to phpMyAdmin to manage my MySQL databases.

Now install phpMyAdmin.
> sudo apt install phpmyadmin

Restart Apache.
> sudo systemctl restart apache2.service

Installing Postfix

Lets install postfix.
> sudo apt install postfix

When prompted select internet site. Next set the mail server name.

Installing cockpit

I’m trying cockpit as my server admin tool.  Do the following to set it up.
> sudo apt install cockpit
> sudo systemctl start cockpit
> sudo systemctl enable cockpit.socket

You can now login to https://yourserver.tld:9090 to administer your server.

Getting root’s and other’s mail

You need to get some local system user’s mail. We’ll use postfix’s virtual file to get the emails to the right place.

Add the following to /etc/postfix/virtual

root admin@yourdomain.tld
postmaster admin@yourdomain.tld
abuse admin@yourdomain.tld

Now add the configuration option to main.cf
> sudo postconf -e “virtual_alias_maps = hash:/etc/postfix/virtual”
Just a couple commands to wrap everything up.
> sudo postmap /etc/postfix/virtual
> sudo systemctl restart postfix
> sudo systemctl enable postfix

Remove Cloud Init

Our server won’t be using cloud-init.  To keep from causing you trouble in the future we will remove it now.

Type:
> sudo apt remove cloud-init cloud-initramfs-copymods cloud-initramfs-dyn-netconf

Final Settings

You may want to enable the linux firewall.
Set your timezone in /etc/php.ini

Conclusion

That’s it for the basic server setup. This is an example of a standard linux server setup. Be sure to use cockpit or webmin to set which services you want to start at boot time. See the other pages for info on configuring servers for virtual webhosting or virtual email hosting. Remember to configure the firewall on the server.

An Easy Way To Delete All Tables From A MySQL Database

Introduction

Sometimes you need to remove all the tables in a database.  For example, when you are installing or testing a web application.  There are GUI tools that can help but we are going to use the command line.

Solution

This is a two step process.

First we use mysqldump and grep to generate an sql file containing the tables to drop.  Change ‘MYDB’ to the name of the database to drop tables from.

mysqldump --add-drop-table --no-data -u root -p MYDB | grep 'DROP TABLE' > drop_tables.sql

Next use mysql CLI to execute the sql file.  Change ‘MYDB’ to the name of the database to drop tables from.

mysql -u root -p MYDB < drop_tables.sql

Conclusion

Thats it.  Straight forward and simple.

My Favorite WordPress Plugins

Introduction

This is a quick rundown of the plugins I like to use on my WordPress sites.  I do try my best not to install tons of plugins on my sites.  For the most part I use small lightweight plugins that do a specific task.

Plugins

They aren’t in any particular order.  So here’s the list.

Plugin:  404Page

You need a custom page not found.  This plugin helps take care of those 404 errors.

Plugin:  Amazon Associates Link Builder

Sorry to say my sites have ads.  This is the official plugin from Amazon.

Plugin:  Contact Form 7

I needed a few forms.  Its the plugin to use.  Seems like everyone uses it.

Plugin:  Display Posts Shortcode

I like to do easy custom posts pages.  This plugin gives me a shortcode I can use on any page.

Plugin:  Duplicator

My goto plugin for backing up and migrating my sites.

Plugin:  Easy WP Meta Description

An easy way to create meta descriptions for search engines.

Plugin:  Enhanced Media Library

Allows you to easily categorize and filter your media.

Plugin:  Flamingo

Adds storage capabilities to contact form 7.

Plugin:  Google Analytics Dashboard For WP

I don’t want to go to Google to see how my sites are doing.  This plugin puts the data I want to see in my wordpress dashboard.

Plugin:  Google XML Sitemaps

Creates sitemap for the search engines.

Plugin:  Insert Pages

This plugin provides shortcodes so I can insert posts into posts on my site.

Plugin:  Lazy Load XT

Got to load your web page fast.  This plugin loads images, youtube and iframes on your pages as they are needed.

Plugin:  Simple Cache

Well the name says it all.  A simple caching plugin for wordpress.

Plugin:  Smush

Its popular.  Optimize your images.

Plugin:  TinyMCE Advanced

Just adds some extra functionality to TinyMCE.

Plugin:  Wordfence Security

The most important plugin of them all.  Protect your site with this plugin.  There are a lot of settings to go through but protecting your site is very important.

Plugin:  wpDiscuz

Just a better comment plugin.

Plugin:  YouTube

Adds shortcodes with more options for embedding your youtube videos.

Conclusion

The above plugins have helped out my sites.  Give one a try.

HOWTO: Configure A UPS on Proxmox 5.x

Introduction

Each of my proxmox servers has its own dedicated UPS.  My servers are low power and the UPS will keep them up for at least 2 hours.  I’m using a Cyberpower UPS connected via USB.

This howto will use a Cyberpower UPS as the example.  Its very easy to make a couple changes to use another UPS.

We will be using NUT to do the heavy lifting.  When done the server will run and shutdown when the battery reaches 20%.  As a bonus notification emails will be sent as well.

Installation and configuration

SSH into your proxmox server with an account that has root privileges.

The only package to install is nut.
>sudo apt install nut

Plug in your UPS to a USB port.  We need to find the USB device information for your UPS.  So lets list our USB devices.
> lsusb

Here’s my list of USB devices.  In this example I’m interested in the Cyberpower.  Copy down the ID of your UPS.

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Create the following config file:  /etc/nut/ups.conf

maxretry = 3
[theUPS]
  driver = usbhid-ups
  port = auto
  desc = "the server UPS"

We need to create a udev rule to allow nut user access to the driver.  The ID you copied down earlier is used here so udev knows which device the rule applies to.  So create:  /etc/udev/rules.d/90-nut-ups.rules

# Rule for a Cyberpower UPS
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0764", ATTR{idProduct}=="0501", MODE="0660", GROUP="nut"

Now restart udev.
> sudo service udev restart

Next unplug the usb cable to the UPS and plug it back in for the rule to work.

Ok.  Its time to configure NUT to run in stand alone mode.  Replace /etc/nut/nut.conf with the following:

MODE=standalone

The ups daemon has 2 configuration files to deal with.  It needs to be configured for the ip and port to listen on.  We also create a user that can monitor the UPS.

Replace /etc/nut/upsd.conf with the following.

# LISTEN <address> [<port>]
LISTEN 127.0.0.1 3493
LISTEN ::1 3493

Replace /etc/nut/upsd.users with the following.

[upsmonitor]
password = YOUR_PASSWORD
upsmon master

The last file to configure is the UPS monitoring daemon. Replace /etc/nut/upsmon.conf with the following.

# Commands for shutdown on power loss
MONITOR theUPS@localhost 1 upsmonitor YOUR_PASSWORD master
POWERDOWNFLAG /etc/killpower
SHUTDOWNCMD "/sbin/shutdown -h now"

Enable the nut server and client services.
> sudo systemctl enable nut-server.service
> sudo systemctl enable nut-client.service

For the final step lets start the server and client services.
> service nut-server start
> service nut-client start

Conclusion

Nut is a pain to configure, but well worth it.

 

 

Creating a MySQL or MariaDB Database and User for WordPress

Introduction

These are just some quick notes on creating a mysql database and user.  This example shows how to set it up for WordPress.

The Steps

Just type the following lines.  Replace ‘dbname’, ‘username’ and ‘password’ with your values.

mysql -u root -p
CREATE DATABASE dbname;
CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON dbname.* TO 'username'@'localhost';
FLUSH PRIVILEGES;
exit