Title: Making a home NAS using NixOS | |
Author: Solène | |
Date: 18 October 2020 | |
Tags: nixos linux nas | |
Description: | |
Still playing with [NixOS](https://nixos.org/), I wanted to experience | |
how difficult it would be to write a NixOS configuration file to | |
turn a computer into a simple NAS with basics features: samba | |
storage, dlna server and auto suspend/resume. | |
What is [NixOS](https://nixos.org/features.html)? As a reminder for | |
some and introduction to the others, NixOS is a Linux distribution | |
built by the Nix package manager, which make it very different than | |
any other operating system out there, except | |
[Guix](https://guix.gnu.org/) | |
which has a similar approach with their own package manager written | |
in Scheme. | |
NixOS uses a declarative configuration approach along with lot of | |
others features derived from Nix. What's big here is you no longer | |
tweak anything in `/etc` or install packages, you can define the | |
working state of the system in one configuration file. This system | |
is a totally different beast than the others OS and require some | |
time to understand how it work. Good news though, **everything** | |
is documented in the man page `configuration.nix`, from fstab | |
configuration to users managements or how to enable samba! | |
Here is the `/etc/nixos/configuration.nix` file on my NAS. | |
It enables ssh server, samba, minidlna and vnstat. Set up a user | |
with my ssh public key. Ready to work. | |
Using `rtcwake` command (Linux specific), it's possible to put | |
the system into standby mode and schedule an auto resume after | |
some time. This is triggered by a cron job at 01h00. | |
{ config, pkgs, ... }: | |
{ | |
# include stuff related to hardware, auto generated at install | |
imports = [ ./hardware-configuration.nix ]; | |
boot.loader.grub.device = "/dev/sda"; | |
networking.interfaces.enp3s0.ipv4.addresses = [ { | |
address = "192.168.42.150"; | |
prefixLength = 24; | |
} ]; | |
networking.defaultGateway = "192.168.42.1"; | |
networking.nameservers = [ "192.168.42.231" ]; | |
i18n.defaultLocale = "fr_FR.UTF-8"; | |
console = { font = "Lat2-Terminus16"; keyMap = "fr"; }; | |
time.timeZone = "Europe/Paris"; | |
environment.systemPackages = with pkgs; [ | |
kakoune vnstat borgbackup utillinux | |
]; | |
networking.firewall.enable = false; | |
services.openssh.enable = true; | |
services.vnstat.enable = true; | |
services.cron.systemCronJobs = [ | |
"0 1 * * * root rtcwake -m mem --date +6h" | |
]; | |
services.samba.enable = true; | |
services.samba.enableNmbd = true; | |
services.samba.extraConfig = '' | |
workgroup = WORKGROUP | |
server string = Samba Server | |
server role = standalone server | |
log file = /var/log/samba/smbd.%m | |
max log size = 50 | |
dns proxy = no | |
map to guest = Bad User | |
''; | |
services.samba.shares = { | |
public = { | |
path = "/home/public"; | |
browseable = "yes"; | |
"writable" = "yes"; | |
"guest ok" = "yes"; | |
"public" = "yes"; | |
"force user" = "share"; | |
}; | |
}; | |
services.minidlna.enable = true; | |
services.minidlna.announceInterval = 60; | |
services.minidlna.friendlyName = "Rorqual"; | |
services.minidlna.mediaDirs = ["A,/home/public/Musique/" | |
"V,/home/public/Videos/"]; | |
# note that tmpfiles are not necesserarly temporary if you don't | |
# set an expire time. Trick given on irc by someone I forgot the | |
name.. | |
systemd.tmpfiles.rules = [ "d /home/public 0755 share users" ]; | |
users.users.solene = { | |
isNormalUser = true; | |
extraGroups = [ "wheel" "sudo" ]; | |
openssh.authorizedKeys.keys = [ | |
"ssh-ed25519 | |
AAAAC3NzaC1lZDI1NTE5AAAAIOIZKLFQXVM15viQXHYRjGqE4LLfvETMkjjgSz0mzMzS | |
personal" | |
"ssh-ed25519 | |
AAAAC3NzaC1lZDI1NTE5AAAAIOIZKLFQXVM15vAQXBYRjGqE6L1fvETMkjjgSz0mxMzS | |
pro" | |
]; | |
}; | |
# I prefer a dedicated one than "nobody" | |
# can't log into it | |
users.users.share= { | |
isNormalUser = false; | |
}; | |
} | |