diff --git a/configuration.nix b/configuration.nix index 65a5205..9e989cb 100755 --- a/configuration.nix +++ b/configuration.nix @@ -42,7 +42,7 @@ ./system-modules/nx2site.nix ./system-modules/postgres.nix ./system-modules/nx2site/proxy.nix - # ./system-modules/nx2site/gitea.nix + ./system-modules/nx2site/gitea.nix ./system-modules/nx2site/vaultwarden.nix ] else []); diff --git a/git-crypt/secrets.nix b/git-crypt/secrets.nix index c6f0ad4..7f066b1 100755 Binary files a/git-crypt/secrets.nix and b/git-crypt/secrets.nix differ diff --git a/home-modules/ssh.nix b/home-modules/ssh.nix index 4f1c885..0d8438f 100755 --- a/home-modules/ssh.nix +++ b/home-modules/ssh.nix @@ -21,7 +21,7 @@ HOST nxgit HostName ssh.${domain} User git - Port 20022 + Port 50022 ''; }; } diff --git a/system-modules/nx2site.nix b/system-modules/nx2site.nix index 65b188d..b8526f3 100644 --- a/system-modules/nx2site.nix +++ b/system-modules/nx2site.nix @@ -1,9 +1,23 @@ -{ config, pkgs, domain, secrets, ... }: +{ config, pkgs, user, domain, secrets, ... }: +let dns-user = "cloudflare"; in { sops.secrets = { - "nx2site/namecheap.pw" = { }; + # "nx2site/namecheap.pw" = { }; # "nx2site/cloudflare/api-token-dns-edit" = { }; - "nx2site/cloudflare/global-api-key" = { }; + "nx2site/cloudflare/global-api-key" = { + owner = dns-user; + }; + }; + + users = { + users = { + "${dns-user}" = { + isSystemUser = true; + group = dns-user; + }; + "${user}".extraGroups = [ dns-user ]; + }; + groups."${dns-user}" = {}; }; systemd = { @@ -19,22 +33,24 @@ u = let account_id = secrets.email.gmail-online.mail; zone_id = "33fecab36e060f49d492127345ea95a0"; - record_id = { + record_id = { # curl --request GET --url https://api.cloudflare.com/client/v4/zones/33fecab36e060f49d492127345ea95a0/dns_records --header 'Content-Type: application/json' --header 'X-Auth-Email: @gmail.com' --header "X-Auth-Key: " -s | jq base = "58d3412e8d88889d1a611b3669f0700f"; - sub = "fc861353142bc05d5dbad1799178e6a1"; base6 = "d1b90e21d2d747dcb30448bd65312927"; + sub = "fc861353142bc05d5dbad1799178e6a1"; sub6 = "b8082b7afe9e80971fc9f9dda16ec284"; + ssh = "c0f14f17f32d6595c202f041dd836eb3"; + ssh6 = "f1ecb2d9d0522d4eec06437688ca76da"; }; passord-file-path = config.sops.secrets."nx2site/cloudflare/global-api-key".path; log-file-path = "/var/log/couldflare.log"; count-file-path = "/var/log/cloudflare-count.txt"; in pkgs.writers.writePython3Bin "dyn_dns" { libraries = with pkgs.python311Packages; [ requests ]; - flakeIgnore = [ "E501" "E305" "E701" "E704" "E302" "E114" "F841" "E121" "E261" "E303"]; + flakeIgnore = [ "E501" "E305" "E701" "E704" "E302" "E114" "F841" "E121" "E261" "E303" ]; } /* python */ '' import requests import subprocess - from datetime import datetime + # from datetime import datetime def get_public_ip(ipv6=False): return subprocess.run(['${pkgs.curl}/bin/curl', '-s', '-6' if ipv6 else '-4', 'https://ifconfig.me'], capture_output=True, text=True).stdout.strip() @@ -43,13 +59,13 @@ my_ip = get_public_ip() my_ip6 = get_public_ip(ipv6=True) - with open("${count-file-path}", "r") as f: - content = f.read() - if content == "": count = 0 - else: count = int(content) - count += 1 - with open("${count-file-path}", "w") as f: - f.write(str(count)) + # with open("${count-file-path}", "r") as f: + # content = f.read() + # if content == "": count = 0 + # else: count = int(content) + # count += 1 + # with open("${count-file-path}", "w") as f: + # f.write(str(count)) # 4 with open("${passord-file-path}", 'r') as pw_file: @@ -85,7 +101,7 @@ }, json={ "comment": "Domain verification record", - "name": "${domain}", + "name": "*.${domain}", "proxied": True, "settings": {}, "tags": [], @@ -95,15 +111,34 @@ } ) + resp_sshd = requests.patch( + 'https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records/${record_id.ssh}', + headers={ + 'Content-Type': 'application/json', + 'X-Auth-Email': '${account_id}', + 'X-Auth-Key': pw + }, + json={ + "comment": "Domain verification record", + "name": "ssh.${domain}", + "proxied": False, + "settings": {}, + "tags": [], + "ttl": 1, # automatic + "content": my_ip, + "type": "A" + } + ) + if resp_base.status_code != 200: print(resp_base.text) - now_str = datetime.now().strftime('%Y/%m/%d-%R') - log_entry = f"At {now_str} - to {my_ip} - Response {resp_base.status_code}\n" - print(log_entry, end="") - with open("${log-file-path}", 'a') as log_file: - log_file.write(log_entry) + # now_str = datetime.now().strftime('%Y/%m/%d-%R') + # log_entry = f"At {now_str} - to {my_ip} - Response {resp_base.status_code}\n" + # print(log_entry, end="") + # with open("${log-file-path}", 'a') as log_file: + # log_file.write(log_entry) # Perform DNS updates # https://developers.cloudflare.com/api/operations/dns-records-for-a-zone-update-dns-record @@ -135,7 +170,7 @@ }, json={ "comment": "Domain verification record", - "name": "${domain}", + "name": "*.${domain}", "proxied": True, "settings": {}, "tags": [], @@ -145,14 +180,32 @@ } ) + resp_sshd = requests.patch( + 'https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records/${record_id.ssh6}', + headers={ + 'Content-Type': 'application/json', + 'X-Auth-Email': '${account_id}', + 'X-Auth-Key': pw + }, + json={ + "comment": "Domain verification record", + "name": "ssh.${domain}", + "proxied": False, + "settings": {}, + "tags": [], + "ttl": 1, # automatic + "content": my_ip6, + "type": "AAAA" + } + ) + if resp_base.status_code != 200: print(resp_base.text) - - now_str = datetime.now().strftime('%Y/%m/%d-%R') - log_entry = f"At {now_str} - to {my_ip6} - Response {resp_base.status_code}\n" - print(log_entry, end="") - with open("${log-file-path}", 'a') as log_file: log_file.write(log_entry) + # now_str = datetime.now().strftime('%Y/%m/%d-%R') + # log_entry = f"At {now_str} - to {my_ip6} - Response {resp_base.status_code}\n" + # print(log_entry, end="") + # with open("${log-file-path}", 'a') as log_file: log_file.write(log_entry) if __name__ == "__main__": main() @@ -164,7 +217,7 @@ ''; serviceConfig = { Type = "oneshot"; - User = "root"; + User = dns-user; }; }; }; @@ -174,7 +227,7 @@ # "172.1.0.9" = [ "matrixdb.docker" ]; # "172.1.4.1" = [ "matrix-ss.docker" ]; # "172.1.0.7" = [ "matrix-ssdb.docker" ]; - "172.1.5.1" = [ "pw.docker" ]; + # "172.1.5.1" = [ "pw.docker" ]; "172.1.6.1" = [ "git.docker" ]; # "172.1.0.10" = [ "gitdb.docker" ]; # "172.1.7.1" = [ "nn.docker" ]; diff --git a/system-modules/nx2site/gitea.nix b/system-modules/nx2site/gitea.nix index 6f877ea..df41284 100644 --- a/system-modules/nx2site/gitea.nix +++ b/system-modules/nx2site/gitea.nix @@ -1,4 +1,5 @@ -{ config, pkgs, lib, domain, ... }: +{ config, pkgs, secrets, user, domain, ... }: +let git-user = "git"; in { sops.secrets = { "postgres-pw" = { owner = config.services.gitea.user; }; @@ -7,36 +8,46 @@ environment.systemPackages = with pkgs; [ gitea ]; + users = { + users = { + "${user}".extraGroups = [ git-user ]; + "${git-user}" = { + isSystemUser = true; + group = git-user; + useDefaultShell = true; + home = config.services.gitea.stateDir; + openssh.authorizedKeys.keys = config.users.users."${user}".openssh.authorizedKeys.keys; + }; + }; + groups."${git-user}" = {}; + }; services.gitea = { enable = true; package = pkgs.gitea; - group = "gitea"; # default - user = "gitea"; # default + group = git-user; + user = git-user; appName = "NxGit"; stateDir = "/var/lib/gitea"; # default useWizard = false; # default # camoHmacKeyFile = ; - customDir = "${config.services.gitea.stateDir}/custom"; # default database = { createDatabase = false; # default host = "127.0.0.1"; # default port = 5432; passwordFile = config.sops.secrets."postgres-pw".path; - # path = "${config.services.gitea.stateDir}/data/gitea.db"; # default - # socket = "/run/postgresql"; socket = null; type = "postgres"; name = "gitea"; # default user = "gitea"; # default }; - # dump = { - # enable = true; - # backupDir = "${config.services.gitea.stateDir}/dump"; # default - # file = null; # default - # interval = "daily"; - # type = "zip"; # default - # }; + dump = { + enable = true; + backupDir = "/var/backup/gitea"; + file = null; # default = chosen by gitea + interval = "daily"; + type = "zip"; # default + }; # extraConfig = null; # default # lfs = { # enable = false; # default @@ -44,25 +55,23 @@ # }; # mailerPasswordFile = null; # default # metricsTokenFile = null; # default - repositoryRoot = "${config.services.gitea.stateDir}/repositories"; # default + # repositoryRoot = "${config.services.gitea.stateDir}/repositories"; # default settings = { log = { LEVEL = "Info"; # LEVEL = "Error"; - ROOT_PATH = "${config.services.gitea.stateDir}/log"; # default }; - # i18n = { - # LANGS = "en-US"; - # }; server = { DISABLE_SSH = false; # default - SSH_PORT = 20022; - # DOMAIN = "pw2.${domain}"; - # HTTP_ADDR = "${config.services.gitea.settings.server.DOMAIN}:${toString config.services.gitea.settings.server.HTTP_PORT}/"; + START_SSH_SERVER = false; # default + SSH_LISTEN_HOST = "0.0.0.0"; + SSH_PORT = secrets.ssh.port; + DOMAIN = "pw.${domain}"; + SSH_DOMAIN = "ssh.${domain}"; + # HTTP_ADDR = "${config.services.gitea.settings.server.DOMAIN}"; # HTTP_PORT = 3000; # default # PROTOCOL = "http"; # default - # ROOT_URL = "https:pw2.${domain}/"; # default - STATIC_ROOT_PATH = "${config.services.gitea.stateDir}/static"; + # ROOT_URL = "https:pw.${domain}/"; # default }; session = { COOKIE_SECURE = true; @@ -73,108 +82,3 @@ }; }; } -# APP_NAME = Gitea: Git with a cup of tea -# RUN_MODE = prod -# RUN_USER = git -# WORK_PATH = /data/gitea - -# [repository] -# ROOT = /data/git/repositories -# ENABLE_PUSH_CREATE_ORG = true -# ENABLE_PUSH_CREATE_USER = true - -# [repository.local] -# LOCAL_COPY_PATH = /data/gitea/tmp/local-repo - -# [repository.upload] -# TEMP_PATH = /data/gitea/uploads - -# [server] -# APP_DATA_PATH = /data/gitea -# DOMAIN = git.nx2.site -# SSH_DOMAIN = git.nx2.site -# HTTP_PORT = 3000 -# ROOT_URL = https://git.nx2.site/ -# DISABLE_SSH = false -# SSH_PORT = 22 -# SSH_LISTEN_PORT = 22 -# LFS_START_SERVER = true -# LFS_JWT_SECRET = aitnnoway -# OFFLINE_MODE = false - -# [database] -# PATH = /data/gitea/gitea.db -# DB_TYPE = postgres -# HOST = giteadb:5432 -# NAME = gitea -# USER = gitea -# PASSWD = -lkjlkj -# LOG_SQL = false -# SCHEMA = -# SSL_MODE = disable - -# [indexer] -# ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve - -# [session] -# PROVIDER_CONFIG = /data/gitea/sessions -# PROVIDER = file - -# [picture] -# AVATAR_UPLOAD_PATH = /data/gitea/avatars -# REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars - -# [attachment] -# PATH = /data/gitea/attachments - -# [log] -# MODE = console -# LEVEL = info -# ROOT_PATH = /data/gitea/log - -# [security] -# INSTALL_LOCK = true -# SECRET_KEY = -# REVERSE_PROXY_LIMIT = 1 -# REVERSE_PROXY_TRUSTED_PROXIES = * -# INTERNAL_TOKEN = faaaaakeeyJuYmYiOjE3MTMxMTAzMjN9.iliwlrfZDTb8oL296gpXRYhC-6_AJdjePO7dk3NT-PE -# PASSWORD_HASH_ALGO = pbkdf2 - -# [service] -# DISABLE_REGISTRATION = true -# REQUIRE_SIGNIN_VIEW = false -# REGISTER_EMAIL_CONFIRM = false -# ENABLE_NOTIFY_MAIL = false -# ALLOW_ONLY_EXTERNAL_REGISTRATION = false -# ENABLE_CAPTCHA = false -# DEFAULT_KEEP_EMAIL_PRIVATE = false -# DEFAULT_ALLOW_CREATE_ORGANIZATION = true -# DEFAULT_ENABLE_TIMETRACKING = true -# NO_REPLY_ADDRESS = noreply.nx2.site - -# [lfs] -# PATH = /data/git/lfs - -# [mailer] -# ENABLED = true -# SMTP_ADDR = smtp.gmail.com -# SMTP_PORT = 587 -# FROM = git@nx2.site -# USER = lennart.kurzweg.lk@gmail.com -# PASSWD = "ihh" - -# [openid] -# ENABLE_OPENID_SIGNIN = true -# ENABLE_OPENID_SIGNUP = false - -# [cron.update_checker] -# ENABLED = false - -# [repository.pull-request] -# DEFAULT_MERGE_STYLE = merge - -# [repository.signing] -# DEFAULT_TRUST_MODEL = committer - -# [oauth2] -# JWT_SECRET = redavt diff --git a/system-modules/nx2site/proxy.nix b/system-modules/nx2site/proxy.nix index df9f34a..d22f510 100644 --- a/system-modules/nx2site/proxy.nix +++ b/system-modules/nx2site/proxy.nix @@ -14,7 +14,7 @@ }; certs = { "${domain}" = { - extraDomainNames = builtins.map (subd: "${subd}.${domain}") [ "git" "git2" "pw" "pw2" "sync" ]; + extraDomainNames = builtins.map (subd: "${subd}.${domain}") [ "git" "pw" "sync" ]; }; }; }; @@ -99,16 +99,16 @@ listen = dl; locations = { "~.*" = { return = "502"; }; }; }; + # "pw.${domain}" = vh // { + # listen = dl; + # locations = let d = "pw.docker:80"; in { + # "/" = { proxyPass = "http://${d}"; }; + # "/admin" = { proxyPass = "http://${d}"; }; + # "/notifications/hub" = { proxyPass = "http://${d}"; }; + # "/notifications/hub/negotiate" = { proxyPass = "http://${d}"; }; + # }; + # }; "pw.${domain}" = vh // { - listen = dl; - locations = let d = "pw.docker:80"; in { - "/" = { proxyPass = "http://${d}"; }; - "/admin" = { proxyPass = "http://${d}"; }; - "/notifications/hub" = { proxyPass = "http://${d}"; }; - "/notifications/hub/negotiate" = { proxyPass = "http://${d}"; }; - }; - }; - "pw2.${domain}" = vh // { listen = dl; locations = let d = with config.services.vaultwarden.config; "${ROCKET_ADDRESS}:${builtins.toString ROCKET_PORT}"; @@ -123,11 +123,11 @@ listen = dl; locations = { "/" = { proxyPass = "http://127.0.0.1:11434"; }; }; }; + # "git.${domain}" = vh // { + # listen = dl; + # locations = { "/" = { proxyPass = "http://git.docker:3000"; }; }; + # }; "git.${domain}" = vh // { - listen = dl; - locations = { "/" = { proxyPass = "http://git.docker:3000"; }; }; - }; - "git2.${domain}" = vh // { http2 = false; listen = dl; locations = { "/" = { proxyPass = "http://127.0.0.1:3000"; }; }; diff --git a/system-modules/nx2site/vaultwarden.nix b/system-modules/nx2site/vaultwarden.nix index c7fe7e7..d5e5546 100644 --- a/system-modules/nx2site/vaultwarden.nix +++ b/system-modules/nx2site/vaultwarden.nix @@ -27,7 +27,7 @@ SMTP_PASSWORD = "@SMTP_PASSWORD@"; LOGIN_RATELIMIT_MAX_BURST = 10; LOGIN_RATELIMIT_SECONDS = 60; - DOMAIN = "https://pw2.${domain}"; + DOMAIN = "https://pw.${domain}"; INVITATION_ORG_NAME = "NxPW"; INVITATIONS_ALLOWED = true; ADMIN_TOKEN = "@ADMIN_TOKEN@"; diff --git a/system-modules/postgres.nix b/system-modules/postgres.nix index f37ad51..b86a5cf 100644 --- a/system-modules/postgres.nix +++ b/system-modules/postgres.nix @@ -32,22 +32,9 @@ shared_preload_libraries = [ ]; # default }; ensureUsers = [ - # { - # name = "${user}"; - # ensureDBOwnership = false; - # ensureClauses = { - # login = true; - # # inherit - # createdb = true; - # bypassrls = true; - # superuser = true; - # createrole = true; - # replication = true; - # }; - # } + # as liong as there is no declarative user management you gotta set a pw by hand + # sudo -u postgres psql -c "ALTER USER gitea PASSWORD 'new-passwd';" { - # as liong as there is no declarative user management you gotta set a pw by hand - # sudo -u postgres psql -c "ALTER USER gitea PASSWORD 'new-passwd';" name = "gitea"; ensureDBOwnership = true; } @@ -57,28 +44,28 @@ } ]; }; -# postgresqlBackup = { -# enable -# startAt -# location -# databases -# backupAll -# compression -# } - - -# postgresqlWalReceiver.receivers."main" = { -# postgresqlPackage = pkgs.postgresql_15; -# directory = /mnt/pg_wal/main/; -# slot = "main_wal_receiver"; -# connection = "postgresql://user@somehost"; -# compress -# extraArgs -# synchronous -# environment -# statusInterval -# }; -# } + postgresqlBackup = { + enable = true; + # startAt = "*-*-* 01:15:00"; + # location = "/var/backup/postgresql"; + databases = config.services.postgresql.ensureDatabases; + backupAll = false; + # compression = "gzip"; + # pgdumpOptions = "-C"; + # compressionLevel = 6; + }; + # postgresqlWalReceiver.receivers."main" = { + # postgresqlPackage = pkgs.postgresql_15; + # directory = /mnt/pg_wal/main/; + # slot = "main_wal_receiver"; + # connection = "postgresql://user@somehost"; + # compress + # extraArgs + # synchronous + # environment + # statusInterval + # }; + # }; }; } diff --git a/system-modules/sshd.nix b/system-modules/sshd.nix index dff0395..7bdd4b3 100644 --- a/system-modules/sshd.nix +++ b/system-modules/sshd.nix @@ -3,7 +3,7 @@ { environment.etc."ssh/ssh_host_ed25519_key.pub".text = if (host == "NxNORTH") then "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF1r5gUQPPS/dGB0SsvWtP6WdNWoxMwhhHRrqlO19cJt root@NxNORTH" - else if ( host == "NxXPS") then + else if ( host == "NxXPS" ) then "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPf+08+t8a0lY2+nR1mhIU3vuksStiJOlojJjzCwFk7r root@NxXPS" else "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBFfZpWVPlujsz3FklSVAM+tuYn4pzDSijhp5CeYNOZk root@NxACE"; @@ -13,7 +13,7 @@ }; services.openssh = { enable = true; - ports = secrets.ssh.ports; + ports = [ secrets.ssh.port ]; settings = { PasswordAuthentication = false; }; diff --git a/system-modules/users.nix b/system-modules/users.nix index f43423e..7920c80 100755 --- a/system-modules/users.nix +++ b/system-modules/users.nix @@ -6,6 +6,7 @@ users.users."${user}" = { isNormalUser = true; extraGroups = [ + # TODO: actually put the groups into the relevant files "networkmanager" "wheel" "audio" @@ -18,7 +19,6 @@ "acme" "nginx" "adbusers" - "gitea" "postgres" ]; useDefaultShell = true;