rnhmjoj
50daabb203
environment.sessionVariables are set before the shell starts, so the wont't pollute the default value before switch to the one set using the environment.variables.
498 lines
12 KiB
Nix
498 lines
12 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
{
|
|
imports = [
|
|
./hardware.nix
|
|
./variables.nix
|
|
./packages.nix
|
|
./jobs.nix
|
|
./matrix.nix
|
|
./email.nix
|
|
./magnetico.nix
|
|
./nameserver.nix
|
|
./custom
|
|
./secrets
|
|
];
|
|
|
|
### State
|
|
# Stateful things to do before updating:
|
|
# 1. Postgres migration (https://www.postgresql.org/docs/current/upgrading.html)
|
|
# 2. Matrix Synapse migration (https://matrix-org.github.io/synapse/latest/upgrade.html)
|
|
system.stateVersion = "22.05";
|
|
|
|
|
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
|
boot.tmpOnTmpfs = true;
|
|
boot.kernel.sysctl = {
|
|
# avoid OOM hangs
|
|
"vm.admin_reserve_kbytes" = 262144;
|
|
};
|
|
|
|
time.timeZone = "Europe/Rome";
|
|
i18n.defaultLocale = "en_US.UTF-8";
|
|
|
|
systemd.enableEmergencyMode = false;
|
|
|
|
networking = {
|
|
hostName = "maxwell";
|
|
|
|
firewall.allowedTCPPorts = [
|
|
443 80 # reverse proxy
|
|
993 # imaps server
|
|
25 465 # smtp(s) server
|
|
3478 # turn server
|
|
5349 # turn server
|
|
3551 # apcups
|
|
18080 # monero p2p
|
|
22000 # syncthing transfer
|
|
64738 # mumble server
|
|
];
|
|
firewall.allowedUDPPorts = [
|
|
53 # powerdns
|
|
1194 # dnscrypt
|
|
3478 # turn server
|
|
21027 # syncthing discovery
|
|
64738 # mumble server
|
|
];
|
|
firewall.allowedUDPPortRanges = [
|
|
{ from=49152; to=49999; } # turn relay
|
|
];
|
|
|
|
usePredictableInterfaceNames = false;
|
|
nameservers = [ "127.0.0.1" ];
|
|
hosts."127.0.0.1" = [ config.var.hostname ];
|
|
};
|
|
|
|
# Only declarative users and no password logins
|
|
users.mutableUsers = false;
|
|
|
|
users.users ={
|
|
# Only needed for local (read emergency) shell access
|
|
root.passwordFile = config.secrets.passwords.root;
|
|
|
|
# Admin
|
|
rnhmjoj = {
|
|
uid = 1000;
|
|
extraGroups = [ "wheel" ];
|
|
isNormalUser = true;
|
|
shell = pkgs.fish;
|
|
openssh.authorizedKeys.keyFiles = [ config.secrets.publicKeys.rnhmjoj ];
|
|
};
|
|
|
|
# Admin
|
|
fazo = {
|
|
extraGroups = [ "wheel" ];
|
|
isNormalUser = true;
|
|
openssh.authorizedKeys.keyFiles = [ config.secrets.publicKeys.fazo ];
|
|
};
|
|
|
|
# User
|
|
meme = {
|
|
isNormalUser = true;
|
|
shell = pkgs.fish;
|
|
openssh.authorizedKeys.keyFiles = [ config.secrets.publicKeys.meme ];
|
|
};
|
|
|
|
# Hosts the cactalogo
|
|
giu = {
|
|
isNormalUser = true;
|
|
shell = pkgs.fish;
|
|
openssh.authorizedKeys.keyFiles = with config.secrets.publicKeys;
|
|
[ rnhmjoj giu ];
|
|
};
|
|
|
|
# Needed to perform remote builds on Maxwell
|
|
builder = {
|
|
description = "Remote Nix builds user";
|
|
isNormalUser = true;
|
|
openssh.authorizedKeys.keyFiles = [ config.secrets.publicKeys.rnhmjoj-builder ];
|
|
};
|
|
|
|
# Use "git" instead of the default name to make
|
|
# SSH operation handier, example:
|
|
# git clone git@maxwell:user/repo
|
|
git = {
|
|
group = "git";
|
|
description = "Git server user";
|
|
home = "/var/lib/gitea";
|
|
isSystemUser = true;
|
|
useDefaultShell = true;
|
|
};
|
|
};
|
|
|
|
users.groups.git = { };
|
|
|
|
# Generate Diffie-Hellman parameters
|
|
# for TLS applications, like nginx.
|
|
security.dhparams = {
|
|
enable = true;
|
|
params.nginx = 2048; # prime modulus bits
|
|
};
|
|
|
|
security.sudo = {
|
|
enable = true;
|
|
# Users don't have a password
|
|
wheelNeedsPassword = false;
|
|
};
|
|
|
|
security.pam.loginLimits = [
|
|
# Limit user process to stop fork bombs
|
|
{ domain = "@users";
|
|
type = "hard";
|
|
item = "nproc";
|
|
value = "400";
|
|
}
|
|
# Disable core dumping
|
|
{ domain = "*";
|
|
type = "soft";
|
|
item = "core";
|
|
value = "0";
|
|
}
|
|
];
|
|
|
|
### ACME certificates
|
|
security.acme = with config.var; {
|
|
defaults.email = "rnhmjoj@inventati.org";
|
|
acceptTerms = true;
|
|
|
|
certs."${hostname}" = {
|
|
group = "maxwell-ydns-eu";
|
|
};
|
|
|
|
certs."riot.${hostname}" = {
|
|
group = "riot-maxwell-ydns-eu";
|
|
};
|
|
};
|
|
|
|
# Allow read access to ACME certificate
|
|
# to specific (service) users.
|
|
users.groups."maxwell-ydns-eu".members = [ "murmur" "turnserver" "nginx" ];
|
|
users.groups."riot-maxwell-ydns-eu".members = [ "nginx" ];
|
|
|
|
|
|
services.openssh = {
|
|
enable = true;
|
|
permitRootLogin = "no";
|
|
passwordAuthentication = false;
|
|
kbdInteractiveAuthentication = false;
|
|
};
|
|
|
|
# Traceroute easter egg
|
|
services.fakeroute = {
|
|
enable = true;
|
|
route = [
|
|
"89.111.117.32" "99.97.110.110" "111.116.32.104" "105.100.101.46"
|
|
"32.73.32.115" "101.101.32.121" "111.117.46.32" "84.104.101.114"
|
|
"101.32.105.115" "32.110.111.32" "108.105.102.101" "32.105.110.32"
|
|
"116.104.101.32" "118.111.105.100" "46.32.79.110" "108.121.32.100"
|
|
"101.97.116.104" ];
|
|
};
|
|
|
|
### Mumble server
|
|
services.murmur = {
|
|
enable = true;
|
|
registerHostname = config.var.hostname;
|
|
registerName = "Maxwell Mumble";
|
|
registerPassword = "$REG_PASSWORD";
|
|
password = "$JOIN_PASSWORD";
|
|
users = 10;
|
|
environmentFile = config.secrets.environments.murmur;
|
|
sslCert = "/var/lib/acme/${config.var.hostname}/fullchain.pem";
|
|
sslKey = "/var/lib/acme/${config.var.hostname}/key.pem";
|
|
};
|
|
|
|
### Syncthing node
|
|
services.syncthing = {
|
|
enable = true;
|
|
};
|
|
|
|
### Monero node with local RPC
|
|
services.monero = {
|
|
enable = true;
|
|
mining = {
|
|
enable = false;
|
|
threads = 4;
|
|
address = config.secrets.monero.address;
|
|
};
|
|
limits = {
|
|
upload = 250;
|
|
download = 625;
|
|
threads = 4;
|
|
};
|
|
rpc.user = config.secrets.monero.user;
|
|
rpc.password = config.secrets.monero.password;
|
|
};
|
|
|
|
### URL shortner
|
|
services.breve = with config.secrets; {
|
|
enable = true;
|
|
hostname = "localhost";
|
|
baseUrl = "https://brve.bit/";
|
|
port = 2000;
|
|
certificate = certs.breve.crt;
|
|
key = certs.breve.key;
|
|
};
|
|
|
|
### Git server
|
|
services.gitea = with config.var; {
|
|
enable = true;
|
|
domain = hostname;
|
|
appName = "Maxwell git server";
|
|
rootUrl = "https://${hostname}/git/";
|
|
user = "git";
|
|
database.user = "git";
|
|
log.level = "Error";
|
|
cookieSecure = true;
|
|
disableRegistration = false;
|
|
settings = {
|
|
# increase cookie expiration time
|
|
security.LOGIN_REMEMBER_DAYS = 365;
|
|
|
|
# file upload size (MB)
|
|
attachment.MAX_SIZE = 10;
|
|
|
|
# new users can only create PR/issues
|
|
service.DEFAULT_ALLOW_CREATE_ORGANIZATION = false;
|
|
repository.MAX_CREATION_LIMIT = 0;
|
|
|
|
# somewhat limit spam
|
|
service.EMAIL_DOMAIN_BLOCKLIST = "gmail.com";
|
|
|
|
# allow the notify webhook to use matrix
|
|
webhook.ALLOWED_HOST_LIST = "maxwell.ydns.eu";
|
|
};
|
|
};
|
|
|
|
### Searx instance
|
|
services.searx = {
|
|
enable = true;
|
|
environmentFile = config.secrets.environments.searx;
|
|
|
|
# Use nginx+uWSGI
|
|
runInUwsgi = true;
|
|
uwsgiConfig = {
|
|
disable-logging = true;
|
|
|
|
# serve using the uwsgi protocol
|
|
socket = "/run/searx/uwsgi.sock";
|
|
chmod-socket = "660";
|
|
|
|
# use /searx as url "mountpoint"
|
|
mount = "/srx=searx.webapp:application";
|
|
module = "";
|
|
manage-script-name = true;
|
|
|
|
# caching
|
|
cache2 = lib.concatStringsSep ","
|
|
[ "name=searxcache"
|
|
"items=2000"
|
|
"blocks=2000"
|
|
"blocksize=4096"
|
|
"bitmap=1"
|
|
];
|
|
};
|
|
|
|
settings =
|
|
{ general.instance_name = "searxwell";
|
|
server.base_url = "https://${config.var.hostname}/";
|
|
server.secret_key = "@SEARX_SECRET@";
|
|
|
|
# Replace DOI links with Sci-Hub
|
|
default_doi_resolver = "sci-hub.st";
|
|
|
|
## Use authenticated APIs for some services
|
|
engines = [
|
|
{ name = "wolframalpha";
|
|
api_key = "@WOLFRAM_API_KEY@";
|
|
}
|
|
{ name = "youtube";
|
|
api_key = "@YOUTUBE_API_KEY@";
|
|
}
|
|
];
|
|
};
|
|
};
|
|
|
|
# Allow nginx access to the uwsgi socket
|
|
users.groups."searx".members = [ "nginx" ];
|
|
|
|
|
|
### Reverse Proxy
|
|
services.nginx =
|
|
with config.var;
|
|
let
|
|
disableLog = ''
|
|
error_log syslog:server=unix:/dev/log crit;
|
|
access_log off;
|
|
'';
|
|
enableSTS = ''
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
'';
|
|
in
|
|
rec {
|
|
enable = true;
|
|
enableReload = true;
|
|
recommendedTlsSettings = true;
|
|
recommendedGzipSettings = true;
|
|
recommendedProxySettings = true;
|
|
|
|
# Large enough to allow file uploads.
|
|
clientMaxBodySize = "1000M";
|
|
|
|
sslDhparam = "${config.security.dhparams.path}/nginx.pem";
|
|
|
|
# Maxwell
|
|
virtualHosts."${hostname}" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
default = true;
|
|
|
|
extraConfig = disableLog + enableSTS;
|
|
|
|
# Returns IP address
|
|
locations."/ip".extraConfig = ''
|
|
default_type text/plain;
|
|
return 200 $remote_addr;
|
|
'';
|
|
|
|
# Asjon code coverage reports
|
|
locations."/asjon/report/" = {
|
|
index = "index.html";
|
|
alias = "/run/nginx/static/asjon/";
|
|
};
|
|
|
|
# Searx instance
|
|
locations."/srx/".extraConfig =
|
|
''
|
|
include ${pkgs.nginx}/conf/uwsgi_params;
|
|
uwsgi_pass unix:/run/searx/uwsgi.sock;
|
|
'';
|
|
locations."/srx/static/".alias = "${pkgs.searx}/share/static/";
|
|
|
|
# Git server
|
|
locations."/git/".proxyPass = "http://localhost:3000/";
|
|
|
|
# Syncthing
|
|
locations."/sync/".proxyPass = "http://localhost:8384/";
|
|
|
|
# User static files
|
|
locations."/~rnhmjoj/" = {
|
|
alias = "/run/nginx/static/rnhmjoj/";
|
|
extraConfig = "charset UTF-8;";
|
|
};
|
|
locations."/~giu/" = {
|
|
alias = "/run/nginx/static/giu/";
|
|
extraConfig = "charset UTF-8;";
|
|
};
|
|
};
|
|
|
|
# Breve URL shortner
|
|
virtualHosts."brve.bit" = with config.secrets; {
|
|
forceSSL = true;
|
|
sslCertificate = certs.breve.crt;
|
|
sslCertificateKey = certs.breve.key;
|
|
|
|
locations."/" = {
|
|
proxyPass = "https://localhost:2000";
|
|
extraConfig = "proxy_ssl_verify off;";
|
|
};
|
|
extraConfig = disableLog;
|
|
};
|
|
|
|
# The Cactalogue
|
|
virtualHosts."cacta.bit" = {
|
|
root = "/run/nginx/static/cactalogue";
|
|
extraConfig = disableLog;
|
|
};
|
|
virtualHosts."cacta.eurofusion.eu" = virtualHosts."cacta.bit";
|
|
};
|
|
|
|
# Bind mount directories for Nginx
|
|
# This avoids giving nginx traversal permission
|
|
systemd.mounts =
|
|
let bindNginx = from: to:
|
|
{ what = from;
|
|
where = "/run/nginx/static/" + to;
|
|
type = "none";
|
|
options = "bind";
|
|
wantedBy = [ "nginx.service" ];
|
|
};
|
|
in [ (bindNginx "/home/rnhmjoj/www" "rnhmjoj")
|
|
(bindNginx "/home/giu/www" "giu")
|
|
(bindNginx "/home/giu/cactalogue" "cactalogue")
|
|
(bindNginx "/var/lib/asjon/tree/report" "asjon")
|
|
];
|
|
|
|
### Misc. services
|
|
services.asjon.enable = true;
|
|
|
|
# Needed for the Asjon memory module
|
|
services.redis.servers."asjon" =
|
|
{ enable = true;
|
|
user = "asjon";
|
|
};
|
|
|
|
|
|
### Program configuration
|
|
programs = {
|
|
fuse.userAllowOther = true;
|
|
fish.enable = true;
|
|
tmux = {
|
|
enable = true;
|
|
newSession = true;
|
|
baseIndex = 1;
|
|
escapeTime = 0;
|
|
historyLimit = 4096;
|
|
keyMode = "vi";
|
|
terminal = "screen-256color";
|
|
customPaneNavigationAndResize = true;
|
|
extraConfig = ''
|
|
set -g mouse on
|
|
|
|
# bindings
|
|
bind | split-window -h
|
|
bind - split-window -v
|
|
bind : command-prompt
|
|
bind -n C-k clear-history
|
|
|
|
# colors
|
|
set -g pane-border-style fg=brightblack
|
|
set -g pane-active-border fg=green
|
|
set -g message-style fg=white,bg=black
|
|
set -g status-style fg=brightblue,bg=black
|
|
setw -g mode-style fg=black,bg=cyan
|
|
|
|
# status line
|
|
set -g status on
|
|
set -g status-justify left
|
|
set -g status-left ""
|
|
set -g status-right-length 60
|
|
set -g status-right '#[fg=yellow]#(cut -d\ -f 1-3 /proc/loadavg) | #[fg=brightgreen]%a %H:%M'
|
|
setw -g window-status-format "#[fg=black#,bg=brightblack] #I #[fg=blue#,bg=black] #W "
|
|
setw -g window-status-current-format "#[fg=white#,bg=cyan] #I #[fg=black#,bg=brightblack] #W "
|
|
'';
|
|
};
|
|
};
|
|
|
|
nix = {
|
|
useSandbox = true;
|
|
# Can connect to the Nix daemon
|
|
# and upload/run code as root!
|
|
trustedUsers = [ "builder" "rnhmjoj" ];
|
|
# Use at most half the cores
|
|
buildCores = 8;
|
|
extraOptions = ''
|
|
# Always keep at least 256MiB free
|
|
min-free = 268435456
|
|
'';
|
|
};
|
|
|
|
environment.sessionVariables = {
|
|
PATH = [ "$HOME/.local/bin/" ];
|
|
XDG_CONFIG_HOME = "$HOME/.config";
|
|
XDG_DATA_HOME = "$HOME/.local/share";
|
|
XDG_CACHE_HOME = "$HOME/.cache";
|
|
SYSTEMD_COLORS = "16";
|
|
};
|
|
|
|
}
|