Tags Archives: https

LAMP Server Migration

The following notes document the migration of a virtual Linux machine running LAMP – Linux Ubuntu, Apache webserver, MySql/MariaDB & PHP, from an existing machine to a new machine and the procedural steps involved.

 

Both old and new machines also run ssh, nfs-server shares, sslh port multiplexer, nextcloud, checkmk, wordpress, phpmyadmin, together with Linux shell script crontab-run backup routines to backup data to an external cloud provider.

 

The scripts and crontab entries had to be migrated, installed and reconfigured on the new server.

 

This is an overview of the steps involved. For more detailed discussion of the specific actions, for example covering mysql, apache, sslh multiplexer, SSL certificates, see the appropriate relevant subject sections of this IT Knowledge Base.

 

 

Initial Preparation

 

First task is to create the new virtual server with Linux Ubuntu OS. This has a new localhost name and new unique publicly accessible IP address.

 

After the migration, the old original server machine is then switched off and deleted from the virtual server provider environment. The new machine name is changed to the old machine name, taking the place of the old machine online.

 

After installing the basic operating system Linux Ubuntu version 20.04 LTS, we migrate existing /usr/local/bin scripts from the old to the new machine, together with any binaries and other files contained in this directory.

 

Later we will configure crontab on the new machine for backups and mysql nextcloud nightly database scan and updates for newly added data files (and deleted/modified data files).

 

We give the new machine the temporary localhost name of “gemininew”.

 

When the migration is complete we will change the name to “gemini”, taking the place of the old machine.

 

The /etc/hosts file entries on the server and on all connecting hosts will then need to be modified so that the entry for gemini points to the NEW IP address and no longer to the old one.

 

In the meantime, for ease of logging in, we have made an entry on the old gemini server /etc/hosts and on our connecting hosts as follows:

 

gemininew  <the new IP address for gemini>

 

while keeping the old gemini IP entry intact for now. Later on towards the end of the migration this old entry will be deleted from the file.

 

 

 

Modify DNS Record

 

We need to modify the DNS record for the domain kevwells.com for the new IP address of the new machine to replace the old one.

 

This is done on the DNS server of our virtual server provider.

 

 

Install Apache

 

Install apache2 on the new machine and define the virtual hosts that are required.

 

 

 

Next, for apache

 

To allow .htaccess files, we need to set the AllowOverride directive within a Directory block pointing to our document root. Add the following block of text inside the VirtualHost block in your configuration file, making sure to use the correct web root directory.

 

 

In my case it is:

 

root@gemininew:/etc/apache2/sites-available# nano 000-default.conf

add this under

<VirtualHost *:80>

 

<Directory /var/www/wordpress/>
AllowOverride All
</Directory>

 

By default the use of .htaccess files is disabled. WordPress and many WordPress plugins use these files extensively for in-directory tweaks to the web server’s behavior.

 

 

Next, we can enable mod_rewrite so that we can utilize the WordPress permalink feature:

 

a2enmod rewrite

 

 

root@gemininew:/etc/apache2/sites-available# a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
systemctl restart apache2
root@gemininew:/etc/apache2/sites-available# systemctl restart apache2
root@gemininew:/etc/apache2/sites-available#

 

This allows you to have more human-readable permalinks to your posts, like the following two examples:

 

http://example.com/2012/post-name/
http://example.com/2012/12/30/post-name

 

The a2enmod command calls a script that enables the specified module within the Apache configuration.

 

next, check to make sure we haven’t made any syntax errors by running the following test.

 

apache2ctl configtest

 

 

root@gemininew:/etc/apache2/sites-available# apache2ctl configtest
AH00558: apache2: Could not reliably determine the server’s fully qualified domain name, using 127.0.1.1. Set the ‘ServerName’ directive globally to suppress this message
Syntax OK
root@gemininew:/etc/apache2/sites-available#

 

 

Ensure apache is running with

 

a2ensite <sites-enabled_configfile>

 

systemctl enable apache2
systemctl start apache2

 

Install Mysql/MariaDB

 

apt install mariadb-server

 

During the installation you’ll be requested to set a mysql server admin user password.

 

If the secure installation utility does not run automatically during the installation process, then you can run it explicitly:

 

mysql_secure_installation utility

 

Next install the php-mysql module:

 

root@gemininew:~# apt-get install php-mysql
Reading package lists… Done
Building dependency tree
Reading state information… Done
php-mysql is already the newest version (2:7.4+75).

 

 

Enable the mysql service and start it:

 

 

 

root@gemini:/var/lib/mysql# systemctl start mysql
root@gemini:/var/lib/mysql# systemctl status mysql
● mysql.service – LSB: Start and stop the mysql database server daemon
Loaded: loaded (/etc/init.d/mysql; generated)
Active: active (running) since Thu 2022-03-03 13:24:50 UTC; 4s ago
Docs: man:systemd-sysv-generator(8)
Process: 4328 ExecStart=/etc/init.d/mysql start (code=exited, status=0/SUCCESS)
Tasks: 33 (limit: 2274)
Memory: 64.0M
CGroup: /system.slice/mysql.service
├─4367 /bin/sh /usr/bin/mysqld_safe
├─4483 /usr/sbin/mysqld –basedir=/usr –datadir=/var/lib/mysql –plugin-dir=/usr/lib/x86_64-linux-gnu/mariadb19/plugin –user=mysql –skip-log-error –pid-file=/run/mysqld/mysqld.pid –socket=/var/run/mysqld/mysqld.sock
└─4484 logger -t mysqld -p daemon error

 

Mar 03 13:24:50 gemini /etc/mysql/debian-start[4538]: Upgrading MySQL tables if necessary.
Mar 03 13:24:50 gemini mysqld[4484]: 2022-03-03 13:24:50 10 [Warning] Access denied for user ‘debian-sys-maint’@’localhost’ (using password: YES)
Mar 03 13:24:50 gemini /etc/mysql/debian-start[4541]: Looking for ‘mysql’ as: /usr/bin/mysql
Mar 03 13:24:50 gemini /etc/mysql/debian-start[4541]: Reading datadir from the MariaDB server failed. Got the following error when executing the ‘mysql’ command line client
Mar 03 13:24:50 gemini /etc/mysql/debian-start[4541]: ERROR 1045 (28000): Access denied for user ‘debian-sys-maint’@’localhost’ (using password: YES)
Mar 03 13:24:50 gemini /etc/mysql/debian-start[4541]: FATAL ERROR: Upgrade failed
Mar 03 13:24:50 gemini /etc/mysql/debian-start[4546]: Checking for insecure root accounts.
Mar 03 13:24:50 gemini mysqld[4484]: 2022-03-03 13:24:50 11 [Warning] Access denied for user ‘debian-sys-maint’@’localhost’ (using password: YES)
Mar 03 13:24:50 gemini mysql[4549]: ERROR 1045 (28000): Access denied for user ‘debian-sys-maint’@’localhost’ (using password: YES)
Mar 03 13:24:51 gemini mysqld[4484]: 2022-03-03 13:24:51 12 [Warning] Access denied for user ‘wordpressuser’@’localhost’ (using password: YES)
lines 3-22/22 (END)

 

 

and we now have the socket for mysqld:

 

root@gemini:/run/mysqld# ls -lias
total 4
586 0 drwxr-xr-x 2 mysql root 80 Mar 3 13:24 .
2 0 drwxr-xr-x 29 root root 880 Mar 3 13:20 ..
678 4 -rw-rw—- 1 mysql mysql 5 Mar 3 13:24 mysqld.pid
677 0 srwxrwxrwx 1 mysql mysql 0 Mar 3 13:24 mysqld.sock
root@gemini:/run/mysqld#

 

 

Test the server:

 

root@gemininew:~#
root@gemininew:~#
root@gemininew:~#
root@gemininew:~# mysqladmin -p -u root version
Enter password:
mysqladmin Ver 8.0.28-0ubuntu0.20.04.3 for Linux on x86_64 ((Ubuntu))
Copyright (c) 2000, 2022, Oracle and/or its affiliates.

 

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

 

Server version 8.0.28-0ubuntu0.20.04.3
Protocol version 10
Connection Localhost via UNIX socket
UNIX socket /var/run/mysqld/mysqld.sock
Uptime: 6 min 48 sec

 

Threads: 2 Questions: 14 Slow queries: 0 Opens: 130 Flush tables: 3 Open tables: 49 Queries per second avg: 0.034
root@gemininew:~#

 

 

 

Run the mysql secure installation utility

 

 

 

/usr/bin/mysql_secure_installation

 

 

This will also set the root password for mysql

 

 

You have to set the root password here:

 

root@gemini:/run/mysqld# /usr/bin/mysql_secure_installation

 

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!

 

In order to log into MariaDB to secure it, we’ll need the current
password for the root user. If you’ve just installed MariaDB, and
you haven’t set the root password yet, the password will be blank,
so you should just press enter here.

 

Enter current password for root (enter for none): ***NOTE**** if you try to enter the password for root here it gives an error at this stage:!!! see below
ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES)
Enter current password for root (enter for none): ****PRESS ENTER***- you set the root password further below!***
OK, successfully used password, moving on…

 

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

 

Set root password? [Y/n] Y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
… Success!

 

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.

 

Remove anonymous users? [Y/n]
… Success!

 

Normally, root should only be allowed to connect from ‘localhost’. This
ensures that someone cannot guess at the root password from the network.

 

Disallow root login remotely? [Y/n]
… Success!

 

By default, MariaDB comes with a database named ‘test’ that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.

 

Remove test database and access to it? [Y/n]
– Dropping test database…
… Success!
– Removing privileges on test database…
… Success!

 

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

 

Reload privilege tables now? [Y/n]
… Success!

 

Cleaning up…

 

All done! If you’ve completed all of the above steps, your MariaDB
installation should now be secure.

 

Thanks for using MariaDB!
root@gemini:/run/mysqld#

 

 

 

root@gemini:~# mysqlshow -u root -p
Enter password:
+——————–+
| Databases |
+——————–+
| gitea |
| information_schema |
| kevwells |
| mysql |
| nextcloud |
| performance_schema |
| phpmyadmin |
| wordpress |
+——————–+

 

root@gemini:~# mysqldump -u root -p –all-databases > allgeminidatabases-backup.sql
Enter password:
root@gemini:~#

 

 

to restore

 

mysql -u root -p < allgeminidatabases-backup.sql

 

root@gemininew:~# mysql -u root -p < allgeminidatabases-backup.sql
Enter password:

 

root@gemininew:~# mysqlshow -u root -p
Enter password:
+——————–+
| Databases |
+——————–+
| gitea |
| information_schema |
| kevwells |
| mysql |
| performance_schema |
| sys |
+——————–+
root@gemininew:~#

 

 

Set up a Mysql Database for WordPress

 

Create an exclusive database for WordPress to control. This can have any name, but we will use the standard name wordpress for this example.

 

Enter the mysql admin client, using:

 

 

root@gemininew:~# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 319
Server version: 10.3.34-MariaDB-0ubuntu0.20.04.1 Ubuntu 20.04

 

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

 

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

 

MariaDB [(none)]>

 

then do the following:

 

MariaDB [(none)]> CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Query OK, 1 row affected (0.001 sec)

MariaDB [(none)]> use wordpress;
Database changed
MariaDB [wordpress]>

MariaDB [(none)]> CREATE USER ‘wordpressuser’@localhost IDENTIFIED BY ‘*********’;  
Query OK, 0 rows affected (0.000 sec)

 

MariaDB [(none)]> GRANT ALL ON wordpress.* TO ‘wordpressuser’@’localhost’;
Query OK, 0 rows affected (0.001 sec)

 

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.001 sec)

 

MariaDB [(none)]>

 

 

you can now exit mariadb:

 

MariaDB [(none)]> exit
Bye
root@gemininew:/#

 

 

Install WordPress

 

next, download and install wordpress:

 

you can do a wget from https://wordpress.org/latest.tar.gz

 

and then unpack at /var/www/wordpress

 

you can then create a /var/www/html -> /var/www/wordpress link

 

and set permissions as follows:

 

chown -R www-data:www-data /var/www/wordpress

 

Next we’ll run two find commands to set the correct permissions on the WordPress directories and files:

 

root@gemininew:~# find /var/www/wordpress/ -type d -exec chmod 750 {} \;
root@gemininew:~# find /var/www/wordpress/ -type f -exec chmod 640 {} \;
root@gemininew:~#

 

Next, modify some of the database connection settings, adjusting database name, the database user, and the associated password you configured within MySQL.

 

Also set the method WordPress should use to write to the filesystem, set this filesystem method to “direct”.

 

If we dont do this it could mean WordPress prompting for FTP credentials for some actions:

 

/var/www/wordpress/wp-config.php

. . .

// ** MySQL settings – You can get this info from your web host ** //
/** The name of the database for WordPress */
define( ‘DB_NAME’, ‘wordpress’ );

 

/** MySQL database username */
define( ‘DB_USER’, ‘wordpressuser’ );

 

/** MySQL database password */
define( ‘DB_PASSWORD’, ‘***password commented out***’ );

 

/** MySQL hostname */
define( ‘DB_HOST’, ‘localhost’ );

 

/** Database Charset to use in creating database tables. */
define( ‘DB_CHARSET’, ‘utf8’ );

 

/** The Database Collate type. Don’t change this if in doubt. */
define( ‘DB_COLLATE’, ” );

 

. . .

define(‘FS_METHOD’, ‘direct’);

 

 

NOTE: we substitute the above with our own password as created for the wordpressuser in mariadb! (not shown here for security reasons)

 

next, in web-browser, open the http://servername/wp-admin link

 

and the wordpress admin dashboard initial setup page should appear.

 

 

 

Firewalling for apache

 

The following ports need to be opened, port 443 and 80.

 

root@gemini:/etc/apache2# ufw status
Status: active

 

To Action From
— —— —-
22 ALLOW Anywhere
80 ALLOW Anywhere
443 ALLOW Anywhere
3306 ALLOW Anywhere
9993 ALLOW Anywhere
2049 ALLOW Anywhere
22 (v6) ALLOW Anywhere (v6)
80 (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
3306 (v6) ALLOW Anywhere (v6)
9993 (v6) ALLOW Anywhere (v6)
2049 (v6) ALLOW Anywhere (v6)

root@gemini:/etc/apache2#

 

 

DO NOT open port 444!

 

NOTE that port 444 is NOT opened on the firewall – this is used internally by apache ie behind the firewall, between apache and sslh. It should not be accessible from outside.

 

 

MySql/MariaDB has to be installed and up and running.

 

Check it is enabled and running using

 

systemctl enable mysql
systemctl start mysql
systemctl status mysql

 

During installation, all being well, mysql/mariadb will start automatically, unless the port used by mysql is already in use.

 

 

 

 

 

Install SSL Certificates

 

SSL/TLS https certificates supplied by Lets Encrypt

 

The apache webserver needs to be running on port 80 to carry out registration to obtain the certificates for each virtual host.

 

Certificates are required for all virtual websites operating on the IP with https:

 

kevwells.com, nextcloud.kevwells.com

 

Use the certbot command-line utility to request the SSL certificates for the websites. You need to run certbot in turn for each virtual host website you are operating on https.

 

Make sure /etc/apache2/ports.conf is set to listen on port 80 and 443 initially for ssl.

 

After obtaining the certificates, and since we are using the sslh multiplexer, you need to change ports.conf all references to Listen 443 port to Listen 444 as this is the port used for sslh multiplexer.

 

The sslh multiplexer separates out incoming traffic on 443 to 444 for Apache and 22 for ssh.

 

Install wordpress under /var/www/wordpress

 

then create symbolic links as follows:

 

/var/www/html -> /var/www/kevwells.com

 

/var/www/kevwells.com -> /var/www/wordpress

 

Configure the wp-config.php file:

 

root@gemini:/var/www/wordpress#
root@gemini:/var/www/wordpress# cat wp-config.php
<?php
//Begin Really Simple SSL session cookie settings
@ini_set(‘session.cookie_httponly’, true);
@ini_set(‘session.cookie_secure’, true);
@ini_set(‘session.use_only_cookies’, true);
//END Really Simple SSL

 

/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the installation.
* You don’t have to use the web site, you can copy this file to “wp-config.php”
* and fill in the values.
*
* This file contains the following configurations:
*
* * MySQL settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* @link https://wordpress.org/support/article/editing-wp-config-php/
*
* @package WordPress
*/

 

 

!!!!! DB_NAME and other variables have been omitted here for security reasons!!!!

 

 

// ** MySQL settings – You can get this info from your web host ** //
/** The name of the database for WordPress */
define( ‘DB_NAME’, ‘***’ );

 

/** MySQL database username */
define( ‘DB_USER’, ‘***’ );

 

/** MySQL database password */
define( ‘DB_PASSWORD’, ‘***’ );

 

/** MySQL hostname */
define( ‘DB_HOST’, ‘localhost’ );

 

/** Database charset to use in creating database tables. */
define( ‘DB_CHARSET’, ‘utf8mb4’ );

 

/** The database collate type. Don’t change this if in doubt. */
define( ‘DB_COLLATE’, ” );

 

/**#@+
* Authentication unique keys and salts.
*
* Change these to different unique phrases! You can generate these using
* the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
*
* You can change these at any point in time to invalidate all existing cookies.
* This will force all users to have to log in again.
*
* @since 2.6.0
*/
define( ‘AUTH_KEY’, ‘;


!!!!!! NOT DISPLAYED HERE FOR SECURITY REASONS!!!!!!!!!!!!!!


 

 

/**
* WordPress database table prefix.
*
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*/
$table_prefix = ‘wp_’;

 

/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*
* For information on other constants that can be used for debugging,
* visit the documentation.
*
* @link https://wordpress.org/support/article/debugging-in-wordpress/
*/
define( ‘WP_DEBUG’, false );

 

/* define( ‘WP_DEBUG’, false ); */

 

/* Add any custom values between this line and the “stop editing” line. */

 

 

/* That’s all, stop editing! Happy publishing. */

 

/** Absolute path to the WordPress directory. */
if ( ! defined( ‘ABSPATH’ ) ) {
define( ‘ABSPATH’, __DIR__ . ‘/’ );
}

 

/** Sets up WordPress vars and included files. */
require_once ABSPATH . ‘wp-settings.php’;

 

/* define(‘WP_ALLOW_REPAIR’, true); */

 

define(‘FS_METHOD’, ‘direct’);

 

@ini_set( ‘upload_max_filesize’ , ‘12800M’ );
@ini_set( ‘post_max_size’, ‘12800M’);
@ini_set( ‘memory_limit’, ‘256M’ );
@ini_set( ‘max_execution_time’, ‘300’ );
@ini_set( ‘max_input_time’, ‘300’ );

 

define(‘FORCE_SSL_ADMIN’, true);

 

define( ‘WP_HOME’, ‘http://3.222.27.169’ );
define( ‘WP_SITEURL’, ‘http://3.222.27.169’ );

 

 

root@gemini:/var/www/wordpress#

 

 

 

 

Install Nextcloud

 

How to configure Nextcloud

 

Nextcloud has to be downloaded and installed under /var/www/nextcloud

 

enter a database name for nextcloud – usually “nextcloud”

 

port is localhost:3306

 

a database username and a password.

 

this gets saved in the nextcloud config file under /var/www/nextcloud/config/config.php

 

Create a virtual host for nextcloud in /etc/apache2/sites-available/<apacheconfigfile>.conf

 

You will also need to define the virtual host ie nextcloud for http port 80 in order to obtain the SSL/TLS certificate from Lets Encrypt.

 

Once this is obtained and installed, you can then delete this port 80 http virtual host for nextcloud.

 

 

 

Switch WordPress from http to https

 

Once you have obtained and installed the SSL certificates for the virtual hosts, you can switch wordpress to https.

 

In practice, the switch from http to https for wordpress was complicated.

 

There are two aspects to this: apache, and wordpress.

 

The apache virtual host definitions are relatively straightforward. See the apache section above.

 

WordPress is a little more involved and complicated.

 

First, you need to install the wordpress plugin Really Simple SSL (if only it were “really simple” in practice).

 

It was difficult trying to switch the wordpress site name in the wordpress dashboard from http to https.

 

Also you need to save permalinks twice, using the Permalinks plugin which must first be installed.

 

Trying to change the wordpress site definitions in the wordpress dashboard under settings – general, did not work, wordpress kept changing them back.

 

I also tried changing the site names using the mysql admin client and sql commands, but these too would get changed back!

 

Finally, I had to add the two definitions to the wp-config.php and also the FORCE_SSL_ADMIN directive:

 

define(‘FORCE_SSL_ADMIN’, true);

 

define( ‘WP_HOME’, ‘http://3.222.27.169’ );
define( ‘WP_SITEURL’, ‘http://3.222.27.169’ );

 

 

Then after numerous attempts, it finally accepted the change from http to https.

 

You also have to save the links again in WordPress Permalinks plugin after changing from http to https:

 

select plain, then back to custom, then plain, then finally set to custom.

 

The links should then function correctly.

 

 

Also in this case, don’t forget we are using sslh multiplexer, so the virtual host definitions for the ports need to be 444 for https and not 443.

 

Make sure these are set in the sites-enabled config file as well as in the apache ports.conf file! (Lets Encrypt changes then to 443 – you have to change them back manually!).

 

Then make sure sslh is running correctly, listening on 443, and passing ssh traffic to 22 sshd, and https traffic on to 444 apache.

 

 

Firewalling – Portmapper

 

Make sure port 111 for nfs portmapper is closed.

 

Portmapper is a service usually used with NFS. When this is not properly firewalled, it can be abused to conduct DDOS attacks.

 

All portmapper services should therefore be behind a firewall and restricted to IPs that need to contact them.

 

For Linux machines, add firewall rules to block port 111 on both UDP and TCP as follows:

 

iptables -I INPUT 1 -m tcp -p tcp –dport 111 -j DROP
iptables -I INPUT 1 -m udp -p udp –dport 111 -j DROP

 

Alternatively, set using the ufw firewall utility in ubuntu with:

 

root@gemini:# ufw deny 111
Rule updated
Rule updated (v6)
root@gemini:#
root@gemini:~# ufw status
Status: active

 

To Action From
— —— —-
22 ALLOW Anywhere
80 ALLOW Anywhere
443 ALLOW Anywhere
3306 ALLOW Anywhere
9993 ALLOW Anywhere
111 DENY Anywhere
2049 ALLOW Anywhere
22 (v6) ALLOW Anywhere (v6)
80 (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
3306 (v6) ALLOW Anywhere (v6)
9993 (v6) ALLOW Anywhere (v6)
111 (v6) DENY Anywhere (v6)
2049 (v6) ALLOW Anywhere (v6)

 

root@gemini:~#

 

 

Modify hosts files

 

The hosts file on the new server and all connecting clients must be updated to point the server name to the new IP address.

 

The new server machine name is changed from gemininew to gemini.

 

Modify /etc/hosts files to define the new machine IP with the server localhost name ie gemini

 

Distribute the new /etc/hosts to all connecting clients. This can be done using scp.

 

 

 

Switch off old virtual machine

 

The final task is to switch off and delete the old virtual machine.

 

This does not actually have to be switched off in order to delete, but to keep things clean in the event of having to request a special restore from the server provider we will switch off correctly first and then delete.

 

Login on the OLD machine,

 

Check the ip address of the machine to make absolutely sure you are logged in on the OLD machine:

 

ifconfig

 

then at the command line, do a:

 

shutdown -h now

 

Then switch off the old machine on the virtual server provider account dashboard.

 

Next you can delete the old virtual server.

 

Make absolutely sure first that you are clicking on and deleting the correct machine!

 

 

Finally, delete any associated snapshot backups associated with the old machine.

 

With that the server migration is now complete. You’ve earned a good cup of coffee!

 

 

 

 

 

 

 

 

 

 

Continue Reading

How to Install the SSLH Multiplexer

My server is using the sslh multiplexer daemon, this uses incoming port 443 for both ssh and https.

 

Reason for this is to avoid ssh connection problems when trying to connect to the server from outgoing routers which do not permit outgoing ssh port 22 connections.

 

If you have administrator access to the router you can modify this, but if you don’t have access, eg when using a router in a residential or commercial building complex to which you don’t have admin access yourself, then a viable workaround is to use port 443 for outgoing ssh connections.

 

This is because port 443 is hardly ever blocked by routers and can thus be relied upon to be accessible.

 

On my server, incoming port 443 ssh connections are therefore redirected to sshd on port 22, while incoming https 443 connections are redirected to https port 444 on apache.

 

Apache must then be configured to listen on port 444 instead of the default 443.

 

 

sslh accepts connections on specified ports, and forwards them further based on tests performed on the first data packet sent by the remote client.

 

sslh acts as a protocol demultiplexer, or a switchboard. Its name comes from its original function to serve SSH and HTTPS on the same port.

 

First, install sslh:

 

apt install sslh

 

then in /etc/default/sslh

 

change:

 

#RUN=no
RUN=yes

 

and set the DAEMON_OPS to use the desired port for sslh and to forward to ssh:

 

Here we want incoming ssh connections to come in on port 444, and forward ssh calls to 22 and all other calls (which will be https for apache) to be forwarded to 444:

 

DAEMON_OPTS=”–user sslh –listen 0.0.0.0:443 –ssh 127.0.0.1:22 –ssl 127.0.0.1:444 –pidfile /var/run/sslh/sslh.pid”

 

so it will look like this:

 

root@gemini:/# cat /etc/default/sslh
# Default options for sslh initscript
# sourced by /etc/init.d/sslh

# Disabled by default, to force yourself
# to read the configuration:
# – /usr/share/doc/sslh/README.Debian (quick start)
# – /usr/share/doc/sslh/README, at “Configuration” section
# – sslh(8) via “man sslh” for more configuration details.
# Once configuration ready, you *must* set RUN to yes here
# and try to start sslh (standalone mode only)

#RUN=no
RUN=yes

# binary to use: forked (sslh) or single-thread (sslh-select) version
# systemd users: don’t forget to modify /lib/systemd/system/sslh.service
DAEMON=/usr/sbin/sslh

#DAEMON_OPTS=”–user sslh –listen <change-me>:443 –ssh 127.0.0.1:22 –ssl 127.0.0.1:443 –pidfile /var/run/sslh/sslh.pid”
DAEMON_OPTS=”–user sslh –listen 0.0.0.0:443 –ssh 127.0.0.1:22 –ssl 127.0.0.1:444 –pidfile /var/run/sslh/sslh.pid”
root@gemini:/#

 

then config systemctl to autostart sslh, then start sslh:

 

systemctl enable sslh
systemctl start sslh

 

Check that its running and listening correctly:

 

root@gemini:/# ps -ef | grep sslh
sslh 611 1 0 Jun28 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 0.0.0.0 443 –ssh 127.0.0.1 22 –tls 127.0.0.1 444 –pidfile /var/run/sslh/sslh.pid
sslh 612 611 0 Jun28 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 0.0.0.0 443 –ssh 127.0.0.1 22 –tls 127.0.0.1 444 –pidfile /var/run/sslh/sslh.pid
sslh 937 612 0 Jun28 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 0.0.0.0 443 –ssh 127.0.0.1 22 –tls 127.0.0.1 444 –pidfile /var/run/sslh/sslh.pid
sslh 1073 612 0 Jun28 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 0.0.0.0 443 –ssh 127.0.0.1 22 –tls 127.0.0.1 444 –pidfile /var/run/sslh/sslh.pid
sslh 9093 612 0 19:22 ? 00:00:00 /usr/sbin/sslh –foreground –user sslh –listen 0.0.0.0 443 –ssh 127.0.0.1 22 –tls 127.0.0.1 444 –pidfile /var/run/sslh/sslh.pid
root 9503 9199 0 20:00 pts/2 00:00:00 grep –color=auto sslh
root@gemini:/# netstat -tulpn | grep sslh
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 611/sslh
root@gemini:/#

 

then, you can access ssh by using:

 

ssh -p 443 username@server-ip

 

and sslh will forward the ssh connection to sshd on port 22 on the server

 

Don’t forget also you must reconfigure apache to listen on port 444 (/etc/apache2/ports.conf and the appropriate sites-enabled conf file – and restart apache after modifying the files).

 

 

sslh Syntax

sslh [ -t num ] [-p listening address] [-l target address for SSL] [-s target address for SSH] [-u username] [-P pidfile] [-v] [-i] [-V] [-f]

OPTIONS

-t num
Timeout before a connection is considered to be SSH. Default is 2s.
-p listening address
Interface and port on which to listen, e.g. foobar:443, where foobar is the name of an interface (typically the IP address on which the Internet connection ends up).

Defaults to 0.0.0.0:443 (listen to port 443 on all available interfaces).
-l target address for SSL
Interface and port on which to forward SSL connection, typically localhost:443.

Defaults to localhost:443 (this assumes you would configure your httpd process to listen to port 443).

Note that you can set sslh to listen on ext_ip:443 and httpd to listen on localhost:443: this allows clients inside your network to just connect directly to httpd.
-s target address for SSH
Interface and port on which to forward SSH connection, defaults to localhost:22.
-v
Increase verboseness.
-V
Prints sslh version.
-u username
Requires to run under the specified username. Defaults to nobody (which is not perfect — ideally sslh should run under its own UID).
-P pidfile
Specifies the file in which to write the PID of the main server. Defaults to /var/run/sslh.pid.
-i
Runs as an inetd server. Options -P (PID file), -p (listen address), -u (user) are ignored.
-f
Runs in foreground. The server will not fork and will remain connected to the terminal. Messages normally sent to syslog will also be sent to stderr.

 

 

root@gemini:/etc# systemctl status sslh
● sslh.service – SSL/SSH multiplexer
Loaded: loaded (/lib/systemd/system/sslh.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2022-03-22 14:58:58 UTC; 17min ago
Docs: man:sslh(8)
Main PID: 823 (sslh)
Tasks: 2 (limit: 2274)
Memory: 812.0K
CGroup: /system.slice/sslh.service
├─823 /usr/sbin/sslh –foreground ”–user sslh –listen 0.0.0.0 443 –ssh 127.0.0.1 22 –tls 127.0.0.1 4>
└─824 /usr/sbin/sslh –foreground ”–user sslh –listen 0.0.0.0 443 –ssh 127.0.0.1 22 –tls 127.0.0.1 4>

 

 

root@gemini:/etc# netstat -tulpn | grep sslh
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 823/sslh
root@gemini:/etc

 

 

 

A Note Regarding Apache and sslh

 

Note also that some programs, such as Lets Encrypt’s SSL Certbot SSL certificate sourcing program automatically define the https port as the default 443, so you then need to remove this and set it to 444, otherwise apache will not start.

 

Apache ports.conf needs to look like this. Note that port 443 is not used:

 

root@gemini:/etc/apache2# cat ports.conf
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 80

<IfModule mod_ssl.c>
#Listen 443
Listen 444
</IfModule>

 

The sites-enabled will also use 444 instead of 443 for virtual host definitions:

 

<VirtualHost 127.0.0.1:444>

ServerName kevwells.com
ServerAlias www.kevwells.com
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

 

Include /etc/letsencrypt/options-ssl-apache.conf

 

SSLCertificateFile /etc/letsencrypt/live/kevwells.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/kevwells.com/privkey.pem

 

</VirtualHost>
</IfModule>

 

 

Continue Reading