TIP: Disable Unattended Upgrades on Ubuntu 18.04 Server

Introduction

When running a server automatic updates can be a dangerous affair.  When I setup my servers I disable this feature in Ubuntu.

The Fix

Edit /etc/apt/apt.conf.d/20auto-upgrades
> sudo nano -w /etc/apt/apt.conf.d/20auto-upgrades

Change the file to the follosing

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "0";

Now reboot the system.
> sudo reboot

Conclution

A quick change to a file.  A reboot and its all done.

HOWTO Ubuntu 18.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 18.04 LTS Base Server Setup

Introduction All of our servers will start with this install. This base server is based on Ubuntu 18.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 18.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 18.04 LTS Base Server Setup

Introduction All of our servers will start with this install. This base server is based on Ubuntu 18.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 python-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” > /etc/skel/website/index.html

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.

HOWTO Ubuntu 18.04 LTS Base Server Setup

Introduction

All of our servers will start with this install. This base server is based on Ubuntu 18.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 18.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

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 libcurl3 unzip
> sudo apt install apache2 php7.2-fpm libapache2-mod-php7.2 mysql-server mysql-client
> sudo apt install libapache2-mod-fcgid php7.2-opcache php-apcu

Install some extra PHP libraries.
> sudo apt install php7.2-gd php7.2-snmp php7.2-mbstring php7.2-mysql
> sudo apt install php7.2-odbc php7.2-imap
> sudo apt install php7.2-xmlrpc php7.2-dba
> sudo apt install php7.2-soap php7.2-zip php7.2-intl php7.2-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

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 setup 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.

TIP: Working with Disk Images Under Linux

Introduction

At times I need to work with disk images under linux.  Now I’m not talking about an image file that is a single partition. I’m talking about a disk image that represents a hard drive with an MBR and multiple partition in it.

Example 1:  Mounting A Disk Image

We need to start by mounting the image file to a loop back device.
> losetup /dev/loop0 yourimage.imgReplace yourimage.img with the path to your image file. Now lets use fdisk to

see the partions on the disk image.
> fdisk -ul /dev/loop0

Fdisk showed that my image file had 2 partitions. One was a linux partition and the other was a linux lvm partition. Let’s mount the linux partition.
> mkdir /mnt/diskimg_p1
> lomount -diskimage /dev/loop0 -partition 1 /mnt/diskimg_p1

This partition turned out to be /boot. You can unmount it just as easy.
> umount /mnt/diskimg_p1

Now unmount the disk image
> losetup -d /dev/loop0

Example 2:  Mount A Disk Image Partition Using Offsets

Here’s another way to mount the partitions. We will use losetup with offsets. So start with the following:
> losetup /dev/loop0 yourimage.img
> fdisk -ul /dev/loop0

Which gives:

Disk /dev/loop0: 4294 MB, 4294967296 bytes
 255 heads, 63 sectors/track, 522 cylinders, total 8388608 sectors
 Units = sectors of 1 * 512 = 512 bytes

Device Boot Start End Blocks Id System
 /dev/loop0p1 * 63 208844 104391 83 Linux
 /dev/loop0p2 208845 8385929 4088542+ 8e Linux

Now the important part is the start blocks. Your start blocks will look different. My starts are 63 and 208845. The sector size is 512. So do 63*512 and 208845*512. That will give you the offset numbers to use in loset. For my setup I do the following.
> losetup -o 32256 /dev/loop1 /dev/loop0
> losetup -o 106928640 /dev/loop2 /dev/loop0
> mkdir /mnt/p1
> mkdir /mnt/p2
> mount /dev/loop1 /mnt/p1
> mount /dev/loop2 /mnt/p2

Now you have the partitions mounted.

Now lets unmount the partitions and cleanup.
> umount /mnt/p1
> umount /mnt/p2
> rmdir /mnt/p1
> rmdir /mnt/p2
> losetup -d /dev/loop1
> losetup -d /dev/loop2
> losetup -d /dev/loop0

Conclusion

Hopefully this tip will help you master the disk image.

TIP: Disable Author Pages in WordPress

Introduction

In most WordPress websites the author pages functionality isn’t needed.   For search engines it can create unwanted duplicate links to your content.

There are a few solutions to the problem.  A couple are:  get a plugin or create an author template for your theme / child theme.  I will be showing you how to create an author template.

The Quick Tip

In your theme directory place the following into author.php

<?php

// Disable author pages
// PHP permanent URL redirection
header("Location: /", true, 301);

?>

This does a permanent redirect to your home page.

Conclusion

Its a quick and easy way to get the job done.

Move MySQL or MariaDB Databases To A New Location

Introduction

This quick TIP covers moving Mysql’s / MariaDB’s database storage to a different location.  This example was done on CentOS7.

Moving the Databases

First we need to stop mysql if it is running. Type the following:
> service mysqld stop

Next copy the data to the new location and fix the ownership.
> cp -R /var/lib/mysql /home/
> mv /home/mysql /home/databases
> chown -R mysql:mysql /home/databases

Save the old databases directory.
> mv /var/lib/mysql/ /var/lib/mysql_old

Now we need to take care of the needs of some scripts that may not know the data has been moved.
> ln -s /home/databases/ /var/lib/mysql
> chown mysql:mysql /var/lib/mysql

Next edit /etc/my.cnf.d/server.cnf to look like the folloeing

[mysqld]
 #datadir=/var/lib/mysql
 #socket=/var/lib/mysql/mysql.sock
 datadir=/home/databases
 socket=/home/databases/mysql.sock
 user=mysql
 # Disabling symbolic-links is recommended to prevent assorted security risks
 symbolic-links=0

[mysqld_safe]
 log-error=/var/log/mysqld.log
 pid-file=/var/run/mysqld/mysqld.pid

Finally we can restart Mysql. Type the follwoing:
> systemctl restart mariadb

Conclusion

Normally this isn’t done much.  However there are those times when the databases have to be in a different place.

Customizing a WordPress Theme By Creating a Child Theme

Introduction

Sooner or later you will want to customize a theme that you are using.  You have up to 4 possibilities.  They range from easy to complex.

First, many themes and the WordPress customizer provide many options for customizing a theme.  This is one of the easiest ways to customize a theme.

Second,  look for a plugin.  This is also an easy solution.  The challenge, find a plugin.  It may take several plugins to get what you want.

Third, create a child theme.  This is a big step compared to the first two choices.  You will need to be familiar with HTML, CSS and PHP.

Forth, create your own theme.  The most complex choice of the four.  If you don’t have the skills needed for web development then this isn’t the choice for you.

In this tutorial I’m going to focus on option three.  I’m using the Twenty Eleven theme.  Its an older theme but does what I want.  I started with the customizer.  I finally needed a change that a child theme could easily handle.

The example below will start with the Twenty Eleven theme.  So lets get started.

Creating a basic child theme

We are going to create a feature packed child them.  The theme won’t do a thing.  This will be the easiest child theme for you to create.

  1.  Create a directory named “MyChildTheme”.
  2. Create an empty text file named “functions.php”.
  3. Create a text file named “style.css” with the following text.
/*
Theme Name: MyChildTheme
Author: You
Description: 2011 child theme for WordPress
Author URI: yourdomain.tld/
Template: twentyeleven
*/
 
@import url(../twentyeleven/style.css);

That’s it.  You now have a fully functional child theme that does nothing.

Adding your custom CSS

I also over rode some of the CSS in the parent theme.  Since my CSS is simple, I added it to my theme’s style.css file.  Add the following CSS to the end of the file.

pre {
  border: solid 1px #111111;
  font-size: 1.3 em;
  color: #001100;
  margin: 10px;
  padding:10px;
  background: #D3D3FF;
}
#main {
  font-family: arial;
  font-size: 1.1em;
}
body {
  background-color: red;
}

The style.css file should look like the following.

/*
Theme Name: MyChildTheme
Author: You
Description: 2011 child theme for WordPress
Author URI: yourdomain.tld/
Template: twentyeleven
*/
 
@import url(../twentyeleven/style.css);

pre {
 border: solid 1px #111111;
 font-size: 1.3 em;
 color: #001100;
 margin: 10px;
 padding:10px;
 background: #D3D3FF;
}
#main {
 font-family: arial;
 font-size: 1.1em;
}
body {
 background-color: red;
}

Adding the side bar to single posts

When you are reading a post like this one the twenty eleven theme doesn’t have a sidebar.  In my child theme I put them back.

  1. Copy page.php and single.php from the twenty eleven theme to your child theme folder.
  2. Open the functions.php file and paste the following.
    <?php
    add_filter('body_class', 'fix_body_class_for_sidebar', 20, 2);
    function fix_body_class_for_sidebar($wp_classes, $extra_classes) {
     if( is_single() || is_page() ){ 
     if (in_array('singular',$wp_classes)){
     foreach($wp_classes as $key => $value) {
     if ($value == 'singular') 
     unset($wp_classes[$key]);
     }
     }
     }
     
     return array_merge($wp_classes, (array) $extra_classes);
    }
    ?>
  3. Open single.php and place the following
    <?php get_sidebar(); ?>

    on the line before

    <?php get_footer(); ?>
  4. Open page.php and place the following
    <?php get_sidebar(); ?>

    on the line before

    <?php get_footer(); ?>

Conclusion

A child theme can be basic or complex.  Best part is it provides a nice way to customize a theme.

Hacking The Aviosys IP Camera 9100 or 9100A

Introduction

In a nutshell I wanted access to the raw jpg files that the server should offer.

Watching the Raw Video Stream

The following URL allows you to watch the mjpeg video stream.

http://yourip/GetData.cgi
Example:  http://192.168.1.10/GetData.cgi

Here’s an example php script to extract the 4 video inputs into 4 image files. Be sure the device to set to round robin mode.

<?
// readstream.php
//
// by Richard Camp
// rcamp at campworld dot net
// Copyright 2006 - 2018
// All rights reserved
//
// There is no warranty. Use at your own risk.
// NOT FOR COMERCIAL USE. Personal use is fine.
//
// INTRODUCTION
// This script parses the stream form a IP Camera 9100 (A) for jpgs.
// Set the camera server for round robbin mode and all 4 inputs.
// Include the script in your script to generate the files.
//   ex.  include('readstream.php')
//
// User provided parameters
$camurl="http://192.168.151.253/GetData.cgi";
$imgpath="./";             // directory where to store images
$fname="img";              // image file name without extension
$log=1;                    // debugging / log flag
$maxcams=4;                // max cams 1-4

// global values
$maxloop=200;               // max images to read from the stream
$portoffset=14;            // ofset into jpg for cam port num
$imgfile=$imgpath.$fname;  // image file name
$camnum=0;                 // camera number

//
// start of script
//
if ($log) echo "readstream.php starting\n";

// open the stream to the video server
if ($log) echo "opening stream $camurl\n";
$fvid=fopen($camurl,"r");
if (!$fvid) {
  // cannot open mjpeg stream
  if ($log) echo "cannot open stream $camurl\n";
} else {
  // We are connected so start reading data
  if ($log) echo "connected to $camurl\n";
  $r='';

  // read a number of images from the stream and 
  // save them to files
  for ($loop=1; $loop<=$maxloop; $loop++) {

    // read the stream until 2 boundaries are found
    // 
    if ($log) echo "reading data\n";
    while (substr_count($r,"--WIN")<2) $r.=fread($fvid,256);

    // get the start and end offsets for the jpg
    // and extract the image
    if ($log) echo "extracting jpeg\n";
    $start = strpos($r,"Content-Type: image/jpeg")+28;
    $end   = strpos($r,"--WIN",$start);
    $frame = substr($r,$start,$end - $start);

    // get the camera port the image belongs to
    $cport=bin2hex($frame[$portoffset]);
    $cpnum=ord($frame[$portoffset]);
    if ($log) echo "image is for camera port $cport hex $cport\n";

    if (($camnum==$cpnum)&&($camnum<$maxcams)) {
      // save the image file
      if (file_exists("$imgfile-$cport.jpg")) {
        if ($log) echo "removing old file\n";
        unlink("$imgfile-$cport.jpg");
      }
      if ($log) echo "saving image file $imgfile-$cport.jpg\n";
      if ($fimg=fopen("$imgfile-$cport.jpg","wb")) {
        fwrite($fimg,$frame);
        fclose($fimg);
      }
      $camnum++;
      if ($camnum==$maxcams) $loop=$maxloop;
    }

    // we need the remainder of the buffer after the second
    // boundary. it contains the start of the next image.
    $r=substr($r,$end+1);    
    if ($log) echo "\n";
  }
}
fclose($fvid);
if ($log) echo "readstream.php complete\n";
?> 

Here’s another php script that reads the mjpeg stream and lets you select which cameras to extract images from, which cameras to flip the image horizonntally, and the creation of thumbnail images.

<?
// readstream.php
//
// by Richard Camp
// rcamp at campworld dot net
// Copyright 2006 - 2018
// All rights reserved
//
// There is no warranty. Use at your own risk.
// NOT FOR COMERCIAL USE. Personal use is fine.
//
// INTRODUCTION
// This script parses the stream form a IP Camera 9100 (A) for jpgs.
// Set the camera server for round robbin mode and all 4 inputs.
// Include the script in your script to generate the files.
//   ex.  include('readstream.php')
//
// User provided parameters
$camurl="http://192.168.151.253/GetData.cgi";
$imgpath="./images/";      // directory where to store images
$fname="img";              // image file name without extension
$log=0;                    // debugging / log flag
$loadcam[0]=1;             // set to 1 to retreive image for cam 1
$loadcam[1]=1;             // set to 1 to retreive image for cam 2
$loadcam[2]=1;             // set to 1 to retreive image for cam 3
$loadcam[3]=1;             // set to 1 to retreive image for cam 4
$camflip[0]=1;             // set to 1 to flip image horizontally for cam 1
$camflip[1]=0;             // set to 1 to flip image horizontally for cam 2
$camflip[2]=1;             // set to 1 to flip image horizontally for cam 3
$camflip[3]=0;             // set to 1 to flip image horizontally for cam 4
$thumbs=1;                 // set to 1 to create image thumbnails
$thumbwidth=160;           // width of thumbnail
$thumbheight=120;          // height of thumbnail

// global values
$maxloop=200;                          // max images to read from the stream
$portoffset=14;                        // ofset into jpg for cam port num
$imgfile=$imgpath.$fname;              // image file name
$lockfile=$imgpath."readstream.lock";  // lock file name

//
// start of script
//
if ($log) echo "readstream.php starting\n";

// create the log file
$flock=fopen($lockfile,"w");
fwrite($flock,"Locked for update");
fclose($flock);
if ($log) echo "Lock file created.\n";

// open the stream to the video server
if ($log) echo "opening stream $camurl\n";
$fvid=fopen($camurl,"r");
if (!$fvid) {
  // cannot open mjpeg stream
  if ($log) echo "cannot open stream $camurl\n";
} else {
  // We are connected so start reading data
  if ($log) echo "connected to $camurl\n";
  $r='';

  // read a number of images from the stream and 
  // save them to files
  for ($loop=1; $loop<=$maxloop; $loop++) {

    // read the stream until 2 boundaries are found
    if ($log) echo "reading data\n";
    while (substr_count($r,"--WIN")<2) $r.=fread($fvid,256);

    // get the start and end offsets for the jpg
    // and extract the image
    if ($log) echo "extracting jpeg\n";
    $start = strpos($r,"Content-Type: image/jpeg")+28;
    $end   = strpos($r,"--WIN",$start);
    $frame = substr($r,$start,$end - $start);

    // get the camera port the image belongs to
    $cport=bin2hex($frame[$portoffset]);
    $cpnum=ord($frame[$portoffset]);
    if ($log) echo "image is for camera port $cport hex $cport\n";

    // if we have not saved the current cam image then process it
    if ($loadcam[$cpnum]==1) {
      $newfile=$imgfile."-$cport.jpg";
      $tmpfile=$newfile.".tmp";
      $thumbfile=$imgfile."-thumb-$cport.jpg";

      // save image into a temp file
      if ($log) echo "saving image file $tmpfile\n";
      if ($fimg=fopen("$tmpfile","wb")) {
        fwrite($fimg,$frame);
        fclose($fimg);
      }

      // flip the image horizontally if it is marked to be flipped
      if ($camflip[$cpnum]==1) {
        if ($log) echo "Flipping image horizontally.\n";
        exec("convert -flop $tmpfile $tmpfile");
      }

      // move temp file to final image file
      if ($log) echo "Renaming $tmpfile to $newfile\n";
      if (!rename($tmpfile,$newfile)) {
        unlink($newfile);
        rename($tmpfile,$newfile);
      } 

      // create thumbnails if the flag is true
      if ($thumbs==1) {
        if ($log) echo "Creating thumbnail image\n";
        $myimg=imagecreatefromjpeg($newfile);
        $iwidth=imagesx($myimg);
        $iheight=imagesy($myimg);
        $tmpimg=imagecreatetruecolor($thumbwidth,$thumbheight); 
        imagecopyresampled($tmpimg,$myimg,0,0,0,0,
                           $thumbwidth-1,$thumbheight-1,$iwidth,$iheight);
        imagedestroy($myimg);
        imagejpeg($tmpimg,$thumbfile.".tmp");
        if (!rename($thumbfile.".tmp",$thumbfile)) {
            unlink($thumbfile);
            rename($thumbfile.".tmp",$thumbfile);
        } 
      } 

      // mark the camera number as processed  and exit the loop when
      // we have all the images.
      $loadcam[$cpnum]=0;
      if (($loadcam[0]+$loadcam[1]+$loadcam[2]+$loadcam[3])==0) $loop=$maxloop;
    }

    // we need the remainder of the buffer after the second
    // boundary. it contains the start of the next image.
    $r=substr($r,$end+1);    
    if ($log) echo "\n";
  }
}
// close the image stream
fclose($fvid);

// remove the lock file
unlink($lockfile);
if ($log) echo "readstream.php complete\n";
?>

 Getting Access to JPGs

I wanted to get the raw JPGs from the video server. This would allow me to put the images up on my website. It took some digging but here it is. Below are the URLs for the image file.

http://yourip/Jpeg/CamImg.jpg

Changing the Video Channel

To get the different video images you’ll need to use round robin mode or change the video channel. The following url changes the channel.

http://yourip/SetChannel.cgi?Channel=M

M=the channel number 0-3

Getting the Video Channel you are on

What channel am I on? The following url shows you how to get the channel number.

http://yourip/GetChannel.cgi

Configuring The Device For Round Robin Mode

Here is the information on setting the camera into round robin mode. Use the following url.

http://yourip/SetChannel.cgi?Channel=M

M=256+C1+C2+C3+C4

Here’s a table with the values for C1-C4

Video Input Off Selected
C1 0 1
C2 0 2
C3 0 4
C4 0 8

For example I want to use cameras 1 and 3 in round robin mode.

So M=256+1+0+4+0=261

Changing the Camera Resolution

This is the quick easy way to change the camera resolution. Use the following url.

http://yourip/ChangeResolution.cgi?ResType=N

N=the following
0 – 176*144
1 – 352*288
2 – 320*240
3 – 640*480

Change the Image Compression

Below is the url for changing the image compression level.

http://yourip/ChangeCompressRatio.cgi?Ratio=x

x = the following ratio
0 = low (image size 18.2kB)
1 = high (image size 25.2kB)
2 = medium (image size 27.2kB)
3 = clarity (image size 30.2kB)
4 = motion (image size 34.7kB)

Get the capabilities

I’m still working on this one. Here is the url for getting the camera capabilities.

http://yourip/GetCapability.cgi

Conclusion

I hope these notes help you out.

HOWTO Ubuntu 16.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 16.04 LTS Base Server Setup

Introduction All of our servers will start with this install. This base server is based on Ubuntu 16.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-get update
> sudo apt-get install vsftpd python-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 bash
> sudo echo “HELLO WORLD” > /etc/skel/website/index.html

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:

# compress all text & html:
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
AddOutputFilterByType DEFLATE application/x-httpd-fastphp
AddOutputFilterByType DEFLATE application/x-httpd-eruby

# 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
  </Directory>
 </VirtualHost>
</Macro>

<Macro VHost80 $host >
 <VirtualHost *:80>
</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> 

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 /sbin/nologin -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 /sbin/nologin -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.

HOWTO Open Suse 42 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 SUSE 42 Base Server Setup

Introduction All of our servers will start with this install. This base server is based on OpenSUSE 42. Downloading the ISO Visit the OpenSUSE website and download the Leap version. Download the install DVD. You could also use the Network … 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:
> zypper in vsftpd python-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.
> mkdir -p /etc/skel/{website,logs,cgi-bin,backup}
> echo “HELLO WORLD” > /etc/skel/website/index.html

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.d/virtual.conf with the following:

# compress all text & html:
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
AddOutputFilterByType DEFLATE application/x-httpd-fastphp
AddOutputFilterByType DEFLATE application/x-httpd-eruby

# 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
  </Directory>
 </VirtualHost>
</Macro>

<Macro VHost80 $host >
 <VirtualHost *:80>
</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>

Enable mod_macro, mod_filter and mod_deflate.
> a2enmod mod_macro
> a2enmod mod_filter
> a2enmod mod_deflate

Restart apache
> systemctl restart httpd

Configuring Let’s Encrypt

Let’s Encrypt needs to be configured to auto renew certs. Lets create a daily cron job
> 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. \\
> useradd -m -U -s /sbin/nologin -c “default website” defaultweb
> passwd defaultweb

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

Update directory permissions.
> chmod g+rwx /home/defaultweb
> 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:
> nano -w /etc/apache2/vhosts.d/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

Reload apache config
systemctl reload httpd

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:
> 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.
> systemctl reload apache

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.\\
> useradd -m -U -s /sbin/nologin -c “Virtual Website User” NEWUSER
> passwd NEWUSER
> usermod -a -G NEWUSER wwwrun
> chmod g+rwx /home/NEWUSER
> 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.
> nano -w /etc/httpd/virtualhosts.d/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

Reload apache config
systemctl reload httpd

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.
> 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.
> systemctl reload apache

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

Conclusion

That’s the complete setup.

HOWTO CentOS 7 Virtual Web Hosting With Apache, 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 CentOS 7.x Base Server Setup

Introduction All of our servers will start with this install. This base server is based on CentOS 7. Downloading the ISO Visit the CentOS website and download the Minimal install ISO. Initial Install Boot the install DVD. The graphical install … 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:
> yum -y install vsftpd ftp python-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.
> mkdir -p /etc/skel/{website,logs,cgi-bin,backup}
> echo “HELLO WORLD” > /etc/skel/website/index.html

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.  Lets start out by creating a directory for virtual host file storage.
> mkdir /etc/httpd/virtualhosts.d

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

# compress all text & html:
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
AddOutputFilterByType DEFLATE application/x-httpd-fastphp
AddOutputFilterByType DEFLATE application/x-httpd-eruby

# 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
  </Directory>
 </VirtualHost>
</Macro>

<Macro VHost80 $host >
 <VirtualHost *:80>
</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> 

# include the virtual host files
IncludeOptional /etc/httpd/virtualhosts.d/*.conf

#undefine the macros
UndefMacro virtHost
UndefMacro VHost80
UndefMacro VHost443

Restart apache
> systemctl restart httpd

Configuring Let’s Encrypt

Let’s Encrypt needs to be configured to auto renew certs. Lets create a daily cron job
> 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. \\
> useradd -s /sbin/nologin -c “default website” defaultweb
> passwd defaultweb

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

Update directory permissions.
> chmod g+rwx /home/defaultweb
> 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:
> nano -w /etc/httpd/virtualhosts.d/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

Reload apache config
systemctl reload httpd

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:
> 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.
> systemctl reload apache

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.\\
> useradd -s /sbin/nologin -c “Virtual Website User” NEWUSER
> passwd NEWUSER
> usermod -a -G NEWUSER apache
> chmod g+rwx /home/NEWUSER
> 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.
> nano -w /etc/httpd/virtualhosts.d/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

Reload apache config
systemctl reload httpd

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.
> 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.
> systemctl reload apache

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

Conclusion

That’s the complete setup.

HOWTO SUSE 42 Base Server Setup

Introduction

All of our servers will start with this install. This base server is based on OpenSUSE 42.

Downloading the ISO

Visit the OpenSUSE website and download the Leap version. Download the install DVD. You could also use the Network install ISO.

Initial Install

Boot the install DVD/CD/USB. Select the ‘Installation’ option from the menu.

The graphical install loads and we’re ready to go.
*Select your language and keyboard. Click next.
*Change the partitioning if you want. Click next.
*Select your timezone. Click next.
*For user interface select server. Click next.
*Enter local user information. Uncheck ‘Automatic Login’. Click next.
*At the bottom of installations settings enable the ssh service. Click install.

First boot

Reboot the machine when the install finishes.
The OS will boot. Log in.

Get everything updated and install a couple of items.
> zypper in nano
> zypper update

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. A change in this howto is that I’m installing RPMs reguardless if they were already installed by another dependency. This guards against RPM changes that could cause a package to not be installed.

We need to add and enable a few repositories.
Add the following Repo for Webmin. Create /etc/zypp/repos.d/webmin.repo

 [Webmin]
 name=Webmin Distribution Neutral
 baseurl=http://download.webmin.com/download/yum
 enabled=1

Install the following RPMs. Multiple lines to make cut and paste easier.
> zypper in make screen bind
> zypper in libmcrypt perl perl-Net-SSLeay perl-Crypt-SSLeay
> zypper in openssl libopenssl-devel man

Run the following to install Webmin:
> rpm –import http://www.webmin.com/jcameron-key.asc
> zypper in webmin
> systemctl enable webmin
> service webmin start

Install MariaDB.
> zypper in mariadb mariadb-tools
> systemctl enable mysql
> systemctl start mysql

Run the following script to setup mariadb.
> mysql_secure_installation

Install Apache web server
> zypper in apache2
> systemctl enable apache2
> systemctl start apache2

Install PHP.
> zypper in php7 php7-fpm apache2-mod_php7
> zypper in php7-gd php7-snmp php7-mbstring php7-mysql php7-devel
> zypper in php7-odbc php7-imap php7-xmlrpc php7-dba php7-mcrypt
> cp /etc/php7/fpm/php-fpm.conf.default /etc/php7/fpm/php-fpm.conf
> cp /etc/php7/fpm/php-fpm.d/www.conf.default /etc/php7/fpm/php-fpm.d/www.conf
> chkconfig php-fpm on
> systemctl start php-fpm.service

Installing and Configuring phpMyAdmin

I prefer to phpMyAdmin to manage my MySQL databases. The nginx config above has the configuration for phpMyAdmin.

Now install phpMyAdmin.
> zypper in phpMyAdmin

Restart apache2.
> systemctl restart apache2

Now test it out.

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
> postconf -e “virtual_alias_maps = hash:/etc/postfix/virtual”
Just a couple commands to wrap everything up.
> postmap /etc/postfix/virtual
> systemctl restart postfix

Final Settings

You may want to enable the linux firewall.

Conclusion

That’s it for the basic server setup. This is an example of a standard linux server setup. Be sure to use setup 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.

HOWTO CentOS 7.x Base Server Setup

Introduction

All of our servers will start with this install. This base server is based on CentOS 7.

Downloading the ISO

Visit the CentOS website and download the Minimal install ISO.

Initial Install

Boot the install DVD.

The graphical install loads and we’re ready to go.
*Choose your language and click next.
The next screen has a menu with groups of settings that need to be configured.
*Click on ‘DATE & TIME’ and set your timezone.
*Click on ‘INSTALLATION DESTINATION’ and click done to let it auto partition the drive.
*Click on ‘NETWORK & HOSTNAME’ and set the hostname. Click the ‘Configure’ button and set the adaptor to auto connect. Then click done.
*Click on ‘SOFTWARE SELECTION’. Select ‘Minimal Install’. Check the option for ‘Compatibility Libraries’. Then click done.
*When done click ‘Begin Installation’.
The installation progress screen has a couple of menu items for setting the root password and creating users.
*set the root password.
*You should create a user to admin the system.
*Click ‘Finish Configuration’ when it appears.
*Click ‘Reboot’ when it appears.

First boot

Reboot the machine when the install finishes.
The OS will boot. Log in.

Get everything updated and install a couple of items.
> yum -y install nano net-tools deltarpm
> yum -y group install ‘Infrastructure Server’
> yum -y upgrade

Disable selinux

Now we need to disable selinux. There is some software that doesn’t play well with selinux.
Edit /etc/selinux/config and change SELINUX=enforcing to SELINUX=disabled

Disable the firewall

> systemctl stop firewalld
> systemctl disable firewalld

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. A change in this howto is that I’m installing RPMs reguardless if they were already installed by another dependency. This guards against RPM changes that could cause a package to not be installed.

We need to add and enable a few repositories.
Type nano -w /etc/yum.repos.d/CentOS-Base.repo
For the centosplus section change ‘enable=0’. Change the 0 to a 1.

We need the webmin repo. Create webmin.repo with the text below.
> nano -w /etc/yum.repos.d/webmin.repo

[Webmin]
 name=Webmin Distribution Neutral
 #baseurl=http://download.webmin.com/download/yum
 mirrorlist=http://download.webmin.com/download/yum/mirrorlist
 enabled=1

And the EPEL repo.
> yum install epel-release

Finish up by installing hte remi repo.
> wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm
> rpm -Uvh remi-release-7.rpm

Edit /etc/yum.repos.d/remi.repo. Change enable=0 to enable=1 in the sections “remi” and “remi-php56”.

Now bring everything up to date.
> yum -y update

Install the following RPMs. Multiple lines to make cut and paste easier.
> yum -y install gcc gcc-c++ wget bison nano make createrepo screen
> yum -y install libmcrypt caching-nameserver

Now lets install webmin. We need SSL support in perl. Setup is easier if you get this installed before webmin.
> yum -y install perl-Net-SSLeay
> rpm –import http://www.webmin.com/jcameron-key.asc
> yum -y install webmin
> systemctl enable webmin
> service webmin start

Install MariaDB.
> yum -y install mariadb-server mariadb
> systemctl enable mariadb
> systemctl start mariadb

Run the following script to setup mariadb.
> mysql_secure_installation

Install PHP.
> yum -y install php php-cli php-fpm
> yum -y install php-gd php-ncurses php-snmp php-mbstring php-mysql php-devel
> yum -y install php-odbc php-imap php-pecl-apc
> yum -y install php-xmlrpc php-dba php-pear-DB php-mcrypt
> systemctl enable php-fpm
> systemctl start php-fpm

Install Apache web server
> yum -y install @web-server
> systemctl enable httpd
> systemctl start httpd

Installing and Configuring phpMyAdmin

I prefer to phpMyAdmin to manage my MySQL databases.

Now install phpMyAdmin.
> yum -y install phpMyAdmin

You will need to add access to phpMyAdmin. By default only the local server can access it. Edit /etc/httpd/conf.d/phpMyAdmin.conf to look like the following.

# phpMyAdmin - Web based MySQL browser written in php
# 
# Allows only localhost by default
#
# But allowing phpMyAdmin to anyone other than localhost should be considered
# dangerous unless properly secured by SSL

Alias /phpMyAdmin /usr/share/phpMyAdmin
Alias /phpmyadmin /usr/share/phpMyAdmin

<Directory /usr/share/phpMyAdmin/>
 AddDefaultCharset UTF-8

<IfModule mod_authz_core.c>
 # Apache 2.4
 Require local
 Require ip 192.168.0.0/16
 Require ip 10.0.0.0/8
 </IfModule>
 <IfModule !mod_authz_core.c>
 # Apache 2.2
 Order Deny,Allow
 Deny from All
 Allow from 127.0.0.1
 Allow from ::1
 </IfModule>
</Directory>

<Directory /usr/share/phpMyAdmin/setup/>
 <IfModule mod_authz_core.c>
 # Apache 2.4
 Require local
 Require ip 192.168.0.0/16
 Require ip 10.0.0.0/8
 </IfModule>
 <IfModule !mod_authz_core.c>
 # Apache 2.2
 Order Deny,Allow
 Deny from All
 Allow from 127.0.0.1
 Allow from 192.168. 
 Allow from 10.
 Allow from ::1
 </IfModule>
</Directory>

# These directories do not require access over HTTP - taken from the original
# phpMyAdmin upstream tarball
#
<Directory /usr/share/phpMyAdmin/libraries/>
 Order Deny,Allow
 Deny from All
 Allow from None
</Directory>

<Directory /usr/share/phpMyAdmin/setup/lib/>
 Order Deny,Allow
 Deny from All
 Allow from None
</Directory>

<Directory /usr/share/phpMyAdmin/setup/frames/>
 Order Deny,Allow
 Deny from All
 Allow from None
</Directory>

# This configuration prevents mod_security at phpMyAdmin directories from
# filtering SQL etc. This may break your mod_security implementation.
#
#<IfModule mod_security.c>
# <Directory /usr/share/phpMyAdmin/>
# SecRuleInheritance Off
# </Directory>
#</IfModule>

Restart Apache.
> systemctl restart httpd

Now test it out.

Installing cockpit

I’m trying cockpit as my server admin tool.  Do the following to set it up.
> yum -y install cockpit cockpit-dashboard cockpit-networkmanager cockpit-packagekit
> yum -y install cockpit-selinux cockpit-sosreport cockpit-storaged
> systemctl start cockpit
> 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
> postconf -e “virtual_alias_maps = hash:/etc/postfix/virtual”
Just a couple commands to wrap everything up.
> postmap /etc/postfix/virtual
> systemctl restart postfix

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 setup 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.

Fix Proxmox Crashing on J1900 and J3455 CPUs

Sometimes kvm has trouble running on some cpus.  Unfortunately you end up finding this out the hard way when proxmox crashes and / or shuts down.  As it turns out its our friend cpu c states.

The solution to the problem is limiting the c states to C1. We will do this by telling the linux kernel the maximum c state to use.

Edit /etc/default/grub and add the following line.

GRUB_CMDLINE_LINUX_DEFAULT="intel_idle.max_cstate=1 processor.max_cstate=1"

Next update grub.
> update-grub

Now reboot the system.
> reboot

Your system should now be crash free.

 

HOWTO Ubuntu 16.04 LTS Base Server Setup

Introduction

All of our servers will start with this install. This base server is based on Ubuntu 16.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 16.04 server ISO.

Initial Install

The install screens are straight forward.  I’m not going to cover them in much detail.  I will cover areas that have settings that are important.  Boot the install DVD.

When you get to the software selection screen select the following software packages.
– DNS Server
– LAMP Server
– standard system utilities
– OpenSSH Server

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-get update
> sudo apt-get install nano net-tools
> sudo apt-get upgrade

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

Now bring everything up to date.
> sudo apt-get update

Install the following packages. Multiple lines to make cut and paste easier.
> sudo apt-get install make screen snmp composer libcurl3 unzip
> sudo apt-get install libapache2-mod-fastcgi php7.0-fpm

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

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

Configure Apache and PHP

Enable the rewrite module.
> sudo a2enmod rewrite

Enable mcrypt in php.
> sudo phpenmod mcrypt

Reload apache.
> sudo systemctl restart apache2.service

Installing and Configuring phpMyAdmin

I prefer to phpMyAdmin to manage my MySQL databases.

Now install phpMyAdmin.
> sudo apt-get install phpmyadmin

Restart Apache.
> sudo systemctl restart apache2.service

Installing Postfix

Lets install postfix.
> sudo apt-get 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-get 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

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 setup 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.

HOWTO Ubuntu 16.04 LTS Magento 2 Server Setup

Introduction

All of our servers will start with this install. This base server is based on CentOS 7. There have been some changes since my 6.x howtos.

Downloading the ISO

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

Initial Install

Boot the install DVD.  The install is straight forward.  I’m only going to cover items that you should select during the install.

On the package selection screen select the following:
‘Web Server LAMP’
‘Mail Server’

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.
> apt-get install nano net-tools
> sudo apt-get upgrade

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. A change in this howto is that I’m installing RPMs reguardless if they were already installed by another dependency. This guards against RPM changes that could cause a package to not be installed. Once again log in to your server.

Now bring everything up to date.
> sudo apt-get update

Install the following RPMs. Multiple lines to make cut and paste easier.
> sudo apt-get install make screen snmp composer libcurl3 unzip

Install some extra PHP libraries.
> sudo apt-get install libapache2-mod-fastcgi php7.0-fpm
> sudo apt-get install php7.0-gd php7.0-snmp php7.0-mbstring php7.0-mysql
> sudo apt-get install php7.0-odbc php7.0-imap
> sudo apt-get install php7.0-xmlrpc php7.0-dba php7.0-mcrypt
> sudo apt-get install php7.0-soap php7.0-zip php7.0-intl php7.0-curl

Configure Apache and PHP

Enable the rewrite module.
> sudo a2enmod rewrite

Enable mcrypt in php.
> sudo phpenmod mcrypt

Reload apache.
> sudo systemctl restart apache2.service

Installing and Configuring phpMyAdmin

I prefer to phpMyAdmin to manage my MySQL databases.

Now install phpMyAdmin.
> sudo apt-get install phpmyadmin

Restart Apache.
> sudo systemctl restart httpd

Installing Postfix

Lets install postfix.
> sudo apt-get 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-get 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

Setup User for Magento

Login to cockpit https://yourserver.tld:9090
Go to the accounts section and add a user for magento.  I named my user ‘madmin’.

Login to your server with ssh and add your new user to the webserver group
> sudo adduser madmin www-data

Change owner and permissions of the web server directory
> sudo chown -R www-data:www-data /var/www/html
> sudo chmod g+w /var/www/html

Configure Apache for Magento

Replace

<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  <Directory /var/www/html>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

Restart apache.
> sudo systemctl restart apache2.service

Setup Mysql Database and User for Magento

Now we need to create the database and user for magento.  You will want to use a different username and password.  Type the following.
> mysql -u root -p
> CREATE DATABASE magento;
> CREATE USER magento@localhost IDENTIFIED BY ‘otnegam’;
> GRANT ALL PRIVILEGES ON magento.* TO magento@localhost IDENTIFIED BY ‘otnegam’;
> FLUSH PRIVILEGES;
> exit

Download and Install Magento

Download the latest version of magento.  The version at the time of this howto is ‘2.2.2’. I downloaded the zip version.  Then copy the download to the magento server.  Place the download in ‘/var/www/html’.

Switch to the web root directory and unzip magento.
> cd /var/www/html/
> sudo unzip magento-2.2.2

Fix file permissions owner.
> sudo chown -R www-data:www-data /var/www/html
> sudo chmod g+w -R /var/www.html

Now open your browser and visit magento on your server.  Finish the setup process using the web gui.

Final Settings

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

Conclusion

That’s it for the basic magento setup. See the other pages for info on configuring servers for virtual webhosting or virtual email hosting. Remember to configure the firewall on the server.

HOWTO: Change Thin LVM to Directory Storage in Proxmox 5.x

Introduction

In Proxmox 5.x LVM thin is the default local storage for VMs.  However I prefer the old method of directory based storage for local storage.  You can find this information in the proxmox wiki.  These are my terse notes to get the job done.

The Conversion

This should only be done on a new installation of proxmox.  In the gui remove the local lvm thin storate.

Type the following to set everything up.
> lvremove pve/data
> lvcreate –name data -l +100%FREE pve
> mkfs.ext4 /dev/pve/data

Add the following to /etc/fstab

/dev/pve/data /var/lib/vz ext4 defaults 0 1

Restart proxmox.  Thats it.