diff --git a/common.nix b/common.nix index 6232196..42d089d 100644 --- a/common.nix +++ b/common.nix @@ -30,8 +30,6 @@ ./services/bazarr.nix ./services/cloudflare-ddns.nix ./services/fail2ban.nix - ./services/suricata.nix - ./services/elk.nix ]; ### Make build time quicker diff --git a/hosts/FredOS-Mediaserver.nix b/hosts/FredOS-Mediaserver.nix index 72ed92a..e76e09f 100644 --- a/hosts/FredOS-Mediaserver.nix +++ b/hosts/FredOS-Mediaserver.nix @@ -28,7 +28,10 @@ networking.firewall.allowedTCPPorts = [ 22 ]; services.openssh = { enable = true; - settings.PermitRootLogin = "no"; + settings = { + PermitRootLogin = "no"; + PasswordAuthentication = false; + }; }; }; } diff --git a/services/elk.nix b/services/elk.nix deleted file mode 100644 index 4b4448c..0000000 --- a/services/elk.nix +++ /dev/null @@ -1,104 +0,0 @@ -{ config, lib, pkgs, ... }: -let - # Pin all three to the same version — mismatches between ES/Kibana/Filebeat cause errors - # Check https://www.docker.elastic.co for latest 8.x tag - elasticVersion = "8.17.0"; - - filebeatConfig = pkgs.writeText "filebeat.yml" '' - filebeat.modules: - - module: suricata - eve: - enabled: true - var.paths: ["/var/log/suricata/eve.json"] - - # Auto-install Kibana dashboards on first run - setup.dashboards.enabled: true - setup.kibana: - host: "kibana:5601" - - output.elasticsearch: - hosts: ["elasticsearch:9200"] - - # Reduce logging noise - logging.level: warning - ''; -in -{ - config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") { - - virtualisation.oci-containers.containers = { - - elasticsearch = { - image = "docker.elastic.co/elasticsearch/elasticsearch:${elasticVersion}"; - environment = { - # Single-node cluster — no replica shards needed - "discovery.type" = "single-node"; - # Security disabled — ES is not exposed externally - "xpack.security.enabled" = "false"; - # Disable enrollment flow (ES 8.x auto-enables this when security is on) - "xpack.security.enrollment.enabled" = "false"; - # Keep heap at 1g; ES default is 50% of RAM which is excessive here - "ES_JAVA_OPTS" = "-Xms1g -Xmx1g"; - }; - volumes = [ "elasticsearch-data:/usr/share/elasticsearch/data" ]; - extraOptions = [ "--network=elk" ]; - }; - - kibana = { - image = "docker.elastic.co/kibana/kibana:${elasticVersion}"; - environment = { - "ELASTICSEARCH_HOSTS" = "http://elasticsearch:9200"; - # Tell Kibana security is off — suppresses the enrollment token screen - "xpack.security.enabled" = "false"; - # Cap Node.js heap — default is uncapped - "NODE_OPTIONS" = "--max-old-space-size=512"; - }; - ports = [ "5601:5601" ]; - extraOptions = [ "--network=elk" ]; - dependsOn = [ "elasticsearch" ]; - }; - - filebeat = { - image = "docker.elastic.co/beats/filebeat:${elasticVersion}"; - extraOptions = [ - "--network=elk" - # root so it can read /var/log/suricata owned by the suricata user - "--user=root" - # Filebeat refuses to start if config file is group/world writable - "--security-opt=no-new-privileges:true" - ]; - volumes = [ - "/var/log/suricata:/var/log/suricata:ro" - "${filebeatConfig}:/usr/share/filebeat/filebeat.yml:ro" - ]; - dependsOn = [ "elasticsearch" "kibana" ]; - }; - - }; - - # Create the elk bridge network before any container starts - systemd.services.init-elk-docker-network = { - description = "Create elk Docker network"; - after = [ "docker.service" ]; - requires = [ "docker.service" ]; - before = [ - "docker-elasticsearch.service" - "docker-kibana.service" - "docker-filebeat.service" - ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = '' - ${pkgs.docker}/bin/docker network inspect elk >/dev/null 2>&1 \ - || ${pkgs.docker}/bin/docker network create elk - ''; - }; - - # Kibana accessible on the LAN - networking.firewall.allowedTCPPorts = [ 5601 ]; - - }; -} diff --git a/services/suricata.nix b/services/suricata.nix deleted file mode 100644 index 34dcfd7..0000000 --- a/services/suricata.nix +++ /dev/null @@ -1,66 +0,0 @@ -{ config, lib, pkgs, ... }: -{ - config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") { - - services.suricata = { - enable = true; - - # DNP3 and Modbus are industrial SCADA protocols disabled in this build. - # Use regex patterns to suppress all rules for both protocols so the - # config test does not fail with parse errors. - disabledRules = [ - "re:modbus" - "re:dnp3" - ]; - - settings = { - vars.address-groups = { - # Your local networks — Suricata won't alert on traffic within these - HOME_NET = "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,127.0.0.0/8]"; - EXTERNAL_NET = "!$HOME_NET"; - }; - - # IDS mode: passive monitoring (read-only, no blocking) - # To enable IPS later, swap this for nfqueue mode - af-packet = [ - { interface = "eno1"; } - ]; - - # Structured JSON log — useful for dashboards and log aggregation - outputs = [ - { - eve-log = { - enabled = true; - filetype = "regular"; - filename = "eve.json"; - community-id = true; - types = [ - { alert = { tagged-packets = "yes"; }; } - { anomaly = {}; } - { drop = {}; } - ]; - }; - } - # Human-readable alert log for quick inspection - { - fast = { - enabled = true; - filename = "fast.log"; - append = "yes"; - }; - } - ]; - - # Enable unix socket so suricatasc can query running state - unix-command.enabled = true; - - classification-file = "${pkgs.suricata}/etc/suricata/classification.config"; - reference-config-file = "${pkgs.suricata}/etc/suricata/reference.config"; - }; - }; - - # Make suricata CLI tools available (suricatasc, suricata-update) - environment.systemPackages = [ pkgs.suricata ]; - - }; -} diff --git a/settings/users.nix b/settings/users.nix index 476ff28..0e03e1b 100644 --- a/settings/users.nix +++ b/settings/users.nix @@ -10,5 +10,9 @@ packages = with pkgs; [ bazaar ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEOgQQ9aO8Ri5oL2c3QntSk05PkryfLNsJQqIcjfKFqL fredrik@nordhammer.it" # FredOS-Gaming + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILTLAr9hSWW5PerZJmDZwmB5sa0DBTe2mM4IwTtcCfX3 fredrik@nordhammer.it" # phone + ]; }; }