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…
 
 
Go to file
Yves G 3f8dd657f3 mediaplayer: add DRM ability to Kodi, for e.g. Netflix 2022-12-04 22:22:46 +01:00
group_vars miscellaneous fixes 2021-11-11 20:42:57 +01:00
roles mediaplayer: add DRM ability to Kodi, for e.g. Netflix 2022-12-04 22:22:46 +01:00
tools 1yr-old; first commit 2018-09-09 21:51:21 +02:00
LICENSE 1yr-old; first commit 2018-09-09 21:51:21 +02:00
README.adoc miscellaneous fixes 2021-11-11 20:42:57 +01:00
bootstrap.adoc from python2 to python3 2020-04-16 13:13:23 +02:00
production 1yr-old; first commit 2018-09-09 21:51:21 +02:00
site.yml miscellaneous fixes 2021-11-11 20:42:57 +01:00

README.adoc

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/////
# 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 Debians 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 theyre in need of way more documentation…

This project is also a way for me to _learn_ Ansible, and Id 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.
.....