tsuki/jupyter: harden security with sops and systemd
This commit is contained in:
parent
fdace82c2f
commit
c98a1a0541
|
@ -1,15 +1,23 @@
|
||||||
{ pkgs, secrets, ... }:
|
{ config, pkgs, lib, ... }: let
|
||||||
{
|
cfg = config.services.jupyter;
|
||||||
users.users.jupyter = {
|
in {
|
||||||
group = "jupyter";
|
sops.secrets."jupyter/password" = {
|
||||||
|
restartUnits = [ "jupyter.service" ];
|
||||||
|
owner = cfg.user;
|
||||||
|
inherit (cfg) group;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
users.users."jupyter".group = "jupyter";
|
||||||
|
users.groups."jupyter".members = [ "nginx" ];
|
||||||
|
|
||||||
services.jupyter = {
|
services.jupyter = {
|
||||||
enable = true;
|
enable = true;
|
||||||
group = "jupyter";
|
group = "jupyter";
|
||||||
ip = "0.0.0.0";
|
password = let
|
||||||
port = secrets.ports.jupyterhub;
|
readFile = f: "open('${f}', 'r', encoding='utf8').read().strip()";
|
||||||
password = secrets.keys.hashed.jupyter;
|
in
|
||||||
|
readFile config.sops.secrets."jupyter/password".path;
|
||||||
|
|
||||||
kernels = {
|
kernels = {
|
||||||
pythonDS = let
|
pythonDS = let
|
||||||
env = (pkgs.python3.withPackages (pythonPackages: with pythonPackages; [
|
env = (pkgs.python3.withPackages (pythonPackages: with pythonPackages; [
|
||||||
|
@ -32,4 +40,59 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.services.jupyter = let
|
||||||
|
notebookConfig = pkgs.writeText "jupyter_config.py" ''
|
||||||
|
c.NotebookApp.notebook_dir = 'notebooks'
|
||||||
|
c.NotebookApp.open_browser = False
|
||||||
|
c.NotebookApp.password = ${cfg.password}
|
||||||
|
c.NotebookApp.password_required = True
|
||||||
|
|
||||||
|
c.NotebookApp.sock = '/run/jupyter/jupyter.sock'
|
||||||
|
c.NotebookApp.sock_mode = '0660'
|
||||||
|
c.NotebookApp.local_hostnames = ['py.nani.wtf']
|
||||||
|
|
||||||
|
c.ConnectionFileMixin.transport = 'ipc'
|
||||||
|
|
||||||
|
${cfg.notebookConfig}
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
environment = {
|
||||||
|
JUPYTER_DATA_DIR = "$STATE_DIRECTORY/data";
|
||||||
|
JUPYTER_RUNTIME_DIR = "$RUNTIME_DIRECTORY";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
RuntimeDirectory = "jupyter";
|
||||||
|
StateDirectory = "jupyter";
|
||||||
|
|
||||||
|
# Hardening
|
||||||
|
CapabilityBoundingSet = "";
|
||||||
|
LockPersonality = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateMounts = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
RemoveIPC = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
UMask = "0007";
|
||||||
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
|
||||||
|
ExecStartPre = ''
|
||||||
|
${pkgs.coreutils}/bin/mkdir -p /var/lib/jupyter/{notebooks,data}
|
||||||
|
'';
|
||||||
|
ExecStart = lib.mkForce ''
|
||||||
|
${cfg.package}/bin/${cfg.command} --NotebookApp.config_file=${notebookConfig}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
"hydra".servers."localhost:${s config.services.hydra.port}" = { };
|
"hydra".servers."localhost:${s config.services.hydra.port}" = { };
|
||||||
"idrac".servers."${ips.idrac}" = { };
|
"idrac".servers."${ips.idrac}" = { };
|
||||||
"invidious".servers."localhost:${s config.services.invidious.port}" = { };
|
"invidious".servers."localhost:${s config.services.invidious.port}" = { };
|
||||||
"jupyter".servers."localhost:${s ports.jupyterhub}" = { };
|
"jupyter".servers."unix:/run/jupyter/jupyter.sock" = { };
|
||||||
"kanidm".servers."localhost:8300" = { };
|
"kanidm".servers."localhost:8300" = { };
|
||||||
"osuchan".servers."localhost:${s ports.osuchan}" = { };
|
"osuchan".servers."localhost:${s ports.osuchan}" = { };
|
||||||
"pgadmin".servers."unix:${config.services.uwsgi.instance.vassals.pgadmin.socket}" = { };
|
"pgadmin".servers."unix:${config.services.uwsgi.instance.vassals.pgadmin.socket}" = { };
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
jupyter:
|
||||||
|
password: ENC[AES256_GCM,data:mm0EHzhK9AqErfsoWWJ5+3ym+VXgEcZ+qadTy3f+NtA=,iv:ntGxklA5oDbGbo3j3ffbAvzGE4c9Ay/SfCWdA6bqzP4=,tag:KG1luMcSjBFm0LVKnoTvGA==,type:str]
|
||||||
grafana:
|
grafana:
|
||||||
oauth2_secret: ENC[AES256_GCM,data:zxfPtiB/o5cC27O9uQzPvQV1qWcp3xxnIi7/P84I2lJ/X4ovAwXuiEqnc7BDAE4E,iv:ZY8BDTMEvR2JiFHKM8iM90UQbmTqH/DoVklWno6Xa4U=,tag:E8GTGk9IJauCgjaoToShBg==,type:str]
|
oauth2_secret: ENC[AES256_GCM,data:zxfPtiB/o5cC27O9uQzPvQV1qWcp3xxnIi7/P84I2lJ/X4ovAwXuiEqnc7BDAE4E,iv:ZY8BDTMEvR2JiFHKM8iM90UQbmTqH/DoVklWno6Xa4U=,tag:E8GTGk9IJauCgjaoToShBg==,type:str]
|
||||||
secretkey: ENC[AES256_GCM,data:aVzqZqwFfm3FcYJE8USxsDbZVwtnF5NJXTAqshv9av4ZeR5YrDfDzLYHHztXMZt2Q7p/6A==,iv:A7x7oRUVvfxqSXRfi9+15z9pE6xX+GZrGU7gXrSKyXE=,tag:2uatRT0XePk2dqZj2ZlM3A==,type:str]
|
secretkey: ENC[AES256_GCM,data:aVzqZqwFfm3FcYJE8USxsDbZVwtnF5NJXTAqshv9av4ZeR5YrDfDzLYHHztXMZt2Q7p/6A==,iv:A7x7oRUVvfxqSXRfi9+15z9pE6xX+GZrGU7gXrSKyXE=,tag:2uatRT0XePk2dqZj2ZlM3A==,type:str]
|
||||||
|
|
Loading…
Reference in New Issue