Setup of a multi-purpose home-server using Ansible: systemd, nftables, port-knocking, etckeeper, Let’s Encrypt, dynamic DNS, OpenLDAP, SSO, mail, PostgreSQL, Dotclear, Gitea, Nextcloud, NFS, XMPP, print & scan, DLNA, Transmission, iodine…
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
Yves G 32e259d777 miscellaneous fixes 9 months ago
group_vars miscellaneous fixes 2 months ago
roles miscellaneous fixes 2 months ago
tools 1yr-old; first commit 3 years ago
LICENSE 1yr-old; first commit 3 years ago
README.adoc miscellaneous fixes 2 months ago
bootstrap.adoc from python2 to python3 2 years ago
production 1yr-old; first commit 3 years ago
site.yml miscellaneous fixes 2 months ago

README.adoc

/////
# The home-server project produces a multi-purpose setup using Ansible.
# Copyright © 2018 Y. Gablin, under the GPL-3.0-or-later license.
# Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing.
/////

= Automated configuration of a home-server
:toc:

== Introduction

This project contains a collection of https://docs.ansible.com/[Ansible] rules, that:

* both automate and document the setup of a home-server, as secure as possible;
* should greatly ease the quick setup of a replacement server, in case the main one has a hardware failure (this is for a single machine, not a datacenter).

Let it be clear, that the target is a *home*-server, not an entreprise solution, not a personal VM “in the Cloud”, but a real hardware machine plugged at home to the xDSL or fiber router, that links you to an ISP.
Besides, this project should not be used without *solid knowledge of Linux and its command-line, as well as https://git-scm.com/[Git]*!

Oh! And I decided to let go of Debian, and use https://www.archlinux.org/[Archlinux] instead.
Someone once questionned me about such a choice for a server; here was my answer:

[quote, Yves, https://linuxfr.org/news/pyruse-1-0-pour-remplacer-fail2ban-et-autres-scruteurs-de-journaux-sur-un-gnu-linux-moderne#comment-1729871]
_____
In practice, Archlinux is working pretty well on a server. Before that, I was using Debian.
My experience (for a server) is such:

Archlinux::
* `−` There is almost always something to handle after software upgrades ⇒ I never let these upgrades run automatically unsupervised.
* `+` On the other hand, the solutions to the problems that arise are always simple, and I know that I can handle them.
* `+` Moreover, the software is always up-to-date, which makes exploring new use-cases so much easier!
* `+` Finally, it is trivial to package new software, as I did with https://yalis.fr/git/yves/pyruse/[Pyruse]; this allows me to avoid `./configure && make install` steps in my Ansible playbook.

Debian::
* `+` Updates usually just happen, almost unnoticed.
* `−` But when there _is_ a failure, I have to delve into Debian’s idiosyncrasies, and this is not always easy…
* `+` Security updates are done in a serious way, which compensates for the age of the packets.
* `−` But as time passes, some software becomes complicated, or even impossible in some cases, to test.

Everything is in the personal balance that suits you.
I am perfectly comfortable with the command line, and Archlinux is better suited to my goals.
But one should not be dogmatic: other Linux distributions may be better suited to other situations.
_____

== What can the server do?

Here is what is currently available (I will not repeat “automated” every time, since everything is done with Ansible):

* a container acting as a https://en.wikipedia.org/wiki/DMZ_(computing)[DMZ], which is the only part of the server, that the Internet can reach;
* firewalls (one for the DMZ, the other for the backend server);
* as much https://freedesktop.org/wiki/Software/systemd/[systemd] as possible (almost all logs, the DMZ, network, ntp, dns…);
* systemd journals’ scrutation with automatic reporting of urgent situations, and a daily report;
* `/etc` changes followed in Git, with a separation between the upstream state (branch `master`) and the everyday state (branch `run`);
* certificate renewal using the https://letsencrypt.org/how-it-works/[ACME protocol], and certificate deployment to the locations where the software needs it;
* software upgrades;
* https://en.wikipedia.org/wiki/Dynamic_DNS[dynamic DNS] handling (remember, this is a _home_ server, where a fixed IPv4 address is not a given);
* centralized handling of users in https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol[LDAP];
* a web portal and https://en.wikipedia.org/wiki/Single_sign-on[SSO], to reach the different web services for registered users;
* a web https://en.wikipedia.org/wiki/User_interface[UI] for handling LDAP entries and mail aliases (also in LDAP);
* mail handling, with SMTP and IMAP;
* a PostgreSQL database;
* an SSH server, hidden with https://en.wikipedia.org/wiki/Port_knocking[port-knocking];
* a web server configured to allow additional contents for clients who port-knocked properly;
* a https://en.wikipedia.org/wiki/Blog[blog];
* a web UI for the Git projects hosted on the server;
* a “personal cloud”, for files (https://en.wikipedia.org/wiki/WebDAV[WebDAV]), contacts (https://en.wikipedia.org/wiki/CardDAV[CardDAV]), and calendars (https://en.wikipedia.org/wiki/CalDAV[CalDAV]), all (and more!) freely synchronizable with an https://www.fairphone.com/en/[Android smartphone];
* automatic mounting of the “personal cloud” files when logging in on the server;
* an https://en.wikipedia.org/wiki/Network_File_System[NFS] server;
* an https://en.wikipedia.org/wiki/XMPP[XMPP] server;
* a print server;
* a scan server;
* a remote-controlled media server (requires audio and video outputs);
* a https://en.wikipedia.org/wiki/Digital_Living_Network_Alliance[DLNA]/uPNP server;
* a private https://en.wikipedia.org/wiki/Pastebin[pastebin]-like service;
* a https://en.wikipedia.org/wiki/BitTorrent[BitTorrent] server;
* a https://github.com/yarrick/iodine[DNS tunnel];
* a SSH-over-link:https://en.wikipedia.org/wiki/Transport_Layer_Security[TLS] tunnel;
* https://en.wikipedia.org/wiki/Bonjour_(software)[Bonjour]-SD (Service-Discovery);
* a web UI for bookmarks (work in progress…);
* a web XMPP client (work in progress…).

== Current status

This configuration has led to a working server, which has been up and running for more than a year.
However:

* the Ansible rules written here still have rough edges;
* this is a quick (one might say hasty) publishing of the current Ansible rules, and they’re in need of way more documentation…

This project is also a way for me to _learn_ Ansible, and I’d be happy to know if I misused Ansible somewhere `:-)`

== Requirements

A domain name is needed.
It is expected that DNS entries are handled by an external service, because the home-server does not do that itself.
For example, https://dns.he.net/[Hurricane Electric] can be used. +
For testing purposes, a free temporary domain may be used, for example at https://freedns.afraid.org/[Free DNS].

At home, the server needs to be connected to a router that has these properties:

* allows machines on the LAN to have a fixed IP: the server, and also all terminals (PC, Android…) that shall be trusted;
* has a “DMZ mode” (ie. route all incoming Internet traffic — with possible exceptions — to a chosen IP on the LAN), or at least port-by-port NAT;
* is a gateway to the Internet for LAN machines;
* allows all incoming and outgoing traffic (most notably SMTP, which tends to be blocked by default);

The server itself should have at least 2GB of RAM, and at least 2 CPU cores (for better multitasking).
On my https://www.udoo.org/udoo-x86/[Basic Udoo X86] (2GB RAM and 4× https://ark.intel.com/fr/products/92124/Intel-Atom-x5-E8000-Processor-2M-Cache-up-to-2_00-GHz[x5-E8000]@1.04GHz CPU), with all of the above services running, I get good performance, 60% RAM used, and an average system load of 8%, which is rather good!

Last but not least, the machine that will run the Ansible playbook should:

* have a version of Ansible greater than 2.2:
** module `include_role` runs dynamically (available since version 2.4),
** modules `ini_file`, `lineinfile`, `mount`, and `replace` use the `path` parameter (available since version 2.3),
** module `ldap_attrs` is used (available since version 3.4),
** module `lineinfile` uses the `firstmatch` parameter (available since version 2.5),
** module `user` uses the `create_home` parameter (available since version 2.5);

* have a static IP address on the LAN, because only this computer will be allowed to run Ansible commands on the server, using the dedicated SSH key;

* have the following software installed: `dig` (DNS lookup), `python-netaddr` (Python3).

== Usage

First, the server must be link:bootstrap.adoc[prepared, so that Ansible can connect and run the rules].

Then the rules are run by launching this command at the root of the project:

```bash
$ ansible-playbook -i production site.yml
```

[literal.small]
.....
# The home-server project produces a multi-purpose setup using Ansible.
# Copyright © 2018 Y. Gablin, under the GPL-3.0-or-later license.
# Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing.
.....