In a pretty good working state
This commit is contained in:
parent
00a97b1d94
commit
2aa6b8efc6
|
@ -0,0 +1,220 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.fudo.chat;
|
||||
|
||||
in {
|
||||
options.fudo.chat = {
|
||||
enable = mkEnableOption "Enable chat server";
|
||||
|
||||
hostname = mkOption {
|
||||
type = types.str;
|
||||
description = "Hostname at which this chat server is accessible.";
|
||||
example = "chat.mydomain.com";
|
||||
};
|
||||
|
||||
site-name = mkOption {
|
||||
type = types.str;
|
||||
description = "The name of this chat server.";
|
||||
example = "My Fancy Chat Site";
|
||||
};
|
||||
|
||||
smtp-server = mkOption {
|
||||
type = types.str;
|
||||
description = "SMTP server to use for sending notification emails.";
|
||||
example = "mail.my-site.com";
|
||||
};
|
||||
|
||||
smtp-user = mkOption {
|
||||
type = types.str;
|
||||
description = "Username with which to connect to the SMTP server.";
|
||||
};
|
||||
|
||||
smtp-password-file = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to a file containing the password to use while connecting to the SMTP server.";
|
||||
};
|
||||
|
||||
state-directory = mkOption {
|
||||
type = types.str;
|
||||
description = "Path at which to store server state data.";
|
||||
default = "/var/lib/mattermost";
|
||||
};
|
||||
|
||||
database = mkOption {
|
||||
type = (types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = "Database name.";
|
||||
};
|
||||
|
||||
hostname = mkOption {
|
||||
type = types.str;
|
||||
description = "Database host.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
description = "Database user.";
|
||||
};
|
||||
|
||||
password-file = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to file containing database password.";
|
||||
};
|
||||
};
|
||||
});
|
||||
description = "Database configuration.";
|
||||
example = {
|
||||
name = "my_database";
|
||||
hostname = "my.database.com";
|
||||
user = "db_user";
|
||||
password-file = /path/to/some/file.pw;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (let
|
||||
pkg = pkgs.mattermost;
|
||||
default-config = builtins.fromJSON (readFile "${pkg}/config/config.json");
|
||||
modified-config = recursiveUpdate default-config {
|
||||
ServiceSettings.SiteURL = "https://${cfg.hostname}";
|
||||
ServiceSettings.ListenAddress = "127.0.0.1:8065";
|
||||
TeamSettings.SiteName = cfg.site-name;
|
||||
EmailSettings = {
|
||||
RequireEmailVerification = true;
|
||||
SMTPServer = cfg.smtp-server;
|
||||
SMTPPort = 587;
|
||||
EnableSMTPAuth = true;
|
||||
SMTPUsername = cfg.smtp-user;
|
||||
SMTPPassword = (fileContents cfg.smtp-password-file);
|
||||
SendEmailNotifications = true;
|
||||
ConnectionSecurity = "STARTTLS";
|
||||
FeedbackEmail = "chat@fudo.org";
|
||||
FeedbackName = "Admin";
|
||||
};
|
||||
EnableEmailInvitations = true;
|
||||
SqlSettings.DriverName = "postgres";
|
||||
SqlSettings.DataSource =
|
||||
"postgres://${cfg.database.user}:${fileContents cfg.database.password-file}@${cfg.database.hostname}:5432/${cfg.database.name}";
|
||||
};
|
||||
mattermost-config-file = pkgs.writeText "mattermost-config.json" (builtins.toJSON modified-config);
|
||||
mattermost-user = "mattermost";
|
||||
mattermost-group = "mattermost";
|
||||
|
||||
in {
|
||||
users = {
|
||||
users = {
|
||||
${mattermost-user} = {
|
||||
isSystemUser = true;
|
||||
group = mattermost-group;
|
||||
};
|
||||
};
|
||||
|
||||
groups = {
|
||||
${mattermost-group} = {
|
||||
members = [ mattermost-user ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
system.activationScripts.mattermost = ''
|
||||
mkdir -p ${cfg.state-directory}
|
||||
'';
|
||||
|
||||
systemd.services.mattermost = {
|
||||
description = "Mattermost Chat Server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
preStart = ''
|
||||
mkdir -p ${cfg.state-directory}/config
|
||||
cp ${mattermost-config-file} ${cfg.state-directory}/config/config.json
|
||||
ln -sf ${pkg}/bin ${cfg.state-directory}
|
||||
ln -sf ${pkg}/fonts ${cfg.state-directory}
|
||||
ln -sf ${pkg}/i18n ${cfg.state-directory}
|
||||
ln -sf ${pkg}/templates ${cfg.state-directory}
|
||||
cp -uRL ${pkg}/client ${cfg.state-directory}
|
||||
chown -R ${mattermost-user}:${mattermost-group} ${cfg.state-directory}
|
||||
chmod u+w -R ${cfg.state-directory}/client
|
||||
chmod o-rwx -R ${cfg.state-directory}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
PermissionsStartOnly = true;
|
||||
ExecStart = "${pkg}/bin/mattermost";
|
||||
WorkingDirectory = cfg.state-directory;
|
||||
Restart = "always";
|
||||
RestartSec = "10";
|
||||
LimitNOFILE = "49152";
|
||||
User = mattermost-user;
|
||||
Group = mattermost-group;
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
appendHttpConfig = ''
|
||||
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;
|
||||
'';
|
||||
|
||||
virtualHosts = {
|
||||
"${cfg.hostname}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8065";
|
||||
|
||||
extraConfig = ''
|
||||
client_max_body_size 50M;
|
||||
proxy_set_header Connection "";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Frame-Options SAMEORIGIN;
|
||||
proxy_buffers 256 16k;
|
||||
proxy_buffer_size 16k;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_cache mattermost_cache;
|
||||
proxy_cache_revalidate on;
|
||||
proxy_cache_min_uses 2;
|
||||
proxy_cache_use_stale timeout;
|
||||
proxy_cache_lock on;
|
||||
proxy_http_version 1.1;
|
||||
'';
|
||||
};
|
||||
|
||||
locations."~ /api/v[0-9]+/(users/)?websocket$" = {
|
||||
proxyPass = "http://127.0.0.1:8065";
|
||||
|
||||
extraConfig = ''
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
client_max_body_size 50M;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Frame-Options SAMEORIGIN;
|
||||
proxy_buffers 256 16k;
|
||||
proxy_buffer_size 16k;
|
||||
client_body_timeout 60;
|
||||
send_timeout 300;
|
||||
lingering_timeout 5;
|
||||
proxy_connect_timeout 90;
|
||||
proxy_send_timeout 300;
|
||||
proxy_read_timeout 90s;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
|
@ -12,5 +12,39 @@ with lib;
|
|||
'';
|
||||
default = [];
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Domain of the
|
||||
'';
|
||||
};
|
||||
|
||||
profile = mkOption {
|
||||
type = with types; nullOr str;
|
||||
example = "desktop";
|
||||
description = ''
|
||||
The profile to use for this host. This will do some profile-dependent
|
||||
configuration, for example removing X-libs from servers and adding UI
|
||||
packages to desktops.
|
||||
'';
|
||||
default = null;
|
||||
};
|
||||
|
||||
site = mkOption {
|
||||
type = with types; nullOr str;
|
||||
example = "seattle";
|
||||
description = ''
|
||||
The site at which this host is located. This will do some site-dependent
|
||||
configuration.
|
||||
'';
|
||||
default = null;
|
||||
};
|
||||
|
||||
www-root = mkOption {
|
||||
type = types.path;
|
||||
description = "Path at which to store www files for serving.";
|
||||
example = /var/www;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,6 +9,27 @@ let
|
|||
database-name = "grafana";
|
||||
database-user = "grafana";
|
||||
|
||||
databaseOpts = { ... }: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = "Database name.";
|
||||
};
|
||||
hostname = mkOption {
|
||||
type = types.str;
|
||||
description = "Hostname of the database server.";
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
description = "Database username.";
|
||||
};
|
||||
password-file = mkOption {
|
||||
type = types.path;
|
||||
description = "File containing the database user's password.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
options.fudo.grafana = {
|
||||
|
@ -30,9 +51,9 @@ in {
|
|||
description = "Path to a file containing the email user's password.";
|
||||
};
|
||||
|
||||
database-password-file = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to a file containing the database user's password.";
|
||||
database = mkOption {
|
||||
type = (types.submodule databaseOpts);
|
||||
description = "Grafana database configuration.";
|
||||
};
|
||||
|
||||
admin-password-file = mkOption {
|
||||
|
@ -52,15 +73,6 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
fudo.postgresql = {
|
||||
databases.${database-name} = {};
|
||||
|
||||
local-users.${database-user} = {
|
||||
password = (fileContents cfg.database-password-file);
|
||||
databases = ["${database-name}"];
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
|
@ -89,6 +101,7 @@ in {
|
|||
|
||||
addr = "127.0.0.1";
|
||||
protocol = "http";
|
||||
port = 3000;
|
||||
domain = "${cfg.hostname}";
|
||||
rootUrl = "https://${cfg.hostname}/";
|
||||
|
||||
|
@ -106,10 +119,10 @@ in {
|
|||
};
|
||||
|
||||
database = {
|
||||
host = "localhost";
|
||||
name = database-name;
|
||||
user = database-user;
|
||||
passwordFile = cfg.database-password-file;
|
||||
host = cfg.database.hostname;
|
||||
name = cfg.database.name;
|
||||
user = cfg.database.user;
|
||||
passwordFile = cfg.database.password-file;
|
||||
type = "postgres";
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
lib: site: config: version:
|
||||
with lib;
|
||||
let
|
||||
db-config = if (config.database != null) then
|
||||
''
|
||||
type = "${config.database.type}"
|
||||
pdo_dsn = "${config.database.type}:host=${config.database.hostname};port=${toString config.database.port};dbname=${config.database.name}"
|
||||
pdo_user = "${config.database.user}"
|
||||
pdo_password = "${fileContents config.database.password-file}"
|
||||
''
|
||||
else "";
|
||||
in ''
|
||||
[webmail]
|
||||
title = "${config.title}"
|
||||
loading_description = "${config.title}"
|
||||
favicon_url = "https://${site}/favicon.ico"
|
||||
theme = "${config.theme}"
|
||||
allow_themes = On
|
||||
allow_user_background = Off
|
||||
language = "en"
|
||||
language_admin = "en"
|
||||
allow_languages_on_settings = On
|
||||
allow_additional_accounts = On
|
||||
allow_additional_identities = On
|
||||
messages_per_page = ${toString config.messages-per-page}
|
||||
attachment_size_limit = ${toString config.max-upload-size}
|
||||
|
||||
[interface]
|
||||
show_attachment_thumbnail = On
|
||||
new_move_to_folder_button = On
|
||||
|
||||
[branding]
|
||||
|
||||
[contacts]
|
||||
enable = On
|
||||
allow_sync = On
|
||||
sync_interval = 20
|
||||
suggestions_limit = 10
|
||||
${db-config}
|
||||
|
||||
[security]
|
||||
csrf_protection = On
|
||||
custom_server_signature = "RainLoop"
|
||||
x_frame_options_header = ""
|
||||
openpgp = On
|
||||
|
||||
admin_login = "admin"
|
||||
admin_password = ""
|
||||
allow_admin_panel = Off
|
||||
allow_two_factor_auth = On
|
||||
force_two_factor_auth = Off
|
||||
hide_x_mailer_header = Off
|
||||
admin_panel_host = ""
|
||||
admin_panel_key = "admin"
|
||||
content_security_policy = ""
|
||||
core_install_access_domain = ""
|
||||
|
||||
[login]
|
||||
default_domain = "${config.domain}"
|
||||
allow_languages_on_login = On
|
||||
determine_user_language = On
|
||||
determine_user_domain = Off
|
||||
welcome_page = Off
|
||||
hide_submit_button = On
|
||||
|
||||
[plugins]
|
||||
enable = Off
|
||||
|
||||
[defaults]
|
||||
view_editor_type = "${config.edit-mode}"
|
||||
view_layout = ${if (config.layout-mode == "bottom") then "2" else "1"}
|
||||
contacts_autosave = On
|
||||
mail_use_threads = ${if config.enable-threading then "On" else "Off"}
|
||||
allow_draft_autosave = On
|
||||
mail_reply_same_folder = Off
|
||||
show_images = On
|
||||
|
||||
[logs]
|
||||
enable = ${if config.debug then "On" else "Off"}
|
||||
|
||||
[debug]
|
||||
enable = ${if config.debug then "On" else "Off"}
|
||||
hide_passwords = On
|
||||
filename = "log-{date:Y-m-d}.txt"
|
||||
|
||||
[social]
|
||||
google_enable = Off
|
||||
fb_enable = Off
|
||||
twitter_enable = Off
|
||||
dropbox_enable = Off
|
||||
|
||||
[cache]
|
||||
enable = On
|
||||
index = "v1"
|
||||
fast_cache_driver = "files"
|
||||
fast_cache_index = "v1"
|
||||
http = On
|
||||
http_expires = 3600
|
||||
server_uids = On
|
||||
|
||||
[labs]
|
||||
allow_mobile_version = ${if config.enable-mobile then "On" else "Off"}
|
||||
check_new_password_strength = On
|
||||
allow_gravatar = On
|
||||
allow_prefetch = On
|
||||
allow_smart_html_links = On
|
||||
cache_system_data = On
|
||||
date_from_headers = On
|
||||
autocreate_system_folders = On
|
||||
allow_ctrl_enter_on_compose = On
|
||||
favicon_status = On
|
||||
use_local_proxy_for_external_images = On
|
||||
detect_image_exif_orientation = On
|
||||
|
||||
[version]
|
||||
current = "${version}"
|
||||
''
|
|
@ -69,7 +69,9 @@ in {
|
|||
acl_file = ${cfg.acl-file}
|
||||
}
|
||||
addresses = ${stringJoin " " cfg.bind-addresses}
|
||||
enable-http = true
|
||||
|
||||
# Binds to port 80!
|
||||
enable-http = false
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@ let
|
|||
container-mail-user = "mailer";
|
||||
container-mail-user-id = 542;
|
||||
container-mail-group = "mailer";
|
||||
trusted-networks = config.fudo.prometheus.trusted-networks;
|
||||
trusted-networks = config.fudo.common.local-networks;
|
||||
|
||||
in rec {
|
||||
options.fudo.mail-server.container = {
|
||||
|
@ -80,11 +80,11 @@ in rec {
|
|||
proxy-headers = ''
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
''
|
||||
;
|
||||
'';
|
||||
trusted-network-string = optionalString ((length trusted-networks) > 0)
|
||||
(concatStringsSep "\n"
|
||||
(map (network: "allow ${network};") trusted-networks)) + "\ndeny all;";
|
||||
|
||||
in {
|
||||
"${cfg.hostname}" = {
|
||||
enableACME = true;
|
||||
|
|
|
@ -51,13 +51,13 @@ let
|
|||
# A list of domains for which we accept mail
|
||||
virtual-mailbox-map-file = builtins.toFile "virtual_mailbox_map"
|
||||
(concatStringsSep "\n"
|
||||
(map (domain: "@${domain} OK") cfg.local-domains));
|
||||
(map (domain: "@${domain} OK") (cfg.local-domains ++ [cfg.domain])));
|
||||
|
||||
sender-login-map-file = let
|
||||
escapeDot = (str: replaceStrings ["."] ["\\."] str);
|
||||
in builtins.toFile "sender_login_maps"
|
||||
(concatStringsSep "\n"
|
||||
(map (domain: "/^(.*)@${escapeDot domain}$/ \${1}") cfg.local-domains));
|
||||
(map (domain: "/^(.*)@${escapeDot domain}$/ \${1}") (cfg.local-domains ++ [cfg.domain])));
|
||||
|
||||
mapped-file = name: "hash:/var/lib/postfix/conf/${name}";
|
||||
|
||||
|
@ -95,6 +95,9 @@ in {
|
|||
services.prometheus.exporters.postfix = mkIf cfg.monitoring {
|
||||
enable = true;
|
||||
systemd.enable = true;
|
||||
showqPath = "/var/lib/postfix/queue/public/showq";
|
||||
user = config.services.postfix.user;
|
||||
group = config.services.postfix.group;
|
||||
};
|
||||
|
||||
services.postfix = {
|
||||
|
@ -103,7 +106,8 @@ in {
|
|||
origin = cfg.domain;
|
||||
hostname = cfg.hostname;
|
||||
destination = ["localhost" "localhost.localdomain"] ++
|
||||
(map (domain: "localhost.${domain}") cfg.local-domains);
|
||||
(map (domain: "localhost.${domain}") cfg.local-domains) ++
|
||||
cfg.local-domains;
|
||||
|
||||
enableHeaderChecks = true;
|
||||
enableSmtp = true;
|
||||
|
@ -153,6 +157,10 @@ in {
|
|||
smtpd_sasl_type = "dovecot";
|
||||
smtpd_sasl_path = "/run/dovecot2/auth";
|
||||
smtpd_sasl_auth_enable = "yes";
|
||||
smtpd_sasl_local_domain = "fudo.org";
|
||||
|
||||
smtpd_sasl_security_options = "noanonymous";
|
||||
smtpd_sasl_tls_security_options = "noanonymous";
|
||||
|
||||
smtpd_sender_login_maps = (pcre-file "sender_login_map");
|
||||
|
||||
|
@ -184,6 +192,9 @@ in {
|
|||
|
||||
smtpd_sender_restrictions = [
|
||||
"check_sender_access ${mapped-file "reject_senders"}"
|
||||
"permit_mynetworks"
|
||||
"permit_sasl_authenticated"
|
||||
"reject_unknown_sender_domain"
|
||||
];
|
||||
|
||||
smtpd_recipient_restrictions = [
|
||||
|
@ -200,6 +211,12 @@ in {
|
|||
"reject_non_fqdn_recipient"
|
||||
];
|
||||
|
||||
smtpd_helo_restrictions = [
|
||||
"permit_mynetworks"
|
||||
"reject_invalid_hostname"
|
||||
"permit"
|
||||
];
|
||||
|
||||
# Handled by submission
|
||||
smtpd_tls_security_level = "may";
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ in {
|
|||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
location."/metrics/node" = {
|
||||
locations."/metrics/node" = {
|
||||
extraConfig = ''
|
||||
${concatStringsSep "\n" (map allow-network fudo-cfg.local-networks)}
|
||||
allow 127.0.0.0/16;
|
||||
|
|
|
@ -8,14 +8,18 @@ let
|
|||
userOpts = { username, ... }: {
|
||||
options = {
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
type = with types; nullOr str;
|
||||
description = "The user's (plaintext) password.";
|
||||
default = null;
|
||||
};
|
||||
|
||||
databases = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = "Databases to which this user has access.";
|
||||
default = [];
|
||||
type = with types; loaOf str;
|
||||
description = "Map of databases to which this user has access, to the required perms.";
|
||||
default = {};
|
||||
example = {
|
||||
my_database = "ALL PRIVILEGES";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -24,19 +28,16 @@ let
|
|||
options = {
|
||||
users = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = "A list of users who should have access to this database.";
|
||||
description = "A list of users who should have full access to this database.";
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
userDatabaseAccess = user: databases:
|
||||
listToAttrs (map (database-name:
|
||||
{
|
||||
name = "DATABASE ${database-name}";
|
||||
value = "ALL PRIVILEGES";
|
||||
})
|
||||
databases);
|
||||
mapAttrs' (database: perms:
|
||||
nameValuePair "DATABASE ${database}" perms)
|
||||
databases;
|
||||
|
||||
stringJoin = joiner: els:
|
||||
if (length els) == 0 then
|
||||
|
@ -54,9 +55,9 @@ let
|
|||
"ALTER USER ${username} ENCRYPTED PASSWORD '${attrs.password}';";
|
||||
|
||||
setPasswordsSql = users:
|
||||
stringJoin "\n"
|
||||
(stringJoin "\n"
|
||||
(mapAttrsToList (username: attrs: setPasswordSql username attrs)
|
||||
users);
|
||||
(filterAttrs (user: attrs: attrs.password != null) users))) + "\n";
|
||||
|
||||
makeLocalUserPasswordEntries = users:
|
||||
stringJoin "\n"
|
||||
|
@ -66,7 +67,7 @@ let
|
|||
(map (db: ''
|
||||
host ${username} ${db} 127.0.0.1/16 md5
|
||||
host ${username} ${db} ::1/128 md5
|
||||
'') attrs.databases))
|
||||
'') (attrNames attrs.databases)))
|
||||
users);
|
||||
|
||||
|
||||
|
@ -99,7 +100,7 @@ in {
|
|||
default = [];
|
||||
};
|
||||
|
||||
local-users = mkOption {
|
||||
users = mkOption {
|
||||
type = with types; loaOf (submodule userOpts);
|
||||
description = "A map of users to user attributes.";
|
||||
example = {
|
||||
|
@ -146,6 +147,13 @@ in {
|
|||
group = "postgres";
|
||||
source = cfg.keytab;
|
||||
};
|
||||
|
||||
"postgresql/private/user-script.sql" = {
|
||||
mode = "0400";
|
||||
user = "postgres";
|
||||
group = "postgres";
|
||||
text = setPasswordsSql cfg.users;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -162,7 +170,7 @@ in {
|
|||
#{ "DATABASE ${username}" = "ALL PRIVILEGES"; };
|
||||
(userDatabaseAccess username attrs.databases);
|
||||
})
|
||||
cfg.local-users;
|
||||
cfg.users;
|
||||
|
||||
extraConfig =
|
||||
''
|
||||
|
@ -179,7 +187,7 @@ in {
|
|||
''
|
||||
local all all ident
|
||||
|
||||
${makeLocalUserPasswordEntries cfg.local-users}
|
||||
${makeLocalUserPasswordEntries cfg.users}
|
||||
|
||||
# host-local
|
||||
host all all 127.0.0.1/32 gss include_realm=0 krb_realm=FUDO.ORG
|
||||
|
@ -189,9 +197,13 @@ in {
|
|||
${makeNetworksEntry cfg.local-networks}
|
||||
'';
|
||||
|
||||
initialScript = pkgs.writeText "database-init.sql" ''
|
||||
${setPasswordsSql cfg.local-users}
|
||||
# initialScript = pkgs.writeText "database-init.sql" ''
|
||||
# ${setPasswordsSql cfg.users}
|
||||
# '';
|
||||
};
|
||||
|
||||
systemd.services.postgresql.postStart = ''
|
||||
${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} ${pkgs.postgresql}/bin/psql --port ${toString config.services.postgresql.port} -f /etc/postgresql/private/user-script.sql -d postgres
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
# Switch between different basic profiles
|
||||
{ lib, config, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
profile = config.fudo.profile;
|
||||
|
||||
profiles = {
|
||||
desktop = ./profiles/desktop.nix {
|
||||
pkgs = pkgs;
|
||||
config = config;
|
||||
};
|
||||
server = ./profiles/server.nix {
|
||||
pkgs = pkgs;
|
||||
config = config;
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
options.fudo.profile = {
|
||||
type = types.enum (attrNames profiles);
|
||||
example = "desktop";
|
||||
description = ''
|
||||
The profile to use for this host. This will do some profile-dependent
|
||||
configuration, for example removing X-libs from servers and adding UI
|
||||
packages to desktops.
|
||||
'';
|
||||
default = "server";
|
||||
};
|
||||
|
||||
config = optionalAttrs (profiles ? profile) profiles.${profile};
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
cool-retro-term
|
||||
chrome-gnome-shell
|
||||
chromium
|
||||
ffmpeg-full
|
||||
firefox
|
||||
gimp
|
||||
glxinfo
|
||||
gnome3.gnome-shell
|
||||
gnome3.gnome-session
|
||||
google-chrome
|
||||
gtk2
|
||||
gtk2-x11
|
||||
gtk3
|
||||
gtkimageview
|
||||
i3lock
|
||||
libfixposix
|
||||
minecraft
|
||||
mplayer
|
||||
nomacs
|
||||
openssl_1_1
|
||||
redshift
|
||||
rhythmbox
|
||||
shotwell
|
||||
spotify
|
||||
sqlite
|
||||
steam
|
||||
system-config-printer
|
||||
virtmanager
|
||||
xorg.xev
|
||||
xzgv
|
||||
virtmanager-qt
|
||||
];
|
||||
|
||||
# Splash screen
|
||||
boot.plymouth.enable = true;
|
||||
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
browseDomains = [config.fudo.domain;];
|
||||
domainName = config.fudo.domain;
|
||||
};
|
||||
|
||||
boot.tmpOnTmpfs = true;
|
||||
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
|
||||
layout = "us";
|
||||
xkbVariant = "dvp";
|
||||
xkbOptions = "ctrl:nocaps";
|
||||
|
||||
desktopManager.gnome3.enable = true;
|
||||
desktopManager.default = "gnome3";
|
||||
|
||||
displayManager.gdm.enable = true;
|
||||
|
||||
windowManager.session = pkgs.lib.singleton {
|
||||
name = "stumpwm";
|
||||
start = ''
|
||||
${pkgs.lispPackages.stumpwm}/bin/stumpwm &
|
||||
waidPID=$!
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
services.printing = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
services.gnome3 = {
|
||||
evolution-data-server.enable = pkgs.lib.mkForce false;
|
||||
gnome-user-share.enable = pkgs.lib.mkForce false;
|
||||
};
|
||||
|
||||
services.dbus.socketActivated = true;
|
||||
|
||||
services.openssh.forwardX11 = true;
|
||||
|
||||
programs.ssh.forwardX11 = true;
|
||||
|
||||
sound.enable = true;
|
||||
|
||||
hardware.pulseaudio.enable = true;
|
||||
|
||||
fonts = {
|
||||
enableCoreFonts = true;
|
||||
enableFontDir = true;
|
||||
enableGhostscriptFonts = false;
|
||||
fontconfig.ultimate.enable = true;
|
||||
|
||||
fonts = with pkgs; [
|
||||
cantarell_fonts
|
||||
dejavu_fonts
|
||||
dina-font
|
||||
dosemu_fonts
|
||||
fira-code
|
||||
fira-code-symbols
|
||||
freefont_ttf
|
||||
liberation_ttf
|
||||
mplus-outline-fonts
|
||||
nerdfonts
|
||||
noto-fonts
|
||||
noto-fonts-cjk
|
||||
noto-fonts-emoji
|
||||
proggyfonts
|
||||
terminus_font
|
||||
ubuntu_font_family
|
||||
ucsFonts
|
||||
unifont
|
||||
vistafonts
|
||||
xlibs.fontadobe100dpi
|
||||
xlibs.fontadobe75dpi
|
||||
xlibs.fontadobeutopia100dpi
|
||||
xlibs.fontadobeutopia75dpi
|
||||
xlibs.fontadobeutopiatype1
|
||||
xlibs.fontarabicmisc
|
||||
xlibs.fontbh100dpi
|
||||
xlibs.fontbh75dpi
|
||||
xlibs.fontbhlucidatypewriter100dpi
|
||||
xlibs.fontbhlucidatypewriter75dpi
|
||||
xlibs.fontbhttf
|
||||
xlibs.fontbhtype1
|
||||
xlibs.fontbitstream100dpi
|
||||
xlibs.fontbitstream75dpi
|
||||
xlibs.fontbitstreamtype1
|
||||
xlibs.fontcronyxcyrillic
|
||||
xlibs.fontcursormisc
|
||||
xlibs.fontdaewoomisc
|
||||
xlibs.fontdecmisc
|
||||
xlibs.fontibmtype1
|
||||
xlibs.fontisasmisc
|
||||
xlibs.fontjismisc
|
||||
xlibs.fontmicromisc
|
||||
xlibs.fontmisccyrillic
|
||||
xlibs.fontmiscethiopic
|
||||
xlibs.fontmiscmeltho
|
||||
xlibs.fontmiscmisc
|
||||
xlibs.fontmuttmisc
|
||||
xlibs.fontschumachermisc
|
||||
xlibs.fontscreencyrillic
|
||||
xlibs.fontsonymisc
|
||||
xlibs.fontsunmisc
|
||||
xlibs.fontwinitzkicyrillic
|
||||
xlibs.fontxfree86type1
|
||||
];
|
||||
};
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
environment = {
|
||||
systemPackages = with pkgs; [
|
||||
];
|
||||
|
||||
noXlibs = true;
|
||||
};
|
||||
|
||||
security = {
|
||||
hideProcessInformation = true;
|
||||
};
|
||||
|
||||
boot.tmpOnTmpfs = true;
|
||||
|
||||
services.xserver.enable = false;
|
||||
|
||||
programs = {
|
||||
gnupg.agent = {
|
||||
enable = true;
|
||||
enableSSHSupport = true;
|
||||
};
|
||||
|
||||
ssh.startAgent = true;
|
||||
};
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
site = config.fudo.site;
|
||||
|
||||
hostname = config.networking.hostName;
|
||||
|
||||
winnipeg-networks = [
|
||||
"208.81.1.128/28"
|
||||
"208.81.3.112/28"
|
||||
"192.168.11.1/24"
|
||||
];
|
||||
|
||||
site-configs = {
|
||||
global-config = {
|
||||
};
|
||||
|
||||
winnipeg = global-config // {
|
||||
time.timeZone = "America/Winnipeg";
|
||||
|
||||
fudo.common.local-networks = winnipeg-networks;
|
||||
|
||||
services.cron = {
|
||||
mailto = "admin@fudo.org";
|
||||
};
|
||||
|
||||
networking = {
|
||||
domain = "fudo.org";
|
||||
search = ["fudo.org"];
|
||||
firewall.enable = false;
|
||||
networkmanager.enable = pkgs.lib.mkForce false;
|
||||
nameservers = [ "1.1.1.1" "208.81.7.14" "2606:4700:4700::1111" ];
|
||||
};
|
||||
|
||||
security.acme.certs."${hostname}" = {
|
||||
email = "admin@fudo.org";
|
||||
|
||||
plugins = [
|
||||
"fullchain.pem"
|
||||
"full.pem"
|
||||
"key.pem"
|
||||
"chain.pem"
|
||||
"cert.pem"
|
||||
];
|
||||
};
|
||||
|
||||
fudo.node-exporter = {
|
||||
enable = true;
|
||||
hostname = hostname;
|
||||
};
|
||||
|
||||
nginx = {
|
||||
enable = true;
|
||||
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedTlsSettings = true;
|
||||
};
|
||||
};
|
||||
|
||||
nutty-club = winnipeg // {
|
||||
defaultGateway = "208.81.3.113";
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
options.fudo.site = mkOption {
|
||||
type = types.enum (attrNames site-configs);
|
||||
example = "nutty-club";
|
||||
description = ''
|
||||
The site at which this host is located. This will do some site-dependent
|
||||
configuration.
|
||||
'';
|
||||
default = "";
|
||||
};
|
||||
|
||||
config = optionalAttrs (site-configs ? site) site-configs.${site};
|
||||
}
|
|
@ -0,0 +1,318 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.fudo.webmail;
|
||||
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
|
||||
webmail-user = "webmail-php";
|
||||
webmail-group = "webmail-php";
|
||||
|
||||
base-data-path = "/var/rainloop";
|
||||
|
||||
fastcgi-conf = builtins.toFile "fastcgi.conf" ''
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
|
||||
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||
fastcgi_param REQUEST_URI $request_uri;
|
||||
fastcgi_param DOCUMENT_URI $document_uri;
|
||||
fastcgi_param DOCUMENT_ROOT $document_root;
|
||||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||
fastcgi_param REQUEST_SCHEME $scheme;
|
||||
fastcgi_param HTTPS $https if_not_empty;
|
||||
|
||||
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
|
||||
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||
|
||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||
fastcgi_param REMOTE_PORT $remote_port;
|
||||
fastcgi_param SERVER_ADDR $server_addr;
|
||||
fastcgi_param SERVER_PORT $server_port;
|
||||
fastcgi_param SERVER_NAME $server_name;
|
||||
|
||||
# PHP only, required if PHP was built with --enable-force-cgi-redirect
|
||||
fastcgi_param REDIRECT_STATUS 200;
|
||||
'';
|
||||
|
||||
site-packages = mapAttrs (site: site-cfg:
|
||||
pkgs.rainloop-community.overrideAttrs (oldAttrs: {
|
||||
# Not sure how to correctly specify this arg...
|
||||
#dataPath = "${base-data-path}/${site}";
|
||||
|
||||
# Overwriting, to correctly create data dir
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
cp -r rainloop/* $out
|
||||
rm -rf $out/data
|
||||
ln -s ${base-data-path}/${site} $out/data
|
||||
ln -s ${site-cfg.favicon} $out/favicon.ico
|
||||
'';
|
||||
}))
|
||||
cfg.sites;
|
||||
|
||||
siteOpts = { site-host, ... }: {
|
||||
options = {
|
||||
title = mkOption {
|
||||
type = types.str;
|
||||
description = "Webmail site title";
|
||||
example = "My Webmail";
|
||||
};
|
||||
|
||||
debug = mkOption {
|
||||
type = types.bool;
|
||||
description = "Turn debug logs on.";
|
||||
default = false;
|
||||
};
|
||||
|
||||
mail-server = mkOption {
|
||||
type = types.str;
|
||||
description = "Mail server from which to send & recieve email.";
|
||||
default = "mail.fudo.org";
|
||||
};
|
||||
|
||||
favicon = mkOption {
|
||||
type = types.str;
|
||||
description = "URL of the site favicon";
|
||||
example = "https://www.somepage.com/fav.ico";
|
||||
};
|
||||
|
||||
messages-per-page = mkOption {
|
||||
type = types.int;
|
||||
description = "Default number of messages to show per page";
|
||||
default = 30;
|
||||
};
|
||||
|
||||
max-upload-size = mkOption {
|
||||
type = types.int;
|
||||
description = "Size limit in MB for uploaded files";
|
||||
default = 30;
|
||||
};
|
||||
|
||||
theme = mkOption {
|
||||
type = types.str;
|
||||
description = "Default theme to use for this webmail site.";
|
||||
default = "Default";
|
||||
};
|
||||
|
||||
# Ideally, don't even allow admin logins, since they'll just add state that can be clobbered
|
||||
# admin-password = mkOption {
|
||||
# type = types.str;
|
||||
# description = "Password to use for the admin user";
|
||||
# };
|
||||
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = "Domain for which the server acts as webmail server";
|
||||
};
|
||||
|
||||
edit-mode = mkOption {
|
||||
type = types.enum ["Plain" "Html" "PlainForced" "HtmlForced"];
|
||||
description = "Default text editing mode for email";
|
||||
default = "Html";
|
||||
};
|
||||
|
||||
layout-mode = mkOption {
|
||||
type = types.enum ["side" "bottom"];
|
||||
description = "Layout mode to use for email preview.";
|
||||
default = "side";
|
||||
};
|
||||
|
||||
enable-threading = mkOption {
|
||||
type = types.bool;
|
||||
description = "Whether to enable threading for email.";
|
||||
default = true;
|
||||
};
|
||||
|
||||
enable-mobile = mkOption {
|
||||
type = types.bool;
|
||||
description = "Whether to enable a mobile site view.";
|
||||
default = true;
|
||||
};
|
||||
|
||||
database = mkOption {
|
||||
type = with types; nullOr (submodule databaseOpts);
|
||||
description = "Database configuration for storing contact data.";
|
||||
example = {
|
||||
name = "my_db";
|
||||
host = "db.domain.com";
|
||||
user = "my_user";
|
||||
password-file = /path/to/some/file.pw;
|
||||
};
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
databaseOpts = { ... }: {
|
||||
options = {
|
||||
type = mkOption {
|
||||
type = types.enum ["pgsql" "mysql"];
|
||||
description = "Driver to use when connecting to the database.";
|
||||
default = "pgsql";
|
||||
};
|
||||
|
||||
hostname = mkOption {
|
||||
type = types.str;
|
||||
description = "Name of host running the database.";
|
||||
example = "my-db.domain.com";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
description = "Port on which the database server is listening.";
|
||||
default = 5432;
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = "Name of the database containing contact info. <user> must have access.";
|
||||
default = "rainloop_contacts";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
description = "User as which to connect to the database.";
|
||||
};
|
||||
|
||||
password-file = mkOption {
|
||||
type = types.path;
|
||||
description = "Password to use when connecting to the database.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
options.fudo.webmail = {
|
||||
enable = mkEnableOption "Enable a RainLoop webmail server.";
|
||||
|
||||
sites = mkOption {
|
||||
type = with types; (loaOf (submodule siteOpts));
|
||||
description = "A map of webmail sites to site configurations.";
|
||||
example = {
|
||||
"webmail.domain.com" = {
|
||||
title = "My Awesome Webmail";
|
||||
layout-mode = "side";
|
||||
favicon = "/path/to/favicon.ico";
|
||||
admin-password = "shh-don't-tell";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users = {
|
||||
users = {
|
||||
${webmail-user} = {
|
||||
isSystemUser = true;
|
||||
description = "Webmail PHP FPM user";
|
||||
group = webmail-group;
|
||||
};
|
||||
};
|
||||
groups = {
|
||||
${webmail-group} = {
|
||||
members = [ webmail-user config.services.nginx.user ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
phpfpm = {
|
||||
pools.webmail = {
|
||||
settings = {
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 50;
|
||||
"pm.start_servers" = 5;
|
||||
"pm.min_spare_servers" = 1;
|
||||
"pm.max_spare_servers" = 8;
|
||||
};
|
||||
|
||||
# Not working....see chmod below
|
||||
user = webmail-user;
|
||||
group = webmail-group;
|
||||
};
|
||||
};
|
||||
|
||||
nginx = {
|
||||
enable = true;
|
||||
|
||||
virtualHosts = mapAttrs (site: site-cfg: {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
root = "${site-packages.${site}}";
|
||||
|
||||
locations = {
|
||||
"/" = {
|
||||
index = "index.php";
|
||||
};
|
||||
|
||||
"/data" = {
|
||||
extraConfig = ''
|
||||
deny all;
|
||||
return 403;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
extraConfig = ''
|
||||
location ~ \.php$ {
|
||||
expires -1;
|
||||
|
||||
include ${fastcgi-conf};
|
||||
fastcgi_index index.php;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools.webmail.socket};
|
||||
}
|
||||
'';
|
||||
})
|
||||
cfg.sites;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.nginx.preStart = let
|
||||
link-configs = concatStringsSep "\n" (mapAttrsToList (site: site-cfg: let
|
||||
cfg-file = builtins.toFile "${site}-rainloop.cfg" (import ./include/rainloop.nix lib site site-cfg site-packages.${site}.version);
|
||||
domain-cfg = builtins.toFile "${site}-domain.cfg" ''
|
||||
imap_host = "${site-cfg.mail-server}"
|
||||
imap_port = 143
|
||||
imap_secure = "TLS"
|
||||
imap_short_login = On
|
||||
sieve_use = Off
|
||||
sieve_allow_raw = Off
|
||||
sieve_host = ""
|
||||
sieve_port = 4190
|
||||
sieve_secure = "None"
|
||||
smtp_host = "${site-cfg.mail-server}"
|
||||
smtp_port = 587
|
||||
smtp_secure = "TLS"
|
||||
smtp_short_login = On
|
||||
smtp_auth = On
|
||||
smtp_php_mail = Off
|
||||
white_list = ""
|
||||
'';
|
||||
|
||||
in ''
|
||||
mkdir -p ${base-data-path}/${site}/_data_/_default_/configs
|
||||
cp ${cfg-file} ${base-data-path}/${site}/_data_/_default_/configs/application.ini
|
||||
|
||||
mkdir -p ${base-data-path}/${site}/_data_/_default_/domains/
|
||||
cp ${domain-cfg} ${base-data-path}/${site}/_data_/_default_/domains/${site-cfg.domain}.ini
|
||||
|
||||
'') cfg.sites);
|
||||
|
||||
in ''
|
||||
${link-configs}
|
||||
|
||||
chown -R ${webmail-user}:${webmail-group} ${base-data-path}
|
||||
chmod -R ug+w ${base-data-path}
|
||||
'';
|
||||
|
||||
systemd.services.phpfpm-webmail.postStart = ''
|
||||
chown ${webmail-user}:${webmail-group} ${config.services.phpfpm.pools.webmail.socket}
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -5,6 +5,7 @@ with lib;
|
|||
imports = [
|
||||
./fudo/acme-for-hostname.nix
|
||||
./fudo/authentication.nix
|
||||
./fudo/chat.nix
|
||||
./fudo/common.nix
|
||||
./fudo/grafana.nix
|
||||
./fudo/kdc.nix
|
||||
|
@ -14,8 +15,10 @@ with lib;
|
|||
./fudo/minecraft-server.nix
|
||||
./fudo/node-exporter.nix
|
||||
./fudo/postgres.nix
|
||||
./fudo/profiles.nix
|
||||
./fudo/prometheus.nix
|
||||
./fudo/sites.nix
|
||||
./fudo/webmail.nix
|
||||
|
||||
../fudo/profiles
|
||||
../fudo/sites
|
||||
];
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ in {
|
|||
domain = "fudo.org";
|
||||
|
||||
local-domains = [
|
||||
"fudo.org"
|
||||
"mail.fudo.org"
|
||||
"${config.networking.hostName}"
|
||||
"selby.ca"
|
||||
|
@ -23,6 +22,7 @@ in {
|
|||
"selbyhomecentre.com"
|
||||
"stewartsoundservices.ca"
|
||||
"rogerwongphoto.com"
|
||||
"chat.fudo.org"
|
||||
];
|
||||
|
||||
alias-users = import ./alias-users.nix;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./desktop.nix
|
||||
./server.nix
|
||||
];
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
{
|
||||
config = mkIf (config.fudo.common.profile == "desktop") {
|
||||
environment.systemPackages = with pkgs; [
|
||||
cool-retro-term
|
||||
chrome-gnome-shell
|
||||
chromium
|
||||
ffmpeg-full
|
||||
firefox
|
||||
gimp
|
||||
glxinfo
|
||||
gnome3.gnome-shell
|
||||
gnome3.gnome-session
|
||||
google-chrome
|
||||
gtk2
|
||||
gtk2-x11
|
||||
gtk3
|
||||
gtkimageview
|
||||
i3lock
|
||||
libfixposix
|
||||
minecraft
|
||||
mplayer
|
||||
nomacs
|
||||
openssl_1_1
|
||||
redshift
|
||||
rhythmbox
|
||||
shotwell
|
||||
spotify
|
||||
sqlite
|
||||
steam
|
||||
system-config-printer
|
||||
virtmanager
|
||||
xorg.xev
|
||||
xzgv
|
||||
virtmanager-qt
|
||||
];
|
||||
|
||||
# Splash screen
|
||||
boot.plymouth.enable = true;
|
||||
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
browseDomains = [config.fudo.domain];
|
||||
domainName = config.fudo.domain;
|
||||
};
|
||||
|
||||
boot.tmpOnTmpfs = true;
|
||||
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
|
||||
layout = "us";
|
||||
xkbVariant = "dvp";
|
||||
xkbOptions = "ctrl:nocaps";
|
||||
|
||||
desktopManager.gnome3.enable = true;
|
||||
desktopManager.default = "gnome3";
|
||||
|
||||
displayManager.gdm.enable = true;
|
||||
|
||||
windowManager.session = pkgs.lib.singleton {
|
||||
name = "stumpwm";
|
||||
start = ''
|
||||
${pkgs.lispPackages.stumpwm}/bin/stumpwm &
|
||||
waidPID=$!
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
services.printing = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
services.gnome3 = {
|
||||
evolution-data-server.enable = pkgs.lib.mkForce false;
|
||||
gnome-user-share.enable = pkgs.lib.mkForce false;
|
||||
};
|
||||
|
||||
services.dbus.socketActivated = true;
|
||||
|
||||
services.openssh.forwardX11 = true;
|
||||
|
||||
programs.ssh.forwardX11 = true;
|
||||
|
||||
sound.enable = true;
|
||||
|
||||
hardware.pulseaudio.enable = true;
|
||||
|
||||
fonts = {
|
||||
enableCoreFonts = true;
|
||||
enableFontDir = true;
|
||||
enableGhostscriptFonts = false;
|
||||
fontconfig.ultimate.enable = true;
|
||||
|
||||
fonts = with pkgs; [
|
||||
cantarell_fonts
|
||||
dejavu_fonts
|
||||
dina-font
|
||||
dosemu_fonts
|
||||
fira-code
|
||||
fira-code-symbols
|
||||
freefont_ttf
|
||||
liberation_ttf
|
||||
mplus-outline-fonts
|
||||
nerdfonts
|
||||
noto-fonts
|
||||
noto-fonts-cjk
|
||||
noto-fonts-emoji
|
||||
proggyfonts
|
||||
terminus_font
|
||||
ubuntu_font_family
|
||||
ucsFonts
|
||||
unifont
|
||||
vistafonts
|
||||
xlibs.fontadobe100dpi
|
||||
xlibs.fontadobe75dpi
|
||||
xlibs.fontadobeutopia100dpi
|
||||
xlibs.fontadobeutopia75dpi
|
||||
xlibs.fontadobeutopiatype1
|
||||
xlibs.fontarabicmisc
|
||||
xlibs.fontbh100dpi
|
||||
xlibs.fontbh75dpi
|
||||
xlibs.fontbhlucidatypewriter100dpi
|
||||
xlibs.fontbhlucidatypewriter75dpi
|
||||
xlibs.fontbhttf
|
||||
xlibs.fontbhtype1
|
||||
xlibs.fontbitstream100dpi
|
||||
xlibs.fontbitstream75dpi
|
||||
xlibs.fontbitstreamtype1
|
||||
xlibs.fontcronyxcyrillic
|
||||
xlibs.fontcursormisc
|
||||
xlibs.fontdaewoomisc
|
||||
xlibs.fontdecmisc
|
||||
xlibs.fontibmtype1
|
||||
xlibs.fontisasmisc
|
||||
xlibs.fontjismisc
|
||||
xlibs.fontmicromisc
|
||||
xlibs.fontmisccyrillic
|
||||
xlibs.fontmiscethiopic
|
||||
xlibs.fontmiscmeltho
|
||||
xlibs.fontmiscmisc
|
||||
xlibs.fontmuttmisc
|
||||
xlibs.fontschumachermisc
|
||||
xlibs.fontscreencyrillic
|
||||
xlibs.fontsonymisc
|
||||
xlibs.fontsunmisc
|
||||
xlibs.fontwinitzkicyrillic
|
||||
xlibs.fontxfree86type1
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
reboot-if-necessary = pkgs.writeScriptBin "reboot-if-necessary" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
|
||||
set -ne
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "FAILED: no sync file provided."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
WALL=${pkgs.utillinux}/bin/wall
|
||||
|
||||
if [ -f $1 ]; then
|
||||
$WALL "$1 exists, rebooting system"
|
||||
${pkgs.systemd}/bin/reboot
|
||||
else
|
||||
$WALL "$1 does not exist, aborting reboot."
|
||||
fi
|
||||
|
||||
exit 0
|
||||
'';
|
||||
|
||||
test-config = pkgs.writeScriptBin "fudo-test-config" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
|
||||
set -ne
|
||||
|
||||
if [ $# -gt 1 ]; then
|
||||
echo "usage: $0 [timeout]"
|
||||
exit 1
|
||||
elif [ $# -eq 1 ]; then
|
||||
TIMEOUT=$1
|
||||
else
|
||||
TIMEOUT=15m
|
||||
fi
|
||||
|
||||
SYNCFILE=$TMP/sync-$(date +"%Y%m%d-%H%M%N")
|
||||
touch $SYNCFILE
|
||||
${pkgs.utillinux}/bin/wall "Launching config. System will restart in $TIMEOUT if $SYNCFILE still exists."
|
||||
systemd-run --on-active=$TIMEOUT ${reboot-if-necessary} $SYNCFILE
|
||||
nixos-rebuild test
|
||||
|
||||
exit 0
|
||||
'';
|
||||
|
||||
in {
|
||||
config = mkIf (config.fudo.common.profile == "server") {
|
||||
environment = {
|
||||
systemPackages = with pkgs; [
|
||||
test-config
|
||||
reboot-if-necessary
|
||||
];
|
||||
|
||||
noXlibs = true;
|
||||
};
|
||||
|
||||
security = {
|
||||
hideProcessInformation = true;
|
||||
};
|
||||
|
||||
networking = {
|
||||
networkmanager.enable = mkForce false;
|
||||
};
|
||||
|
||||
boot.tmpOnTmpfs = true;
|
||||
|
||||
services.xserver.enable = false;
|
||||
|
||||
programs = {
|
||||
gnupg.agent = {
|
||||
enable = true;
|
||||
enableSSHSupport = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./portage.nix
|
||||
./seattle.nix
|
||||
];
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
admin = "admin@fudo.org";
|
||||
|
||||
nameservers = [
|
||||
"1.1.1.1"
|
||||
"208.81.7.14"
|
||||
"2606:4700:4700::1111"
|
||||
];
|
||||
|
||||
hostname = config.networking.hostName;
|
||||
|
||||
gateway = "208.81.3.113";
|
||||
gateway6 = "2605:e200:d200:1::1";
|
||||
|
||||
in {
|
||||
config = mkIf (config.fudo.common.site == "portage") {
|
||||
time.timeZone = "America/Winnipeg";
|
||||
|
||||
services.cron = {
|
||||
mailto = admin;
|
||||
};
|
||||
|
||||
networking = {
|
||||
domain = "fudo.org";
|
||||
search = ["fudo.org"];
|
||||
firewall.enable = false;
|
||||
nameservers = nameservers;
|
||||
|
||||
defaultGateway = gateway;
|
||||
# defaultGateway6 = gateway6;
|
||||
};
|
||||
|
||||
fudo.node-exporter = {
|
||||
enable = true;
|
||||
hostname = hostname;
|
||||
};
|
||||
|
||||
security.acme.certs.${hostname} = {
|
||||
email = "admin@fudo.org";
|
||||
# plugins = [
|
||||
# "fullchain.pem"
|
||||
# "full.pem"
|
||||
# "key.pem"
|
||||
# "chain.pem"
|
||||
# "cert.pem"
|
||||
# ];
|
||||
};
|
||||
|
||||
# TODO: We...could run nginx in a container
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedTlsSettings = true;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
{ lib, config, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
admin = "niten@fudo.org";
|
||||
|
||||
local-domain = "sea.fudo.org";
|
||||
|
||||
in {
|
||||
|
||||
config = mkIf (config.fudo.common.site == "seattle") {
|
||||
|
||||
time.timeZone = "America/Los_Angeles";
|
||||
|
||||
services.cron = {
|
||||
mailto = admin;
|
||||
};
|
||||
|
||||
networking = {
|
||||
domain = local-domain;
|
||||
search = [local-domain "fudo.org"];
|
||||
firewall.enable = false;
|
||||
networkmanager.enable = pkgs.lib.mkForce false;
|
||||
|
||||
# Until Comcast gets it's shit together... :(
|
||||
enableIPv6 = false;
|
||||
};
|
||||
|
||||
users.extraUsers = {
|
||||
guest = {
|
||||
isNormalUser = true;
|
||||
uid = 1000;
|
||||
description = "Guest User";
|
||||
extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"];
|
||||
};
|
||||
ken = {
|
||||
isNormalUser = true;
|
||||
uid = 10035;
|
||||
createHome = true;
|
||||
description = "Ken Selby";
|
||||
extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"];
|
||||
group = "users";
|
||||
home = "/home/selby/ken";
|
||||
hashedPassword = "$6$EwK9fpbH8$gYVzYY1IYw2/G0wCeUxXrZZqvjWCkCZbBqCOhxowbMuYtC5G0vp.AoYhVKWOJcHJM2c7TdPmAdnhLIe2KYStf.";
|
||||
};
|
||||
xiaoxuan = {
|
||||
isNormalUser = true;
|
||||
uid = 10065;
|
||||
createHome = true;
|
||||
description = "Xiaoxuan Jin";
|
||||
extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"];
|
||||
group = "users";
|
||||
home = "/home/xiaoxuan";
|
||||
hashedPassword = "$6$C8lYHrK7KvdKm/RE$cHZ2hg5gEOEjTV8Zoayik8sz5h.Vh0.ClCgOlQn8l/2Qx/qdxqZ7xCsAZ1GZ.IEyESfhJeJbjLpykXDwPpfVF0";
|
||||
};
|
||||
};
|
||||
|
||||
fileSystems."/mnt/documents" = {
|
||||
device = "whitedwarf.${local-domain}:/volume1/Documents";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
fileSystems."/mnt/downloads" = {
|
||||
device = "whitedwarf.${local-domain}:/volume1/Downloads";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
fileSystems."/mnt/music" = {
|
||||
device = "doraemon.${local-domain}:/volume1/Music";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
fileSystems."/mnt/video" = {
|
||||
device = "doraemon.${local-domain}:/volume1/Video";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
# fileSystems."/mnt/security" = {
|
||||
# device = "panopticon.${local-domain}:/srv/kerberos/data";
|
||||
# fsType = "nfs4";
|
||||
# };
|
||||
fileSystems."/mnt/cargo_video" = {
|
||||
device = "cargo.${local-domain}:/volume1/video";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
fileSystems."/mnt/photo" = {
|
||||
device = "cargo.${local-domain}:/volume1/pictures";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
|
||||
# Should use this eventually...
|
||||
# fudo.localNetwork = {
|
||||
# masterNameServer = {
|
||||
# ip = "10.0.0.1";
|
||||
# ipReverseDomain = "0.10.in-addr.arpa";
|
||||
# };
|
||||
|
||||
# domain = "${local-domain}";
|
||||
|
||||
# hostAliases = {
|
||||
# kadmin = "slab";
|
||||
# kdc = "slab";
|
||||
# photo = "doraemon";
|
||||
# music = "doraemon";
|
||||
# panopticon = "hyperion";
|
||||
# hole = "dnshole";
|
||||
# ipfs = "nostromo";
|
||||
# };
|
||||
|
||||
# hosts = {
|
||||
# slab = {
|
||||
# ipv4Address = "10.0.0.1";
|
||||
# };
|
||||
# volsung = {
|
||||
# ipv4Address = "10.0.0.106";
|
||||
# macAddress = "ac:bc:32:7b:75:a5";
|
||||
# };
|
||||
# nest = {
|
||||
# ipv4Address = "10.0.0.176";
|
||||
# macAddress = "18:b4:30:16:7c:5a";
|
||||
# };
|
||||
# monolith = {
|
||||
# ipv4Address = "10.0.0.100";
|
||||
# macAddress = "6c:62:6d:c8:b0:d8";
|
||||
# };
|
||||
# brother-wireless = {
|
||||
# ipv4Address = "10.0.0.160";
|
||||
# macAddress = "c0:38:96:64:49:65";
|
||||
# };
|
||||
# doraemon = {
|
||||
# ipv4Address = "10.0.0.52";
|
||||
# macAddress = "00:11:32:0a:06:c5";
|
||||
# };
|
||||
# lm = {
|
||||
# ipv4Address = "10.0.0.21";
|
||||
# macAddress = "52:54:00:D8:34:92";
|
||||
# };
|
||||
# ubiquiti-wifi = {
|
||||
# ipv4Address = "10.0.0.126";
|
||||
# macAddress = "04:18:d6:20:48:fb";
|
||||
# };
|
||||
# front-light = {
|
||||
# ipv4Address = "10.0.0.221";
|
||||
# macAddress = "94:10:3e:48:94:ed";
|
||||
# };
|
||||
# ipad = {
|
||||
# ipv4Address = "10.0.0.202";
|
||||
# macAddress = "9c:35:eb:48:6e:71";
|
||||
# };
|
||||
# chromecast-2 = {
|
||||
# ipv4Address = "10.0.0.215";
|
||||
# macAddress = "a4:77:33:59:a2:ba";
|
||||
# };
|
||||
# taipan = {
|
||||
# ipv4Address = "10.0.0.107";
|
||||
# macAddress = "52:54:00:34:c4:78";
|
||||
# };
|
||||
# dns-hole = {
|
||||
# ipv4Address = "10.0.0.185";
|
||||
# macAddress = "b8:27:eb:b2:95:fd";
|
||||
# };
|
||||
# family-tv = {
|
||||
# ipv4Address = "10.0.0.205";
|
||||
# macAddress = "84:a4:66:3a:b1:f8";
|
||||
# };
|
||||
# spark = {
|
||||
# ipv4Address = "10.0.0.108";
|
||||
# macAddress = "78:24:af:04:f7:dd";
|
||||
# };
|
||||
# babycam = {
|
||||
# ipv4Address = "10.0.0.206";
|
||||
# macAddress = "08:ea:40:59:5f:9e";
|
||||
# };
|
||||
# hyperion = {
|
||||
# ipv4Address = "10.0.0.109";
|
||||
# macAddress = "52:54:00:33:46:de";
|
||||
# };
|
||||
# cargo = {
|
||||
# ipv4Address = "10.0.0.50";
|
||||
# macAddress = "00:11:32:75:d8:b7";
|
||||
# };
|
||||
# cam-entrance = {
|
||||
# ipv4Address = "10.0.0.31";
|
||||
# macAddress = "9c:8e:cd:0e:99:7b";
|
||||
# };
|
||||
# cam-driveway = {
|
||||
# ipv4Address = "10.0.0.32";
|
||||
# macAddress = "9c:8e:cd:0d:3b:09";
|
||||
# };
|
||||
# cam-deck = {
|
||||
# ipv4Address = "10.0.0.33";
|
||||
# macAddress = "9c:8e:cd:0e:98:c8";
|
||||
# };
|
||||
# nostromo = {
|
||||
# ipv4Address = "10.0.0.2";
|
||||
# macAddress = "14:fe:b5:ca:a2:c9";
|
||||
# };
|
||||
# zbox = {
|
||||
# ipv4Address = "10.0.0.110";
|
||||
# macAddress = "18:60:24:91:CC:27";
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
};
|
||||
}
|
|
@ -408,4 +408,11 @@
|
|||
hashed-password = "{SSHA}LSz1WjWfjRwAM3xm+QZ71vFj997dnZC6";
|
||||
};
|
||||
|
||||
# Used to send messages from the chat server
|
||||
chat = {
|
||||
uid = 10111;
|
||||
group = "fudo";
|
||||
common-name = "Fudo Chat";
|
||||
hashed-password = "{SSHA}XDYAM2JE4PXssywRzO4tVSbn5lUZOgg7";
|
||||
};
|
||||
}
|
||||
|
|
138
hosts/france.nix
138
hosts/france.nix
|
@ -2,8 +2,9 @@
|
|||
|
||||
with lib;
|
||||
let
|
||||
hostname = "france.fudo.org";
|
||||
mail-hostname = "france.fudo.org";
|
||||
domain = "fudo.org";
|
||||
hostname = "france.${domain}";
|
||||
mail-hostname = hostname;
|
||||
host_ipv4 = "208.81.3.117";
|
||||
all-hostnames = [];
|
||||
|
||||
|
@ -29,20 +30,26 @@ in {
|
|||
../hardware-configuration.nix
|
||||
|
||||
../defaults.nix
|
||||
|
||||
# These should really both be settings...
|
||||
# ../networks/fudo.org.nix
|
||||
# ../profiles/server.nix
|
||||
];
|
||||
|
||||
fudo.profile = "server";
|
||||
fudo.site = "nutty-club";
|
||||
fudo.local-networks = [
|
||||
fudo.common = {
|
||||
# Sets some server-common settings. See /etc/nixos/fudo/profiles/...
|
||||
profile = "server";
|
||||
|
||||
# Sets some common site-specific settings: gateway, monitoring, etc. See /etc/nixos/fudo/sites/...
|
||||
site = "portage";
|
||||
|
||||
domain = domain;
|
||||
|
||||
www-root = /srv/www;
|
||||
|
||||
local-networks = [
|
||||
"208.81.1.128/28"
|
||||
"208.81.3.112/28"
|
||||
"172.17.0.0/16"
|
||||
"127.0.0.0/8"
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
docker
|
||||
|
@ -60,14 +67,6 @@ in {
|
|||
dovecot = [ "dovecot._metrics._tcp.fudo.org" ];
|
||||
rspamd = [ "rspamd._metrics._tcp.fudo.org" ];
|
||||
};
|
||||
# Connections will be allowed from these networks. No auth is performed--the
|
||||
# data is read-only anyway.
|
||||
trusted-networks = [
|
||||
"208.81.1.128/28"
|
||||
"208.81.3.112/28"
|
||||
"172.17.0.0/16"
|
||||
"127.0.0.0/8"
|
||||
];
|
||||
};
|
||||
|
||||
fudo.grafana = {
|
||||
|
@ -75,15 +74,20 @@ in {
|
|||
hostname = "monitor.fudo.org";
|
||||
smtp-username = "metrics";
|
||||
smtp-password-file = "/srv/grafana/secure/smtp.passwd";
|
||||
database-password-file = "/srv/grafana/secure/db.passwd";
|
||||
admin-password-file = "/srv/grafana/secure/admin.passwd";
|
||||
secret-key-file = "/srv/grafana/secure/secret.key";
|
||||
prometheus-host = "metrics.fudo.org";
|
||||
database = {
|
||||
name = "grafana";
|
||||
hostname = "localhost";
|
||||
user = "grafana";
|
||||
password-file = /srv/grafana/secure/db.passwd;
|
||||
};
|
||||
};
|
||||
|
||||
# So that grafana waits for postgresql
|
||||
systemd.services.grafana.requires = [
|
||||
"postgresql"
|
||||
systemd.services.grafana.after = [
|
||||
"postgresql.service"
|
||||
];
|
||||
|
||||
fudo.postgresql = {
|
||||
|
@ -95,7 +99,7 @@ in {
|
|||
# We allow connections from local networks. Auth is still required. Outside
|
||||
# of these networks, no access is allowed.
|
||||
#
|
||||
# TODO: that's probably to strict, allow kerberos connections from anywhere.
|
||||
# TODO: that's probably too strict, allow kerberos connections from anywhere?
|
||||
local-networks = [
|
||||
"208.81.1.128/28"
|
||||
"208.81.3.112/28"
|
||||
|
@ -103,6 +107,34 @@ in {
|
|||
"127.0.0.1/8"
|
||||
"172.17.0.0/16"
|
||||
];
|
||||
|
||||
users = {
|
||||
grafana = {
|
||||
password = fileContents "/srv/grafana/secure/db.passwd";
|
||||
databases = {
|
||||
grafana = "ALL PRIVILEGES";
|
||||
};
|
||||
};
|
||||
mattermost = {
|
||||
password = fileContents "/srv/mattermost/secure/db.passwd";
|
||||
databases = {
|
||||
mattermost = "ALL PRIVILEGES";
|
||||
};
|
||||
};
|
||||
webmail = {
|
||||
password = fileContents "/srv/webmail/secure/db.passwd";
|
||||
databases = {
|
||||
webmail = "ALL PRIVILEGES";
|
||||
};
|
||||
};
|
||||
niten = {};
|
||||
};
|
||||
|
||||
databases = {
|
||||
grafana = ["niten"];
|
||||
mattermost = ["niten"];
|
||||
webmail = ["niten"];
|
||||
};
|
||||
};
|
||||
|
||||
# Not all users need access to france; don't allow LDAP-user access.
|
||||
|
@ -133,10 +165,14 @@ in {
|
|||
|
||||
# TODO: loop over v4 and v6 IPs.
|
||||
listen-uris = [
|
||||
"ldap://${host_ipv4}/"
|
||||
"ldaps://${host_ipv4}/"
|
||||
"ldap://localhost/"
|
||||
"ldaps://localhost/"
|
||||
"ldap:///"
|
||||
"ldaps:///"
|
||||
# "ldap://${host_ipv4}/"
|
||||
# "ldaps://${host_ipv4}/"
|
||||
# "ldap://localhost/"
|
||||
# "ldaps://localhost/"
|
||||
# "ldap://127.0.1.1/"
|
||||
# "ldaps://127.0.1.1/"
|
||||
"ldapi:///"
|
||||
];
|
||||
|
||||
|
@ -191,13 +227,51 @@ in {
|
|||
dkim.signing = true;
|
||||
};
|
||||
|
||||
fudo.webmail = {
|
||||
enable = true;
|
||||
|
||||
sites = {
|
||||
"webmail.fudo.link" = {
|
||||
title = "Fudo Link Webmail";
|
||||
favicon = "/etc/nixos/static/fudo.link/favicon.ico";
|
||||
mail-server = mail-hostname;
|
||||
domain = "fudo.link";
|
||||
edit-mode = "Plain";
|
||||
layout-mode = "bottom";
|
||||
database = {
|
||||
name = "webmail";
|
||||
hostname = "localhost";
|
||||
user = "webmail";
|
||||
password-file = /srv/webmail/secure/db.passwd;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fudo.chat = {
|
||||
enable = true;
|
||||
|
||||
hostname = "chat.fudo.org";
|
||||
site-name = "Fudo Chat";
|
||||
smtp-server = "france.fudo.org";
|
||||
smtp-user = "chat";
|
||||
smtp-password-file = /srv/mattermost/secure/smtp.passwd;
|
||||
database = {
|
||||
name = "mattermost";
|
||||
hostname = "localhost";
|
||||
user = "mattermost";
|
||||
password-file = /srv/mattermost/secure/db.passwd;
|
||||
};
|
||||
};
|
||||
|
||||
networking = {
|
||||
hostName = hostname;
|
||||
|
||||
dhcpcd.enable = false;
|
||||
useDHCP = false;
|
||||
interfaces.enp4s0f0.useDHCP = true;
|
||||
interfaces.enp4s0f1.useDHCP = true;
|
||||
# Why on earth would these use DHCP?
|
||||
# interfaces.enp4s0f0.useDHCP = true;
|
||||
# interfaces.enp4s0f1.useDHCP = true;
|
||||
|
||||
# TODO: fix IPv6
|
||||
enableIPv6 = false;
|
||||
|
@ -276,6 +350,16 @@ in {
|
|||
options = ["subvol=gitlab"];
|
||||
label = "pool0";
|
||||
};
|
||||
"/var/lib/lxd/storage-pools/pool0" = {
|
||||
fsType = "btrfs";
|
||||
label = "pool0";
|
||||
device = "/dev/disk/by-label/pool0";
|
||||
};
|
||||
"/var/lib/lxd/storage-pools/pool1" = {
|
||||
fsType = "btrfs";
|
||||
label = "pool1";
|
||||
device = "/dev/france-user/fudo-user";
|
||||
};
|
||||
};
|
||||
|
||||
##
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
{ lib, config, pkgs, ... }:
|
||||
|
||||
let
|
||||
hostname = config.networking.hostName;
|
||||
|
||||
www-root = "/var/www";
|
||||
|
||||
index = pkgs.writeTextFile {
|
||||
name = "index.html";
|
||||
|
||||
text = ''
|
||||
<html>
|
||||
<head>
|
||||
<title>${hostname}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>${hostname}</title>
|
||||
</body>
|
||||
</html>
|
||||
'';
|
||||
destination = www-root + ("/" + hostname);
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
config = {
|
||||
time.timeZone = "America/Winnipeg";
|
||||
|
||||
services.cron = {
|
||||
mailto = "admin@fudo.org";
|
||||
};
|
||||
|
||||
networking = {
|
||||
domain = "fudo.org";
|
||||
|
||||
search = ["fudo.org"];
|
||||
|
||||
firewall.enable = false;
|
||||
|
||||
networkmanager.enable = pkgs.lib.mkForce false;
|
||||
|
||||
defaultGateway = "208.81.3.113";
|
||||
|
||||
nameservers = [ "1.1.1.1" "208.81.7.14" "2606:4700:4700::1111" ];
|
||||
};
|
||||
|
||||
security.acme.certs."${hostname}" = {
|
||||
email = "admin@fudo.org";
|
||||
|
||||
plugins = [
|
||||
"fullchain.pem"
|
||||
"full.pem"
|
||||
"key.pem"
|
||||
"chain.pem"
|
||||
"cert.pem"
|
||||
];
|
||||
};
|
||||
|
||||
services = {
|
||||
prometheus.exporters.node = {
|
||||
enable = true;
|
||||
enabledCollectors = [ "systemd" ];
|
||||
user = "node";
|
||||
};
|
||||
|
||||
nginx = {
|
||||
enable = true;
|
||||
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
virtualHosts = {
|
||||
|
||||
"${hostname}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
root = www-root + ("/" + hostname);
|
||||
|
||||
listen = [
|
||||
{
|
||||
addr = hostname;
|
||||
port = 80;
|
||||
ssl = false;
|
||||
}
|
||||
{
|
||||
addr = hostname;
|
||||
port = 443;
|
||||
ssl = true;
|
||||
}
|
||||
];
|
||||
|
||||
locations."/metrics/node" = {
|
||||
extraConfig = ''
|
||||
allow 208.81.1.128/28;
|
||||
allow 208.81.3.112/28;
|
||||
allow 127.0.0.0/16;
|
||||
deny all;
|
||||
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
'';
|
||||
# proxy_set_header Host $http_host;
|
||||
|
||||
proxyPass = "http://127.0.0.1:9100/metrics";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
config.time.timeZone = "America/Los_Angeles";
|
||||
|
||||
config.services.cron = {
|
||||
mailto = "niten@fudo.org";
|
||||
};
|
||||
|
||||
services.printing.enable = true;
|
||||
|
||||
config.networking = {
|
||||
domain = "sea.fudo.org";
|
||||
search = ["sea.fudo.org" "fudo.org"];
|
||||
firewall.enable = false;
|
||||
networkmanager.enable = pkgs.lib.mkForce false;
|
||||
|
||||
# Until Comcast gets it's shit together... :(
|
||||
enableIPv6 = false;
|
||||
};
|
||||
|
||||
config.fileSystems."/mnt/documents" = {
|
||||
device = "whitedwarf.sea.fudo.org:/volume1/Documents";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
config.fileSystems."/mnt/downloads" = {
|
||||
device = "whitedwarf.sea.fudo.org:/volume1/Downloads";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
config.fileSystems."/mnt/music" = {
|
||||
device = "doraemon.sea.fudo.org:/volume1/Music";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
config.fileSystems."/mnt/video" = {
|
||||
device = "doraemon.sea.fudo.org:/volume1/Video";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
# fileSystems."/mnt/security" = {
|
||||
# device = "panopticon.sea.fudo.org:/srv/kerberos/data";
|
||||
# fsType = "nfs4";
|
||||
# };
|
||||
config.fileSystems."/mnt/cargo_video" = {
|
||||
device = "cargo.sea.fudo.org:/volume1/video";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
config.fileSystems."/mnt/photo" = {
|
||||
device = "cargo.sea.fudo.org:/volume1/pictures";
|
||||
fsType = "nfs4";
|
||||
};
|
||||
|
||||
config.users.extraUsers = {
|
||||
guest = {
|
||||
isNormalUser = true;
|
||||
uid = 1000;
|
||||
description = "Guest User";
|
||||
extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"];
|
||||
};
|
||||
ken = {
|
||||
isNormalUser = true;
|
||||
uid = 10035;
|
||||
createHome = true;
|
||||
description = "Ken Selby";
|
||||
extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"];
|
||||
group = "users";
|
||||
home = "/home/selby/ken";
|
||||
hashedPassword = "$6$EwK9fpbH8$gYVzYY1IYw2/G0wCeUxXrZZqvjWCkCZbBqCOhxowbMuYtC5G0vp.AoYhVKWOJcHJM2c7TdPmAdnhLIe2KYStf.";
|
||||
};
|
||||
xiaoxuan = {
|
||||
isNormalUser = true;
|
||||
uid = 10065;
|
||||
createHome = true;
|
||||
description = "Xiaoxuan Jin";
|
||||
extraGroups = ["audio" "video" "disk" "floppy" "lp" "cdrom" "tape" "input"];
|
||||
group = "users";
|
||||
home = "/home/xiaoxuan";
|
||||
hashedPassword = "$6$C8lYHrK7KvdKm/RE$cHZ2hg5gEOEjTV8Zoayik8sz5h.Vh0.ClCgOlQn8l/2Qx/qdxqZ7xCsAZ1GZ.IEyESfhJeJbjLpykXDwPpfVF0";
|
||||
};
|
||||
};
|
||||
|
||||
config.fudo.localNetwork = {
|
||||
masterNameServer = {
|
||||
ip = "10.0.0.1";
|
||||
ipReverseDomain = "0.10.in-addr.arpa";
|
||||
};
|
||||
|
||||
domain = "sea.fudo.org";
|
||||
|
||||
hostAliases = {
|
||||
kadmin = "slab";
|
||||
kdc = "slab";
|
||||
photo = "doraemon";
|
||||
music = "doraemon";
|
||||
panopticon = "hyperion";
|
||||
hole = "dnshole";
|
||||
ipfs = "nostromo";
|
||||
};
|
||||
|
||||
hosts = {
|
||||
slab = {
|
||||
ipv4Address = "10.0.0.1";
|
||||
};
|
||||
volsung = {
|
||||
ipv4Address = "10.0.0.106";
|
||||
macAddress = "ac:bc:32:7b:75:a5";
|
||||
};
|
||||
nest = {
|
||||
ipv4Address = "10.0.0.176";
|
||||
macAddress = "18:b4:30:16:7c:5a";
|
||||
};
|
||||
monolith = {
|
||||
ipv4Address = "10.0.0.100";
|
||||
macAddress = "6c:62:6d:c8:b0:d8";
|
||||
};
|
||||
brother-wireless = {
|
||||
ipv4Address = "10.0.0.160";
|
||||
macAddress = "c0:38:96:64:49:65";
|
||||
};
|
||||
doraemon = {
|
||||
ipv4Address = "10.0.0.52";
|
||||
macAddress = "00:11:32:0a:06:c5";
|
||||
};
|
||||
lm = {
|
||||
ipv4Address = "10.0.0.21";
|
||||
macAddress = "52:54:00:D8:34:92";
|
||||
};
|
||||
ubiquiti-wifi = {
|
||||
ipv4Address = "10.0.0.126";
|
||||
macAddress = "04:18:d6:20:48:fb";
|
||||
};
|
||||
front-light = {
|
||||
ipv4Address = "10.0.0.221";
|
||||
macAddress = "94:10:3e:48:94:ed";
|
||||
};
|
||||
ipad = {
|
||||
ipv4Address = "10.0.0.202";
|
||||
macAddress = "9c:35:eb:48:6e:71";
|
||||
};
|
||||
chromecast-2 = {
|
||||
ipv4Address = "10.0.0.215";
|
||||
macAddress = "a4:77:33:59:a2:ba";
|
||||
};
|
||||
taipan = {
|
||||
ipv4Address = "10.0.0.107";
|
||||
macAddress = "52:54:00:34:c4:78";
|
||||
};
|
||||
dns-hole = {
|
||||
ipv4Address = "10.0.0.185";
|
||||
macAddress = "b8:27:eb:b2:95:fd";
|
||||
};
|
||||
family-tv = {
|
||||
ipv4Address = "10.0.0.205";
|
||||
macAddress = "84:a4:66:3a:b1:f8";
|
||||
};
|
||||
spark = {
|
||||
ipv4Address = "10.0.0.108";
|
||||
macAddress = "78:24:af:04:f7:dd";
|
||||
};
|
||||
babycam = {
|
||||
ipv4Address = "10.0.0.206";
|
||||
macAddress = "08:ea:40:59:5f:9e";
|
||||
};
|
||||
hyperion = {
|
||||
ipv4Address = "10.0.0.109";
|
||||
macAddress = "52:54:00:33:46:de";
|
||||
};
|
||||
cargo = {
|
||||
ipv4Address = "10.0.0.50";
|
||||
macAddress = "00:11:32:75:d8:b7";
|
||||
};
|
||||
cam-entrance = {
|
||||
ipv4Address = "10.0.0.31";
|
||||
macAddress = "9c:8e:cd:0e:99:7b";
|
||||
};
|
||||
cam-driveway = {
|
||||
ipv4Address = "10.0.0.32";
|
||||
macAddress = "9c:8e:cd:0d:3b:09";
|
||||
};
|
||||
cam-deck = {
|
||||
ipv4Address = "10.0.0.33";
|
||||
macAddress = "9c:8e:cd:0e:98:c8";
|
||||
};
|
||||
nostromo = {
|
||||
ipv4Address = "10.0.0.2";
|
||||
macAddress = "14:fe:b5:ca:a2:c9";
|
||||
};
|
||||
zbox = {
|
||||
ipv4Address = "10.0.0.110";
|
||||
macAddress = "18:60:24:91:CC:27";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
root@france.26610:1573312038
|
|
@ -1,151 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
cool-retro-term
|
||||
chrome-gnome-shell
|
||||
chromium
|
||||
ffmpeg-full
|
||||
firefox
|
||||
gimp
|
||||
glxinfo
|
||||
gnome3.gnome-shell
|
||||
gnome3.gnome-session
|
||||
google-chrome
|
||||
gtk2
|
||||
gtk2-x11
|
||||
gtk3
|
||||
gtkimageview
|
||||
i3lock
|
||||
libfixposix
|
||||
minecraft
|
||||
mplayer
|
||||
nomacs
|
||||
openssl_1_1
|
||||
redshift
|
||||
rhythmbox
|
||||
shotwell
|
||||
spotify
|
||||
sqlite
|
||||
steam
|
||||
system-config-printer
|
||||
virtmanager
|
||||
xorg.xev
|
||||
xzgv
|
||||
virtmanager-qt
|
||||
];
|
||||
|
||||
boot.plymouth.enable = true;
|
||||
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
browseDomains = ["sea.fudo.org"];
|
||||
domainName = "sea.fudo.org";
|
||||
};
|
||||
|
||||
boot.tmpOnTmpfs = true;
|
||||
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
|
||||
layout = "us";
|
||||
xkbVariant = "dvp";
|
||||
xkbOptions = "ctrl:nocaps";
|
||||
|
||||
desktopManager.gnome3.enable = true;
|
||||
desktopManager.default = "gnome3";
|
||||
|
||||
displayManager.gdm.enable = true;
|
||||
|
||||
windowManager.session = pkgs.lib.singleton {
|
||||
name = "stumpwm";
|
||||
start = ''
|
||||
${pkgs.lispPackages.stumpwm}/bin/stumpwm &
|
||||
waidPID=$!
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
services.printing = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
services.gnome3 = {
|
||||
evolution-data-server.enable = pkgs.lib.mkForce false;
|
||||
gnome-user-share.enable = pkgs.lib.mkForce false;
|
||||
};
|
||||
|
||||
services.dbus.socketActivated = true;
|
||||
|
||||
services.openssh.forwardX11 = true;
|
||||
|
||||
programs.ssh.forwardX11 = true;
|
||||
|
||||
sound.enable = true;
|
||||
|
||||
hardware.pulseaudio.enable = true;
|
||||
|
||||
fonts = {
|
||||
enableCoreFonts = true;
|
||||
enableFontDir = true;
|
||||
enableGhostscriptFonts = false;
|
||||
fontconfig.ultimate.enable = true;
|
||||
|
||||
fonts = with pkgs; [
|
||||
cantarell_fonts
|
||||
dejavu_fonts
|
||||
dina-font
|
||||
dosemu_fonts
|
||||
fira-code
|
||||
fira-code-symbols
|
||||
freefont_ttf
|
||||
liberation_ttf
|
||||
mplus-outline-fonts
|
||||
nerdfonts
|
||||
noto-fonts
|
||||
noto-fonts-cjk
|
||||
noto-fonts-emoji
|
||||
proggyfonts
|
||||
terminus_font
|
||||
ubuntu_font_family
|
||||
ucsFonts
|
||||
unifont
|
||||
vistafonts
|
||||
xlibs.fontadobe100dpi
|
||||
xlibs.fontadobe75dpi
|
||||
xlibs.fontadobeutopia100dpi
|
||||
xlibs.fontadobeutopia75dpi
|
||||
xlibs.fontadobeutopiatype1
|
||||
xlibs.fontarabicmisc
|
||||
xlibs.fontbh100dpi
|
||||
xlibs.fontbh75dpi
|
||||
xlibs.fontbhlucidatypewriter100dpi
|
||||
xlibs.fontbhlucidatypewriter75dpi
|
||||
xlibs.fontbhttf
|
||||
xlibs.fontbhtype1
|
||||
xlibs.fontbitstream100dpi
|
||||
xlibs.fontbitstream75dpi
|
||||
xlibs.fontbitstreamtype1
|
||||
xlibs.fontcronyxcyrillic
|
||||
xlibs.fontcursormisc
|
||||
xlibs.fontdaewoomisc
|
||||
xlibs.fontdecmisc
|
||||
xlibs.fontibmtype1
|
||||
xlibs.fontisasmisc
|
||||
xlibs.fontjismisc
|
||||
xlibs.fontmicromisc
|
||||
xlibs.fontmisccyrillic
|
||||
xlibs.fontmiscethiopic
|
||||
xlibs.fontmiscmeltho
|
||||
xlibs.fontmiscmisc
|
||||
xlibs.fontmuttmisc
|
||||
xlibs.fontschumachermisc
|
||||
xlibs.fontscreencyrillic
|
||||
xlibs.fontsonymisc
|
||||
xlibs.fontsunmisc
|
||||
xlibs.fontwinitzkicyrillic
|
||||
xlibs.fontxfree86type1
|
||||
];
|
||||
};
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
base = "dc=fudo,dc=org";
|
||||
ldap = import ../config/fudo/ldap.nix;
|
||||
|
||||
in {
|
||||
|
||||
imports = [
|
||||
../config/fudo/ldap.nix
|
||||
];
|
||||
|
||||
services.openldap = {
|
||||
enable = true;
|
||||
suffix = base;
|
||||
rootdn = "cn=admin,${base}";
|
||||
rootpwFile = "/srv/ldap/secure/root.pw";
|
||||
};
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
environment = {
|
||||
systemPackages = with pkgs; [
|
||||
];
|
||||
|
||||
noXlibs = true;
|
||||
};
|
||||
|
||||
security.hideProcessInformation = true;
|
||||
|
||||
boot.tmpOnTmpfs = true;
|
||||
|
||||
services.xserver.enable = false;
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
# Starts an Nginx server on $HOSTNAME just to get a cert for this host
|
||||
|
||||
{ config, pkgs, environment, ... }:
|
||||
|
||||
let
|
||||
hostname = config.networking.hostName;
|
||||
|
||||
wwwRoot = pkgs.writeTextFile {
|
||||
name = "index.html";
|
||||
|
||||
text = ''
|
||||
<html>
|
||||
<head>
|
||||
<title>${hostname}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>${hostname}</title>
|
||||
</body>
|
||||
</html>
|
||||
'';
|
||||
destination = "/www";
|
||||
};
|
||||
|
||||
in {
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
virtualHosts."${hostname}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
root = wwwRoot + ("/" + "www");
|
||||
};
|
||||
};
|
||||
|
||||
security.acme.certs = {
|
||||
${hostname}.email = "admin@fudo.org";
|
||||
};
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
{ config, pkgs, environment, ... }:
|
||||
|
||||
let
|
||||
databaseName = "powerdns";
|
||||
userName = "powerdns";
|
||||
reverseIp = ip: builtins.concatStringsSep "." (lib.lists.reverseList(lib.strings.splitString "." ip));
|
||||
fullReverseIp = ip: "${reverseIp ip}.in-addr.arpa";
|
||||
hostRecord = domain_id: type: name: content: ''
|
||||
INSERT INTO records (domain_id, name, type, content) VALUES ($domain_id, '${name}', '${type}', '${content}');
|
||||
'';
|
||||
|
||||
in {
|
||||
environment = {
|
||||
systemPackages = with pkgs; [
|
||||
postgresql_11_gssapi
|
||||
powerdns
|
||||
];
|
||||
};
|
||||
|
||||
services.postgresql.users."${userName}" = {
|
||||
passwd = "some_junk";
|
||||
databases = ["${databaseName}"];
|
||||
};
|
||||
|
||||
services.postgresql.databases."${databaseName} = {
|
||||
"${databaseName}" = ''
|
||||
CREATE TABLE domains (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
master VARCHAR(128) DEFAULT NULL,
|
||||
last_check INT DEFAULT NULL,
|
||||
type VARCHAR(6) NOT NULL,
|
||||
notified_serial INT DEFAULT NULL,
|
||||
account VARCHAR(40) DEFAULT NULL,
|
||||
CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT)))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX name_index ON domains(name);
|
||||
|
||||
|
||||
CREATE TABLE records (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
domain_id INT DEFAULT NULL,
|
||||
name VARCHAR(255) DEFAULT NULL,
|
||||
type VARCHAR(10) DEFAULT NULL,
|
||||
content VARCHAR(65535) DEFAULT NULL,
|
||||
ttl INT DEFAULT NULL,
|
||||
prio INT DEFAULT NULL,
|
||||
disabled BOOL DEFAULT 'f',
|
||||
ordername VARCHAR(255),
|
||||
auth BOOL DEFAULT 't',
|
||||
CONSTRAINT domain_exists
|
||||
FOREIGN KEY(domain_id) REFERENCES domains(id)
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT)))
|
||||
);
|
||||
|
||||
CREATE INDEX rec_name_index ON records(name);
|
||||
CREATE INDEX nametype_index ON records(name,type);
|
||||
CREATE INDEX domain_id ON records(domain_id);
|
||||
CREATE INDEX recordorder ON records (domain_id, ordername text_pattern_ops);
|
||||
|
||||
|
||||
CREATE TABLE supermasters (
|
||||
ip INET NOT NULL,
|
||||
nameserver VARCHAR(255) NOT NULL,
|
||||
account VARCHAR(40) NOT NULL,
|
||||
PRIMARY KEY(ip, nameserver)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE comments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
domain_id INT NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
type VARCHAR(10) NOT NULL,
|
||||
modified_at INT NOT NULL,
|
||||
account VARCHAR(40) DEFAULT NULL,
|
||||
comment VARCHAR(65535) NOT NULL,
|
||||
CONSTRAINT domain_exists
|
||||
FOREIGN KEY(domain_id) REFERENCES domains(id)
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT)))
|
||||
);
|
||||
|
||||
CREATE INDEX comments_domain_id_idx ON comments (domain_id);
|
||||
CREATE INDEX comments_name_type_idx ON comments (name, type);
|
||||
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);
|
||||
|
||||
|
||||
CREATE TABLE domainmetadata (
|
||||
id SERIAL PRIMARY KEY,
|
||||
domain_id INT REFERENCES domains(id) ON DELETE CASCADE,
|
||||
kind VARCHAR(32),
|
||||
content TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX domainidmetaindex ON domainmetadata(domain_id);
|
||||
|
||||
|
||||
CREATE TABLE cryptokeys (
|
||||
id SERIAL PRIMARY KEY,
|
||||
domain_id INT REFERENCES domains(id) ON DELETE CASCADE,
|
||||
flags INT NOT NULL,
|
||||
active BOOL,
|
||||
content TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX domainidindex ON cryptokeys(domain_id);
|
||||
|
||||
|
||||
CREATE TABLE tsigkeys (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255),
|
||||
algorithm VARCHAR(50),
|
||||
secret VARCHAR(255),
|
||||
CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT)))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);
|
||||
|
||||
INSERT INTO domains (id, name, master, type) VALUES (1, '${config.fudo.localNetwork.domain}', '${config.fudo.localNetwork.masterNameServer.ip}', 'MASTER');
|
||||
INSERT INTO domains (id, name, master, type) VALUES (2, '${config.fudo.localNetwork.masterNameServer.ipReverseDomain}', '${config.fudo.localNetwork.masterNameServer.ip}', 'MASTER');
|
||||
|
||||
${hostRecord 1 "SOA" config.fudo.localDomain "${config.fudo.localNetwork.domain}. hostmaster.${config.fudo.localNetwork.domain}."}
|
||||
${hostRecord 2 "SOA" config.fudo.masterNameServer.ipReverseDomain "${config.fudo.localNetwork.masterNameServer.ipReverseDomain} hostmaster.${config.fudo.localNetwork.domain}."}
|
||||
${hostRecord 1 "NS" config.fudo.localNetwork.domain config.fudo.localNetwork.masterNameServer.ip}
|
||||
${hostRecord 2 "NS" config.fudo.localNetwork.masterNameServer.ipReverseDomain config.fudo.localNetwork.masterNameServer.ip}
|
||||
|
||||
${builtins.concatStringsSep "\n" (lib.attrSets.mapAttrs (host: attrs: hostRecord 1 "A" host attrs.ipv4Address) config.fudo.localNetwork.hosts)}
|
||||
${builtins.concatStringsSep "\n" (lib.attrSets.mapAttrs (host: attrs: hostRecord 2 "PTR" (fullReverseIp attrs.ipv4Address) host) config.fudo.localNetworkhosts)}
|
||||
${builtins.concatStringsSep "\n" (lib.attrSets.mapAttrs (alias: host: hostRecord 1 "CNAME" alias host) config.fudo.localNetwork.hostAliases)}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{ containers.https =
|
||||
let
|
||||
hostname = "${config.hostname}.fudo.link";
|
||||
incomingCertDir = "/srv/${config.hostname}/certs";
|
||||
containerCertsDir = "/etc/letsencrypt/live";
|
||||
|
||||
in {
|
||||
autoStart = true;
|
||||
|
||||
bindMounts = [
|
||||
{
|
||||
"${containerCertsDir}" = {
|
||||
hostPath = "${incomingCertsDir}";
|
||||
isReadOnly = false;
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
config = { config, pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
nginx
|
||||
];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
virtualHosts."${hostname}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
root = "/var/www";
|
||||
};
|
||||
|
||||
security.acme.certs = {
|
||||
"${hostname}".email = config.adminEmail;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
{ config, pkgs, environment, ... }:
|
||||
|
||||
let
|
||||
hostPath = /srv + ("/" + config.networking.hostName);
|
||||
srcCertificateDirectory = hostPath + "/certs";
|
||||
dstCertificateDirectory = "/etc/pki/certs/postgres";
|
||||
dstPrivateKey = dstCertificateDirectory + /private/privkey.pem;
|
||||
srcKeytabPath = hostPath + /keytabs/postgres;
|
||||
dstKeytabPath = "/etc/postgresql-common/keytab";
|
||||
|
||||
in {
|
||||
|
||||
containers.postgres = {
|
||||
autoStart = true;
|
||||
|
||||
bindMounts = {
|
||||
"${dstCertificateDirectory}" = {
|
||||
hostPath = "${srcCertificateDirectory}";
|
||||
isReadOnly = false;
|
||||
};
|
||||
"${dstKeytabPath}" = {
|
||||
hostPath = "${srcKeytabPath}";
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
|
||||
config = { config, pkgs, environment, ... }: {
|
||||
environment.etc."${dstPrivateKey}".mode = "0400";
|
||||
|
||||
boot.tmpOnTmpfs = true;
|
||||
|
||||
# Kind of a stupid hack...bindMounts can't specify perms, and it defaults to
|
||||
# permissive (even for nested files). So, explicitly make the keys private.
|
||||
# TODO: eventually, use bindMount perms, hopefully?
|
||||
boot.postBootCommands = ''
|
||||
chown postgres ${dstKeytabPath}/postgres.keytab
|
||||
chmod 400 ${dstKeytabPath}/postgres.keytab
|
||||
chown -R postgres ${dstCertificateDirectory}
|
||||
chown 400 ${dstCertificateDirectory}/private/privkey.pem
|
||||
'';
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_10;
|
||||
enableTCPIP = true;
|
||||
|
||||
extraConfig =
|
||||
''
|
||||
krb_server_keyfile = '${dstKeytabPath}/postgres.keytab'
|
||||
|
||||
ssl = true
|
||||
ssl_cert_file = '${dstCertificateDirectory}/cert.pem'
|
||||
ssl_key_file = '${dstCertificateDirectory}/private/privkey.pem'
|
||||
'';
|
||||
|
||||
authentication =
|
||||
''
|
||||
local all all ident
|
||||
|
||||
# host-local
|
||||
host all all 127.0.0.1/32 gss include_realm=0 krb_realm=FUDO.ORG
|
||||
host all all ::1/128 gss include_realm=0 krb_realm=FUDO.ORG
|
||||
|
||||
# local network
|
||||
host all all 10.0.0.1/24 gss include_realm=0 krb_realm=FUDO.ORG
|
||||
host all all 2601:600:997f:fc00::/60 gss include_realm=0 krb_realm=FUDO.ORG
|
||||
'';
|
||||
|
||||
initialScript = pkgs.writeText "backend-initscript" ''
|
||||
CREATE ROLE niten;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 254 B |
Binary file not shown.
After Width: | Height: | Size: 436 B |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1 @@
|
|||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
Loading…
Reference in New Issue