Compare commits
10 commits
3115fbb41c
...
b9ed7f1eb8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9ed7f1eb8 | ||
|
|
997042d9be | ||
|
|
94af056548 | ||
|
|
9d9236cd53 | ||
|
|
cc166f8794 | ||
|
|
2ca39ee7c9 | ||
|
|
655235c6ba | ||
|
|
94025116d0 | ||
|
|
beafc15d79 | ||
|
|
3b3e2c9b57 |
8 changed files with 293 additions and 95 deletions
|
|
@ -6,6 +6,9 @@
|
|||
...
|
||||
}:
|
||||
|
||||
let
|
||||
sshKeyMac = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbHk7YasSMK5FBCArKLeqIoaGXsN+WlgVquObyC5Zec raphael@MacBook-Pro-de-raphael.local";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
../global.nix
|
||||
|
|
@ -122,6 +125,9 @@
|
|||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
|
||||
users.users.raphael.openssh.authorizedKeys.keys = [
|
||||
sshKeyMac
|
||||
];
|
||||
services = {
|
||||
seatd.enable = true;
|
||||
xserver = {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@
|
|||
mode = "0440";
|
||||
};
|
||||
|
||||
age.secrets."forgejo-oidc-secret" = {
|
||||
file = ../../secrets/forgejo-oidc-secret.age;
|
||||
owner = "kanidm";
|
||||
group = "forgejo";
|
||||
mode = "0440";
|
||||
};
|
||||
|
||||
age.secrets."nextcloud-database" = {
|
||||
file = ../../secrets/nextcloud-database.age;
|
||||
owner = "nextcloud";
|
||||
|
|
|
|||
BIN
secrets/forgejo-oidc-secret.age
Normal file
BIN
secrets/forgejo-oidc-secret.age
Normal file
Binary file not shown.
|
|
@ -16,6 +16,7 @@ in
|
|||
"nextcloud-database.age".publicKeys = users ++ systems;
|
||||
"nextcloud-oidc-secret.age".publicKeys = users ++ systems;
|
||||
"grafana-oidc-secret.age".publicKeys = users ++ systems;
|
||||
"forgejo-oidc-secret.age".publicKeys = users ++ systems;
|
||||
"kandim-admin.age".publicKeys = users ++ systems;
|
||||
"kandim-idmAdmin.age".publicKeys = users ++ systems;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,57 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
giteaDomain = "git.enium.eu";
|
||||
gitDomain = "git.enium.eu";
|
||||
in
|
||||
{
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
appName = "Enium Git";
|
||||
user = "gitea";
|
||||
group = "gitea";
|
||||
database.type = "sqlite3";
|
||||
services = {
|
||||
forgejo = {
|
||||
enable = true;
|
||||
database.type = "postgres";
|
||||
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = giteaDomain;
|
||||
ROOT_URL = "https://${giteaDomain}/";
|
||||
SSH_PORT = 42131;
|
||||
HTTP_ADDR = "127.0.0.1";
|
||||
HTTP_PORT = 3042;
|
||||
DISABLE_REGISTRATION = true;
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
||||
SHOW_REGISTRATION_BUTTON = false;
|
||||
DISABLE_REGULAR_LOGIN = true;
|
||||
};
|
||||
settings = {
|
||||
server = {
|
||||
"DEFAULT.APP_NAME" = "Enium Git";
|
||||
"DEFAULT.APP_SLOGAN" = "Born2Code";
|
||||
DOMAIN = gitDomain;
|
||||
ROOT_URL = "https://${gitDomain}/";
|
||||
SSH_PORT = 42131;
|
||||
HTTP_ADDR = "127.0.0.1";
|
||||
HTTP_PORT = 3042;
|
||||
DISABLE_REGISTRATION = true;
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
||||
SHOW_REGISTRATION_BUTTON = false;
|
||||
DISABLE_REGULAR_LOGIN = true;
|
||||
};
|
||||
|
||||
service = {
|
||||
DISABLE_REGISTRATION = true;
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
||||
};
|
||||
oauth2 = {
|
||||
ENABLED = true;
|
||||
NAME = "Enium";
|
||||
CLIENT_ID = "forgejo";
|
||||
CLIENT_SECRET = "${config.age.secrets.forgejo-oidc-secret.path}";
|
||||
SCOPES = "openid email profile groups";
|
||||
LOGIN_ATTRIBUTE_PATH = "preferred_username";
|
||||
AUTH_URL = "https://git.enium.eu/ui/oauth2";
|
||||
TOKEN_URL = "https://git.enium.eu/oauth2/token";
|
||||
API_URL = "https://git.enium.eu/oauth2/openid/forgejo/userinfo";
|
||||
CODE_CHALLENGE_METHOD = "S256";
|
||||
ENABLE_AUTO_REGISTRATION = true;
|
||||
UPDATE_AVATAR = true;
|
||||
};
|
||||
|
||||
web = {
|
||||
DISABLE_LOCAL_LOGIN = true;
|
||||
};
|
||||
|
||||
oauth2_client = {
|
||||
ENABLE_AUTO_REGISTRATION = true;
|
||||
security = {
|
||||
LOGIN_REMEMBER_DAYS = 14;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${giteaDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:3042";
|
||||
nginx.virtualHosts."${gitDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:3042";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,11 +77,6 @@ in
|
|||
smtpd_tls_cert_file = "/var/lib/acme/mail.enium.eu/fullchain.pem";
|
||||
smtpd_tls_key_file = "/var/lib/acme/mail.enium.eu/key.pem";
|
||||
|
||||
smtpd_milters = "unix:/run/rspamd/rspamd.sock";
|
||||
non_smtpd_milters = "unix:/run/rspamd/rspamd.sock";
|
||||
milter_protocol = "6";
|
||||
milter_default_action = "accept";
|
||||
milter_mail_macros = "i {mail_addr} {client_addr} {client_name} {auth_authen}";
|
||||
};
|
||||
master."submission" = {
|
||||
type = "inet";
|
||||
|
|
@ -107,7 +102,7 @@ in
|
|||
systemd.services.postfix.preStart = lib.mkMerge [
|
||||
(lib.mkAfter ''
|
||||
umask 077
|
||||
echo "[in-v3.mailjet.com]:587 $(cat ${mailjet-pass}):$(cat ${mailjet-pass})" > /var/lib/postfix/sasl_passwd
|
||||
echo "[in-v3.mailjet.com]:587 $(cat ${mailjet-user}):$(cat ${mailjet-pass})" > /var/lib/postfix/sasl_passwd
|
||||
chown postfix:postfix /var/lib/postfix/sasl_passwd
|
||||
chmod 600 /var/lib/postfix/sasl_passwd
|
||||
${pkgs.postfix}/bin/postmap /var/lib/postfix/sasl_passwd
|
||||
|
|
@ -143,7 +138,7 @@ in
|
|||
extraConfig = ''
|
||||
protocols = imap lmtp
|
||||
auth_mechanisms = plain login
|
||||
disable_plaintext_auth = yes
|
||||
disable_plaintext_auth = no
|
||||
base_dir = /run/dovecot
|
||||
|
||||
userdb {
|
||||
|
|
@ -240,57 +235,51 @@ in
|
|||
|
||||
services.rspamd = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
worker "controller" {
|
||||
bind_socket = "127.0.0.1:11334";
|
||||
password = "admin";
|
||||
postfix.enable = true;
|
||||
extraConfig = ''
|
||||
worker "controller" {
|
||||
bind_socket = "127.0.0.1:11334";
|
||||
password = "admin";
|
||||
};
|
||||
|
||||
worker "normal" {
|
||||
bind_socket = "127.0.0.1:11333";
|
||||
};
|
||||
|
||||
worker "rspamd_proxy" {
|
||||
bind_socket = "127.0.0.1:11332";
|
||||
milter = yes;
|
||||
timeout = 120s;
|
||||
upstream "local" {
|
||||
self_scan = yes;
|
||||
};
|
||||
};
|
||||
|
||||
actions {
|
||||
reject = 12;
|
||||
add_header = 6;
|
||||
greylist = 4;
|
||||
};
|
||||
|
||||
classifier "bayes" {
|
||||
backend = "redis";
|
||||
servers = "127.0.0.1:6381";
|
||||
autolearn = true;
|
||||
min_learns = 200;
|
||||
new_schema = true;
|
||||
cache = true;
|
||||
|
||||
statfile {
|
||||
symbol = "BAYES_HAM";
|
||||
spam = false;
|
||||
};
|
||||
|
||||
worker "normal" {
|
||||
bind_socket = "127.0.0.1:11333";
|
||||
statfile {
|
||||
symbol = "BAYES_SPAM";
|
||||
spam = true;
|
||||
};
|
||||
|
||||
worker "rspamd_proxy" {
|
||||
bind_socket = "127.0.0.1:11332";
|
||||
milter = yes;
|
||||
timeout = 120s;
|
||||
upstream "local" {
|
||||
self_scan = yes;
|
||||
};
|
||||
};
|
||||
|
||||
actions {
|
||||
reject = 12;
|
||||
add_header = 6;
|
||||
greylist = 4;
|
||||
};
|
||||
|
||||
milter {
|
||||
unix_socket = "/run/rspamd/milter.sock";
|
||||
unix_permissions = 0660;
|
||||
user = "rspamd";
|
||||
group = "postfix";
|
||||
};
|
||||
|
||||
classifier "bayes" {
|
||||
backend = "redis";
|
||||
servers = "127.0.0.1:6381";
|
||||
autolearn = true;
|
||||
min_learns = 200;
|
||||
new_schema = true;
|
||||
cache = true;
|
||||
|
||||
statfile {
|
||||
symbol = "BAYES_HAM";
|
||||
spam = false;
|
||||
};
|
||||
|
||||
statfile {
|
||||
symbol = "BAYES_SPAM";
|
||||
spam = true;
|
||||
};
|
||||
|
||||
learn_condition = <<EOD
|
||||
learn_condition = <<EOD
|
||||
return function(task)
|
||||
return true
|
||||
end
|
||||
|
|
@ -318,6 +307,7 @@ EOD;
|
|||
};
|
||||
security.acme.certs."mail.enium.eu" = {
|
||||
listenHTTP = ":80";
|
||||
group = "dovecot2";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
let
|
||||
cfg = config.service.selfhost.monitor;
|
||||
dashboardsDir = ../../assets/grafana_dashboards;
|
||||
monitored = [
|
||||
"nginx"
|
||||
"grafana"
|
||||
|
|
@ -18,7 +19,36 @@ in
|
|||
enable = true;
|
||||
package = pkgs.grafana;
|
||||
dataDir = "/var/lib/grafana";
|
||||
provision = {
|
||||
dashboards.settings.providers = [
|
||||
{
|
||||
name = "nixos-dashboards";
|
||||
type = "file";
|
||||
updateIntervalSeconds = 30;
|
||||
editable = false;
|
||||
|
||||
options = {
|
||||
path = "/etc/grafana/dashboards";
|
||||
foldersFromFilesStructure = false;
|
||||
};
|
||||
}
|
||||
];
|
||||
datasources.settings.datasources = [
|
||||
{
|
||||
name = "Prometheus";
|
||||
type = "prometheus";
|
||||
uid = "prometheus";
|
||||
access = "proxy";
|
||||
url = "http://127.0.0.1:9090";
|
||||
isDefault = true;
|
||||
editable = false;
|
||||
jsonData = {
|
||||
httpMethod = "POST";
|
||||
timeInterval = "15s";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
settings = {
|
||||
server = {
|
||||
root_url = "https://monitor.enium.eu";
|
||||
|
|
@ -26,17 +56,36 @@ in
|
|||
serve_from_sub_path = false;
|
||||
};
|
||||
|
||||
users = {
|
||||
auto_assign_org = true;
|
||||
auto_assign_org_role = "Viewer";
|
||||
"auth.generic_oauth" = {
|
||||
enabled = true;
|
||||
name = "Enium";
|
||||
allow_sign_up = true;
|
||||
client_id = "grafana";
|
||||
client_secret = "$__file{${config.age.secrets.grafana-oidc-secret.path}}";
|
||||
scopes = "openid profile email groups";
|
||||
auth_url = "https://auth.enium.eu/ui/oauth2";
|
||||
token_url = "https://auth.enium.eu/oauth2/token";
|
||||
api_url = "https://auth.enium.eu/oauth2/openid/grafana/userinfo";
|
||||
redirect_uri = "https://monitor.enium.eu/login/generic_oauth";
|
||||
use_pkce = true;
|
||||
use_refresh_token = true;
|
||||
login_attribute_path = "preferred_username";
|
||||
name_attribute_path = "name";
|
||||
email_attribute_path = "email";
|
||||
groups_attribute_path = "groups";
|
||||
role_attribute_path = "contains(groups, 'grafana_superadmins@enium.eu') && 'GrafanaAdmin' || contains(groups, 'grafana_admins@enium.eu') && 'Admin' || contains(groups, 'grafana_editors@enium.eu') && 'Editor' || 'Viewer'";
|
||||
allow_assign_grafana_admin = true;
|
||||
role_attribute_strict = false;
|
||||
skip_org_role_sync = false;
|
||||
};
|
||||
|
||||
log.level = "debug";
|
||||
auth = {
|
||||
disable_login_form = true;
|
||||
disable_signout_menu = false;
|
||||
};
|
||||
|
||||
security = {
|
||||
cookie_secure = true;
|
||||
cookie_samesite = "none";
|
||||
allow_embedding = true;
|
||||
};
|
||||
};
|
||||
|
|
@ -157,6 +206,8 @@ in
|
|||
ruleFiles = lib.mkForce [ "/etc/prometheus/services.rules" ];
|
||||
};
|
||||
|
||||
environment.etc."grafana/dashboards".source = dashboardsDir;
|
||||
|
||||
environment.etc."prometheus/services.rules".text = ''
|
||||
groups:
|
||||
- name: services
|
||||
|
|
|
|||
|
|
@ -9,6 +9,22 @@ let
|
|||
cfg = config.service.selfhost.sso;
|
||||
kanidm-admin = config.age.secrets."kanidm-admin".path;
|
||||
kanidm-idmAdmin = config.age.secrets."kanidm-idmAdmin".path;
|
||||
imagesDir = "/user/share/kanidm/assets";
|
||||
kanidmLogo = pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/doc-sheet/forgejo/refs/heads/forgejo/assets/logo.svg";
|
||||
name = "kanidm.svg";
|
||||
sha256 = "sha256-rP7aZURtHBfF2OYuGLcKZhbvIN+B596T/3kaOxHUvig=";
|
||||
};
|
||||
grafanaLogo = pkgs.fetchurl {
|
||||
url = "https://upload.wikimedia.org/wikipedia/commons/a/a1/Grafana_logo.svg";
|
||||
name = "grafana.svg";
|
||||
sha256 = "sha256-UjE6ArLCa52o3XGUmpqPoakbEOeFi+zfsnATi1FtWmQ=";
|
||||
};
|
||||
nextcloudLogo = pkgs.fetchurl {
|
||||
url = "https://upload.wikimedia.org/wikipedia/commons/6/60/Nextcloud_Logo.svg";
|
||||
name = "nextcloud.svg";
|
||||
sha256 = "sha256-hL51zJkFxUys1CoM8yUxiH8BDw111wh3Qv7eTLm+XYo=";
|
||||
};
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg {
|
||||
|
|
@ -26,7 +42,6 @@ in
|
|||
package = pkgs.kanidmWithSecretProvisioning_1_8;
|
||||
enableServer = true;
|
||||
serverSettings = {
|
||||
role = "WriteReplica";
|
||||
domain = "enium.eu";
|
||||
origin = "https://auth.enium.eu";
|
||||
bindaddress = "127.0.0.1:9000";
|
||||
|
|
@ -47,17 +62,137 @@ in
|
|||
mailAddresses = [
|
||||
"raphael@enium.eu"
|
||||
];
|
||||
groups = [
|
||||
"grafana_superadmins"
|
||||
"forgejo_admins"
|
||||
"nextcloud_user"
|
||||
];
|
||||
};
|
||||
};
|
||||
groups = {
|
||||
grafana_superadmins = {
|
||||
present = true;
|
||||
};
|
||||
grafana_admins = {
|
||||
present = true;
|
||||
};
|
||||
grafana_editors = {
|
||||
present = true;
|
||||
};
|
||||
grafana_users = {
|
||||
present = true;
|
||||
};
|
||||
forgejo_admins = {
|
||||
present = true;
|
||||
};
|
||||
forgejo_users = {
|
||||
present = true;
|
||||
};
|
||||
nextcloud_user = {
|
||||
present = true;
|
||||
};
|
||||
};
|
||||
systems.oauth2 = {
|
||||
forgejo = {
|
||||
present = true;
|
||||
displayName = "Forjego";
|
||||
originUrl = "https://git.enium.eu";
|
||||
imageFile = kanidmLogo;
|
||||
originLanding = "https://git.enium.eu/user/oauth2/Enium/callback";
|
||||
basicSecretFile = config.age.secrets.forgejo-oidc-secret.path;
|
||||
public = false;
|
||||
enableLocalhostRedirects = false;
|
||||
allowInsecureClientDisablePkce = true;
|
||||
preferShortUsername = true;
|
||||
scopeMaps = {
|
||||
forgejo_admins = [
|
||||
"email"
|
||||
"openid"
|
||||
"profile"
|
||||
"groups"
|
||||
];
|
||||
forgejo_users = [
|
||||
"email"
|
||||
"openid"
|
||||
"profile"
|
||||
"groups"
|
||||
];
|
||||
};
|
||||
claimMaps = {
|
||||
groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup = {
|
||||
forgejo_admins = [
|
||||
"forgejo_admins"
|
||||
];
|
||||
forgejo_users = [
|
||||
"forgejo_users"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
grafana = {
|
||||
present = true;
|
||||
displayName = "Grafana";
|
||||
imageFile = grafanaLogo;
|
||||
originUrl = "https://monitor.enium.eu";
|
||||
originLanding = "https://monitor.enium.eu/login/generic_oauth";
|
||||
basicSecretFile = config.age.secrets.grafana-oidc-secret.path;
|
||||
public = false;
|
||||
enableLocalhostRedirects = false;
|
||||
allowInsecureClientDisablePkce = false;
|
||||
preferShortUsername = true;
|
||||
scopeMaps = {
|
||||
grafana_superadmins = [
|
||||
"email"
|
||||
"openid"
|
||||
"profile"
|
||||
"groups"
|
||||
];
|
||||
grafana_admins = [
|
||||
"email"
|
||||
"openid"
|
||||
"profile"
|
||||
"groups"
|
||||
];
|
||||
grafana_editors = [
|
||||
"email"
|
||||
"openid"
|
||||
"profile"
|
||||
"groups"
|
||||
];
|
||||
grafana_users = [
|
||||
"email"
|
||||
"openid"
|
||||
"profile"
|
||||
"groups"
|
||||
];
|
||||
};
|
||||
claimMaps = {
|
||||
groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup = {
|
||||
grafana_superadmins = [
|
||||
"grafana_superadmins"
|
||||
];
|
||||
grafana_admins = [
|
||||
"grafana_admins"
|
||||
];
|
||||
grafana_editors = [
|
||||
"grafana_editors"
|
||||
];
|
||||
grafana_users = [
|
||||
"grafana_users"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
nextcloud = {
|
||||
present = true;
|
||||
displayName = "Nextcloud";
|
||||
imageFile = nextcloudLogo;
|
||||
originUrl = "https://nextcloud.enium.eu";
|
||||
originLanding = "https://nextcloud.enium.eu/login";
|
||||
basicSecretFile = config.age.secrets.nextcloud-oidc-secret.path;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue