Initial commit
This commit is contained in:
commit
f6b942023c
1
.envrc
Normal file
1
.envrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export NIX_PATH=nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=$(expand_path .)/configuration.nix:/nix/var/nix/profiles/per-user/root/channels
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
result
|
||||||
|
.*.swp
|
18
README.md
Normal file
18
README.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
hamburg.freifunk.net Statistik
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Initiales Setup
|
||||||
|
-----
|
||||||
|
1. System starten
|
||||||
|
2. Passwörter liegen nach dem Start des ersten Dienstes jeweils unter `/var/lib/*/*.pw`
|
||||||
|
3. Nginx konfigurieren um ACME zu benutzen
|
||||||
|
4. services.influxdb.extraConfig.http.auth-enabled auf true setzen
|
||||||
|
5. Config für Collector erstellen und hier ablegen: /var/lib/private/collector/ffhh.conf
|
||||||
|
6. Grafana konfigurieren
|
||||||
|
|
||||||
|
|
||||||
|
Development
|
||||||
|
-----
|
||||||
|
Starten des Systems:
|
||||||
|
QEMU_NET_OPTS="hostfwd=tcp:127.0.0.1:2222-:22,hostfwd=tcp:127.0.0.1:8080-:80" nixos-shell
|
||||||
|
Zugriff dann per SSH über 127.0.0.1:2222 und HTTP über 127.0.0.1:8080.
|
9
acme.nix
Normal file
9
acme.nix
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
security.acme.acceptTerms = true;
|
||||||
|
security.acme.email = "kontakt@hamburg.freifunk.net";
|
||||||
|
users.groups.certs = {
|
||||||
|
members = [ "nginx" ];
|
||||||
|
};
|
||||||
|
}
|
29
collector.nix
Normal file
29
collector.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
collector = pkgs.fetchFromGitHub {
|
||||||
|
owner = "tokudan";
|
||||||
|
repo = "ffhh-stats";
|
||||||
|
rev = "76c61a0c0f7d276fd79026b551780e318901adf6";
|
||||||
|
sha256 = "0irnc8ffm413aq3sh64sd2457yp2ax4paaf0ss9r1pkbkb8q5dgx";
|
||||||
|
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.services.collector = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
requires = [ "influxdb.service" ];
|
||||||
|
path = [ pkgs.wget ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 65;
|
||||||
|
DynamicUser = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
StateDirectory = "collector";
|
||||||
|
# The config file is actually in /var/lib/private/collector, systemd maps that path to /var/lib/collector
|
||||||
|
ExecStart = "${pkgs.ruby.withPackages (ps: with ps; [ json ])}/bin/ruby ${collector}/query-data.influx --config /var/lib/collector/ffhh.conf";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
104
configuration.nix
Normal file
104
configuration.nix
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
# Edit this configuration file to define what should be installed on
|
||||||
|
# your system. Help is available in the configuration.nix(5) man page
|
||||||
|
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
||||||
|
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[
|
||||||
|
./acme.nix
|
||||||
|
./sshusers.nix
|
||||||
|
./nginx.nix
|
||||||
|
./grafana.nix
|
||||||
|
./influxdb.nix
|
||||||
|
./collector.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# Use the GRUB 2 boot loader.
|
||||||
|
boot.loader.grub.enable = true;
|
||||||
|
boot.loader.grub.version = 2;
|
||||||
|
boot.loader.grub.device = "/dev/vda";
|
||||||
|
|
||||||
|
swapDevices = [{ device = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0-part2"; randomEncryption.enable = true; randomEncryption.source = "/dev/random"; }];
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
hostName = "stats";
|
||||||
|
domain = "hamburg.freifunk.net";
|
||||||
|
hostId = "7d7135dd";
|
||||||
|
firewall.rejectPackets = true;
|
||||||
|
firewall.logRefusedConnections = false;
|
||||||
|
usePredictableInterfaceNames = false;
|
||||||
|
dhcpcd.enable = false;
|
||||||
|
nameservers = [ "213.133.99.99" "213.133.100.100" "213.133.98.98" ];
|
||||||
|
interfaces.eth0 = {
|
||||||
|
ipv4.addresses = [ { address = "142.132.181.225"; prefixLength = 32; } ];
|
||||||
|
ipv6.addresses = [ { address = "2a01:4f8:1c17:dbfb::1"; prefixLength = 64; } ];
|
||||||
|
};
|
||||||
|
defaultGateway = { address = "172.31.1.1"; interface = "eth0"; };
|
||||||
|
defaultGateway6 = { address = "fe80::1"; interface = "eth0"; };
|
||||||
|
};
|
||||||
|
|
||||||
|
# Automatic update each day
|
||||||
|
system.autoUpgrade.enable = true;
|
||||||
|
system.autoUpgrade.allowReboot = true;
|
||||||
|
nix = {
|
||||||
|
autoOptimiseStore = true;
|
||||||
|
gc.automatic = true;
|
||||||
|
gc.options = "--delete-older-than 14d";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Select internationalisation properties.
|
||||||
|
i18n.defaultLocale = "de_DE.UTF-8";
|
||||||
|
|
||||||
|
# Set your time zone.
|
||||||
|
time.timeZone = "Europe/Berlin";
|
||||||
|
|
||||||
|
# List packages installed in system profile. To search, run:
|
||||||
|
# $ nix search wget
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
git htop lsof mosh nano screen socat traceroute vim wget
|
||||||
|
];
|
||||||
|
|
||||||
|
# Some programs need SUID wrappers, can be configured further or are
|
||||||
|
# started in user sessions.
|
||||||
|
programs.mtr.enable = true;
|
||||||
|
programs.screen.screenrc = ''
|
||||||
|
hardstatus alwayslastline
|
||||||
|
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B} %m-%d %{W}%c:%s %{g}]'
|
||||||
|
defscrollback 1000
|
||||||
|
'';
|
||||||
|
|
||||||
|
# List services that you want to enable:
|
||||||
|
|
||||||
|
# Support mosh connections
|
||||||
|
programs.mosh.enable = true;
|
||||||
|
|
||||||
|
# Open ports in the firewall.
|
||||||
|
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||||
|
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||||
|
|
||||||
|
# User configuration for root.
|
||||||
|
# Other users are defined in sshusers.nix
|
||||||
|
users.extraUsers.root = {
|
||||||
|
hashedPassword = "!!";
|
||||||
|
};
|
||||||
|
users.motd = with config; ''
|
||||||
|
Welcome to ${networking.hostName}.${networking.domain}
|
||||||
|
|
||||||
|
- This server is NixOS
|
||||||
|
- All changes must be done through the git repository at
|
||||||
|
/etc/nixos or https://github.com/freifunkhamburg/stats-nixos-config/
|
||||||
|
- Other changes will be lost
|
||||||
|
|
||||||
|
OS: NixOS ${system.nixos.release} (${system.nixos.codeName})
|
||||||
|
Version: ${system.nixos.version}
|
||||||
|
Kernel: ${boot.kernelPackages.kernel.version}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# This value determines the NixOS release with which your system is to be
|
||||||
|
# compatible, in order to avoid breaking some software such as database
|
||||||
|
# servers. You should change this only after NixOS release notes say you
|
||||||
|
# should.
|
||||||
|
system.stateVersion = "21.11"; # Did you read the comment?
|
||||||
|
}
|
53
grafana.nix
Normal file
53
grafana.nix
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.grafana = {
|
||||||
|
enable = true;
|
||||||
|
analytics.reporting.enable = false;
|
||||||
|
protocol = "socket";
|
||||||
|
rootUrl = "https://stats.besaid.de/";
|
||||||
|
auth.anonymous.enable = false;
|
||||||
|
security = {
|
||||||
|
adminUser = "dfrank";
|
||||||
|
adminPasswordFile = "/var/lib/grafana/admin.pw";
|
||||||
|
secretKeyFile = "/var/lib/grafana/security.key";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.grafana.serviceConfig = {
|
||||||
|
# upstream module already defines most hardening options
|
||||||
|
IPAddressDeny = "any";
|
||||||
|
IPAddressAllow = "localhost";
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ExecStartPost = [
|
||||||
|
(pkgs.writeScript "grafana-socket-perms" ''
|
||||||
|
#!${pkgs.stdenv.shell}
|
||||||
|
until chmod -c 666 /run/grafana/grafana.sock ; do sleep 1; done
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
systemd.services.grafana-init = {
|
||||||
|
description = "Grafana Service Daemon - initialize files";
|
||||||
|
wantedBy = [ "grafana.service" ];
|
||||||
|
before = [ "grafana.service" ];
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
script = ''
|
||||||
|
#!${pkgs.stdenv.shell}
|
||||||
|
set -euo pipefail
|
||||||
|
# Make sure everything but the password ends up on stderr
|
||||||
|
exec 3>&1 >&2
|
||||||
|
mkdir -p /var/lib/grafana
|
||||||
|
if [ ! -s /var/lib/grafana/admin.pw ]; then
|
||||||
|
head -c 30 /dev/urandom | base64 > /var/lib/grafana/admin.pw
|
||||||
|
chmod 400 /var/lib/grafana/admin.pw
|
||||||
|
chown grafana:grafana /var/lib/grafana/admin.pw
|
||||||
|
fi
|
||||||
|
if [ ! -s /var/lib/grafana/security.key ]; then
|
||||||
|
head -c 30 /dev/urandom | base64 > /var/lib/grafana/security.key
|
||||||
|
chmod 400 /var/lib/grafana/security.key
|
||||||
|
chown grafana:grafana /var/lib/grafana/security.key
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
80
influxdb.nix
Normal file
80
influxdb.nix
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
environment.systemPackages = [ pkgs.influxdb ];
|
||||||
|
services.influxdb = {
|
||||||
|
enable = true;
|
||||||
|
dataDir = "/var/lib/influxdb";
|
||||||
|
extraConfig = {
|
||||||
|
meta.reporting-disabled = true;
|
||||||
|
data.query-log-enabled = false;
|
||||||
|
http.bind-address = "localhost:8086";
|
||||||
|
http.auth-enabled = false;
|
||||||
|
http.log-enabled = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.influxdb = {
|
||||||
|
before = [ "grafana.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
LockPersonality = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ReadWritePaths = "/var/lib/influxdb";
|
||||||
|
RestrictAddressFamilies = [ "~AF_PACKET" "~AF_NETLINK" "~AF_UNIX" ];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
RemoveIPC = true;
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = [ "~@clock" "~@cpu-emulation" "~@debug" "~@module" "~@mount" "~@obsolete" "~@privileged" "~@raw-io" "~@reboot" "~@resources" "~@swap" ];
|
||||||
|
CapabilityBoundingSet = "";
|
||||||
|
IPAddressDeny = "any";
|
||||||
|
IPAddressAllow = "localhost";
|
||||||
|
UMask = "077";
|
||||||
|
RuntimeDirectory = "influxdb";
|
||||||
|
ExecStartPost = lib.mkForce [ (pkgs.writeShellScript "influxdb-first-run" ''
|
||||||
|
#!${pkgs.stdenv.shell}
|
||||||
|
set -euo pipefail
|
||||||
|
if [ ! -s /var/lib/influxdb/admin.pw ]; then
|
||||||
|
INIT=1
|
||||||
|
head -c 30 /dev/urandom | base64 > /var/lib/influxdb/admin.pw
|
||||||
|
chmod 400 /var/lib/influxdb/admin.pw
|
||||||
|
fi
|
||||||
|
if [ ! -s /var/lib/influxdb/knotendaten.pw ]; then
|
||||||
|
head -c 30 /dev/urandom | base64 > /var/lib/influxdb/knotendaten.pw
|
||||||
|
chmod 400 /var/lib/influxdb/knotendaten.pw
|
||||||
|
fi
|
||||||
|
if [ ! -s /var/lib/influxdb/grafana.pw ]; then
|
||||||
|
head -c 30 /dev/urandom | base64 > /var/lib/influxdb/grafana.pw
|
||||||
|
chmod 400 /var/lib/influxdb/grafana.pw
|
||||||
|
fi
|
||||||
|
until ${pkgs.curl}/bin/curl --connect-timeout 1 http://127.0.0.1:8086/ping; do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
if [ -v INIT ]; then
|
||||||
|
read -r adminpw < /var/lib/influxdb/admin.pw
|
||||||
|
read -r knotendatenpw < /var/lib/influxdb/knotendaten.pw
|
||||||
|
read -r grafanapw < /var/lib/influxdb/grafana.pw
|
||||||
|
${config.services.influxdb.package}/bin/influx -execute 'create database freifunk'
|
||||||
|
${config.services.influxdb.package}/bin/influx -database freifunk -execute "create user admin with password '$adminpw'"
|
||||||
|
${config.services.influxdb.package}/bin/influx -database freifunk -execute "create user grafana with password '$grafanapw'"
|
||||||
|
${config.services.influxdb.package}/bin/influx -database freifunk -execute "create user knotendaten with password '$knotendatenpw'"
|
||||||
|
${config.services.influxdb.package}/bin/influx -database freifunk -execute "grant read on freifunk to grafana"
|
||||||
|
${config.services.influxdb.package}/bin/influx -database freifunk -execute "grant all on freifunk to admin"
|
||||||
|
fi
|
||||||
|
'') ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
17
nginx.nix
Normal file
17
nginx.nix
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
#logError = "/dev/null";
|
||||||
|
recommendedGzipSettings = true;
|
||||||
|
recommendedOptimisation = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
virtualHosts."stats" = {
|
||||||
|
default = true;
|
||||||
|
locations."/".proxyPass = "http://unix:${config.services.grafana.socket}:/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
32
sshusers.nix
Normal file
32
sshusers.nix
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
# Setup users. To add a new user:
|
||||||
|
# 1. Add the name of the user to the list in the second-to-last line
|
||||||
|
# 2. Make sure that the git repo contains the key as "$USER.pub"
|
||||||
|
# 3. Make sure that the commit ("rev") contains the latest commit hash. If it correct, jump to step 7.
|
||||||
|
# 4. If you changed the commit, manipulate the sha512 entry by changing the first character from 0 to 1 or 1 to 0.
|
||||||
|
# 5. Run "nixos-rebuild build"
|
||||||
|
# 6. Wait for a message about an invalid hash and replace the hash in this file with the new one.
|
||||||
|
# 7. Run "nixos-rebuild switch"
|
||||||
|
# 8. Let the user login and change their password
|
||||||
|
|
||||||
|
let
|
||||||
|
sshkeys = pkgs.fetchFromGitHub {
|
||||||
|
owner = "freifunkhamburg";
|
||||||
|
repo = "ssh-keys";
|
||||||
|
rev = "286c324f0c0c9ddfd37eee286d064b36dc5e4c2c";
|
||||||
|
sha512 = "034d5y75wr8vyz3r222hxar1wm0vmqryvgcji2lh1f8jxpgs3nchb0w2qv44msz085s9p4i92s96z9cb8zapmwj3anm0p8f156pf34c";
|
||||||
|
};
|
||||||
|
getpubkeys = user: builtins.readFile "${sshkeys}/${user}.pub";
|
||||||
|
mkuser = user: { name = user; isNormalUser = true; extraGroups = [ "wheel" ]; initialPassword = "test1234"; openssh.authorizedKeys.keys = [ (getpubkeys user) ]; };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
# Only allow login through pubkey
|
||||||
|
passwordAuthentication = false;
|
||||||
|
challengeResponseAuthentication = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users = lib.genAttrs [ "tokudan" ] mkuser ;
|
||||||
|
}
|
Loading…
Reference in a new issue