Setting up MariaDB for WordPress 4.9.4 on OpenBSD 6.2 part3

The Bitter DB …

Welcome back to installing WordPress 4.9.4 on OpenBSD 6.2.  In this installment we are going to install MariaDB for WordPress to use as a data store.  To be successful we will need to configure our Mariadb web access user to run as a socket in our chrooted environment, and secure the database against malicious users. To that end our goals are too:

  1. Install the MariaDB -10.0.32v1 required by WordPress
  2. Configure PHP to use the MariaDB libraries 
  3. Configure MariaDB to run correctly in a Chroot’d environment that httpd uses.

To test our MariaDB and httpds ability to talk to it through the php socket we will need to set up our testing environment.  We will be using two terminal sessions in two separate windows today:

  1. A “VPS” in which we will be starting httpd sessions in debug mode 
  2. A “Maintenance” widow to be used to make any changes to your configuration files etc.

Open a ssh connection using you Client window to your VPS as our beloved ”bob” and su to root.  We will need root privileges to make our changes.

Now we will need to make some test files.  The first test file will make sure curl is functioning through the php socket by making a connection to WordPress.org.  In your Maintenance window using your favorite editor create  file in /var/www/htdocs called test_curl.php.

Vi /var/www/htdocs/test_curl.php

Paste the following into the file.

<?php
$_h = curl_init();
curl_setopt($_h, CURLOPT_HEADER, 1);
curl_setopt($_h, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($_h, CURLOPT_HTTPGET, 1);
//curl_setopt($_h, CURLOPT_URL,'https://jetpack.wordpress.com' );
curl_setopt($_h, CURLOPT_URL,'https://planet.wordpress.org' );
curl_setopt($_h, CURLOPT_DNS_USE_GLOBAL_CACHE, false );
curl_setopt($_h, CURLOPT_DNS_CACHE_TIMEOUT, 2 );
var_dump(curl_exec($_h));
var_dump(curl_getinfo($_h));
var_dump(curl_error($_h)); 
?>

And save the file.  As you can see, it instantiates a curl object, loads some basic properties, executes the connection and dumps the results of the connection, the configuration details and any errors.

The second test file we will create test the MariaDB connection through the PHP socket.   In your Maintenance window using your favorite editor create  file in /var/www/htdocs called test_mysql.php.

Vi /var/www/htdocs/test_mysql.php

Paste the following into the file.

<?php
$user = “’your mysql user’”;
$pwd = “your password”;
$host = "127.0.0.1";
$db = “your database name“;
$link = mysqli_connect("$host", "$user", "$pwd" , "$db");
if (!$link) {
   echo "Error: Unable to connect to MySQL using user as $user and password as $pwd ." . PHP_EOL;
   echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
   echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
   $time = time();
   $hash = md5(“your email”  . time() . mt_rand() );
   echo "hash = $hash" . PHP_EOL;
   echo "time = $time" . PHP_EOL;
   exit;
}

echo "Success: A proper connection to MySQL was made using user as $user and password as $pwd! The my_db database is great." . PHP_EOL;
echo "Host information: " . mysqli_get_host_info($link) . PHP_EOL;
$time = time();
$hash = md5( $value . time() . mt_rand() );
echo "hash = $hash" . PHP_EOL;
echo "time = $time" . PHP_EOL;
mysqli_close($link);
?>

You will need to update the “your mysql user”, “your password”, “your database name”, and “your email” with valid values once you have that information before we can test with this file.

Lets install the MariaDB.  Now that we have the PKG system setup, we just need to query our Mirror to see if they have the MariaDB we want to install.  But first lets refresh our memory on what we have installed from Setting up WordPress on OpenBSD 6.2 part2 by using pkg_info

pkg_info

Returns:

colorls-6.0         ls(1) that can use color to display file attributes

curl-7.55.1         get files from FTP, Gopher, HTTP or HTTPS servers

femail-1.0p1        simple SMTP client

femail-chroot-1.0p2 simple SMTP client for chrooted web servers

gettext-0.19.8.1p1  GNU gettext runtime libraries and programs

jpeg-1.5.1p0v0      SIMD-accelerated JPEG codec replacement of libjpeg

libiconv-1.14p3     character set conversion library

libxml-2.9.5        XML parsing library

mariadb-client-10.0.32v1 multithreaded SQL database (client)

nghttp2-1.26.0      library for HTTP/2

php-7.0.23          server-side HTML-embedded scripting language

php-curl-7.0.23     curl URL library extensions for php5

php-gd-7.0.23       image manipulation extensions for php5

php-mysqli-7.0.23   mysql database access extensions for php5

png-1.6.31          library for manipulating PNG images

quirks-2.367        exceptions to pkg_add rules

xz-5.2.3p0          LZMA compression and decompression tools

But what’s this?  The MariaDB is already installed?  Well, not the part we need.  What your seeing is the mariadb-client-10.0.32v1 multithreaded SQL database (client) which was an install requirement for “php-mysqli-7.0.23   mysql database access extensions for php5.“(See pkg_info section in the Setting up WordPress on OpenBSD 6.2 Part 2 on install requirements)  We need the “server” component for the mariadb as well. Lets check for that on the mirror:

pkg_info -Q mariadb

Returns:

mariadb-client-10.0.32v1 (installed)

mariadb-server-10.0.32v1

mariadb-tests-10.0.32v1

Lets install the matching server component

pkg_add mariadb-server-10.0.32v1

As you saw, there are a lot of components to the mariadb install.  You are also encouraged to read the /usr/local/share/doc/pkg-readmes/ for the mariadb-server-10.0.32v1 install.  Do so.  One of the first things you are asked to do in the /usr/local/share/doc/pkg-readmes/mariadb-server-10.0.32v1 is to run the /usr/local/bin/mysql_install_db in order to create the default database.

/usr/local/bin/mysql_install_db

Unfortunately, “/usr/local/share/doc/pkg-readmes/mariadb-server-10.0.32v1” makes no mention of /usr/local/bin/mysql_secure_installation which runs you through some basic security setup needed for mariadb to run on a production server.  Good thing the /usr/local/bin/mysql_install_db does.  But before we can do that process we need to enable the mysql daemon.

rcctl enable mysqld

Now start the mysqld daemon

rcctl start mysqld

Now execute the mysql_secure_installation 

/usr/local/bin/mysql_secure_installation

You are now presented with a series of questions:

  1. “Enter the current password for root (enter for none):” Press Enter.
  2. “Set root password?” [Y/n]” Use your password vault to generate and store a password for the mysql root login, then enter it here and hit enter.
  3. “Remove anonymous users? [Y/n]”  Enter “Y”, we do not want anonymous users on our system.
  4. “Disallow root login remotely? [Y,n]” Enter “Y”, never let root have direct access to anything. Always login in with a low level user and then elevate your privileges.
  5. “Remove test database and access to it? [Y/n]” Enter “Y”, test databases are for a test environment.
  6. “Reload privilege tables now? [Y,n]” Enter “Y”, this activates all of our changes immediately.

You should now be at the command prompt.  Lets test your “root” login by using the mysql client

mysql -u root -p <your root password>

You should have a mysql prompt if everything went as planned.  Now lets exit back out to the terminal by typing quit.

quit

Now let tell php all about mysql by editing the /etc/php-7.0.ini…

vi /etc/php-7.0.ini

…and scroll down to the extension section, it looks a lot like this:

;;;;;;;;;;;;;;;;;;;;;;

; Dynamic Extensions ;

;;;;;;;;;;;;;;;;;;;;;;

; If you wish to have an extension loaded automatically, use the following

; syntax:

;

;   extension=modulename.extension

;

; For example, on Windows:

;

;   extension=msql.dll

;

; … or under UNIX:

;

;   extension=msql.so

;

; … or with a path:

;

;   extension=/path/to/extension/msql.so

;

; If you only provide the name of the extension, PHP will look for it in its

; default extension directory.

;

; Windows Extensions

; Note that ODBC support is built in, so no dll is needed for it.

; Note that many DLL files are located in the extensions/ (PHP 4) ext/ (PHP 5+)

; extension folders as well as the separate PECL DLL download (PHP 5+).

; Be sure to appropriately set the extension_dir directive.

;

;extension=php_bz2.dll

;extension=php_curl.dll

;extension=php_fileinfo.dll

;extension=php_ftp.dll

;extension=php_gd2.dll

Verify the path to the mysqli.so using find.

find / -name mysqli.so

Add the path returned by Find at the end of the extension section as in this example:

extension=/usr/local/lib/php-7.0/modules/mysqli.so

Save the file.  Now lets do a little testing.  In your VPS window make sure your running as root.  Now lets start or httpd in debug (-d) mode with verbosity turned to medium (-vv) using our httpd_config.test (-f /etc/httd_config.test)

httpd -d -vv -f /etc/httpd_config.test

Open up your web browser and point it to http://<IP address of your server>.   You should see the out put of the phpinfo() function.  Notice that there is now a section called mysqli curtesy of mysqli.so.

Type ctrl+c to shutdown the httpd daemon.

Lets add a database and a user to mysql for WordPress to use.  At you terminal command prompt login as root to mysql

mysql -u root -p <your root password>

Lets create a database called wp_website1.  Type the following:

Create database wp_website1;

Now lets create a user that can access wp_website1 for WordPress to use.  First generate a pass word in your password vault and save it then use it in the following query.  Type the following:

Create user ‘wp_user’@‘127.0.0.1’ identified by ‘your_password_from_vault’;

Do not use ‘localhost’, use ‘127.0.0.1’ to force mysql to use the database socket for this user.  The /var/run/mysql/mysql.sock is the only way for our chroot’d environment to talk to mysql.

Lets grant wp_user rights to do things on wp_website1

Grant all on wp_website1.* to ‘wp_user’@‘127.0.0.1’;

Now exit mysql by typing quit.

Lets edit the /var/www/htdocs/test_mysql.php file and enter in your wp_user, password, database name and email information; being mindful that the user has both double and single quotes around the name and that some meta-characters like “$” need to be escaped with a leading “\” if they are used in the password.

Great, lets test our database connection.  In your VPS window start up you httpd daemon.  

httpd -d -vv -f /etc/httpd_config.test

In Your Maintenance window restart php and mysql

rcctl restart mysqld
rcctl restart php70_fpm

Now in you web browser enter the following URL http://“your IP address”/test_mysql.php.  You should see something like the following:

Success: A proper connection to MySQL was made using user as ‘wp_user’ and password as <your password> The my_db database is great. Host information: 127.0.0.1 via TCP/IP hash = f133bb3bf8278ec4eb48ae1fdff56382 time = 1521508293

While we are at it lets finish up the curl component.  Curl is installed, but since it operates in a chroot it needs a few pieces moved into /var/www in order to be able to grab external url’s. Those pieces are the following:

/etc/resolv.conf

/etc/services

/etc/ssl

Remember we are in a chroot environment and the root for that environment is /var/www.  We need to keep the same directory relationship here so we need to add /var/www to each destination. We will do that using mkdir and cp:

mkdir -p /var/www/etc
mkdir -p /var/www/etc/ssl/lib
mkdir -p /var/www/etc/ssl/private
cp /etc/resolv.conf /var/www/etc/resolv.conf
cp /etc/services /var/www/etc/services
cp -R /etc/ssl /var/www/etc/

Now we can test curl.  In your VPS window start up you httpd daemon.  

httpd -d -vv -f /etc/httpd_config.test

In Your Maintenance window restart php.

rcctl restart php70_fpm

Now in you web browser enter the following URL http://“your IP address”/test_curl.php.  You should see something like the following:

string(130999) “HTTP/1.1 200 OK Server: nginx Date: Tue, 20 Mar 2018 18:32:01 GMT Content-Type: text/html Content-Length: 130714 Connection: keep-alive Vary: Accept-Encoding Last-Modified: Tue, 20 Mar 2018 18:30:27 GMT X-Frame-Options: SAMEORIGIN X-nc: EXPIRED ord 1 Accept-Ranges: bytes

And the web page for WordPress.org should display blow that.

Ok lets shut down our services to secure our server until next time:

ctrl+c in your VPS window to stop our debug httpd.
rcctl stop php70_fpm
rcctl stop mysql

Not bad!  Lets summarize our achievements today…

  1. We created test scripts to verify php-curl and MariaDB functionality through php and httpd
  2. We installed MariaDB, and setup a user for WordPress to use with the appropriate permissions and socket access through php
  3. Finished setting up the curl component for php
  4. And verified base MariaDB connectivity and curl functionality with our scripts.

Another good days work.  Stay tuned, much more to come.

Setting up httpd, PHP, PKG, chroot for WordPress 4.9.4 on OpenBSD 6.2 part2

PKG, Chroot, PHP oh my!

Welcome back to Installing WordPress 4.9.4 on OpenBSD 6.2.  In this installment we are going to look into enabling the httpd web server on OpenBSD 6.2, install php-7.0.23 and its associated components needed for serving WordPress PHP content.  Our goals for this post is to:

  1. Go over the PKG system for installing applications
  2. Discuss Chroot and httpd daemon
  3. Set up the PKG system to pull the binaries we require
  4. Install the php-7.0.23 components we need
  5. Configure php
  6. Configure and test the httpd_config.test file to server both html and php

Much like we did with ssh,  we will test our php installs and the web server httpd using a combination of windows.  We will be using two terminal sessions in two separate windows today:

  1. A “VPS” in which we will be starting httpd sessions in debug mode 
  2. A “Maintenance” widow to be used to make any changes to your configuration files etc.

Open a ssh connection using you Client window to your VPS as “bob” and su to root.  We will need root privileges to make our changes.

Lets create a test httpd configuration file to try our new changes in.  We will call this test httpd config file httpd_config.test.  To make the httpd_config.test, simply use “cp” to make a copy of /etc/examples/http.config to a new name and place it into the /etc directory.  The /etc/examples directory has a bunch of sample scripts to use as starting points.  Just remember to never use one directly, make a copy and place it in /etc before editing.

cp /etc/examples/httpd.config /etc/httpd_config.test

Now edit the /etc/httpd.conf file in your favorite text editor to look like this:

# $OpenBSD: httpd.conf,v 1.14 2015/02/04 08:39:35 florian Exp $
#
# Macros
#
ext_addr="*"
#
# Global Options
#
# prefork 3
#
# Servers
#
# A minimal default server
server "default" {
        listen on $ext_addr port 80
        root “/htdocs”
directory index “index.html”
}
types {
        include "/usr/share/misc/mime.types"
}

This tells the httpd daemon to listen on all external IP addresses and take http requests on port 80 and process them by executing the index.html file located in /var/www/htdocs using the mime type located in the file /usr/share/misc/mime.types”

We will change the httpd.conf to process requests properly in the future, but for now, this will get us up and testing.  Now in your editor create the /var/www/htdocs/index.html file and copy this into it:

<html>
  <body>
    <h1>This is my index.html test page</h1>
  </body>
</Html>

And save it.  Now it’s time to test.  

<Test>

In your VPS window make sure your running as root.  Now lets start or httpd in debug (-d) mode with verbosity turned to medium (-vv) using our httpd_config.test (-f /etc/httd_config.test)

httpd -d -vv -f /etc/httpd_config.test

Open up your web browser and point it to http://<IP address of your server>.  You should see in rather large letters “This is my index.html test page” displayed.  Now shut off the httpd debug session using ctrl+c in the VPS window.

</Test>

As we build up our system we will be performing similar tests to verify we have a working system as we configure each piece.

 

$PKG_PATH

Before we can install anything we will need to setup the Package Management(PKG) system on our VPS.  The PKG system is a collection of application and libraries the OpenBSD Ports Team has ported to the OpenBSD platform.   This collection has been vetted to the best of their abilities for security vulnerabilities and to insure compatibility with the OS itself.  An application may have dependencies on other binaries.  An application package when installed will check for those dependencies and will ask you if it can install them, if you agree, then it does.  In this way you get a completely installed program that uses shared dependencies with other programs, so it does not have to install the same file twice.  PKG relies on Mirrors which are stores located around the world of applications installs that are downloaded via HTTP or FTP protocol.  You must first setup the environment variable $PKG_PATH to a suitable Mirror near you that contains the binaries you are after,  and not all Mirrors contain the same applications so sometime you will need to look around.  I used the Mirror out of Boulder, Colorado ftp://ftp3.usa.openbsd.org/pub/OpenBSD/.  

You need to provide a complete path to the package store which looks something like this “ftp://ftp3.usa.openbsd.org/pub/OpenBSD/6.2/packages/amd64/”.  But if you back up your user directories  like I do you will want to make this path dynamic incase you upgrade your OpenBSD to a newer version.  Restoring your root directory to the new system would point you to the wrong Mirror if this is hardcoded.  So lets make this dynamic:

Connect to your VPS with your Maintenance window as bob and su to root and change directory to roots home directory

Cd ~

In your favorite editor open the “.profile”.  Add the following lines after the export PATH statement

PKG_PATH=ftp://ftp3.usa.openbsd.org/pub/OpenBSD/`uname -r`/packages/`uname -m`/
export PKG_PATH

On system startup or login, this loads a PKG_PATH variable for the root user only (because who else should be installing software on a server?) and exports it for use on the system.  The `uname -r` sets the current version of the OS and the `name -m` sets the processor sku that was installed dynamically.  Now you can copy the root .profile file to any server and the PKG_PATH will point to the correct package location.  Now exit out of root and su back in with the login switch (-l) so the .profile is reloaded then echo the PKG_PATH to confirm our change:

exit
su root -l
echo $PKG_PATH

In my case I get “ftp://ftp3.usa.openbsd.org/pub/OpenBSD/6.2/packages/amd64/” where “6.2” and “and64” are provided by the `uname -r` and `name -m` respectively.

 

chroot

A quick word about chroot, sometimes referred to as a “sandbox” and often incorrectly referred to as a “jail”.  Chroot (short for change root) is a process where a given user or process is constrained to a subtree of a directory structure.  Once “chrooted” the process cannot see above the subtree and the top most path is now “/“.  This keeps malicious users or bad code from trashing the whole file system as they cannot see or access anything outside of the chroot.  The OpenBSD web server httpd runs under /var/www/ and is chrooted to /var/www.  From httpds perspective, it runs under /.  It cannot see above /var/www. Here is an example:

 

This is the directory structure of /var.

This is what httpd chrooted to /var/www sees

/var

   |-Account

   |-audit

   |-authpf

   |-backups

   |-cache

   |—fontconfig

   |-crash

   |-cron

   |—atjobs

   |—tabs

   |-db

   |—acpi

   |—ldap

   |—ns

   |—pkg

   |—–colorls-6.0

   |—–quirks-2.367

   |—xkb

   |—yubikey

   |-empty

   |-games

   |—hackdir

   |—–save

   |—phantasia

   |—save

   |-log

   |—rdist

   |-mail

   |-nsd

   |—db

   |—etc

   |—run

   |—–xfr

   |—zones

   |—–master

   |—–slave

   |-quotas

   |-run

   |—rc.d

   |-spool

   |—ftp

   |—–bin

   |—–etc

   |—–hidden

   |—lock

   |—output

   |—–lpd

   |—smtpd

   |—–corrupt

   |—–incoming

   |—–offline

   |—–purge

   |—–queue

   |——-36

   |——-9c

   |—–temporary

   |-sysmerge

   |-syspatch

   |-unbound

   |—db

   |—etc

   |-www

   |—acme

   |—bin

   |—cache

   |—cgi-bin

   |—conf

   |—htdocs

   |—–bgplg

   |—logs

   |—run

   |-yp

/

   |-acme

   |-bin

   |-cache

   |-cgi-bin

   |-conf

   |-htdocs

   |—bgplg

   |-logs

   |-run

Chroot generally means two things to us.  The first thing is that we have greatly reduced the threat surface of a malicious web user.  The second thing is, as we will see later, if we need anything outside of the chroot we need to copy it into the chroot to use it.  There are exceptions such as sockets but for the most part, you are confined to the chroot.  However it is not fool proof and should never be considered a “Jail”.

Ok lets load the PHP packages we need for this project. Here is the list of applications we will need to grab:

php-7.0.23 – base PHP package
php-gd-7.0.23 – PHP
image manipulation extensions
php-mysqli-7.0.23 – PHP
mysql database access extensions

php-curl-7.0.23 – PHP command line Universal Resource Locator that allows you to connect and communicate to those interfaces

The primary tools we will use for loading packages onto our system are pkg_info and pkg_add.  

 

pkg_info

Pkg_info will allow us to query our Mirror to see whats available among other capabilities. An example of this would be “pkg_info -Q ”<name>  searches for all packages with <name> in the name.  Do not include the version number in the query.  Found one your curious about?  Type pkg_info -q <name> and you’ll get a brief synopsis of what it is for.  For example:

To find all php packages available on your Mirror…

pkg_info -Q php

Returns a list of applications with “php” in the name:

drupal6-phpmailer-2.2p2
gpsd-php-2.95p8
p5-PHP-Serialization-0.34
p5-PHP-Session-0.27
pear-Date-Holidays_PHPdotNet-0.1.2p1
php-5.5.37p0
php-5.6.23p0
php-7.0.23
…

To find out what, say, php-7.0.23 is all about (mind the “q” – size matters here)…

pkg_info -q php-7.0.23

Returns a synopsis of that package:

server-side HTML-embedded scripting language

php-curl-7.0.23
php-gd-7.0.23
php-mysqli-7.0.23

At the most basic level, PHP can do anything any other CGI program can
do, such as collect form data, generate dynamic page content, or send
and receive cookies.

PHP also has support for talking to other services using protocols such
as IMAP, SNMP, NNTP, POP3, or even HTTP. You can also open raw network
sockets and interact using other protocols.

This package installs a stand-alone binary which can be used for
command-line scripts, as well as an Apache module. It also contains the
pdo_sqlite driver that implements the PHP Data Objects (PDO) interface
to enable access to SQLite 3 databases.

Maintainer: Robert Nagy <robert@openbsd.org>

WWW: http://www.php.net/

Don’t be fooled, the php applications listed in the synopsis are not dependencies,  they are just part of the synopsis, included at the authors discretion.  If you want to see the dependencies,  we have a switch (-f) for that.  But it dumps everything about the package, we will need to filter it a bit using grep:

pkg_info -f php-7.0.23 | grep ‘^@depend’ | cut -f 3 -d :

Returns:

gettext-0.19.7
femail-chroot-1.0p2
libxml-2.9.3

Bare in mind each dependency most likely has its own list of dependencies it needs to install.

Now you know what php-7.0.23 is and what it is used for and what will get installed besides php-7.0.23 to make php-7.0.23 work correctly.  Kinda cool huh?

 

pkg_add

Pkg_add will install (or update) an application.  It also has some useful switches but I leave those up to you dear reader to explore.  To use pkg_add is fairly simple:

pkg_add -n php-7.0.23

Will show what would be installed but does not do the install and list the dependencies of the package to be installed with a extraction progress indicator by %.  It will tell you if any new scripts were installed in /etc/rc.d and where to look in /usr/local/share/doc/pkg_readmes for extra documentation 

pkg_add php-7.0.23

Installs the package and gives you the same output as  pkg_add -n php-7.0.23. You can list several packages on the same call to pkg_add.  I prefer to call them one at a time.

Ok onto the installs.  This is the easy part because a lot of developers who donate their time to the OpenBSD project have made it that way.  In your terminal as root run the following commands:

pkg_add php-7.0.23
pkg_add php-curl-7.0.23
pkg_add php-gd-7.0.23
pkg_add php-mysqli-7.0.23

To see everything that has bee installed on your system, typing pkg_info by itself will give you a list of everything currently installed:

pkg_info

Returns:

colorls-6.0         ls(1) that can use color to display file attributes
curl-7.55.1         get files from FTP, Gopher, HTTP or HTTPS servers
femail-1.0p1        simple SMTP client
femail-chroot-1.0p2 simple SMTP client for chrooted web servers
gettext-0.19.8.1p1  GNU gettext runtime libraries and programs
jpeg-1.5.1p0v0      SIMD-accelerated JPEG codec replacement of libjpeg
libiconv-1.14p3     character set conversion library
libxml-2.9.5        XML parsing library
mariadb-client-10.0.32v1 multithreaded SQL database (client)
nghttp2-1.26.0      library for HTTP/2
php-7.0.23          server-side HTML-embedded scripting language
php-curl-7.0.23     curl URL library extensions for php5
php-gd-7.0.23       image manipulation extensions for php5
php-mysqli-7.0.23   mysql database access extensions for php5
png-1.6.31          library for manipulating PNG images
quirks-2.367        exceptions to pkg_add rules
xz-5.2.3p0          LZMA compression and decompression tools

We now have our php components installed.  But before we can use them we have to configure them.  To do that we need to:

  1. Set up an /var/www/htdocs/index.php to test with
  2. Alter the /etc/httpd_config.test file
  3. Create the empty /etc/rc.conf.local file
  4. Enable and start the php daemon.
  5. Check your work using your web browser
  6. Configure curl in php7.0.ini
  7. Check your work using your web browser to see if curl was configured.

Lets create the /var/www/htdocs/index.php by using touch.

touch /var/www/htdocs/index.php

Now using your favorite editor change the empty file contents to:

<?php phpinfo(); ?>

Save Index.php.  Now edit /etc/httpd_config.test and change the contents of the server block  to the following:

# A minimal default server
server "default" {
        listen on $ext_addr port 80
        root "/htdocs"
#       directory index "index.html"
        directory {
                index "index.php"
        }
        location "*.php" {
                fastcgi socket "/run/php-fpm.sock"
        }
}

Save the /etc/httpd_config.test.  Now lets enable PHP.  We need to make a /etc/rc.conf.local using touch.

Touch /etc/rc.conf.local

Now using rcctl we will enable php fastcgi socket to run

rcctl enable php70_fpm

You can check the /etc/rc.conf.local file,  you should see one line in there that looks like this:

pkg_scripts=php70_fpm

Start the php70_fpm using rcctl

rcctl start php70_fpm

Start your httpd debug session in its own window as we did before.  Open up your web browser and point it to http://<IP address of your server>.    You should see the rather large summary of php components available to your web service.  But we are missing the “command line URL” processor or “curl” component.  We need to configure that in the /etc/php-7.0.ini.  Open the /etc/php-7.0.ini and scroll down to the extension section, it looks a lot like this:

;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
; If you wish to have an extension loaded automatically, use the following
; syntax:
;
;   extension=modulename.extension
;
; For example, on Windows:
;
;   extension=msql.dll
;
; ... or under UNIX:
;
;   extension=msql.so
;
; ... or with a path:
;
;   extension=/path/to/extension/msql.so
;
; If you only provide the name of the extension, PHP will look for it in its
; default extension directory.
;
; Windows Extensions
; Note that ODBC support is built in, so no dll is needed for it.
; Note that many DLL files are located in the extensions/ (PHP 4) ext/ (PHP 5+)
; extension folders as well as the separate PECL DLL download (PHP 5+).
; Be sure to appropriately set the extension_dir directive.
;
;extension=php_bz2.dll
;extension=php_curl.dll
;extension=php_fileinfo.dll
;extension=php_ftp.dll
;extension=php_gd2.dll
…

Verify the path to the curl.so using find.

find / -name curl.so

Add the following line at the end of the extension section:

extension=/usr/local/lib/php-7.0/modules/curl.so

Save the /etc/php7.0.ini and restart php using rcctl

rcctl restart php70_fpm

Start your httpd debug session in its own window as we did before.  Open up your web browser and point it to http://<IP address of your server>.  You should see the rather large summary of php components available to your web service, including a section called “Curl”.  This  good as WordPress uses curl to process requests for plugins and themes.

 

Ok, enough fun for today.  Lets shutdown our httpd by executing a ctrl+c in the window running it.  The php daemon will now start automatically when the server is restarted.  If you want to shut php down as well, use rcctl.

rcctl stop php70_fpm

The httpd will be enabled later using rcctl after we have a working WordPress install.

It is better to keep your web server offline until you have it secured against malicious intruders.

So today we have accomplished quite a lot.  I went over the PKG system, how to configure it and some basic techniques on how to use it.  I discussed httpd daemon and the chrooted environment it runs in.  We set up the httpd_config.test file for testing our httpd configuration and ran it in debug mode as we tested first HTML file and later PHP file serving.  We installed all of our php components, created the rc.conf.local file and enabled php and configured CURL and the php70_fpm fastcgi socket to work in our chrooted httpd environment. All in all a good day.

Setting up sshd for WordPress 4.9.4 on OpenBSD 6.2 – part1

plumbing behind sshd on OpenBSD

sshd, a n00bs tail …

What better way to start a blog than to share how I built the OpenBSD server that hosts WordPress on it.  Or more specifically, how I started by setting up sshd securely.  This will be a multi-part series of posts that covers the major pain points I went through. Plus, I have all that learning from my previous build to post that I, er, didn’t .. write down. God damn it. Well, this time it will be different.

I should point out that this is not a “How To” on building and configuring a OpenBSD server. This series is about getting WordPress installed on a OpenBSD server in a reasonably secured fashion. Visit the OpenBSD.org site to learn more about building a OpenBSD server. I also use a iMac and am quite familiar with using terminal windows. If your using MS Windows, my condolences, they make some fine products, their operating systems however, was never one of my favorites.

NOTE: I HIGHLY recommend acquiring a password vault like 1Password. You will be needing to save many crucial logins and passwords before we are done with this series.

Now, where to house the new Server? My house was definitely out.

1. I had  no protection from power outages (and I live in a high wind area)

2. The monthly costs of having a business line through my ISP was high yet they had a sketchy service history

3. No redundancy in the event of hardware failure

4. I would have to buy hardware

5. Having to keep the server up 24/7

So I decided to rent space and build a virtual private server (VPS) on Vultr.com which provide the following benefits:

1. Power outages were no longer an issue

2. The current monthly charges are around $8.00/mo.

3. It is a VPS, hardware issues should be non-existent from where I’m sitting

4. I didn’t have to buy the Data center grade hardware

5. Server up time is “always” with some maintenance windows and or I touch it in un-professional ways.

The best part is Vultr.com host OpenBSD 6.1 OS out of the box! Easy Peasy, Weasy. They even had an ISO available that had 6.2, which I used, that took me through the traditional setup procedure.

I went to GoDaddy.com and reserved my domain, then off to Vultr.com to set up my Vultr.com account and setup my OpenBSD server in like 2 minutes using Vultr.com website. A very convenient experience.

But before we start setting up WordPress lets make our server a little more secure so no one trashes our hard earned creation by securing SSH access. Here are our goals, simply put, we want to prevent a malicious user trying to attack our box through SSH by using the following techniques.

1. Every *nix box has the administrative user “root”. We want to prevent the user “root” from logging into our box to make guessing an admin user easy. Users can only use a low level account to login with which means they have to guess the account name and are not an admin if they gain access. There is a good probability that the user they guessed cannot elevate their permissions to root level.

2. All SSH sessions use port 22 to connect the server, Script Kiddies scan IPs for a port 22 that responds to brute force SSH login requests. We will make SSH listen to another port to keep login scans on port 22 from filling our logs.

3. SSH provides us the ability to use encrypted RSA keys. RSA keys uniquely identify a user by having the public key on our VPS hosting our website and the private key on the users local server. Both keys share the same passphrase. With this setup, a user must have the appropriate private key on the box they are establishing a connection with and the correct passphrase. It is known as two factor authorization.

4. Password only connections will not be allowed. We will deny all connections that do not utilize a RSA key for access.

Ssh stands for Secure SHell and has two main programs. The server side secure shell daemon (sshd) and the client side secure shell (ssh) you connect to the server with.

SSHD

Being a daemon (or service for you windows users) sshd and is located on /etc/rc.d/sshd and is started at boot time if enabled, which it is by default. On startup sshd uses it’s config file /etc/ssh/sshd_config to tell it how to run and what security to impose on each session that is connecting to the Openbsd server – which is currently minimal. It is this configuration file we will be updating to secure our connection to our OpenBSD.

SSH

To connect the a remote sshd we use the ssh client program which is located on  /usr/bin/ssh on a *nix desktop. We will be using three terminal sessions in three separate windows today

1. A “VPS” in which we will be starting SSHD sessions in debug mode

2. A “Client” where we will be connecting to the SSHD debug sessions to test settings and making changes to the sshd debug configuration file.

3. A “Maintenance” widow and is used in the event that your production sshd_config gets set incorrectly and no longer allows connections, this is your failsafe. it can also be used to make any changes to your sshd_config.test file.

You should be able to connect as “root” to your server at this point. Do so now using your “Maintenance” window. You will need to add a low level user to OpenBSD to use as the ssh login later. We shall call our low level user “bob” in this tutorial, you can call him anything you like.  Make sure you add that user to the “wheel” group when prompted for default login group.  The wheel group contains the users who are allowed to elevate themselves to “root”, the almighty, an probably other things I have yet to discover.  “root” can do anything, including dropping your server like a hot rock and giving you the opportunity to re-build it from scratch; always type wisely when using root privileges .

Lets give bob a password…

passwd bob

…enter and confirm a password for bob. Make sure both “bob” and root have secure passwords which you of course added to your password vault.  You’ll thank me later.

Time to setup our testing environment. Making changes to our new servers /etc/ssh/sshd_config file directly is dangerous without testing those changes first, you can lock yourself out of your own server. To avoid that awkwardness, we are going to make a test /etc/ssh/sshd_config.test file. We can then test our changes to the sshd before we commit to them by using the -f switch to point to a different config file. We will then test each change and verify we get the result we want and we do not loose access to our server. After we are satisfied that all of our changes meet our needs, we will swap out the sshd_config file with the sshd_config.test and restart the servers sshd daemon. At that point our changes will be live and in production.

Open a ssh connection using you Client window to your VPS as “bob” and su to root to test to see if you have a valid user that you can ssh in with and verify that your user is in the “wheel” group. We will need root privileges to make some of our changes later.

Lets create a test sshd configuration file to try our new changes in and to prevent those changes from locking us out of our server. We will call this test sshd config file sshd_config.test. To make the sshd_config.test, simply use “cp” to make a copy of sshd_config to a new name.

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.test

Now we want to start a new test ssh daemon using the /etc/ssh/sshd_config.test  but use a new port as two sshd processes cannot share the same port. We are using the file switch (-f) so we use our new test config file and debug switch (-d[dd]) so we can see the connection process. Multiple “d” increase the verbosity of the debug output. The maximum is 3. The port switch (-p) will keep us from trying to use the default port 22 and instead use port  44433. After testing, If you type ctrl+c it will kill the sshd process and clean up the connections for you. You should ssh as bob in the Client window to your server and then su to root privileges.

<begin test>

In the VPS window end your sshd session (type ctl+c) if you have one. In the Client window exit your ssh connection (type exit+<Enter>) if you have one. Back in the VPS window, as root, start your debug ssh daemon:

/usr/sbin/sshd -f /etc/ssh/sshd_config.test -p 44433 -d

In the Client  window connect to your VPS on the test port.

ssh bob@12.345.67.899 -p44433

if you successfully connect to the debug sshd, stop your sshd by going to the VPS terminal window it is running in and type ctrl+c thus shutting down the sshd using the /etc/ssh/sshd_config.test. This will terminate your connection in the Client window too.

<end test/>

You will want to repeat the above test after you make each change or every couple of changes to your sshd_config.test file. Using the above setup guarantees you will not “lock” yourself out of your own server.

Let address out first goal – Prevent root from logging in. Re-start VPS sshd using sshd_config.test as shown in the <test> above.  In the Client window connect to your server as bob and elevate bob to root. When OpenBSD is distributed, all if its configuration files are set with the defaults listed but commented out using the “#” comment character. Though it looks like these options are not in use, they are the defaults. Using your favorite editor open the sshd_config.test and perform the following:

Uncomment “#PermitRootLogin prohibit-password” (# is the comment  character; delete it) set it to “PermitRootLogin no” this prevents root from using ssh to login directly to your OS even if they have a RSA key.

Save your your changes to the  sshd_config.test. Time to test. Re-start your sshd in your VPS window.

/usr/sbin/sshd -f /etc/ssh/sshd_config.test -p 44433 -d

… but connect as the root user in the Client window.

ssh root@12.345.67.899 -p44433  

You should get “permission denied” this time.  Re-attempt your Client login using bob.

ssh bob@12.345.67.899 -p44433

You should get ssh welcome screen. You have now prevented a malicious user from trying to login in with the one known user on most *nix boxes, “root”. It should be noted that your Maintenance window is still up and connected as root. This will still be the case but all future connections will prevent root as a login user.

Lets address our second goal – make sshd listen to another port to keep login scans on port 22 from filling our logs.  In the Client window connect to your server as bob and elevate bob to root. Using your favorite editor open the sshd_config.test and perform the following:

Un-comment the “#Port 22” port setting (# is the comment  character;    delete it) and set the port from 22 to another number to keep script kiddies from trying gain access through the default ssh port and filling your logs with those annoying attempts.  You can use “netstat -nat | grep LISTEN” to see which ports is currently in use and pick a different one.  Aim for a high number like i did in the example to avoid conflicts. The port setting should look like this

Port 44433

Save your your changes to the  sshd_config.test. Time to test. Re-start your sshd in your VPS window. But we do not need the “-p” switch this time as it has been set in the sshd_config.test file.

/usr/sbin/sshd -f /etc/ssh/sshd_config.test -d

… Connect using your Client window as bob. You still need to force the port to 44433 from the client.

ssh bob@12.345.67.899 -p44433

You should get ssh welcome screen. You now have prevented IP scans for ssh port 22 from filling your logs.

Lets address our third goal – setting up two factor authentication based on RSA keys. RSA keys are an authorization mechanism where the private key sits on your local server and the other public key is installed on all the servers you wish to authenticate too. RSA keys can have a passphrase (yes, phrases such as “You’ve Cat to be Kitten Me Right Meow!”) added to make them a  two factor authorization mechanism which I recommend for this application.  We will use RSA keys to stop anyone from logging in through ssh without a private key on their server.  If they manage to acquire a copy of your private key they will still need the passphase.  The private key can be transferred to another computer(s) so you can use this key on multiple computers to access the remote servers if you desire.

On your local computer use your Maintenance window move to your user .ssh directory (ex: CD ~/.ssh) or /home/<your login>/.ssh

To make a RSA_ID key we will need to invoke ssh-keygen and pass a filename(-f) switch to tell ssh-keygen what file name to use.  Type the following (you can use another file name other than “bob_rsa_id”):

ssh-keygen -f bob_rsa_id

When prompted for a RSA_ID  passphrase type one in (and store that in your password vault, see I told you you would thanks me latter…).   This will generate a public and a private key of 2048 bits. bob_rsa_id is your private key that need to stay in your .ssh directory,  bob_rsa_id.pub is your public key and is placed on any server you want to authenticate your local server too. Now we copy your public key to the VPS .  The command to do this is scp (secure copy).  Scp uses the following format -scp <source> <target> so we need to be in the .ssh directory when you do the copy.

Using your Maintenance window type the following:

scp bob_rsa_id.pub bob@12.345.67.899:~/.ssh

This copies the public key bob_rsa_id.pub from your local server to the VPS into the .ssh directory under the home directory(~) of the low level user account bob.  You will get prompted for bobs password before the copy happens so have it handy. When your copy is finished, ssh onto the VPS and make sure your in your “.ssh” directory (cd ~/.ssh).  Type “ls -la”

ls -la

Verify your  _rsa_id.pub is there. Now we are going to push the contents of the  _rsa_id.pub into the authorized_keys file.  Type “cat  bob_rsa_id.pub >> authorized_keys”. Make sure you use ‘>>’ not ‘>’ as ‘>’ will over write the file.  We want to append to the bottom of the file.

cat bob_rsa_id.pub >> authorized_keys

Type “cat authorizes_keys” and verify the bob_rsa_id.pub  contents are there.

cat authorizes_keys

Time to test. Start your sshd with the sshd_config.test file in the VPS window.

/usr/sbin/sshd -f /etc/ssh/sshd_config.test -d

In the Client window we will open a connection to the test sshd a little differently this time.  We use the “-i” switch to tell ssh we want to use a specific RSA private key to authenticate with.

ssh bob@12.345.67.899 -p44433 -i bob_rsa_id

When prompted for a RSA_ID passphrase you should see “bob_rsa_id” in the request.  Use the passphrase you used when generating the RSA key. If you are successful on the first login attempt, you should now be logged in as bob on your VPS using your RSA two factor authentication. It should be pointed out that if your login attempt is not successful for any reason the login security protocol will default back to keyboard interactive and allow you to log in using “bob”’s password at this point. We will fix that security hole next.

On to our our fourth goal – Password only connections will not be allowed. Elevate bob to root privileges and open /etc/ssh/sshd_config.test in your text editor. Some of these values are already set as the default though they commented out, uncomment them anyway to show clear intent for the next Administrator that comes along.

Uncomment “#PubkeyAuthentication yes”, verify it is set to “yes” this should be the default.

Uncomment “#PasswordAuthentication yes” and set it to PasswordAuthentication no 

Uncomment “#PermitEmptyPasswords no” this should be the default.

Uncomment “#ChallengeResponseAuthentication yes” and set it to ChallengeResponseAuthentication no 

Save your your changes to the  sshd_config.test. Time to test. Re-start your sshd in your VPS window.

/usr/sbin/sshd -f /etc/ssh/sshd_config.test -d

In the Client window we will open a connection to the test sshd. Again we use the “-i” switch to tell ssh we want to use a specific RSA private key to authenticate with.

ssh bob@12.345.67.899 -p44433 -i bob_rsa_id

When prompted for a RSA_ID passphrase you should see “bob_rsa_id” in the request.  Use the passphrase you used when generating the RSA key. You will have three attempts to get this right and you should not see a “fall back” to keyboard interactive password prompt. Log “bob” back out (type “exit”) and re-attempt with a bogus passphrase. After the third attempt should should get a “Permission denied (publickey).” And be returned to your local system prompt. SSH sessions on your VPS is now secured to only users who have a RSA key and a proper passphrase to use it.

Ok, now the moment of truth, it’s time to go live with your changes to the sshd_config file. Remember that maintenance window we discussed earlier that you were logged in as “root”? Check to make sure that is still open and working. It is our failsafe remember. To make our changes to the sshd_config.test file go live, we need to replace the sshd_config file with the sshd_config.test file. But first we want to save our default sshd_config file incase something goes sideways and we need to restore it. We will the “Move” command here. First we make a copy of sshd_config and call it sshd_config_old.

mv /etc/ssh/sshd_config  /etc/ssh/sshd_config_old

Now we rename sshd_config.test to sshd_config.

mv /etc/ssh/sshd_config.test /etc/ssh/sshd_config

run “rcctl sshd restart” to pick up the new configuration changes.  Your tested changes are now running confidently in production. Time to test. Make sure your VPS window is not running a debug session of sshd. Ctrl+c in that window sill stop it if it is. In your Client window make sure your not logged in. Typing “exit+<return>” until your back to your local machine prompt. Now using your client window simply log in as “bob” using your RSA key.

ssh bob@12.345.67.899 -p44433 -i bob_rsa_id

When prompted for a RSA_ID passphrase you should see “bob_rsa_id” in the request.  Use the passphrase you used when generating the RSA key. If it was successful, great, you have completed your goals. If it was not a successful login you can use your Maintenance window to open up your sshd_config to see if you missed a step and ultimately rename your sshd_config back to sshd_config.test and sshd_config_old back to sshd_config to get you back to where you were before starting this adventure. However I doubt you will need to do that as you tested your changes through out this process. Remember to backup your RSA public and private keys!

Congratulations! You have made your Openbsd ssh sessions much more secure than they were and we covered some import concepts as well. Today we learned how to

• prevent root logins

• move the port sshd listens on to another less common port

• setup and use RSA keys to prevent unauthorized access to your server

• Remove the ability to use a keyboard interactive login/password to gain access

Not a bad couple of hours worth of work. But this is the first step in getting WordPress installed on Openbsd. We have much more fun to look forward too.