From Linux Install to WordPress

A typical installation of Debian 8.x (Jessie) precedes this where I only select base system and ssh server options during operating system installation.  After installation, this is a typical configuration to get me up and running. These are my notes.

Debian Customization

These are customizations to suit my taste.

apt-get update && apt-get upgrade
dpkg-reconfigure dash
echo UseDNS no >>/etc/ssh/sshd_config && /etc/init.d/ssh restart
apt-get install fail2ban vim-nox unzip

Webserver Installation: nginx

wget http://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key
echo 'deb http://nginx.org/packages/debian/ jessie nginx' >> /etc/apt/sources.list
echo 'deb-src http://nginx.org/packages/debian/ jessie nginx' >> /etc/apt/sources.list
apt-get update && apt-get install nginx

nginx Configuration

There are a few customizations I make and I have scripted most of this since it’s repetitive.

In the first line below, worker_processes 2; is derived from grep 'cpu cores' /proc/cpuinfo | head -1
sed -i 's/user[ ]*nginx/user www-data/g; s/worker_processes[ ]*1/worker_processes 2/g' /etc/nginx/nginx.conf
sed -i 's/access_log.*;/access_log off;/g' /etc/nginx/nginx.conf
sed -i '/access_log off;/a client_max_body_size 12m;' /etc/nginx/nginx.conf
/etc/init.d/nginx restart

With basic configuration changes made to nginx.conf, I now focus on creating the site configuration.

rm /etc/nginx/conf.d/*

cat <<EOF >>/etc/nginx/conf.d/`hostname`.conf
server {
        listen 80;
        root /var/www;
        index index.php index.html index.htm;

        server_name techish.net www.techish.net;

        location / {
                try_files $uri $uri/ /index.php;
        }

        location ~ .php$ {
                try_files $uri =404;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name
;
                include fastcgi_params;
                fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        }

    location ~ /.well-known {
                allow all;
        }
}
EOF

That concludes nginx installation and configuration to THIS point. I’ll revisit toward the end when I implement SSL.

PHP 7 Installation

I use dotdeb to install PHP 7.0 via apt-get.

echo 'deb http://packages.dotdeb.org jessie all' >> /etc/apt/sources.list
echo 'deb-src http://packages.dotdeb.org jessie all' >> /etc/apt/sources.list
wget https://www.dotdeb.org/dotdeb.gpg
apt-key add dotdeb.gpg
apt-get update
apt-get install php7.0-fpm php7.0-mysql php7.0-gd php7.0-mcrypt

PHP 7 Configuration

With PHP7 installation completed, I make a few changes.

sed -i 's/^upload_max_filesize.*/upload_max_filesize = 10m/g; s/^allow_url_fopen.*/allow_url_fopen = Off/g; s/^post_max_size.*/post_max_size = 12m/g' /etc/php/7.0/fpm/php.ini

MySQL (MariaDB) Installation

Installing MariaDB is pretty straight forward with only a minor tweak in the configuration at the end.

apt-get install mariadb-server

MariaDB Configuration

sed -i 's/^bind-address/#bind-address/g; /^#bind-address/a skip-networking' /etc/mysql/my.cnf
mysql_secure_installation

Restart Services & Test

Restart the services and test out things to make sure everything works.

systemctl restart nginx.service
systemctl restart php7-fpm.service
systemctl restart mysql.service

WordPress Installation

WordPress installation is straight forward.

Database Preparation

Make sure to substitute wordpress, wpuser and ... below to reflect your database, database username and database user password.
cd /var/www
mysql -uroot -p -e create database wordpress; grant all on wordpress.* to 'wpuser'@'%' identified by '...'; flush privileges

WordPress Download & Extract

wget https://wordpress.org/latest.zip
unzip latest.zip
mv wordpress/* .
rm -rf wordpress/; rm latest.zip
chown www-data.www-data -R .

WordPress Configuration

At this point, the database is ready to go and I just visit my website to finish the WordPress installation via Web interface.

Let’s Encrypt SSL Certificate

Installation

openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Add Jessie backports repo and install.

echo 'deb http://ftp.debian.org/debian jessie-backports main' >>/etc/apt/sources.list
apt-get update
apt-get install certbot -t jessie-backports

Certificate Generation

I generate a certificate for my top level domain and subdomain.

certbot certonly --webroot -w /var/www -d techish.net
certbot certonly --webroot -w /var/www -d www.techish.net

nginx SSL Configuration

Create a directory in /etc/nginx to store a few snippets of nginx configuration.

mkdir /etc/nginx/ssl

Create SSL parameters configuration file, ssl-params.conf, that we’ll call in our site configuration file.

cat <<EOF >>/etc/nginx/ssl/ssl-params.conf
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
    ssl_ecdh_curve secp384r1;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    add_header Strict-Transport-Security max-age=63072000; includeSubdomains; preload;
    add_header Strict-Transport-Security max-age=63072000; includeSubdomains;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
EOF

Create a configuration file, ssl-kreider.conf, that will reference where my top level domain SSL certificate is stored. I call this file from main nginx site configuration file later.

cat <<EOF >>/etc/nginx/ssl/ssl-kreider.conf
ssl_certificate /etc/letsencrypt/live/techish.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/techish.net/privkey.pem;
EOF

Create a configuration file, ssl-www-kreider.conf, that will reference where my www subdomain SSL certificate is stored. I call this file from main nginx site configuration file later.

cat <<EOF >>/etc/nginx/ssl/ssl-www-kreider.conf
ssl_certificate /etc/letsencrypt/live/www.techish.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.techish.net/privkey.pem;
EOF

I update my main site’s nginx configuration.

Note that `hostname` will expand the system hostname automatically. Replace `hostname`.conf (including backticks) with your configuration file name as applicable.
vim /etc/nginx/conf.d/`hostname`.conf

My finalized site configuration file.

server {
        listen 80;
        server_name techish.net www.techish.net;
        return 307 https://techish.net$request_uri;
}

server {
        listen 443 ssl;
        include ssl/ssl-kreider.conf;
        include ssl/ssl-params.conf;
        root /var/www;
        index index.php index.html index.htm;

        server_name techish.net;

        location / {
                try_files $uri $uri/ /index.php;
        }

        location ~ .php$ {
                try_files $uri =404;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name                                                                                                                               ;
                include fastcgi_params;
                fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        }
}

How to Join a Debian Linux Server to a Windows Domain

I’ve added a few servers to a test Windows domain and some of those servers include Debian Linux operating systems. Here are the basic steps on joining a Debian server to Windows Active Directory Domain and setting up domain user login on the Linux server.

I assume you have an installation of Debian up and running.  I used Debian 8 Jessie in my post.

Install Necessary Packages

$ apt-get install realmd ntp adcli sssd

Post Installation Tasks

$ mkdir -p /var/lib/samba/private
$ systemctl enable sssd

Join Domain

Make sure we can get information about the domain we want to join.

$ realm discover techish.local
techish.local
  type: kerberos
  realm-name: TECHISH.LOCAL
  domain-name: techish.local
  configured: no
  server-software: active-directory
  client-software: sssd
  required-package: sssd-tools
  required-package: sssd
  required-package: libnss-sss
  required-package: libpam-sss
  required-package: adcli
  required-package: samba-common-bin

All looks good, now join.

$ realm join --user=administrator techish.local
Password for administrator:
 * Installing necessary packages: samba-common-bin, sssd-tools

Start SSSD

$ systemctl start sssd

At this point, should be joined and we can now test authentication for users…

$ getent passwd rkreider@techish.local
rkreider@techish.local:*:485401343:485400513:Richard J. Kreider:/home/techish.local/rkreider:/bin/bash

Home Directory Setup

$ echo session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 | tee -a /etc/pam.d/common-session

Local Admin Privileges

Think Domain Admin on a Windows PC, but for Linux – sudo.

On Debian 8.6, this was installed when sssd was installed – but, just to make sure:

$ apt-get install libsss-sudo
$ echo %domain admins@techish.local ALL= ALL | tee -a /etc/sudoers.d/domain_admins

Logging in as Domain User

login as: techish
kreider
techish
kreider@debian's password:
rkreider@techish.local@debian:~$

Mixing Stable, Unstable, Testing and Experimental Packages in Debian

This is a very useful article from ServerFault on installing mixed packages in Debian.

Many people seem to be afraid of mixing stable with testing, but frankly, testing is fairly stable in its own right, and with proper preferences and solution checking, you can avoid the stability drift that puts your core packages on the unstable path.

Testing is fairly stable??, you ask. Yes. In order for a package to migrate from unstable to testing, it has to have zero open bugs for 10 consecutive days. Chances are that, especially for the more popular packages, somebody is going to submit a bug report for an unstable version if something is wrong.

Even if you don’t want to mix the environments, it’s still nice to have the option there in case you run into some thing that requires a newer version than what is in stable.

Here’s what I recommend for setting this up:

First, create the following files in /etc/apt/preferences.d:

security.pref:

Package: *
Pin: release l=Debian-Security
Pin-Priority: 1000

stable.pref:

Package: *
Pin: release a=stable
Pin-Priority: 900

testing.pref:

Package: *
Pin: release a=testing
Pin-Priority: 750

unstable.pref:

Package: *
Pin: release a=unstable
Pin-Priority: 50

experimental.pref:

Package: *
Pin: release a=experimental
Pin-Priority: 1

(Don’t be afraid of the unstable/experimental stuff here. The priorities are low enough that it’s never going to automatically install any of that stuff. Even the testing branch will behave, as it’s only going to install the packages you want to be in testing.)

Now, creating a matching set for /etc/apt/sources.list.d:

security.list:

deb     http://security.debian.org/         stable/updates  main contrib non-free
deb     http://security.debian.org/         testing/updates main contrib non-free

stable.list:

deb     http://mirror.steadfast.net/debian/ stable main contrib non-free
deb-src http://mirror.steadfast.net/debian/ stable main contrib non-free
deb     http://ftp.us.debian.org/debian/    stable main contrib non-free
deb-src http://ftp.us.debian.org/debian/    stable main contrib non-free

testing.list: Same as stable.list, except with testing.

unstable.list: Same as stable.list, except with unstable.

experimental.list: Same as stable.list, except with experimental.

You can replace the steadfast.net mirror with whatever you want. I’d recommend using netselect-apt to figure out the fastest mirror, and use that for your first choice. The ftp.us.debian.org can be used as a backup. It’s also important to use the terms stable, testing, unstable, etc., instead of squeeze, wheezy, sid, etc., since stable is a moving target and when it comes time to upgrade to the latest stable, apt/aptitude will figure that out automatically.

You can also add a oldstable in sources.lists.d and preferences.d (use a priority of 1), though this moniker will tend to expire and disappear before the next stable cycle. In cases like that, you can use http://archive.debian.org/debian/ and hardcode the Debian version (etch, lenny, etc.).

To install the testing version of a package, simply use aptitude install lib-foobar-package/testing, or just jump into aptitude’s GUI and select the version inside of the package details (hit enter on the package you’re looking at).

If you get complaints of package conflicts, look at the solutions first. In most cases, the first one is going to be don’t install this version. Learn to use the per-package accept/reject resolver choices. For example, if you’re installing foobar-package/testing, and the first solution is don’t install foobar-package/testing, then mark that choice as rejected, and the other solutions will never veer to that path again. In cases like these, you’ll probably have to install a few other testing packages.

If it’s getting too hairy (like it’s trying to upgrade libc or the kernel or some other huge core system), then you can either reject those upgrade paths or just back out of the initial upgrade altogether. Remember that it’s only going to upgrade stuff to testing/unstable if you allow it to.

New Linux Server Build

I finished up a new linux server build tonight. Migrated WordPress, DNS, mail, FTP and a handful of other services to this new server as well as installing LXDE GUI front-end.

width=804

LXDE

Debian Handbook

I have added the Debian Handbook to my Resources navigation menu.

Debian 6.0 Handbook

The handbook is available at: https://techish.net/debian-handbook/

You can install it on your Debian system (available in Unstable):

apt-get install debian-handbook

The documentation is stored in: /usr/share/doc/debian-handbook/.

You can also download the handbook from Raphael’s site: http://raphaelhertzog.com/2012/05/10/the-debian-administrators-handbook-is-available/ as well as from the handbook development site: http://debian-handbook.info/