Howto set up WordPress on Ubuntu LAMP-server [Ubuntu Server 14.04 LTS]

Welcome,

In this blog-post we will look at setting up WordPress on our LAMP-server running on Ubuntu Server 14.04 LTS.

lamp

After installing LAMP in Ubuntu Server 14.04 LTS we start by configuring MySQL. We want to make sure to use UTF-8 character-set everywhere possible. Let’s start to find out what we got by default when it comes to collation and character sets in MySQL. Login as root to MySQL from a terminal or ssh-shell…

mysql_login

Now type in the following SQL and hit return:

mysql> show variables where variable_name like 'ch%' or variable_name like 'col%';

this will give you a response similar to the table below:

+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
| collation_connection     | utf8_general_ci            |
| collation_database       | latin1_swedish_ci          |
| collation_server         | latin1_swedish_ci          |
+--------------------------+----------------------------+
11 rows in set (0.00 sec)

We see here that we have some records with latin1 and also collation_connection is utf8_general_ci rather than utf8_unicode_ci. The argument for using utf8_unicode_ci instead of utf8_general_ci can be read here. Maybe you even want to go with utf8mb4  as default…

[mysqld]
init_connect='SET collation_connection = utf8mb4_unicode_ci; SET NAMES utf8mb4;'
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
skip-character-set-client-handshake

…However, I’m perfectly fine with using only the original utf8 (utf8mb3) as default, since I do not need more than the first 65,536 codepoints (which uses 1 to 3 bytes per character). I’m not planning to blog in full Cantonese any time soon :)  If you are in need for full coverage of CJVK (Chinese, Japanese, Vietnam, Korean) you should go with utf8mb4 that uses 1 to 4 bytes per character. You can read more about MySQL and uft8mb4 here.

Let’s do the configuration:

In /etc/mysql we have the config-file my.cnf

root@ubuntu01:~# cd /etc/mysql/
root@ubuntu01:/etc/mysql# ls -al
total 24
drwxr-xr-x  3 root root 4096 Jun 22 19:42 .
drwxr-xr-x 94 root root 4096 Jun 23 16:14 ..
drwxr-xr-x  2 root root 4096 Jun 22 19:42 conf.d
-rw-------  1 root root  333 Jun 18 15:04 debian.cnf
-rwxr-xr-x  1 root root 1220 Jan 21 22:31 debian-start
-rw-r--r--  1 root root 3704 Jun 20 15:19 my.cnf

Put the following entries in the config-file my.cnf under the [mysqld] section:

[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci; SET NAMES utf8;'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake

Restart MySQL-daemon:

 root@ubuntu01:/etc/mysql# service mysql restart

Now, running the show variables statement again shows this:

+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
| collation_connection     | utf8_unicode_ci            |
| collation_database       | utf8_unicode_ci            |
| collation_server         | utf8_unicode_ci            |
+--------------------------+----------------------------+
11 rows in set (0.00 sec)

Looks okay now. We can test that the default values works as expected by creating a dummy database…

mysql> create database junk_db;
Query OK, 1 row affected (0.00 sec)

…and look with what parameters it was created:

mysql> show create database junk_db;

| junk_db  | CREATE DATABASE `junk_db` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */ |

1 row in set (0.00 sec)

Nice! Both character set and collation were the expected ones. Now create a dummy table in this db…

mysql> use junk_db;
Database changed

mysql> create table junk_table (name varchar(255));
Query OK, 0 rows affected (0.00 sec)

…and look how it was created:

mysql> show create table junk_table;

| junk_table | CREATE TABLE `junk_table` ( `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci    |

1 row in set (0.00 sec)

Same thing here. Looks just as it should. Please note that the default engine is InnoDB which is the one I want by default. Now drop this database…

mysql> drop database junk_db;
Query OK, 0 rows affected (0.00 sec)

…and create the WordPress database. I prefix it with wp_ and then using the domain name just for clarity:

mysql> create database wp_creang;
Query OK, 1 row affected (0.00 sec)

Show all databases in MySQL:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| wp_creang          |
+--------------------+
4 rows in set (0.01 sec)

Verify that the database was created with utf8 and utf8_unicode_ci…

mysql> show create database wp_creang;

| wp_creang | CREATE DATABASE `wp_creang` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci */ |

1 row in set (0.00 sec)

Create a user that we later will use with wordpress to connect to this database, again I’m giving it a suitable name for clarity. Password_here should of course be substituted with your chosen password.

mysql> create user wpuser_creang@localhost identified by 'password_here';
Query OK, 0 rows affected (0.00 sec)

Give the user full permission to access and manipulate this database:

mysql> grant all privileges on wp_creang.* to wpuser_creang@localhost;
Query OK, 0 rows affected (0.00 sec)

Now, just to verify everything looks okay, switch to the internal MySQL database:

mysql> use mysql
Database changed
 mysql> select host,user,password from user;
             
| localhost | wpuser_creang    | *E6B......... |
+-----------+------------------+---------------+
6 rows in set (0.00 sec)
 mysql> select host,db,user from db;
+-----------+-----------+---------------+
| host      | db        | user          |
+-----------+-----------+---------------+
| localhost | wp_creang | wpuser_creang |
+-----------+-----------+---------------+
1 row in set (0.00 sec)

Everything looks okay here, so let’s make the change take effect:

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

Now having the db prepared let’s download and install WordPress:

WordPress installation

Make a download folder under /usr/src or in any other preferred location

root@ubuntu01:/etc/mysql# cd /usr/src/
root@ubuntu01:/usr/src# mkdir download
root@ubuntu01:/usr/src# cd download/

Download the latest WordPress tarball:

root@ubuntu01:/usr/src/download# wget http://wordpress.org/latest.tar.gz

Unpack, This will create a directory called wordpress in your download directory.

root@ubuntu01:/usr/src/download# tar xvzf latest.tar.gz

Install php5-gd and libssh2-php

root@ubuntu01:/usr/src/download# apt-get update
root@ubuntu01:/usr/src/download# apt-get install php5-gd libssh2-php

Copy the sample config

root@ubuntu01:/usr/src/download# cd wordpress/
root@ubuntu01:/usr/src/download/wordpress# cp wp-config-sample.php wp-config.php

And put this in your newly created wp-config.php, I use VIM to edit the file…

root@ubuntu01:/usr/src/download/wordpress# vi wp-config.php
/** The name of the database for WordPress */
define('DB_NAME', 'wp_creang');

/** MySQL database username */
define('DB_USER', 'wpuser_creang');

/** MySQL database password */
define('DB_PASSWORD', 'password_here');

/** MySQL hostname */
define('DB_HOST', 'localhost');

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

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

define( 'WP_POST_REVISIONS', 5 );

The last entry makes sure only five revisions of posts are kept in the database. The default is 30 but I do not want that many in order to keep the db small and tidy. Put in whatever value you want here.

Now when the configuration is done create a folder that will work as a home directory for this site under Apache webserver. I chose the domain name as folder name for clarity. Under Ubuntu Server the apache directory is located at /var/www

root@ubuntu01:/usr/src/download/wordpress# cd /var/www/
root@ubuntu01:/var/www# mkdir creang

Listing the www-folder now shows this:

root@ubuntu01:/var/www# ls -l
drwxr-xr-x 2 root root 4096 Jun 20 16:11 creang
drwxr-xr-x 2 root root 4096 Jun 18 15:04 html

Now, copy or move the wordpress folder content into this folder. I’m using rsync to copy it over:

root@ubuntu01:/var/www/creang# cd /usr/src/download/
root@ubuntu01:/usr/src/download# rsync -avP wordpress/ /var/www/creang/

Create an uploads-folder under the wp-content folder.

root@ubuntu01:/usr/src/download# cd /var/www/creang/wp-content/
root@ubuntu01:/var/www/creang/wp-content# mkdir uploads

Change the owner of the files recursively to your user and group. I’m using nobody and www-data here.

root@ubuntu01:/var/www/creang/wp-content# cd ..
root@ubuntu01:/var/www/creang# chown -R nobody:www-data *

Apache config:

Let’s start by checking what version of apache we have:

root@ubuntu01:/var/www/creang# apache2 -v
Server version: Apache/2.4.7 (Ubuntu)
Server built:   Mar 10 2015 13:05:59

Ok, so we have apache 2.4. We will set this site up as one of several name-based web sites on a single IP-address. For the 2.4-version of Apache the examples for this can be found here.

Now, just making sure apache listens to port 80, check the contents of ports.conf:

root@ubuntu01:/var/www/creang/wp-content# cd /etc/apache2/
root@ubuntu01:/etc/apache2# more ports.conf
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 80

<IfModule ssl_module>
        Listen 443
</IfModule>

<IfModule mod_gnutls.c>
        Listen 443
</IfModule>

We can also see if apache is running and what address it is bound to by this command:

root@ubuntu01:/etc/apache2# netstat -nap
Active Internet connections (servers and established)
Proto Local Address Foreign Address State   PID/Program name
tcp   0.0.0.0:80    0.0.0.0:*       LISTEN  8270/apache2

Okay, so everything looks as it should. Apache listens on port 80 already. Now, start by editing the apache2.conf

root@ubuntu01:/etc/apache2# vi apache2.conf

Set servername to something suitable, like localhost:

# Global configuration
#
ServerName localhost

Now, comment out the Directory /var/www, we don’t need that directory enabled any longer.

#<Directory /var/www>
#       Options Indexes FollowSymLinks
#       AllowOverride None
#       Require all granted
#</Directory>

Disable the default configuration file /etc/apache2/sites-enabled/000-default.conf

root@ubuntu01:/etc/apache2/sites-enabled# a2dissite 000-default.conf
Site 000-default disabled.

The a2dissite-command does the removal of the symlink in folder sites-enabled. We double check that the job is done.

root@ubuntu01:/etc/apache2/sites-enabled# ls -al
drwxr-xr-x 2 root root 4096 Jun 20 17:11 .
drwxr-xr-x 8 root root 4096 Jun 20 16:51 ..

Indeed empty. Now copy the default config file as a skel for our new config file. I use the name vhosts-default.conf

root@ubuntu01:/etc/apache2/sites-available# cp 000-default.conf vhosts-default.conf

Now, having both the .com and the .se domain with the same name I want them all to point to the same site redirecting to www.creang.com regardless if you type creang.com, creang.se or www.creang.se in your browser they will all redirect to www.creang.com. This will require a little DNS-configuration and some Apache-config as well. In DNS, I set up both www-subdomains as CNAME-records pointing to the naked domain name. Like this.

creang.com
----------
@    A      85.225.140.7
www  CNAME  creang.com.
creang.se
----------
@    A      85.225.140.7
www  CNAME  creang.com.

Two A-records are set up to point to the public IP-address of the server. They will be updated automatically via ddclient should my ip-address change, read more about how to configure that here.

Now, with these records in place we now configure our vhosts-default.conf like this:

<VirtualHost *:80>
        ServerName creang.com
        ServerAlias creang.se
        ServerAlias www.creang.se
        RedirectMatch 301 (.*) http://www.creang.com$1
</VirtualHost>
<VirtualHost *:80>
        ServerName www.creang.com
        DocumentRoot /var/www/creang
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        <Directory /var/www/creang>
                Options Indexes FollowSymLinks
                AllowOverride All
                Require all granted
        </Directory>
</VirtualHost>

The first VirtualHost section takes care of the redirect. Since this is a permanent redirect I went with 301, good for SEO-purposes. The second section points out the document root and sets some permissions where AllowOverride All is important for enabling the use of .htaccess-files, which we will use from WordPress in order to enable mod_rewrite and the use of clean urls.

Create a .htaccess file under /var/www/creang

root@ubuntu01:/etc/apache2# cd /var/www/creang/
root@ubuntu01:/var/www/creang# touch .htaccess
root@ubuntu01:/var/www/creang# chown nobody:www-data .htaccess
root@ubuntu01:/var/www/creang# chmod 664 .htaccess

Enable the rewrite module:

root@ubuntu01:/var/www/creang# a2enmod rewrite

Enable our site (adding the symlink to sites-enabled)

root@ubuntu01:/etc/apache2/sites-available# a2ensite vhosts-default.conf

A quick check shows the symlink was added:

root@ubuntu01:/etc/apache2/sites-enabled# ls -al
drwxr-xr-x 2 root root 4096 Jun 20 20:11 .
drwxr-xr-x 8 root root 4096 Jun 29 16:29 ..
lrwxrwxrwx 1 root root   38 Jun 20 18:07 vhosts-default.conf -> ../sites-available/vhosts-default.conf

Now we need to restart our apache server in order for the new wordpress site to come alive. Be aware that if you have configured your machine with a public IP-address then maybe you should set a temporary firewall rule in place first, so that only you (your ip-address) are allowed to access the server during setup of wordpress. Not so fun if anyone hijacks your wordpress installation.

Maybe something similar to below in order to allow only clients from a specific IP-range…and don’t forget to temporary remove the any-client-accept-rule and verify that the new rule takes full effect before continuing. Delete this rule later when you go live.

iptables -I INPUT 4 -p tcp --dport 80 -m iprange --src-range 85.229.17.1-85.229.17.254 -j ACCEPT

Restart or reload Apache service

 root@ubuntu01:/etc/apache2# service apache2 restart

Point your browser to your url. You should now see the welcome screen.

wp_initial_config

Type in your info and just click Install WordPress and you are done! :)

wp_confirm_install

Well…Almost done!, we want to use clean urls, login to you site with your newly created user…

wp_login

After login, go to Settings->Permalinks

wp_permalinks_settings

And choose your preferred way of displaying urls. Mine is using custom structure with both category and postname giving me urls such as this one:

http://www.creang.com/howtoforge/howto_set_up_your_perfectly_silent_home_server/

wp_permalinks

After “Save Changes” you will now have something similar to this in your .htaccess file:

root@ubuntu01:/var/www/creang# more .htaccess

# BEGIN WordPress
 <IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteRule ^index\.php$ - [L]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /index.php [L]
 </IfModule>
# END WordPress

Out of curiosity we can take a peek at the wordpress db and now see how the tables in the wp database were created. Since WordPress 4.2 utf8mb4 is used whenever possible, read more about it here https://make.wordpress.org/core/2015/04/02/the-utf8mb4-upgrade/

mysql> use wp_creang;

Database changed
mysql> show tables;
+-----------------------+
| Tables_in_wp_creang   |
+-----------------------+
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+
11 rows in set (0.00 sec)
mysql> show create table wp_comments;

...ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

Indeed utf8mb4 is used here.

That’s all for now. In the next blog-post we will look at setting up the WordPress-plugin Akismet to protect comments and contact forms from spam. Edit! Now available here.

 

Howto set up a Miraclebox 7 with Swedish cable provider comhem

Welcome,

The other day I decided to try out a Miraclebox 7 HD C/T2 Hybrid, using it with the Swedish cable provider comhem. The reason for this was I wanted to see if it was possible to record broadcasts unencrypted and later be able to play it back on any device, such as a computer. Here’s a walkthrough as to what I did…

miraclebox7_pic1

First of all, in order to be able to do recordings in an unencrypted way with comhem you need to use the built-in card reader with the Miraclebox.

miraclebox7_pic2
One built-in card-reader at the top and two CA-module slots underneath, and a front usb-port to the left.

You will not be able to record every HD-channel unencrypted although you are legally paying for a subscription with several HD-channels in the plan. Only Svt1 HD and Svt2 HD and all of the SD-channels will be available for recording. This has to do with the pairing comhem uses for the other HD-channels meaning the card has to be paired with your Set-top-box or CA-module (CI+). Comhem does not allow pairing with this box, but you can of course, with this box, put your card in a supported CA-module (CI+)…

comhem_ca_modul_med_ci_plus

…and then put the paired module (with card) in one of the CA-slots in the miraclebox, but that will make the recordings encrypted and locked for playback to that particular box only. That was not the mission of this project. However, most people does only have the basic-plan with comhem which does only come with two HD-channels (Svt1 HD and Svt2 HD), both of which does not require pairing but decryption, hence can be recorded unencrypted with the miraclebox built-in card-reader provided you have a card and a subscription with comhem. In that case, it makes perfect sense to use the built-in card reader since you will be able to record, in an unencrypted fashion, every channel you subscribe to. Please note that the following channels, as of June 2015, does not require a card, but only a set-top-box in order to be tuned into.

  • 1, SVT1
  • 2, SVT2
  • 4, TV4
  • 6, TV6
  • 14 FOX
  • 15 TV4 Fakta
  • 42 Axess TV
  • 125 Kunskapskanalen
  • 153 SVTB/SVT24

Now when we have the background, let’s start by flashing the box with the latest and greatest firmware. The fw can be downloaded from the miraclebox site here: fw_download_site

Now download and unzip the file m7-v2-11-87-ci-.zip and put the unzipped file FAC.MIRACLEBOX.7hdpvr.CIP.v2.11.87.ird on a usb-stick. Put that usb stick into one of the usb slots in the miraclebox (front- or back-side doesn’t matter which one).

miraclebox7_fwupdate2
Usb-stick with new firmware plugged into back-side usb port.

The box will automatically pick up that the new firmware is available.

miraclebox7_fwupdate3
Start the fw-upgrade by pressing the red button

 

miraclebox7_fwupdate4

Just wait until done. When finished and rebooted, choose “cable” and start the channel search…

miraclebox7_channel_search_cable

 

miraclebox_channel_search1

miraclebox_channel_search2

miraclebox_channel_search3

Now, you should be all set for watching and recording your channels. Please note that you need to plug in your comhem card into the card-reader otherwise you won’t be able to watch any encrypted channels in your subscription-plan. This is what will meet you in that case, see below. The chip-on-card should face downwards when inserted into the box.

miraclebox_encrypted_channel

The miraclebox 7 does not have any internal hard-drive slot so you have to use either a usb-drive/stick or some sort of network attached storage. The box will read ntfs drives which is a good thing for plug-and-play operability when moving your recordings to a PC or the like for playback or editing.

Borrowing a friends card temporarily just to try out the quality of a HD-recordings shows this:

recordings_folder

The recording creates a folder named Recordings with three files in it. The ts-file is the container with the video and sound muxed together. Opening the ts-file in tsMuxeR shows that, besides the video, the recording picks up both the MPEG-Audio track and the AC3 5.1-channel track. And the resolution of the video is 720p at 50 fps, sweet :)

recording_details

Recording a normal SD-channel gives typically these result:

recording_details2

My findings: It works very well to do unencrypted recordings with this box, but one thing to consider is that this box has only one tuner which makes it impossible to record any encrypted channel while watching another. You need a box with at least two tuners in that case. Maybe the VU+ Duo2 or Miraclebox 9 HD C/T2 TWIN is a better option in that case.

Please note that sharing any of your recordings with others can be subject of piracy and is not something I support, that is something you must avoid doing. You are allowed to keep copies of your recordings for your own personal use.

Miraclebox 7 features:

miraclebox7_features

Howto set up automatic dynamic DNS update using ddclient [Ubuntu]

Welcome

Does your ISP only offer you a dynamically allocated public ip-address through dhcp? You are not alone! Dynamic-DNS to the rescue! As we all may know, a DNS A-record i.e. example.com resolves to a particular ip-address i.e. 1.2.3.4. You normally set this record manually by logging in to your DNS-provider-account. However, if your ISP does not offer you a static ip-address it can be a hassle to run i.e. a webserver, should the ip-address suddenly change making your DNS-record point to a now obsolete address. Visitors lost in cyberspace. The way around this is to set up a deamon running on your server that regularly checks for changes in the ip-address, typically every 5 minutes, and make changes to your dns-account when needed. In this blog-post we will look at setting up ddclient for this purpose. We will use the Linux Ubuntu-distro when doing this. Let’s do it.

First install ddclient:

apt-get install ddclient

This will install and start a configuration wizard. Type in your data.

ddclient1

I choose “other” here since my dns-provider is not listed.

ddclient2

ddclient3

ddclient4

ddclient5

ddclient6

My NIC was named em1 which can be shown running the ifconfig command

ddclient7

ddclient8

ddclient9

ddclient10

ddclient11

That was the last entry, now I get this at the prompt when finishing:

update-rc.d: warning:  stop runlevel arguments (1) do not match ddclient Default-Stop values (0 1 6)

This warning can be ignored. Checking with sysv-rc-conf  we can see that the ddclient service is configured to be on for runlevels 2,3,4,5 as it should be.

root@ubuntu01:~# sysv-rc-conf --list ddclient
ddclient     1:off      2:on    3:on    4:on    5:on

Let’s check what /etc/default/ddclient now looks like

root@ubuntu01:~# more /etc/default/ddclient

# Configuration for ddclient scripts
# generated from debconf on Tue Jun 23 11:47:25 CEST 2015
#
# /etc/default/ddclient

run_ipup="false"

run_daemon="true"

daemon_interval="300"

Ok, so everything looks nice and dandy here. deamon-mode true and update interval check every 300 seconds (5 minutes). Now take a peek what we got in /etc/ddclient.conf

root@ubuntu01:~# more /etc/ddclient.conf
# Configuration file for ddclient generated by debconf
#
# /etc/ddclient.conf

protocol=dyndns2
use=if, if=em1
server=dns.loopia.se/XDynDNSServer/XDynDNS.php
login=creang.com
password='password_here'
creang.com,creang.se

Ok, so no using of ssl here, I want the deamon to use ssl when calling my dns-provider-account for security reasons, so I put that as well in the config file, also my dns-provider does only support system=custom

ssl=yes
custom=yes

Please note that the line use=if, if=em1 will check for any change in ip-address against the NIC. This is viable if you have the public-ip assigned directly to your network interface, like I have. If you are running your server behind a router/firewall using NAT-forwarding then you will want to configure the use of requesting a web-page in order to fetch your current public ip-address, like this:

use=web, web=dns.loopia.se/checkip/checkip.php, 
web-skip='Current IP Address:'

Now, all done!

Just restart the service with:

 root@ubuntu01:~# service ddclient restart

We can now see that the deamon is running just fine with the pstree -p command

ddclient_pstree

ddclient running as process 1348, runs every 300 seconds, five minutes

root@ubuntu01:~# ps -ef|grep ddclient
root  1348  1  0 13:10 pts/0  00:00:00 ddclient - sleeping for 110 seconds

Should you want to re-run the configuration wizard, use this command:

dpkg-reconfigure ddclient

Double check that everything is working correctly with this command:

root@ubuntu01:~# ddclient -daemon=0 -debug -verbose -noquiet
...
DEBUG:    get_ip: using if, em1 reports 85.225.140.7
SUCCESS:  creang.com: skipped: IP address was already set to 85.225.140.7.
SUCCESS:  creang.se: skipped: IP address was already set to 85.225.140.7.

Howto set up your perfectly silent home server [Ubuntu Server 14.04 LTS]

Welcome.

This guide will walk you through setting up a dead-silent Linux home server with Ubuntu Server 14.04.2 LTS that you can have running twenty-four-seven-365 in your living room without getting annoyed by any fan or hard-drive noise. This server has no moving parts in it except for the AC/DC-current running through the electronics. Let’s dig in!

First let’s get some appropriate hardware. After doing some research I went for the Shuttle DS57U barebone which is a fanless Slim-PC. You can find a great review of it here: Shuttle DS57U Review

This barebone comes with everything except hard-drive, memory modules and operating system. The barebone alone will set you down at around $230 (1900 SEK), sales tax excluded, price as of june 2015.

Since the focus of this project is not to get away cheap but to have a stable, dead-silent server, I went on the prowl for a suitable SSD and then of course a pair of SO-DIMMs. Also, I will have a lot of writes to this machine so I went for a more expensive datacenter ssd, the Samsung 845DC Pro-series that will stand the test of time. You may want to go for a cheaper alternative here, this Samsung-drive however, will also have protection from exposure to data corruption or loss caused by unexpected power outages.

Procurement-list (prices as of June 2015 in Sweden, VAT excl.):

  • 1 x Shuttle DS57U – Celeron 3205U 1.5 GHz, $230 (1900 SEK)
  • 2 x Kingston Valueram/8GB, KVR16LS11/8, $110 (2x$55) (880 SEK)
  • 1 x Samsung 845DC Pro 400GB SSD Data Center, $315 (2560 SEK)

Ok, so lets install the hardware…this is pretty straight forward. Flip the case and unscrew the two screws holding each lid. Slide forward and open.

shuttle_open_case

Now, unscrew the drive-guide and fixate it to the ssd, use the two black screws coming with the shuttle case.

ssd_mounted_in_guide

Plug the ssd into the hard-drive slot and fixate it by putting the screw back in place. Put the two SO-DIMMs in the memory slots, be gentle and don’t touch the memory modules more than necessary holding only on the edges, make sure they snap in-place correctly. The result will look like this.

shuttle_ssd_and_memory_installed

Now, put the covers back on, and connect all the wires and fire up the machine. Hit Del or Esc to enter Bios-setup.

bios_setup_hit_del_or_esc

Ok, so because this machine is a server and we want it to always be ON we change the setting “Power-On after Power-Fail” to [Power On]. Disable EuP Function to enable this alternative.

bios4

Now, save and exit. Having downloaded and burnt the Ubunto-iso-image before, now is the time to plug in an external usb-dvd-drive into the Shuttle and load it with the Ubuntu-dvd-media. You can of course use a prepared, with Ubuntu, usb-stick if you rather use that for installation. Reboot and start the installation.

external_dvd_usb_drive

When asked about partitioning, I chose to use all available space on the ssd to be used for the Ubuntu-installation, but you can of course choose to partition your drive in any way you prefer. When asked which software to install I selected OpenSSH-server and LAMP-server since I will later install and run wordpress on this box using LAMP (Linux, Apache, MySQL, PHP).

software_installation

Now point your ssh-client to the ip-address of your Shuttle-server. If you use dhcp, you can find out what ip-address the machine got after bootup by typing the command ifconfig from a terminal. I get up to five public ip-addresses (dhcp-assigned) from my ISP so I will use one dedicated to this machine. I will later blog about how to configure automatic dynamic-dns updates should the ip-address change. Edit! Now available here howto-set-up-automatic-dynamic-dns-update-using-ddclient

The DS57U comes with two built-in NICs so you might want to use one for your home internal network (192.168.X.X) plugged into your broadband router and one plugged into a (dumb) switch sitting first in line with the connection toward your ISP. Or maybe you prefer to team the NICs for redundancy, I will however start with using just one NIC with a public IP-address. Let’s start to secure and configure this beast.

Log in with SSH and become root with “sudo -s”, the -s option gives you a root-shell. Just type exit and hit return whenever you want to exit from this shell.

jbilander@ubuntu01:~$ sudo -s
[sudo] password for jbilander:
root@ubuntu01:~#

putty

Run these two commands as root to get the latest updates installed

root@ubuntu01:~# apt-get update
root@ubuntu01:~# apt-get upgrade

Let’s start by disabling ipv6. I know some people say this is not conforming to best practice but I don’t care :) I’m not going to run ipv6 on this machine so I want to get rid of it. To disable ipv6, you have to open /etc/sysctl.conf using any text editor (I use VIM) and insert the following lines:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Comment out anything related to ipv6 in /etc/hosts

# The following lines are desirable for IPv6 capable hosts
#::1     localhost ip6-localhost ip6-loopback
#ff02::1 ip6-allnodes
#ff02::2 ip6-allrouters

Change sshd to only listen to ipv4, in file /etc/ssh/sshd_config change to:

AddressFamily inet

In /etc/dhcp/dhclient.conf delete the entries below…

dhcp6.name-servers, dhcp6.domain-search,
dhcp6.fqdn, dhcp6.sntp-servers;

…and put in the semi-colon after the last entry (ntp-servers). It should now look like this:

request subnet-mask, broadcast-address, time-offset, routers, domain-name, domain-name-servers, domain-search, host-name, netbios-name-servers, netbios-scope, interface-mtu, rfc3442-classless-static-routes, ntp-servers;

Now, after a reboot we should be all set, and no more using of tcp6 or udp6, right?. Running the command netstat -nap however shows this:

udp        0 0.0.0.0:3704                           739/dhclient
udp        0 0.0.0.0:68                             739/dhclient
udp6       0 :::52382                               739/dhclient

Why the udp6-entry when we have deleted all the dhcp6-entries in dhclient.conf? It appears to be a bug, read here, I guess I’ll have to live with it for the time being.

Lets set up a firewalling using iptables:

Iptables comes with Ubuntu by default but does not have any rules added to it by default, hence no blocking of traffic by default. I’m going to configure the machine to listen to port 22 and 80 only, allowing ssh and http incoming traffic from any source, and block all other incoming traffic. There is one accept-rule that we need to ensure so that our server can function correctly. The loopback device. Services on the computer need to be able to communicate with each other by sending network packets to each other through the loopback device. Add these rules one-by-one from the command-line for a basic configuration:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -j DROP

You can double check the entries with command iptables -S to verify.

Now, persist the change with these two commands:

apt-get update
apt-get install iptables-persistent

Should you need to delete a rule you can do it by this command giving the -D option and row number, in this case input-rule number four will be deleted: iptables -D INPUT 4

If you need to add a new rule at a certain row i.e. 5, maybe open up for incoming https traffic (port 443) then use this command

iptables -I INPUT 5 -p tcp --dport 443 -j ACCEPT

Line numbers and rules will be shown by this command:

iptables -L --line-numbers

If you do any changes to iptables from now on, persist the change with this command before rebooting:

iptables-save > /etc/iptables/rules.v4

Reboot machine!

That’s all for now, in the next blog we will look at howto configure LAMP-server and setup wordpress on this server. Edit! Now available here: howto_set_up_wordpress_on_ubuntu_lamp_server