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