This repository contains Ansible playbooks and roles to transform your RaspberryPi (or another system based on Debian/Ubuntu) into a NAS. At the very heart, the term NAS refers to a machine with:
- a secure OpenSSH server to automatically backup files
- encrypted file transfer (SSH)
- key-based authentication (e.g. backupnas for UNIX clients, FreeFileSync for Windows clients)
- with all users created and configured automatically
fail2ban
enabled
However, this playbook supports a variety of services (e.g. Samba, DLNA, Nextcloud) that can be plugged in by specifying one or more tags.
While most configuration options are hard-coded to fit the recommendations for the respective service, you can configure (among others):
- users, their SSH keys and passwords
- storage locations
- folders accessible via DLNA
- mail account used for system notifications
mount
: automatically mount external hard drives to store user data/backups atbackup
: schedule restic to securely backup the entire user data (at 2 a.m.) to a local directory / external hard drive or remote location (SFTP)cloud
: Nextcloud server to upload and share files in a personal cloud- encrypted file transfer (HTTPS)
- automatically renewed SSL certificates (Let's Encrypt)
- Mozilla's intermediate SSL configuration (secure but aiming for compatibility)
- fully installed and configured
- including all required components and users
- applying performance recommendations and hardening
- encrypted file transfer (HTTPS)
samba
: Samba server to access stored files from any desktop or mobile device in your network- password authentication for users, optional guest shares
- unencrypted file transfer
dlna
: DLNA server to access stored media files from a SmartTV etc.- automatically discover and play videos and/or music
- unencrypted file transfer
mumble
: Mumble server (aka. Murmur) for low-latency voice chatsddns
: dynamic DNS update client- hourly (and on reboot) reports the device's IP address to DynV6, to have it accessible via a domain
auto-upgrade
: keep installed software up-to-dateufw
: firewall to restrict incoming traffic to the selected services (i.e. specified tags)openvpn-config
: make the device an OpenVPN client/server to form a network with another device
In order to apply this playbook to one of your machines, there are basically two steps required:
-
configure the inventory to your needs
-
Run the playbook, using tags to precisely choose which services to install:
ansible-playbook -i inventories/example setup.yml --tags samba,nextcloud
The configuration consists of
- global variables at
group_vars/all.yml
- an Ansible inventory containing
- the address of the remote machine(s) at
hosts.yml
- specific variables at
group_vars/nas/vars.yml
- specific credentials in an Ansible vault at
group_vars/nas/vault
- the address of the remote machine(s) at
- files to be copied to the remote machine in the
files
folder
The example inventory at inventories/example
can be copied and fully adapted to your needs.
The configuration variables are loosely structured by the features that this playbook offers. If you use tags to selectively enable features, you only have to adapt their variables and may omit others.
Check existing files for available variables and their meaning.
Interval | Description | Active when feature selected |
---|---|---|
daily at 2 a.m. | backup user data | backup |
daily at 5 a.m. | rescan miniDLNA directories | dlna |
Note: Instead of forwarding relevant ports from your router to the NAS, strongly consider using a VPN to avoid any unencrypted file transfer (e.g. Samba) via internet.
The NAS runs different services that operate on various ports. When operating the NAS behind a router (i.e. firewall), these ports have to be accessible.
In case you insist on using port forwarding, the following ports are used by the respective services:
Service | TCP | UDP |
---|---|---|
Samba | 139, 445 | 137, 138 |
OpenSSH | 22 | |
Nextcloud | 80, 443 |
These are the default ports. Strongly-consider to expose the services at non-default ports to prevent the load and risk caused by bots. An execption are the ports 80 and 443, as they are required for the automatic certificate renewal.
This repository contains make goals (scripts) to setup a permanent OpenVPN connection between machines with internet access. One of them acts as the server and thus must be reachable via internet (e.g. dynamic DNS).
There are multiple participants in such an OpenVPN setup:
- certificate authority (CA): owns the key that will sign server and client certificates; may be an offline machine (more secure but requires manually copying files) or your Ansible host
- server: accepts OpenVPN connections by clients; must be accessible via internet (best to use dynamic DNS)
- clients: connect to the server; must have internet access to reach the server
Depending on a machine's role (i.e. type of participant), a different property has to be used in the respective Ansible inventory.
Use the openvpn.server
property in the inventory of the machine that will act as the server and use the openvpn.client
property for all remaining machines.
On the CA machine, initialize the CA, generating key and certificate:
make openvpn-ca-init
On the Ansible host and for each participant, install OpenVPN, create a certificate request and retrieve it:
make ANSIBLE_INVENTORY=<inventory> openvpn-initialize
On the Ansible host, pack the retrieved requests:
make openvpn-pack-requests
If you use a dedicated offline machine as CA: This will create a ZIP file including all retrieved requests at
./files-ca-transit/requests.zip
. Copy this archive file to the same relative path on the CA machine now.
On the CA machine, import and sign all requests:
make openvpn-ca-sign-requests
If you use a dedicated offline machine as CA: This will create a ZIP file including all certificates at
./files-ca-transit/certificates.zip
. Copy this archive file to the same relative path on the Ansible host now.
Extract the certificate archive
make openvpn-extract-certificates
and distribute the certificates to each OpenVPN participant via
make ANSIBLE_INVENTORY=<inventory> openvpn-configure
This will also start the OpenVPN service on each machine and should leave you with a working OpenVPN setup (wait a few minutes).