diff --git a/flake.nix b/flake.nix index d0d795f..e7b223f 100644 --- a/flake.nix +++ b/flake.nix @@ -60,6 +60,18 @@ ./modules/common/tty.nix ]; }; + + # grey-area - Services host (Forgejo, Jellyfin, etc.) + grey-area = nixpkgs.lib.nixosSystem { + inherit system specialArgs; + modules = [ + ./machines/grey-area/configuration.nix + ./machines/grey-area/hardware-configuration.nix + ./modules/common/nix.nix + ./modules/common/base.nix + ./modules/common/tty.nix + ]; + }; }; # Custom packages for the home lab @@ -83,6 +95,7 @@ echo " - congenital-optimist (Threadripper workstation)" echo " - sleeper-service (Xeon file server)" echo " - reverse-proxy (VPS edge server)" + echo " - grey-area (Services host: Forgejo, Jellyfin, etc.)" echo "" echo "Build with: nixos-rebuild build --flake .#" echo "Switch with: nixos-rebuild switch --flake .#" diff --git a/machines/grey-area/configuration.nix b/machines/grey-area/configuration.nix index 55c1c87..8b7cb23 100644 --- a/machines/grey-area/configuration.nix +++ b/machines/grey-area/configuration.nix @@ -1,21 +1,25 @@ { config, pkgs, ... }: { - imports = - [ # Include the results of the hardware scan. - ./hardware-configuration.nix - ./starship.nix - ./aliases.nix - ./podman.nix - ./libvirt.nix - ./incus.nix - ./jellyfin.nix - ./tailscale.nix - ./calibre-web.nix - ./audiobook.nix - #./ollama.nix - ./forgejo.nix - ]; + imports = [ + # Hardware configuration + ./hardware-configuration.nix + + # Shared modules + ../../modules/common/base.nix + ../../modules/network/common.nix + ../../modules/virtualization/podman.nix + ../../modules/virtualization/libvirt.nix + ../../modules/virtualization/incus.nix + ../../modules/users/sma.nix + + # Services + ./services/jellyfin.nix + ./services/calibre-web.nix + ./services/audiobook.nix + ./services/forgejo.nix + #./services/ollama.nix + ]; # Swap zram zramSwap = { @@ -36,7 +40,18 @@ fileSystems."/mnt/remote/media" = { device = "sleeper-service:/mnt/storage"; fsType = "nfs"; - options = [ "x-systemd.automount" ]; + options = [ + "x-systemd.automount" + "x-systemd.idle-timeout=60" + "x-systemd.device-timeout=10" + "x-systemd.mount-timeout=10" + "noauto" + "soft" + "intr" + "timeo=10" + "retrans=3" + "_netdev" + ]; }; # Enable all unfree hardware support. @@ -48,11 +63,21 @@ # Networking networking.hostName = "grey-area"; - networking.networkmanager.enable = true; + networking.networkmanager.enable = true; + + # Add hostname resolution for sleeper-service NFS server + networking.extraHosts = '' + 10.0.0.8 sleeper-service + ''; # Set your time zone. time.timeZone = "Europe/Oslo"; + # Text mode configuration (headless server) + services.xserver.enable = false; + services.displayManager.defaultSession = "none"; + boot.kernelParams = [ "systemd.unit=multi-user.target" ]; + systemd.targets.graphical.enable = false; i18n.defaultLocale = "en_US.UTF-8"; console = { @@ -60,19 +85,6 @@ keyMap = "no"; }; - users.users.geir = { - isNormalUser = true; - extraGroups = [ "wheel" - "networkmanager" - "libvirt" - "podman" - "incus-admin" - ]; - packages = with pkgs; [ - bottom fastfetch nerdfetch - ]; - }; - environment.systemPackages = with pkgs; [ neovim emacs nano curl htop glances kitty wget git inxi nethogs fastfetch @@ -84,12 +96,9 @@ services.openssh.settings.PasswordAuthentication = true; - # Enable Netdata - services.netdata.enable = true; - # Firewall networking.firewall.enable = true; - networking.firewall.allowedTCPPorts = [ 22 19999 23231]; + networking.firewall.allowedTCPPorts = [ 22 23231]; networking.firewall.allowedUDPPorts = [ 22 23231 ]; networking.nftables.enable = true; system.stateVersion = "23.05"; # Do not change this, it maintains data compatibility. diff --git a/machines/grey-area/nixos/aliases.nix b/machines/grey-area/nixos/aliases.nix deleted file mode 100644 index b619bda..0000000 --- a/machines/grey-area/nixos/aliases.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ config, pkgs, ... }: -{ - environment.systemPackages = with pkgs; [ - tldr - eza - bat - ripgrep - ]; - environment.shellAliases = { - vi = "nvim"; - vim = "nvim"; - h = "tldr"; - # oxidized - ls = "eza -l"; - cat = "bat"; - grep = "rg"; - top = "btm --color gruvbox"; - # some tools - }; -} diff --git a/machines/grey-area/nixos/incus.nix b/machines/grey-area/nixos/incus.nix deleted file mode 100644 index 6f592d9..0000000 --- a/machines/grey-area/nixos/incus.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ config, pkgs, ... }: -{ - virtualisation.incus = { - enable = true; - ui.enable = true; - package = pkgs.incus; - }; - - environment.systemPackages = with pkgs; [ - incus - lxc - ]; - networking.firewall.allowedTCPPorts = [ 8443 ]; -} diff --git a/machines/grey-area/nixos/kitty.nix b/machines/grey-area/nixos/kitty.nix deleted file mode 100644 index 38e8dd5..0000000 --- a/machines/grey-area/nixos/kitty.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ config, pkgs, lib, ... }: -{ - environment.systemPackages = with pkgs; - [ - kitty kitty-themes termpdfpy - ]; -} diff --git a/machines/grey-area/nixos/libvirt.nix b/machines/grey-area/nixos/libvirt.nix deleted file mode 100644 index a39d094..0000000 --- a/machines/grey-area/nixos/libvirt.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ config, pkgs, ... }: -{ - virtualisation.libvirtd.enable = true; - environment.systemPackages = with pkgs; [ - qemu_kvm - libvirt - polkit - ]; -} diff --git a/machines/grey-area/nixos/nextcloud.nix b/machines/grey-area/nixos/nextcloud.nix deleted file mode 100644 index 8d1feb9..0000000 --- a/machines/grey-area/nixos/nextcloud.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ pkgs, ... }: - -{ - # Nextcloud Config - environment.etc."nextcloud-admin-pass".text = "siKKerhet666"; - services.nextcloud = { - enable = true; - hostName = "server1.tail807ea.ts.net"; - - # Ssl Let'encrypt - #hostName = "cloud.geokkjer.eu"; - #https = true; - - # Auto-update Nextcloud Apps - autoUpdateApps.enable = true; - # Set what time makes sense for you - autoUpdateApps.startAt = "05:00:00"; - # enable redis cache - configureRedis = true; - # Create db locally , maybe not needed with sqlite - database.createLocally = true; - # Config options - config = { - dbtype = "sqlite"; - adminpassFile = "/etc/nextcloud-admin-pass"; - trustedProxies = [ "46.226.104.98" "100.75.29.52" ]; - extraTrustedDomains = [ "localhost" "*.cloudflare.net" "*.tail807ea.ts.net" "46.226.104.98" "*.geokkjer.eu" ]; - }; - }; -} diff --git a/machines/grey-area/nixos/open-vscode-server.nix b/machines/grey-area/nixos/open-vscode-server.nix deleted file mode 100644 index e5637f6..0000000 --- a/machines/grey-area/nixos/open-vscode-server.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ pkgs, configs, ... }: -{ - services.openvscode-server = { - enable = true; - telemetryLevel = "off"; - port = 3003; - host = "0.0.0.0"; - }; -} diff --git a/machines/grey-area/nixos/podman.nix b/machines/grey-area/nixos/podman.nix deleted file mode 100644 index 44f2f43..0000000 --- a/machines/grey-area/nixos/podman.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ config, pkgs, ... }: -{ - virtualisation.podman.enable = true; - virtualisation.podman.dockerCompat = true; - virtualisation.podman.dockerSocket.enable = true; - - #virtualisation.defaultNetwork.settings.dns_enabled = true; - environment.systemPackages = with pkgs; [ - podman-tui - podman-compose - ]; - - } diff --git a/machines/grey-area/nixos/starship.nix b/machines/grey-area/nixos/starship.nix deleted file mode 100644 index d935427..0000000 --- a/machines/grey-area/nixos/starship.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ pkgs, ... }: -{ - environment.systemPackages = with pkgs; [ - starship - ]; -} diff --git a/machines/grey-area/nixos/tailscale.nix b/machines/grey-area/nixos/tailscale.nix deleted file mode 100644 index e4942fd..0000000 --- a/machines/grey-area/nixos/tailscale.nix +++ /dev/null @@ -1,18 +0,0 @@ -{config, pkgs, ... }: - { - environment.systemPackages = with pkgs; [ - tailscale - ]; - - services.tailscale.enable = true; - networking.firewall = { - # trace: warning: Strict reverse path filtering breaks Tailscale exit node - # use and some subnet routing setups. Consider setting - # `networking.firewall.checkReversePath` = 'loose' - checkReversePath = "loose"; - trustedInterfaces = [ "tailscale0" ]; - }; - } -#+end80808080 * nginx - -#+begin_src nix diff --git a/machines/grey-area/nixos/tty.nix b/machines/grey-area/nixos/tty.nix deleted file mode 100644 index b09a9f6..0000000 --- a/machines/grey-area/nixos/tty.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ pkgs, ... }: -{ - services.getty.greetingLine = ''\l''; - - console = { - earlySetup = true; - - # Joker palette - colors = [ - "1b161f" - "ff5555" - "54c6b5" - "d5aa2a" - "bd93f9" - "ff79c6" - "8be9fd" - "bfbfbf" - - "1b161f" - "ff6e67" - "5af78e" - "ffce50" - "caa9fa" - "ff92d0" - "9aedfe" - "e6e6e6" - ]; - }; -} diff --git a/machines/grey-area/nixos/writefreely.nix b/machines/grey-area/nixos/writefreely.nix deleted file mode 100644 index 9667411..0000000 --- a/machines/grey-area/nixos/writefreely.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ pkgs, configs, ... }: -{ - services.writefreely = { - enable = true; - admin.name = "geir@geokkjer.eu"; - host = "blog.geokkjer.eu"; - database = { - type = "sqlite3"; - #filename = "writefreely.db"; - #database = "writefreely"; - }; - nginx = { - # Enable Nginx and configure it to serve WriteFreely. - enable = true; - }; - settings = { - server = { - port = 8088; - bind = "0.0.0.0"; - }; - }; - }; - - networking.firewall.allowedTCPPorts = [ 8088 ]; - networking.firewall.allowedUDPPorts = [ 8088 ]; -} diff --git a/machines/grey-area/services/forgejo.nix b/machines/grey-area/services/forgejo.nix index 56046d6..d5b8c89 100644 --- a/machines/grey-area/services/forgejo.nix +++ b/machines/grey-area/services/forgejo.nix @@ -13,9 +13,9 @@ DISABLE_REGISTRATION = true; }; server = { - ROOT_URL = "http://apps:3000"; + ROOT_URL = "https://git.geokkjer.eu"; SSH_DOMAIN = "git.geokkjer.eu"; - SSH_PORT = 2222; + SSH_PORT = 1337; }; repository = { ENABLE_PUSH_CREATE_USER = true; diff --git a/machines/reverse-proxy/configuration.nix b/machines/reverse-proxy/configuration.nix index 9e5b67f..f7a5ac3 100644 --- a/machines/reverse-proxy/configuration.nix +++ b/machines/reverse-proxy/configuration.nix @@ -19,8 +19,8 @@ # DMZ-specific firewall configuration - very restrictive networking.firewall = { enable = true; - # Allow HTTP/HTTPS from external network and Git SSH on port 2222 - allowedTCPPorts = [ 80 443 2222 ]; + # Allow HTTP/HTTPS from external network and Git SSH on port 1337 + allowedTCPPorts = [ 80 443 1337 ]; allowedUDPPorts = [ ]; # SSH only allowed from Tailscale network (100.64.0.0/10) extraCommands = '' @@ -88,7 +88,7 @@ } server { - listen 2222; + listen 1337; proxy_pass git_ssh_backend; proxy_timeout 300s; proxy_connect_timeout 10s; diff --git a/modules/security/ssh-keys.nix b/modules/security/ssh-keys.nix index 32668bd..60818e5 100644 --- a/modules/security/ssh-keys.nix +++ b/modules/security/ssh-keys.nix @@ -51,11 +51,11 @@ User geir IdentityFile ~/.ssh/id_ed25519_dev - Host grey-area grey-area.home 10.0.0.11 + Host grey-area grey-area.home 10.0.0.12 User geir IdentityFile ~/.ssh/id_ed25519_dev - Host reverse-proxy reverse-proxy.home 10.0.0.12 + Host reverse-proxy reverse-proxy.home 46.226.104.98 User geir IdentityFile ~/.ssh/id_ed25519_dev @@ -66,12 +66,12 @@ IdentityFile ~/.ssh/id_ed25519_admin Host admin-grey grey-area.admin - Hostname 10.0.0.11 + Hostname 10.0.0.12 User sma IdentityFile ~/.ssh/id_ed25519_admin Host admin-reverse reverse-proxy.admin - Hostname 10.0.0.12 + Hostname 46.226.104.98 User sma IdentityFile ~/.ssh/id_ed25519_admin diff --git a/modules/users/sma.nix b/modules/users/sma.nix index 7a6f100..86bf65f 100644 --- a/modules/users/sma.nix +++ b/modules/users/sma.nix @@ -7,6 +7,7 @@ users.users.sma = { description = "Diziet Sma - System Administrator"; isNormalUser = true; + group = "sma"; # Primary group # Admin privileges extraGroups = [ @@ -126,7 +127,10 @@ # Admin user home directory permissions systemd.tmpfiles.rules = [ - "d /home/sma 0755 sma users -" - "d /home/sma/.ssh 0700 sma users -" + "d /home/sma 0755 sma sma -" + "d /home/sma/.ssh 0700 sma sma -" ]; + + # Create the sma group + users.groups.sma = {}; } diff --git a/modules/virtualization/incus.nix b/modules/virtualization/incus.nix index 7b071d0..25f07d9 100644 --- a/modules/virtualization/incus.nix +++ b/modules/virtualization/incus.nix @@ -10,10 +10,6 @@ incus lxc ]; - users.users.geir = { - extraGroups = [ - "incus-admin" - ]; - }; + networking.firewall.allowedTCPPorts = [ 8443 ]; } diff --git a/research/forgejo.md b/research/forgejo.md new file mode 100644 index 0000000..3d013cd --- /dev/null +++ b/research/forgejo.md @@ -0,0 +1,467 @@ +# Forgejo Best Practices and Configuration Guide + +## Overview + +Forgejo is a self-hosted lightweight software forge focused on scaling, federation, and privacy. This document outlines best practices for configuring and securing a Forgejo instance, along with potential improvements for the current setup. + +## Current Configuration Analysis + +### Current Setup Summary +- **Service**: Forgejo running on grey-area machine +- **User**: `git` user (follows best practices) +- **Mode**: Production (`RUN_MODE = "prod"`) +- **URL**: `https://git.geokkjer.eu` +- **SSH**: Port 1337 on `git.geokkjer.eu` +- **Registration**: Disabled (security best practice) + +### Configuration Location +- Configuration file: `/home/geir/Home-lab/machines/grey-area/services/forgejo.nix` + +## Security Best Practices + +### 1. Authentication and Access Control + +**Current Status**: ✅ Registration disabled +```nix +service = { + DISABLE_REGISTRATION = true; +}; +``` + +**Recommendations**: +- Consider implementing OAuth2/OIDC for centralized authentication +- Enable two-factor authentication (2FA) +- Set up proper user management policies + +**Potential Improvements**: +```nix +service = { + DISABLE_REGISTRATION = true; + REQUIRE_SIGNIN_VIEW = true; # Require login to view repos + ENABLE_CAPTCHA = true; # Enable captcha for forms + DEFAULT_ALLOW_CREATE_ORGANIZATION = false; +}; + +security = { + INSTALL_LOCK = true; + SECRET_KEY = "your-secret-key-here"; # Use secrets management + LOGIN_REMEMBER_DAYS = 7; + COOKIE_REMEMBER_NAME = "forgejo_incredible"; + COOKIE_USERNAME = "forgejo_username"; + COOKIE_SECURE = true; # HTTPS only cookies + ENABLE_LOGIN_STATUS_COOKIE = true; +}; +``` + +### 2. SSH Configuration + +**Current Status**: ✅ Custom SSH port (1337) +```nix +server = { + SSH_PORT = 1337; +}; +``` + +**Additional SSH Security**: +```nix +ssh = { + DISABLE_SSH = false; + START_SSH_SERVER = true; + SSH_SERVER_HOST_KEYS = "ssh/forgejo.rsa, ssh/gogs.rsa"; + SSH_KEY_TEST_PATH = "/tmp"; + SSH_KEYGEN_PATH = "ssh-keygen"; + SSH_SERVER_CIPHERS = "chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr"; + SSH_SERVER_KEY_EXCHANGES = "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1"; + SSH_SERVER_MACS = "hmac-sha2-256-etm@openssh.com,hmac-sha2-256,hmac-sha1"; +}; +``` + +### 3. Database Security + +**Recommendation**: Use PostgreSQL instead of SQLite for production +```nix +database = { + DB_TYPE = "postgres"; + HOST = "127.0.0.1:5432"; + NAME = "forgejo"; + USER = "forgejo"; + PASSWD = "secure-password"; # Use secrets management + SSL_MODE = "require"; + CHARSET = "utf8"; +}; +``` + +## Performance Optimization + +### 1. Caching Configuration +```nix +cache = { + ADAPTER = "redis"; + INTERVAL = 60; + HOST = "127.0.0.1:6379"; + ITEM_TTL = "16h"; +}; + +session = { + PROVIDER = "redis"; + PROVIDER_CONFIG = "127.0.0.1:6379"; + COOKIE_NAME = "i_like_forgejo"; + COOKIE_SECURE = true; + GC_INTERVAL_TIME = 86400; + SESSION_LIFE_TIME = 86400; + DOMAIN = "git.geokkjer.eu"; +}; +``` + +### 2. Repository Management +```nix +repository = { + ENABLE_PUSH_CREATE_USER = true; # Already configured ✅ + ENABLE_PUSH_CREATE_ORG = false; + DEFAULT_BRANCH = "main"; + PREFERRED_LICENSES = "Apache License 2.0,MIT License,GPL-3.0-or-later"; + DISABLE_HTTP_GIT = false; + ACCESS_CONTROL_ALLOW_ORIGIN = ""; + USE_COMPAT_SSH_URI = false; + DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH = false; + ENABLE_PUSH_CREATE_USER = true; + ENABLE_PUSH_CREATE_ORG = false; +}; +``` + +### 3. Indexer Configuration +```nix +indexer = { + ISSUE_INDEXER_TYPE = "bleve"; + ISSUE_INDEXER_PATH = "indexers/issues.bleve"; + REPO_INDEXER_ENABLED = true; + REPO_INDEXER_PATH = "indexers/repos.bleve"; + UPDATE_BUFFER_LEN = 20; + MAX_FILE_SIZE = 1048576; +}; +``` + +## Backup and Disaster Recovery + +### 1. Data Backup Strategy +```bash +# Database backup (if using PostgreSQL) +pg_dump -U forgejo -h localhost forgejo > forgejo_backup_$(date +%Y%m%d).sql + +# Repository data backup +tar -czf forgejo_repos_$(date +%Y%m%d).tar.gz /var/lib/forgejo/data/ + +# Configuration backup +cp /etc/forgejo/app.ini forgejo_config_$(date +%Y%m%d).ini +``` + +### 2. Automated Backup with NixOS +```nix +# Add to configuration.nix +services.postgresqlBackup = { + enable = true; + databases = [ "forgejo" ]; + startAt = "daily"; + location = "/backup/postgresql"; +}; + +systemd.services.forgejo-backup = { + description = "Backup Forgejo repositories"; + startAt = "daily"; + script = '' + ${pkgs.gnutar}/bin/tar -czf /backup/forgejo/repos_$(date +%Y%m%d).tar.gz /var/lib/forgejo/data/ + ''; + serviceConfig = { + Type = "oneshot"; + User = "root"; + }; +}; +``` + +## Monitoring and Logging + +### 1. Logging Configuration +```nix +log = { + MODE = "file"; + LEVEL = "Info"; + ROOT_PATH = "/var/log/forgejo"; + REDIRECT_MACARON_LOG = true; + MACARON_PREFIX = "[Macaron]"; + ROUTER_LOG_LEVEL = "Info"; + ROUTER_PREFIX = "[Router]"; + ENABLE_SSH_LOG = true; +}; +``` + +### 2. Metrics and Monitoring +```nix +metrics = { + ENABLED = true; + TOKEN = "your-metrics-token"; # Use secrets management +}; + +# Add Prometheus monitoring +services.prometheus.exporters.forgejo = { + enable = true; + port = 3001; + configFile = "/etc/forgejo/app.ini"; +}; +``` + +## Email Configuration + +### SMTP Setup +```nix +mailer = { + ENABLED = true; + SMTP_ADDR = "smtp.your-provider.com"; + SMTP_PORT = 587; + FROM = "noreply@geokkjer.eu"; + USER = "your-smtp-user"; + PASSWD = "your-smtp-password"; # Use secrets management + ENABLE_HELO = true; + HELO_HOSTNAME = "git.geokkjer.eu"; + SKIP_VERIFY = false; + USE_CERTIFICATE = true; + CERT_FILE = "/path/to/cert.pem"; + KEY_FILE = "/path/to/key.pem"; + IS_TLS_ENABLED = true; +}; +``` + +## Web UI and UX Improvements + +### 1. UI Configuration +```nix +ui = { + EXPLORE_PAGING_NUM = 20; + ISSUE_PAGING_NUM = 20; + MEMBERS_PAGING_NUM = 20; + FEED_MAX_COMMIT_NUM = 5; + FEED_PAGING_NUM = 20; + SITEMAP_PAGING_NUM = 20; + GRAPH_MAX_COMMIT_NUM = 100; + CODE_COMMENT_LINES = 4; + DEFAULT_SHOW_FULL_NAME = false; + SEARCH_REPO_DESCRIPTION = true; + USE_SERVICE_WORKER = true; +}; + +"ui.meta" = { + AUTHOR = "Forgejo"; + DESCRIPTION = "Git with a cup of tea! Painless self-hosted git service."; + KEYWORDS = "go,git,self-hosted,gitea,forgejo"; +}; +``` + +### 2. Webhook Configuration +```nix +webhook = { + QUEUE_LENGTH = 1000; + DELIVER_TIMEOUT = 5; + SKIP_TLS_VERIFY = false; + ALLOWED_HOST_LIST = ""; + PAGING_NUM = 10; + PROXY_URL = ""; + PROXY_HOSTS = ""; +}; +``` + +## Federation (Future Feature) + +Forgejo is working on ActivityPub federation support: + +```nix +federation = { + ENABLED = false; # Not yet available + SHARE_USER_STATISTICS = false; + MAX_SIZE = 4; + ALGORITHMS = "rsa-sha256,rsa-sha512,ed25519"; +}; +``` + +## Potential Improvements for Current Setup + +### 1. Immediate Improvements + +1. **Add Database Configuration**: + - Migrate from SQLite to PostgreSQL for better performance + - Configure connection pooling + +2. **Enhance Security**: + - Add `REQUIRE_SIGNIN_VIEW = true` to require authentication for viewing + - Configure proper SSL/TLS settings + - Implement secrets management for sensitive values + +3. **Add Monitoring**: + - Enable metrics collection + - Set up log rotation + - Configure health checks + +4. **Backup Strategy**: + - Implement automated backups + - Set up off-site backup storage + +### 2. Medium-term Improvements + +1. **Performance Optimization**: + - Add Redis for caching and sessions + - Configure repository indexing + - Optimize garbage collection + +2. **User Experience**: + - Configure email notifications + - Set up custom themes/branding + - Add webhook integrations + +3. **Integration**: + - Set up CI/CD integration + - Configure external authentication (LDAP/OAuth) + - Add container registry support + +### 3. Enhanced Configuration Example + +```nix +{ pkgs, config, ... }: +{ + services.forgejo = { + enable = true; + user = "git"; + stateDir = "/var/lib/forgejo"; + database = { + type = "postgres"; + host = "127.0.0.1"; + port = 5432; + name = "forgejo"; + user = "forgejo"; + passwordFile = "/run/secrets/forgejo-db-password"; + }; + }; + + services.forgejo.settings = { + DEFAULT = { + RUN_MODE = "prod"; + WORK_PATH = "/var/lib/forgejo"; + }; + + service = { + DISABLE_REGISTRATION = true; + REQUIRE_SIGNIN_VIEW = true; + ENABLE_CAPTCHA = true; + DEFAULT_ALLOW_CREATE_ORGANIZATION = false; + }; + + server = { + ROOT_URL = "https://git.geokkjer.eu"; + SSH_DOMAIN = "git.geokkjer.eu"; + SSH_PORT = 1337; + CERT_FILE = "/etc/ssl/certs/forgejo.crt"; + KEY_FILE = "/etc/ssl/private/forgejo.key"; + DISABLE_SSH = false; + START_SSH_SERVER = true; + }; + + repository = { + ENABLE_PUSH_CREATE_USER = true; + ENABLE_PUSH_CREATE_ORG = false; + DEFAULT_BRANCH = "main"; + PREFERRED_LICENSES = "Apache License 2.0,MIT License,GPL-3.0-or-later"; + }; + + security = { + INSTALL_LOCK = true; + SECRET_KEY_PATH = "/run/secrets/forgejo-secret-key"; + LOGIN_REMEMBER_DAYS = 7; + COOKIE_SECURE = true; + ENABLE_LOGIN_STATUS_COOKIE = true; + }; + + log = { + MODE = "file"; + LEVEL = "Info"; + ROOT_PATH = "/var/log/forgejo"; + REDIRECT_MACARON_LOG = true; + }; + + metrics = { + ENABLED = true; + TOKEN_PATH = "/run/secrets/forgejo-metrics-token"; + }; + + mailer = { + ENABLED = true; + SMTP_ADDR = "smtp.fastmail.com"; + SMTP_PORT = 587; + FROM = "noreply@geokkjer.eu"; + USER = "forgejo@geokkjer.eu"; + PASSWD_PATH = "/run/secrets/forgejo-smtp-password"; + IS_TLS_ENABLED = true; + }; + + other = { + SHOW_FOOTER_VERSION = true; + SHOW_FOOTER_TEMPLATE_LOAD_TIME = false; + }; + }; + + # PostgreSQL configuration + services.postgresql = { + enable = true; + ensureDatabases = [ "forgejo" ]; + ensureUsers = [ + { + name = "forgejo"; + ensurePermissions = { + "DATABASE forgejo" = "ALL PRIVILEGES"; + }; + } + ]; + }; + + # Redis for caching + services.redis.servers.forgejo = { + enable = true; + port = 6379; + bind = "127.0.0.1"; + }; + + # Backup configuration + services.postgresqlBackup = { + enable = true; + databases = [ "forgejo" ]; + startAt = "daily"; + location = "/backup/postgresql"; + }; + + # Secrets management + age.secrets = { + forgejo-db-password.file = ../secrets/forgejo-db-password.age; + forgejo-secret-key.file = ../secrets/forgejo-secret-key.age; + forgejo-metrics-token.file = ../secrets/forgejo-metrics-token.age; + forgejo-smtp-password.file = ../secrets/forgejo-smtp-password.age; + }; +} +``` + +## Security Checklist + +- [ ] **Authentication**: Disable registration, enable 2FA +- [ ] **Authorization**: Implement proper access controls +- [ ] **Encryption**: Use HTTPS, secure SSH configuration +- [ ] **Database**: Use PostgreSQL with SSL, regular backups +- [ ] **Secrets**: Use proper secrets management (agenix/sops) +- [ ] **Monitoring**: Enable logging, metrics collection +- [ ] **Updates**: Regular security updates, vulnerability scanning +- [ ] **Network**: Firewall configuration, rate limiting +- [ ] **Backup**: Automated backups, disaster recovery plan + +## References + +- [Forgejo Official Documentation](https://forgejo.org/docs/) +- [Forgejo Configuration Reference](https://forgejo.org/docs/latest/admin/config-cheat-sheet/) +- [Forgejo Security Guide](https://forgejo.org/docs/latest/admin/security/) +- [NixOS Forgejo Module](https://search.nixos.org/options?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=forgejo) + +## Last Updated +June 7, 2025 diff --git a/research/ssh-forwarding-solutions.md b/research/ssh-forwarding-solutions.md index cec156b..a0c9ab3 100644 --- a/research/ssh-forwarding-solutions.md +++ b/research/ssh-forwarding-solutions.md @@ -248,7 +248,7 @@ Host git.geokkjer.eu **Configuration**: 1. Enable nginx stream module -2. Configure Git SSH on port 2222 +2. Configure Git SSH on port 1337 3. Update Forgejo SSH_DOMAIN setting 4. Test with alternative port