@ -13,7 +13,7 @@ let
} )
] ;
} ;
pkgs = ( import ( fetchTarball " h t t p s : / / g i t h u b . c o m / N i x O S / n i x p k g s -c h a n n e l s /a r c h i v e / n i x o s - 2 0. 0 3 . t a r . g z " ) nixpkgsOptions ) ;
pkgs = ( import ( fetchTarball " h t t p s : / / g i t h u b . c o m / N i x O S / n i x p k g s /a r c h i v e / n i x o s - 2 1. 1 1 . t a r . g z " ) nixpkgsOptions ) ;
presets = {
base = ( import ./presets/base.nix ) ;
kvm = ( import ./presets/kvm.nix ) ;
@ -25,6 +25,9 @@ let
} ;
nodes = ( import ./data/nodes.nix ) ;
tincConfiguration = ( import ./lib/tinc-configuration.nix ) ;
trackSystemMetrics = ( import ./lib/track-system-metrics.nix ) ;
trackServiceMetrics = ( import ./lib/track-service-metrics.nix ) ;
httpHealthChecks = ( import ./lib/http-health-checks.nix ) ;
in {
network = {
inherit pkgs ;
@ -33,6 +36,7 @@ in {
" m a c h i n e - b o r g 2 - 0 1 . c r y t o . n e t " = { pkgs , lib , . . . }: {
system . stateVersion = " 1 8 . 0 9 " ;
networking . hostName = " m a c h i n e - b o r g 2 - 0 1 " ;
# FIXME: Why is this needed?
nixpkgs . overlays = [ ] ;
@ -42,6 +46,8 @@ in {
presets . kvm
./hardware-configurations/machine-borg2-01.nix
( tincConfiguration { hostname = " m a c h i n e - b o r g 2 - 0 1 . c r y t o . n e t " ; nodes = nodes ; } )
( trackSystemMetrics nodes . " m a c h i n e - b o r g 2 - 0 1 . c r y t o . n e t " . internalIpv4 )
( trackServiceMetrics nodes . " m a c h i n e - b o r g 2 - 0 1 . c r y t o . n e t " . internalIpv4 )
] ;
boot . loader . grub . device = lib . mkForce " / d e v / v d a " ;
@ -71,6 +77,7 @@ in {
group = " b a c k u p - f 0 x " ;
authorizedKeys = [
" s s h - e d 2 5 5 1 9 A A A A C 3 N z a C 1 l Z D I 1 N T E 5 A A A A I N j J D P 2 T D y j 1 X / L 6 g N g H C X A S I W o W / V n J 7 7 F Q y 3 9 V R T i 8 f 0 x @ e l e p h a n t u s "
" s s h - e d 2 5 5 1 9 A A A A C 3 N z a C 1 l Z D I 1 N T E 5 A A A A I B + d w s W e 1 / u j R 0 N 4 I x P v 7 m f y i u K W U R c 6 Q w Y N J + V V 8 K A 6 f 0 x @ b e h e m o t h "
] ;
authorizedKeysAppendOnly = [
" s s h - e d 2 5 5 1 9 A A A A C 3 N z a C 1 l Z D I 1 N T E 5 A A A A I G 7 W S U Y 6 Y 2 l s I a w o 8 d P B u 4 / O m x 6 c 7 / 1 S M D 9 v e / v p c o r N b o r g - b a c k u p @ t e r r a "
@ -94,41 +101,37 @@ in {
" m a c h i n e - h a l e s s - 0 3 . c r y t o . n e t " = { pkgs , lib , config , . . . } @ args : {
system . stateVersion = " 1 9 . 0 3 " ;
networking . hostName = " m a c h i n e - h a l e s s - 0 3 " ;
imports = [
presets . base
presets . kvm
./hardware-configurations/machine-haless-03.nix
( tincConfiguration { hostname = " m a c h i n e - h a l e s s - 0 3 . c r y t o . n e t " ; nodes = nodes ; } )
] ;
deployment . healthChecks . http = let
makeHostChecker = { protocol , port }: host : {
scheme = protocol ;
port = port ;
path = " / " ;
host = host ;
description = " ${ host } ( ${ protocol } : ${ toString port } ) i s u p " ;
} ;
httpHosts = hosts : map ( makeHostChecker { protocol = " h t t p " ; port = 80 ; } ) hosts ;
httpsHosts = hosts : map ( makeHostChecker { protocol = " h t t p s " ; port = 443 ; } ) hosts ;
in lib . mkMerge [
( httpHosts [
( trackSystemMetrics nodes . " m a c h i n e - h a l e s s - 0 3 . c r y t o . n e t " . internalIpv4 )
( trackServiceMetrics nodes . " m a c h i n e - h a l e s s - 0 3 . c r y t o . n e t " . internalIpv4 )
( httpHealthChecks {
http = [
" i o m f a t s . c r y t o . n e t "
" c a s t l e r o l a n d . c r y t o . n e t "
" a w e s o m e d u d e . c r y t o . n e t "
" m a t r i x - r o o m s . c r y t o . n e t "
" v a l i d a t e m . c r y t o . n e t "
" n i x o s - m a n u a l - m d x . c r y t o . n e t "
] )
( httpsHosts [
" g e o j s o n . c r y t o . n e t "
" o s s w o r k s . n l "
] ;
https = [
" i o m f a t s . c r y t o . n e t "
" c a s t l e r o l a n d . c r y t o . n e t "
" a w e s o m e d u d e . c r y t o . n e t "
" m a t r i x - r o o m s . c r y t o . n e t "
" v a l i d a t e m . c r y t o . n e t "
" n i x o s - m a n u a l - m d x . c r y t o . n e t "
] )
" g e o j s o n . c r y t o . n e t "
" o s s w o r k s . n l "
] ;
} )
] ;
networking . firewall . allowedTCPPorts = [ 80 443 ] ;
@ -166,6 +169,10 @@ in {
( nginxPresets . letsEncrypt )
{ root = ./sources/modular-matrix ; }
] ;
" g e o j s o n . c r y t o . n e t " = lib . mkMerge [
( nginxPresets . letsEncrypt )
{ root = ../../image-to-geojson/static ; }
] ;
# "validatem.cryto.net" = lib.mkMerge [
# (nginxPresets.letsEncrypt)
# { root = ./sources/validatem-site; }
@ -174,6 +181,10 @@ in {
( nginxPresets . letsEncrypt )
{ root = ../../validatem/site/build ; }
] ;
" o s s w o r k s . n l " = lib . mkMerge [
( nginxPresets . letsEncrypt )
{ root = ../../ossworks-site/build ; }
] ;
" n i x o s - m a n u a l - m d x . c r y t o . n e t " = lib . mkMerge [
( nginxPresets . letsEncrypt )
{ root = ../../nixos-manual-mdx/build ; }
@ -222,8 +233,11 @@ in {
} ;
} ;
users . extraUsers . mobile-proxy = {
users . groups . mobile-proxy = { } ;
users . users . mobile-proxy = {
description = " m o b i l e - p r o x y S e r v i c e U s e r " ;
isSystemUser = true ;
group = " m o b i l e - p r o x y " ;
} ;
systemd . services . mobile-proxy = let
@ -250,8 +264,11 @@ in {
} ;
} ;
users . extraUsers . matrix-rooms = {
users . groups . matrix-rooms = { } ;
users . users . matrix-rooms = {
description = " m o b i l e - p r o x y S e r v i c e U s e r " ;
isSystemUser = true ;
group = " m a t r i x - r o o m s " ;
} ;
systemd . services . matrix-rooms = let
@ -283,12 +300,15 @@ in {
" m a c h i n e - k o n j a s s i e m - 0 2 . c r y t o . n e t " = { pkgs , lib , config , . . . } @ args : {
system . stateVersion = " 2 0 . 0 3 " ;
networking . hostName = " m a c h i n e - k o n j a s s i e m - 0 2 " ;
imports = [
presets . base
presets . kvm
./hardware-configurations/machine-konjassiem-02.nix
( tincConfiguration { hostname = " m a c h i n e - k o n j a s s i e m - 0 2 . c r y t o . n e t " ; nodes = nodes ; } )
( trackSystemMetrics nodes . " m a c h i n e - k o n j a s s i e m - 0 2 . c r y t o . n e t " . internalIpv4 )
( trackServiceMetrics nodes . " m a c h i n e - k o n j a s s i e m - 0 2 . c r y t o . n e t " . internalIpv4 )
] ;
services . postgresql = {
@ -331,13 +351,40 @@ in {
} ;
# NOTE: Workaround that removes `setuid` from the disallowed syscall list, because otherwise sendmail/opensmtpd breaks
systemd . services . gitea . serviceConfig . SystemCallFilter = lib . mkForce " ~ @ c l o c k @ c p u - e m u l a t i o n @ d e b u g @ k e y r i n g @ m e m l o c k @ m o d u l e @ m o u n t @ o b s o l e t e @ r a w - i o @ r e b o o t @ r e s o u r c e s @ s w a p " ;
# systemd.services.gitea.serviceConfig.SystemCallFilter = lib.mkForce "~@clock @cpu-emulation @debug @keyring @memlock @module @mount @obsolete @raw-io @reboot @resources @swap";
# Temporary workaround to make opensmtpd sendmail work (ref. https://github.com/NixOS/nixpkgs/issues/103446)
# Can remain enabled
systemd . services . gitea . serviceConfig . PrivateMounts = lib . mkForce true ;
systemd . services . gitea . serviceConfig . PrivateTmp = lib . mkForce true ;
systemd . services . gitea . serviceConfig . ProtectControlGroups = lib . mkForce true ;
systemd . services . gitea . serviceConfig . ProtectHome = lib . mkForce true ;
systemd . services . gitea . serviceConfig . ProtectSystem = lib . mkForce " f u l l " ; # downgraded from "strict"
# Have to be disabled
systemd . services . gitea . serviceConfig . LockPersonality = lib . mkForce false ;
systemd . services . gitea . serviceConfig . MemoryDenyWriteExecute = lib . mkForce false ;
systemd . services . gitea . serviceConfig . NoNewPrivileges = lib . mkForce false ;
systemd . services . gitea . serviceConfig . PrivateDevices = lib . mkForce false ;
systemd . services . gitea . serviceConfig . PrivateUsers = lib . mkForce false ;
systemd . services . gitea . serviceConfig . ProtectClock = lib . mkForce false ;
systemd . services . gitea . serviceConfig . ProtectHostname = lib . mkForce false ;
systemd . services . gitea . serviceConfig . ProtectKernelLogs = lib . mkForce false ;
systemd . services . gitea . serviceConfig . ProtectKernelModules = lib . mkForce false ;
systemd . services . gitea . serviceConfig . ProtectKernelTunables = lib . mkForce false ;
systemd . services . gitea . serviceConfig . RestrictAddressFamilies = lib . mkForce [ ] ;
systemd . services . gitea . serviceConfig . RestrictRealtime = lib . mkForce false ;
systemd . services . gitea . serviceConfig . RestrictSUIDSGID = lib . mkForce false ;
systemd . services . gitea . serviceConfig . SystemCallArchitectures = lib . mkForce " " ;
systemd . services . gitea . serviceConfig . SystemCallFilter = lib . mkForce [ ] ;
# FIXME: Healthcheck for this!
services . gitea = {
enable = true ;
user = " g i t " ;
appName = " C r y t o G i t " ;
repositoryRoot = " / v a r / l i b / r e p o s i t o r i e s " ;
log . level = " I n f o " ;
domain = " g i t . c r y t o . n e t " ;
httpAddress = " l o c a l h o s t " ;
@ -351,57 +398,38 @@ in {
user = " g i t " ;
} ;
extraConfig = ''
[ database ]
LOG_SQL = false
[ service ]
ENABLE_CAPTCHA = true
REGISTER_EMAIL_CONFIRM = true
ENABLE_NOTIFY_MAIL = true
ENABLE_USER_HEATMAP = false
[ security ]
PASSWORD_COMPLEXITY = off
[ session ]
PROVIDER = file
[ mailer ]
ENABLED = true
MAILER_TYPE = sendmail
FROM = " C r y t o G i t " < noreply @ git . cryto . net >
SENDMAIL_PATH = $ { pkgs . system-sendmail } /bin/sendmail
'' ;
settings = {
server = {
LOCAL_ROOT_URL = " h t t p : / / l o c a l h o s t : 3 0 0 0 / " ;
} ;
# FIXME: Use this instead of extraConfig in 20.09
# settings = {
# database = {
# LOG_SQL = false;
# };
database = {
LOG_SQL = false ;
} ;
# service = {
# ENABLE_CAPTCHA = true;
# REGISTER_EMAIL_CONFIRM = true;
# ENABLE_NOTIFY_MAIL = true;
# ENABLE_USER_HEATMAP = false;
# };
service = {
ENABLE_CAPTCHA = true ;
REGISTER_EMAIL_CONFIRM = true ;
ENABLE_NOTIFY_MAIL = true ;
ENABLE_USER_HEATMAP = false ;
} ;
# security = {
# PASSWORD_COMPLEXITY = "off";
# };
security = {
PASSWORD_COMPLEXITY = " o f f " ;
INTERNAL_TOKEN = lib . mkForce " e y J h b G c i O i J I U z I 1 N i I s I n R 5 c C I 6 I k p X V C J 9 . e y J u Y m Y i O j E 2 M D U 0 N z Q 1 M z h 9 . X q S 6 - h a 2 2 V N g t U P _ m V k Z X C M m s t - l O 8 b l F A E p W M S l U 5 g " ;
} ;
# session = {
# PROVIDER = "file";
# };
session = {
PROVIDER = " f i l e " ;
} ;
# mailer = {
# ENABLED = true;
# MAILER_TYPE = "sendmail";
# FROM = "\"Cryto Git\" <noreply@git.cryto.net>";
# SENDMAIL_PATH = "${pkgs.system-sendmail}/bin/sendmail";
# };
# } ;
mailer = {
ENABLED = true ;
MAILER_TYPE = " s e n d m a i l " ;
FROM = " \" C r y t o G i t \" < n o r e p l y @ g i t . c r y t o . n e t > " ;
SENDMAIL_PATH = " ${ pkgs . system-sendmail } / b i n / s e n d m a i l " ;
} ;
} ;
} ;
# FIXME: DKIM/DMARC
@ -415,4 +443,161 @@ in {
'' ;
} ;
} ;
" m a c h i n e - p i k a c h u - 0 2 . c r y t o . n e t " = { pkgs , lib , config , . . . } @ args : {
system . stateVersion = " 1 9 . 0 3 " ;
networking . hostName = " m a c h i n e - p i k a c h u - 0 2 " ;
imports = [
presets . base
presets . kvm
./hardware-configurations/machine-pikachu-02.nix
( tincConfiguration { hostname = " m a c h i n e - p i k a c h u - 0 2 . c r y t o . n e t " ; nodes = nodes ; } )
( trackSystemMetrics nodes . " m a c h i n e - p i k a c h u - 0 2 . c r y t o . n e t " . internalIpv4 )
( trackServiceMetrics nodes . " m a c h i n e - p i k a c h u - 0 2 . c r y t o . n e t " . internalIpv4 )
] ;
} ;
" m a c h i n e - w o r k b o t - 0 1 . c r y t o . n e t " = { pkgs , lib , config , . . . } @ args : {
system . stateVersion = " 1 8 . 0 3 " ;
networking . hostName = " m a c h i n e - w o r k b o t - 0 1 " ;
imports = [
presets . base
./hardware-configurations/machine-workbot-01.nix
( tincConfiguration { hostname = " m a c h i n e - w o r k b o t - 0 1 . c r y t o . n e t " ; nodes = nodes ; } )
( trackSystemMetrics " 1 2 7 . 0 . 0 . 1 " )
( trackServiceMetrics " 1 2 7 . 0 . 0 . 1 " )
( httpHealthChecks {
both = [
" h y d r a . c r y t o . n e t "
" p r o m e t h e u s . c r y t o . n e t "
" m e t r i c s . c r y t o . n e t "
# "nix-cache.cryto.net" # Not directory-indexable
] ;
} )
] ;
services . nginx = {
enable = true ;
virtualHosts = {
" 4 0 4 . c r y t o . n e t " = {
# Pseudo-hostname just to set a default when no Host header is specified
default = true ;
extraConfig = ''
return 404 ;
'' ;
} ;
" h y d r a . c r y t o . n e t " = lib . mkMerge [
( nginxPresets . letsEncrypt )
( nginxPresets . reverseProxy " h t t p : / / l o c a l h o s t : 3 3 3 3 / " )
] ;
" p r o m e t h e u s . c r y t o . n e t " = lib . mkMerge [
( nginxPresets . letsEncrypt )
( nginxPresets . reverseProxy " h t t p : / / l o c a l h o s t : 9 0 9 0 / " )
] ;
" m e t r i c s . c r y t o . n e t " = lib . mkMerge [
( nginxPresets . letsEncrypt )
( nginxPresets . reverseProxy " h t t p : / / l o c a l h o s t : 8 4 5 2 / " )
] ;
" n i x - c a c h e . c r y t o . n e t " = lib . mkMerge [
( nginxPresets . letsEncrypt )
{ root = " / v a r / l i b / h y d r a - b u i l d s " ; }
] ;
} ;
} ;
services . postgresql = {
enable = true ;
} ;
services . hydra = {
enable = true ;
port = 3333 ;
hydraURL = " h t t p : / / h y d r a . c r y t o . n e t / " ;
notificationSender = " h y d r a @ c r y t o . n e t " ;
useSubstitutes = false ;
minimumDiskFree = 20 ;
minimumDiskFreeEvaluator = 20 ;
buildMachinesFiles = pkgs . lib . mkIf ( config . nix . buildMachines == [ ] ) [ ] ;
extraConfig = ''
store_uri = file:///var/lib/hydra-builds?secret-key=/var/lib/hydra/binary-cache.key&write-nar-listing=1
binary_cache_public_uri = https://nix-cache.cryto.net
'' ;
} ;
services . prometheus = {
enable = true ;
globalConfig = {
scrape_interval = " 3 0 s " ;
} ;
scrapeConfigs = let
nameInstance = address : name : {
source_labels = [ " _ _ a d d r e s s _ _ " ] ;
target_label = " i n s t a n c e " ;
regex = address ;
replacement = name ;
} ;
mapToPort = port : builtins . map ( host : " ${ host . internalIpv4 } : ${ builtins . toString port } " ) ;
mapToPortRelabel = port : builtins . map ( host : ( nameInstance " ${ host . internalIpv4 } : ${ builtins . toString port } " host . friendlyName ) ) ;
# Replace the workbot node (ie. ourselves) with an entry that points directly at localhost instead
nodes_ = builtins . attrValues ( nodes // {
" m a c h i n e - w o r k b o t - 0 1 . c r y t o . n e t " = {
friendlyName = " w o r k b o t " ;
internalIpv4 = " l o c a l h o s t " ;
} ;
} ) ;
in [
{
job_name = " p r o m e t h e u s " ;
static_configs = [ {
targets = [
" l o c a l h o s t : 9 0 9 0 "
] ;
} ] ;
relabel_configs = [
( nameInstance " l o c a l h o s t : 9 0 9 0 " " w o r k b o t " )
] ;
} {
job_name = " n o d e s " ;
scrape_interval = " 1 0 s " ;
static_configs = [ {
targets = mapToPort 9100 nodes_ ;
} ] ;
relabel_configs = mapToPortRelabel 9100 nodes_ ;
} {
job_name = " s y s t e m d " ;
scrape_interval = " 6 0 s " ;
static_configs = [ {
targets = mapToPort 9333 nodes_ ;
} ] ;
relabel_configs = mapToPortRelabel 9333 nodes_ ;
}
] ;
} ;
services . grafana = {
enable = true ;
port = 8452 ;
rootUrl = " h t t p s : / / m e t r i c s . c r y t o . n e t / " ;
security = let
credentials = import ../private/grafana-credentials.nix ;
in {
adminUser = credentials . username ;
adminPassword = credentials . password ;
} ;
auth = {
anonymous . enable = true ;
} ;
} ;
networking . firewall . allowedTCPPorts = [
80
443
] ;
} ;
}