diff --git a/config/fudo/chat.nix b/config/fudo/chat.nix new file mode 100644 index 0000000..d82d10a --- /dev/null +++ b/config/fudo/chat.nix @@ -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; + ''; + }; + }; + }; + }; + }); +} diff --git a/config/fudo/common.nix b/config/fudo/common.nix index 3679ff9..ddbe3c6 100644 --- a/config/fudo/common.nix +++ b/config/fudo/common.nix @@ -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; + }; }; } diff --git a/config/fudo/grafana.nix b/config/fudo/grafana.nix index 10ee540..61f869f 100644 --- a/config/fudo/grafana.nix +++ b/config/fudo/grafana.nix @@ -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"; }; diff --git a/config/fudo/include/rainloop.nix b/config/fudo/include/rainloop.nix new file mode 100644 index 0000000..4ab985a --- /dev/null +++ b/config/fudo/include/rainloop.nix @@ -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}" +'' diff --git a/config/fudo/kdc.nix b/config/fudo/kdc.nix index 71954f4..b8a4124 100644 --- a/config/fudo/kdc.nix +++ b/config/fudo/kdc.nix @@ -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 ''; }; }; diff --git a/config/fudo/mail-container.nix b/config/fudo/mail-container.nix index 948172b..c26c974 100644 --- a/config/fudo/mail-container.nix +++ b/config/fudo/mail-container.nix @@ -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; diff --git a/config/fudo/mail/postfix.nix b/config/fudo/mail/postfix.nix index 927f8c5..940ffd3 100644 --- a/config/fudo/mail/postfix.nix +++ b/config/fudo/mail/postfix.nix @@ -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"; diff --git a/config/fudo/node-exporter.nix b/config/fudo/node-exporter.nix index 82236cb..6bc7cf3 100644 --- a/config/fudo/node-exporter.nix +++ b/config/fudo/node-exporter.nix @@ -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; diff --git a/config/fudo/postgres.nix b/config/fudo/postgres.nix index d24cc80..5eb348b 100644 --- a/config/fudo/postgres.nix +++ b/config/fudo/postgres.nix @@ -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 + ''; }; } diff --git a/config/fudo/profiles.nix b/config/fudo/profiles.nix deleted file mode 100644 index 0a1d78d..0000000 --- a/config/fudo/profiles.nix +++ /dev/null @@ -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}; -} diff --git a/config/fudo/profiles/desktop.nix b/config/fudo/profiles/desktop.nix deleted file mode 100644 index 1aa0d53..0000000 --- a/config/fudo/profiles/desktop.nix +++ /dev/null @@ -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 - ]; - }; -} diff --git a/config/fudo/profiles/server.nix b/config/fudo/profiles/server.nix deleted file mode 100644 index 70c9271..0000000 --- a/config/fudo/profiles/server.nix +++ /dev/null @@ -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; - }; -} diff --git a/config/fudo/sites.nix b/config/fudo/sites.nix deleted file mode 100644 index d7e242e..0000000 --- a/config/fudo/sites.nix +++ /dev/null @@ -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}; -} diff --git a/config/fudo/webmail.nix b/config/fudo/webmail.nix new file mode 100644 index 0000000..310b8bf --- /dev/null +++ b/config/fudo/webmail.nix @@ -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. 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} + ''; + }; +} diff --git a/config/local.nix b/config/local.nix index 14a1f85..2da9c2c 100644 --- a/config/local.nix +++ b/config/local.nix @@ -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 ]; } diff --git a/fudo/email.nix b/fudo/email.nix index bea47a5..e622728 100644 --- a/fudo/email.nix +++ b/fudo/email.nix @@ -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; diff --git a/fudo/profiles/default.nix b/fudo/profiles/default.nix new file mode 100644 index 0000000..e327416 --- /dev/null +++ b/fudo/profiles/default.nix @@ -0,0 +1,8 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./desktop.nix + ./server.nix + ]; +} diff --git a/fudo/profiles/desktop.nix b/fudo/profiles/desktop.nix new file mode 100644 index 0000000..302fcc9 --- /dev/null +++ b/fudo/profiles/desktop.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 + ]; + }; + }; +} diff --git a/fudo/profiles/server.nix b/fudo/profiles/server.nix new file mode 100644 index 0000000..1011659 --- /dev/null +++ b/fudo/profiles/server.nix @@ -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; + }; + }; + }; +} diff --git a/fudo/sites/default.nix b/fudo/sites/default.nix new file mode 100644 index 0000000..6caa1b3 --- /dev/null +++ b/fudo/sites/default.nix @@ -0,0 +1,8 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./portage.nix + ./seattle.nix + ]; +} diff --git a/fudo/sites/portage.nix b/fudo/sites/portage.nix new file mode 100644 index 0000000..e7e1469 --- /dev/null +++ b/fudo/sites/portage.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; + }; + }; +} diff --git a/fudo/sites/seattle.nix b/fudo/sites/seattle.nix new file mode 100644 index 0000000..12246a2 --- /dev/null +++ b/fudo/sites/seattle.nix @@ -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"; + # }; + # }; + # }; + }; +} diff --git a/fudo/users.nix b/fudo/users.nix index 9089b58..85b3322 100644 --- a/fudo/users.nix +++ b/fudo/users.nix @@ -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"; + }; } diff --git a/hosts/france.nix b/hosts/france.nix index b9657d7..85ec23d 100644 --- a/hosts/france.nix +++ b/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 = [ - "208.81.1.128/28" - "208.81.3.112/28" - "172.17.0.0/16" - "127.0.0.0/8" - ]; + 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"; + }; }; ## diff --git a/networks/fudo.org.nix b/networks/fudo.org.nix deleted file mode 100644 index 9b4ba6e..0000000 --- a/networks/fudo.org.nix +++ /dev/null @@ -1,112 +0,0 @@ -{ lib, config, pkgs, ... }: - -let - hostname = config.networking.hostName; - - www-root = "/var/www"; - - index = pkgs.writeTextFile { - name = "index.html"; - - text = '' - - - ${hostname} - - -

${hostname} - - - ''; - 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"; - }; - }; - }; - }; - }; - }; -} diff --git a/networks/sea.fudo.org.nix b/networks/sea.fudo.org.nix deleted file mode 100644 index b3e3a86..0000000 --- a/networks/sea.fudo.org.nix +++ /dev/null @@ -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"; - }; - }; - }; -} diff --git a/profiles/.#ldap-server.nix b/profiles/.#ldap-server.nix deleted file mode 120000 index e216937..0000000 --- a/profiles/.#ldap-server.nix +++ /dev/null @@ -1 +0,0 @@ -root@france.26610:1573312038 \ No newline at end of file diff --git a/profiles/desktop.nix b/profiles/desktop.nix deleted file mode 100644 index 445d47d..0000000 --- a/profiles/desktop.nix +++ /dev/null @@ -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 - ]; - }; - -} diff --git a/profiles/ldap-server.nix b/profiles/ldap-server.nix deleted file mode 100644 index 84378d3..0000000 --- a/profiles/ldap-server.nix +++ /dev/null @@ -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"; - }; -} diff --git a/profiles/server.nix b/profiles/server.nix deleted file mode 100644 index cb3ff2c..0000000 --- a/profiles/server.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ config, pkgs, ... }: - -{ - environment = { - systemPackages = with pkgs; [ - ]; - - noXlibs = true; - }; - - security.hideProcessInformation = true; - - boot.tmpOnTmpfs = true; - - services.xserver.enable = false; -} diff --git a/profiles/services/basic_acme.nix b/profiles/services/basic_acme.nix deleted file mode 100644 index b323c04..0000000 --- a/profiles/services/basic_acme.nix +++ /dev/null @@ -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 = '' - - - ${hostname} - - -

${hostname} - - - ''; - 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"; - }; -} diff --git a/profiles/services/local_nameserver.nix b/profiles/services/local_nameserver.nix deleted file mode 100644 index c744fe8..0000000 --- a/profiles/services/local_nameserver.nix +++ /dev/null @@ -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)} - ''; - }; - }; -} diff --git a/profiles/vm/http.nix b/profiles/vm/http.nix deleted file mode 100644 index b644ef4..0000000 --- a/profiles/vm/http.nix +++ /dev/null @@ -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; - }; - }; - }; - }; -} diff --git a/profiles/vm/postgres.nix b/profiles/vm/postgres.nix deleted file mode 100644 index fde59a8..0000000 --- a/profiles/vm/postgres.nix +++ /dev/null @@ -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; - ''; - }; - }; - }; -} diff --git a/static/fudo.link/android-chrome-192x192.png b/static/fudo.link/android-chrome-192x192.png new file mode 100644 index 0000000..777edee Binary files /dev/null and b/static/fudo.link/android-chrome-192x192.png differ diff --git a/static/fudo.link/android-chrome-512x512.png b/static/fudo.link/android-chrome-512x512.png new file mode 100644 index 0000000..c3b6d04 Binary files /dev/null and b/static/fudo.link/android-chrome-512x512.png differ diff --git a/static/fudo.link/apple-touch-icon.png b/static/fudo.link/apple-touch-icon.png new file mode 100644 index 0000000..1575743 Binary files /dev/null and b/static/fudo.link/apple-touch-icon.png differ diff --git a/static/fudo.link/favicon-16x16.png b/static/fudo.link/favicon-16x16.png new file mode 100644 index 0000000..a1a9e16 Binary files /dev/null and b/static/fudo.link/favicon-16x16.png differ diff --git a/static/fudo.link/favicon-32x32.png b/static/fudo.link/favicon-32x32.png new file mode 100644 index 0000000..4ba22e1 Binary files /dev/null and b/static/fudo.link/favicon-32x32.png differ diff --git a/static/fudo.link/favicon.ico b/static/fudo.link/favicon.ico new file mode 100644 index 0000000..1023abe Binary files /dev/null and b/static/fudo.link/favicon.ico differ diff --git a/static/fudo.link/site.webmanifest b/static/fudo.link/site.webmanifest new file mode 100644 index 0000000..45dc8a2 --- /dev/null +++ b/static/fudo.link/site.webmanifest @@ -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"} \ No newline at end of file