# Service/daemon detection heuristics # Detects installed server software by checking processes, ports, packages, and config files SERVICES = [ # ── Web Servers ── {"name": "Nginx", "cat": "web", "process": ["nginx"], "ports": [80, 443, 8080], "pkg": ["nginx", "nginx-full", "nginx-extras"], "configs": ["/etc/nginx/nginx.conf", "/etc/nginx/sites-available/", "/etc/nginx/conf.d/"]}, {"name": "Apache", "cat": "web", "process": ["apache2", "httpd"], "ports": [80, 443, 8080], "pkg": ["apache2", "httpd"], "configs": ["/etc/apache2/apache2.conf", "/etc/httpd/conf/httpd.conf", "/etc/apache2/sites-available/"]}, {"name": "Caddy", "cat": "web", "process": ["caddy"], "ports": [80, 443], "pkg": ["caddy"], "configs": ["/etc/caddy/Caddyfile"]}, {"name": "Lighttpd", "cat": "web", "process": ["lighttpd"], "ports": [80], "pkg": ["lighttpd"], "configs": ["/etc/lighttpd/lighttpd.conf"]}, {"name": "HAProxy", "cat": "web", "process": ["haproxy"], "ports": [80, 443, 8404], "pkg": ["haproxy"], "configs": ["/etc/haproxy/haproxy.cfg"]}, {"name": "Traefik", "cat": "web", "process": ["traefik"], "ports": [80, 443, 8080], "pkg": [], "configs": ["/etc/traefik/traefik.yml", "/etc/traefik/traefik.toml"]}, {"name": "Varnish", "cat": "web", "process": ["varnishd"], "ports": [6081, 6082], "pkg": ["varnish"], "configs": ["/etc/varnish/default.vcl"]}, {"name": "Squid", "cat": "web", "process": ["squid"], "ports": [3128], "pkg": ["squid"], "configs": ["/etc/squid/squid.conf"]}, # ── SSH / Remote Access ── {"name": "OpenSSH", "cat": "remote", "process": ["sshd"], "ports": [22, 2222], "pkg": ["openssh-server"], "configs": ["/etc/ssh/sshd_config", "/etc/ssh/ssh_config"]}, {"name": "Dropbear", "cat": "remote", "process": ["dropbear"], "ports": [22], "pkg": ["dropbear"], "configs": ["/etc/dropbear/", "/etc/default/dropbear"]}, {"name": "Mosh", "cat": "remote", "process": ["mosh-server"], "ports": [], "pkg": ["mosh"], "configs": []}, {"name": "x2go", "cat": "remote", "process": ["x2goserver"], "ports": [22], "pkg": ["x2goserver"], "configs": ["/etc/x2go/"]}, {"name": "xrdp", "cat": "remote", "process": ["xrdp"], "ports": [3389], "pkg": ["xrdp"], "configs": ["/etc/xrdp/xrdp.ini", "/etc/xrdp/sesman.ini"]}, {"name": "VNC (TigerVNC)", "cat": "remote", "process": ["Xvnc", "x0vncserver"], "ports": [5900, 5901], "pkg": ["tigervnc-standalone-server"], "configs": ["~/.vnc/config"]}, {"name": "Cockpit", "cat": "remote", "process": ["cockpit-ws"], "ports": [9090], "pkg": ["cockpit"], "configs": ["/etc/cockpit/cockpit.conf"]}, {"name": "Webmin", "cat": "remote", "process": ["miniserv.pl"], "ports": [10000], "pkg": ["webmin"], "configs": ["/etc/webmin/miniserv.conf"]}, {"name": "Shellinabox", "cat": "remote", "process": ["shellinaboxd"], "ports": [4200], "pkg": ["shellinabox"], "configs": ["/etc/default/shellinabox"]}, # ── FTP / File Transfer ── {"name": "vsftpd", "cat": "ftp", "process": ["vsftpd"], "ports": [21], "pkg": ["vsftpd"], "configs": ["/etc/vsftpd.conf", "/etc/vsftpd/vsftpd.conf"]}, {"name": "ProFTPD", "cat": "ftp", "process": ["proftpd"], "ports": [21], "pkg": ["proftpd", "proftpd-basic"], "configs": ["/etc/proftpd/proftpd.conf"]}, {"name": "Pure-FTPd", "cat": "ftp", "process": ["pure-ftpd"], "ports": [21], "pkg": ["pure-ftpd"], "configs": ["/etc/pure-ftpd/pure-ftpd.conf", "/etc/pure-ftpd/conf/"]}, {"name": "SFTP (OpenSSH)", "cat": "ftp", "process": ["sftp-server"], "ports": [22], "pkg": [], "configs": ["/etc/ssh/sshd_config"]}, {"name": "rsyncd", "cat": "ftp", "process": ["rsync"], "ports": [873], "pkg": ["rsync"], "configs": ["/etc/rsyncd.conf"]}, # ── DNS ── {"name": "BIND9", "cat": "dns", "process": ["named"], "ports": [53], "pkg": ["bind9"], "configs": ["/etc/bind/named.conf", "/etc/bind/named.conf.local", "/etc/bind/named.conf.options"]}, {"name": "Unbound", "cat": "dns", "process": ["unbound"], "ports": [53], "pkg": ["unbound"], "configs": ["/etc/unbound/unbound.conf"]}, {"name": "dnsmasq", "cat": "dns", "process": ["dnsmasq"], "ports": [53], "pkg": ["dnsmasq"], "configs": ["/etc/dnsmasq.conf", "/etc/dnsmasq.d/"]}, {"name": "PowerDNS", "cat": "dns", "process": ["pdns_server"], "ports": [53], "pkg": ["pdns-server"], "configs": ["/etc/powerdns/pdns.conf"]}, {"name": "CoreDNS", "cat": "dns", "process": ["coredns"], "ports": [53], "pkg": [], "configs": ["/etc/coredns/Corefile"]}, {"name": "Pi-hole", "cat": "dns", "process": ["pihole-FTL"], "ports": [53, 80], "pkg": ["pihole"], "configs": ["/etc/pihole/setupVars.conf", "/etc/pihole/pihole-FTL.conf"]}, {"name": "AdGuard Home", "cat": "dns", "process": ["AdGuardHome"], "ports": [53, 3000], "pkg": [], "configs": ["/opt/AdGuardHome/AdGuardHome.yaml"]}, # ── Mail ── {"name": "Postfix", "cat": "mail", "process": ["master"], "ports": [25, 587], "pkg": ["postfix"], "configs": ["/etc/postfix/main.cf", "/etc/postfix/master.cf"]}, {"name": "Exim", "cat": "mail", "process": ["exim4", "exim"], "ports": [25, 587], "pkg": ["exim4", "exim4-daemon-heavy"], "configs": ["/etc/exim4/exim4.conf.template", "/etc/exim4/update-exim4.conf.conf"]}, {"name": "Sendmail", "cat": "mail", "process": ["sendmail"], "ports": [25], "pkg": ["sendmail"], "configs": ["/etc/mail/sendmail.cf", "/etc/mail/sendmail.mc"]}, {"name": "Dovecot", "cat": "mail", "process": ["dovecot"], "ports": [143, 993, 110, 995], "pkg": ["dovecot-core", "dovecot-imapd"], "configs": ["/etc/dovecot/dovecot.conf", "/etc/dovecot/conf.d/"]}, {"name": "OpenDKIM", "cat": "mail", "process": ["opendkim"], "ports": [8891], "pkg": ["opendkim"], "configs": ["/etc/opendkim.conf", "/etc/opendkim/"]}, {"name": "OpenDMARC", "cat": "mail", "process": ["opendmarc"], "ports": [8893], "pkg": ["opendmarc"], "configs": ["/etc/opendmarc.conf"]}, {"name": "SpamAssassin", "cat": "mail", "process": ["spamd"], "ports": [783], "pkg": ["spamassassin"], "configs": ["/etc/spamassassin/local.cf"]}, {"name": "ClamAV", "cat": "mail", "process": ["clamd", "freshclam"], "ports": [3310], "pkg": ["clamav", "clamav-daemon"], "configs": ["/etc/clamav/clamd.conf", "/etc/clamav/freshclam.conf"]}, {"name": "Amavis", "cat": "mail", "process": ["amavisd", "amavisd-new"], "ports": [10024], "pkg": ["amavisd-new"], "configs": ["/etc/amavis/conf.d/"]}, {"name": "Roundcube", "cat": "mail", "process": [], "ports": [], "pkg": ["roundcube"], "configs": ["/etc/roundcube/config.inc.php", "/var/www/roundcube/config/config.inc.php"]}, {"name": "Rainloop", "cat": "mail", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/rainloop/data/_data_/_default_/configs/application.ini"]}, # ── Databases ── {"name": "MySQL/MariaDB", "cat": "db", "process": ["mysqld", "mariadbd"], "ports": [3306], "pkg": ["mysql-server", "mariadb-server"], "configs": ["/etc/mysql/my.cnf", "/etc/mysql/mariadb.conf.d/", "/etc/mysql/mysql.conf.d/", "/etc/my.cnf"]}, {"name": "PostgreSQL", "cat": "db", "process": ["postgres", "postgresql"], "ports": [5432], "pkg": ["postgresql"], "configs": ["/etc/postgresql/", "/var/lib/postgresql/data/postgresql.conf"]}, {"name": "MongoDB", "cat": "db", "process": ["mongod", "mongos"], "ports": [27017], "pkg": ["mongodb-org", "mongod"], "configs": ["/etc/mongod.conf"]}, {"name": "Redis", "cat": "db", "process": ["redis-server"], "ports": [6379], "pkg": ["redis-server", "redis"], "configs": ["/etc/redis/redis.conf", "/etc/redis.conf"]}, {"name": "Memcached", "cat": "db", "process": ["memcached"], "ports": [11211], "pkg": ["memcached"], "configs": ["/etc/memcached.conf"]}, {"name": "SQLite", "cat": "db", "process": [], "ports": [], "pkg": ["sqlite3"], "configs": []}, {"name": "CouchDB", "cat": "db", "process": ["beam.smp"], "ports": [5984], "pkg": ["couchdb"], "configs": ["/etc/couchdb/local.ini"]}, {"name": "InfluxDB", "cat": "db", "process": ["influxd"], "ports": [8086], "pkg": ["influxdb", "influxdb2"], "configs": ["/etc/influxdb/influxdb.conf", "/etc/influxdb/config.toml"]}, {"name": "Elasticsearch", "cat": "db", "process": ["java.*elasticsearch"], "ports": [9200, 9300], "pkg": ["elasticsearch"], "configs": ["/etc/elasticsearch/elasticsearch.yml"]}, {"name": "Cassandra", "cat": "db", "process": ["java.*cassandra"], "ports": [9042, 7000], "pkg": ["cassandra"], "configs": ["/etc/cassandra/cassandra.yaml"]}, {"name": "Neo4j", "cat": "db", "process": ["java.*neo4j"], "ports": [7474, 7687], "pkg": ["neo4j"], "configs": ["/etc/neo4j/neo4j.conf"]}, {"name": "RethinkDB", "cat": "db", "process": ["rethinkdb"], "ports": [8080, 28015], "pkg": ["rethinkdb"], "configs": ["/etc/rethinkdb/instances.d/"]}, {"name": "ClickHouse", "cat": "db", "process": ["clickhouse-server"], "ports": [8123, 9000], "pkg": ["clickhouse-server"], "configs": ["/etc/clickhouse-server/config.xml"]}, {"name": "etcd", "cat": "db", "process": ["etcd"], "ports": [2379, 2380], "pkg": ["etcd"], "configs": ["/etc/etcd/etcd.conf.yml"]}, {"name": "Valkey", "cat": "db", "process": ["valkey-server"], "ports": [6379], "pkg": ["valkey"], "configs": ["/etc/valkey/valkey.conf"]}, {"name": "KeyDB", "cat": "db", "process": ["keydb-server"], "ports": [6379], "pkg": ["keydb"], "configs": ["/etc/keydb/keydb.conf"]}, # ── DB Admin Tools ── {"name": "phpMyAdmin", "cat": "dbadmin", "process": [], "ports": [], "pkg": ["phpmyadmin"], "configs": ["/etc/phpmyadmin/config.inc.php"]}, {"name": "Adminer", "cat": "dbadmin", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/adminer/"]}, {"name": "pgAdmin", "cat": "dbadmin", "process": ["pgadmin"], "ports": [5050], "pkg": ["pgadmin4"], "configs": ["/etc/pgadmin/config_system.py"]}, # ── Git / Code Forges ── {"name": "Gitea", "cat": "git", "process": ["gitea"], "ports": [3000], "pkg": [], "configs": ["/etc/gitea/app.ini", "/var/lib/gitea/custom/conf/app.ini"]}, {"name": "GitLab", "cat": "git", "process": ["gitlab-workhorse", "puma", "sidekiq", "gitaly"], "ports": [8080, 80, 443], "pkg": ["gitlab-ce", "gitlab-ee"], "configs": ["/etc/gitlab/gitlab.rb"]}, {"name": "Gogs", "cat": "git", "process": ["gogs"], "ports": [3000], "pkg": [], "configs": ["/etc/gogs/app.ini", "/home/git/gogs/custom/conf/app.ini"]}, {"name": "Forgejo", "cat": "git", "process": ["forgejo"], "ports": [3000], "pkg": [], "configs": ["/etc/forgejo/app.ini"]}, {"name": "cgit", "cat": "git", "process": [], "ports": [], "pkg": ["cgit"], "configs": ["/etc/cgitrc"]}, {"name": "Gitolite", "cat": "git", "process": [], "ports": [], "pkg": ["gitolite3"], "configs": ["~/.gitolite.rc"]}, {"name": "GitBucket", "cat": "git", "process": ["java.*gitbucket"], "ports": [8080], "pkg": [], "configs": ["~/.gitbucket/gitbucket.conf"]}, {"name": "OneDev", "cat": "git", "process": ["java.*onedev"], "ports": [6610, 6611], "pkg": [], "configs": ["/opt/onedev/conf/server.properties"]}, # ── CI/CD ── {"name": "Jenkins", "cat": "ci", "process": ["java.*jenkins"], "ports": [8080], "pkg": ["jenkins"], "configs": ["/etc/default/jenkins", "/var/lib/jenkins/config.xml"]}, {"name": "Drone", "cat": "ci", "process": ["drone-server"], "ports": [80, 443], "pkg": [], "configs": []}, {"name": "Woodpecker CI", "cat": "ci", "process": ["woodpecker-server"], "ports": [8000], "pkg": [], "configs": []}, {"name": "GoCD", "cat": "ci", "process": ["java.*go.jar"], "ports": [8153, 8154], "pkg": ["go-server"], "configs": ["/etc/go/cruise-config.xml"]}, {"name": "Buildbot", "cat": "ci", "process": ["buildbot"], "ports": [8010], "pkg": ["buildbot"], "configs": ["/etc/buildbot/"]}, {"name": "Concourse", "cat": "ci", "process": ["concourse"], "ports": [8080], "pkg": [], "configs": []}, {"name": "GitLab Runner", "cat": "ci", "process": ["gitlab-runner"], "ports": [], "pkg": ["gitlab-runner"], "configs": ["/etc/gitlab-runner/config.toml"]}, {"name": "Act Runner", "cat": "ci", "process": ["act_runner"], "ports": [], "pkg": [], "configs": ["/etc/act_runner/config.yaml"]}, # ── Containers / Orchestration ── {"name": "Docker", "cat": "container", "process": ["dockerd", "containerd"], "ports": [2375, 2376], "pkg": ["docker-ce", "docker.io"], "configs": ["/etc/docker/daemon.json"]}, {"name": "Podman", "cat": "container", "process": ["podman"], "ports": [], "pkg": ["podman"], "configs": ["/etc/containers/registries.conf", "/etc/containers/policy.json"]}, {"name": "LXD/LXC", "cat": "container", "process": ["lxd", "lxcfs"], "ports": [8443], "pkg": ["lxd", "lxc"], "configs": ["/etc/lxc/default.conf"]}, {"name": "Portainer", "cat": "container", "process": ["portainer"], "ports": [9000, 9443], "pkg": [], "configs": []}, {"name": "Kubernetes (k3s)", "cat": "container", "process": ["k3s"], "ports": [6443], "pkg": [], "configs": ["/etc/rancher/k3s/config.yaml"]}, {"name": "MicroK8s", "cat": "container", "process": ["microk8s"], "ports": [16443], "pkg": ["microk8s"], "configs": []}, {"name": "Nomad", "cat": "container", "process": ["nomad"], "ports": [4646], "pkg": ["nomad"], "configs": ["/etc/nomad.d/"]}, {"name": "Docker Registry", "cat": "container", "process": ["registry"], "ports": [5000], "pkg": [], "configs": ["/etc/docker/registry/config.yml"]}, {"name": "Yacht", "cat": "container", "process": [], "ports": [8000], "pkg": [], "configs": []}, # ── Monitoring ── {"name": "Prometheus", "cat": "monitor", "process": ["prometheus"], "ports": [9090], "pkg": ["prometheus"], "configs": ["/etc/prometheus/prometheus.yml"]}, {"name": "Grafana", "cat": "monitor", "process": ["grafana-server", "grafana"], "ports": [3000], "pkg": ["grafana"], "configs": ["/etc/grafana/grafana.ini"]}, {"name": "Zabbix", "cat": "monitor", "process": ["zabbix_server", "zabbix_agentd"], "ports": [10051, 10050], "pkg": ["zabbix-server-mysql", "zabbix-agent"], "configs": ["/etc/zabbix/zabbix_server.conf", "/etc/zabbix/zabbix_agentd.conf"]}, {"name": "Nagios", "cat": "monitor", "process": ["nagios"], "ports": [80], "pkg": ["nagios4"], "configs": ["/etc/nagios4/nagios.cfg", "/usr/local/nagios/etc/nagios.cfg"]}, {"name": "Netdata", "cat": "monitor", "process": ["netdata"], "ports": [19999], "pkg": ["netdata"], "configs": ["/etc/netdata/netdata.conf"]}, {"name": "Node Exporter", "cat": "monitor", "process": ["node_exporter"], "ports": [9100], "pkg": ["prometheus-node-exporter"], "configs": []}, {"name": "Telegraf", "cat": "monitor", "process": ["telegraf"], "ports": [], "pkg": ["telegraf"], "configs": ["/etc/telegraf/telegraf.conf"]}, {"name": "Collectd", "cat": "monitor", "process": ["collectd"], "ports": [25826], "pkg": ["collectd"], "configs": ["/etc/collectd/collectd.conf"]}, {"name": "Icinga2", "cat": "monitor", "process": ["icinga2"], "ports": [5665], "pkg": ["icinga2"], "configs": ["/etc/icinga2/icinga2.conf"]}, {"name": "Uptime Kuma", "cat": "monitor", "process": ["uptime-kuma"], "ports": [3001], "pkg": [], "configs": []}, {"name": "Monit", "cat": "monitor", "process": ["monit"], "ports": [2812], "pkg": ["monit"], "configs": ["/etc/monit/monitrc", "/etc/monitrc"]}, {"name": "Checkmk", "cat": "monitor", "process": ["cmk"], "ports": [80], "pkg": ["check-mk-raw"], "configs": ["/etc/check_mk/main.mk"]}, {"name": "Loki", "cat": "monitor", "process": ["loki"], "ports": [3100], "pkg": [], "configs": ["/etc/loki/config.yaml"]}, {"name": "Promtail", "cat": "monitor", "process": ["promtail"], "ports": [9080], "pkg": [], "configs": ["/etc/promtail/config.yml"]}, {"name": "Graylog", "cat": "monitor", "process": ["java.*graylog"], "ports": [9000, 12201], "pkg": ["graylog-server"], "configs": ["/etc/graylog/server/server.conf"]}, {"name": "Fluentd", "cat": "monitor", "process": ["fluentd", "td-agent"], "ports": [24224], "pkg": ["td-agent"], "configs": ["/etc/td-agent/td-agent.conf", "/etc/fluent/fluent.conf"]}, # ── VPN / Tunnels ── {"name": "WireGuard", "cat": "vpn", "process": [], "ports": [51820], "pkg": ["wireguard", "wireguard-tools"], "configs": ["/etc/wireguard/wg0.conf"]}, {"name": "OpenVPN", "cat": "vpn", "process": ["openvpn"], "ports": [1194], "pkg": ["openvpn"], "configs": ["/etc/openvpn/server.conf", "/etc/openvpn/server/"]}, {"name": "StrongSwan (IPsec)", "cat": "vpn", "process": ["charon", "starter"], "ports": [500, 4500], "pkg": ["strongswan"], "configs": ["/etc/ipsec.conf", "/etc/strongswan.conf"]}, {"name": "Tailscale", "cat": "vpn", "process": ["tailscaled"], "ports": [], "pkg": ["tailscale"], "configs": []}, {"name": "ZeroTier", "cat": "vpn", "process": ["zerotier-one"], "ports": [9993], "pkg": ["zerotier-one"], "configs": ["/var/lib/zerotier-one/"]}, {"name": "Headscale", "cat": "vpn", "process": ["headscale"], "ports": [8080], "pkg": [], "configs": ["/etc/headscale/config.yaml"]}, {"name": "Nebula", "cat": "vpn", "process": ["nebula"], "ports": [4242], "pkg": [], "configs": ["/etc/nebula/config.yml"]}, {"name": "frp", "cat": "vpn", "process": ["frps", "frpc"], "ports": [7000, 7500], "pkg": [], "configs": ["/etc/frp/frps.ini", "/etc/frp/frps.toml"]}, {"name": "Cloudflared", "cat": "vpn", "process": ["cloudflared"], "ports": [], "pkg": ["cloudflared"], "configs": ["/etc/cloudflared/config.yml"]}, {"name": "ngrok", "cat": "vpn", "process": ["ngrok"], "ports": [4040], "pkg": [], "configs": ["~/.ngrok2/ngrok.yml"]}, # ── Firewall / Security ── {"name": "UFW", "cat": "security", "process": [], "ports": [], "pkg": ["ufw"], "configs": ["/etc/ufw/ufw.conf", "/etc/ufw/user.rules", "/etc/ufw/user6.rules"]}, {"name": "iptables", "cat": "security", "process": [], "ports": [], "pkg": ["iptables"], "configs": ["/etc/iptables/rules.v4", "/etc/iptables/rules.v6"]}, {"name": "nftables", "cat": "security", "process": ["nft"], "ports": [], "pkg": ["nftables"], "configs": ["/etc/nftables.conf"]}, {"name": "Fail2Ban", "cat": "security", "process": ["fail2ban-server"], "ports": [], "pkg": ["fail2ban"], "configs": ["/etc/fail2ban/jail.conf", "/etc/fail2ban/jail.local", "/etc/fail2ban/jail.d/"]}, {"name": "CrowdSec", "cat": "security", "process": ["crowdsec"], "ports": [8080], "pkg": ["crowdsec"], "configs": ["/etc/crowdsec/config.yaml"]}, {"name": "OSSEC", "cat": "security", "process": ["ossec-analysisd"], "ports": [1514], "pkg": ["ossec-hids"], "configs": ["/var/ossec/etc/ossec.conf"]}, {"name": "Snort", "cat": "security", "process": ["snort"], "ports": [], "pkg": ["snort"], "configs": ["/etc/snort/snort.conf"]}, {"name": "Suricata", "cat": "security", "process": ["suricata"], "ports": [], "pkg": ["suricata"], "configs": ["/etc/suricata/suricata.yaml"]}, {"name": "ModSecurity", "cat": "security", "process": [], "ports": [], "pkg": ["libapache2-mod-security2"], "configs": ["/etc/modsecurity/modsecurity.conf"]}, {"name": "AppArmor", "cat": "security", "process": ["apparmor"], "ports": [], "pkg": ["apparmor"], "configs": ["/etc/apparmor.d/"]}, {"name": "SELinux", "cat": "security", "process": [], "ports": [], "pkg": ["selinux-utils"], "configs": ["/etc/selinux/config"]}, {"name": "Wazuh", "cat": "security", "process": ["wazuh-manager"], "ports": [1514, 1515, 55000], "pkg": ["wazuh-manager"], "configs": ["/var/ossec/etc/ossec.conf"]}, # ── Auth / SSO ── {"name": "Keycloak", "cat": "auth", "process": ["java.*keycloak"], "ports": [8080, 8443], "pkg": [], "configs": ["/opt/keycloak/conf/keycloak.conf"]}, {"name": "Authentik", "cat": "auth", "process": ["authentik"], "ports": [9000, 9443], "pkg": [], "configs": []}, {"name": "Authelia", "cat": "auth", "process": ["authelia"], "ports": [9091], "pkg": [], "configs": ["/etc/authelia/configuration.yml"]}, {"name": "OpenLDAP", "cat": "auth", "process": ["slapd"], "ports": [389, 636], "pkg": ["slapd", "ldap-utils"], "configs": ["/etc/ldap/slapd.d/", "/etc/openldap/slapd.conf"]}, {"name": "FreeIPA", "cat": "auth", "process": ["ipa"], "ports": [80, 443, 389, 636], "pkg": ["freeipa-server"], "configs": ["/etc/ipa/default.conf"]}, {"name": "Vault", "cat": "auth", "process": ["vault"], "ports": [8200], "pkg": ["vault"], "configs": ["/etc/vault.d/vault.hcl"]}, {"name": "Teleport", "cat": "auth", "process": ["teleport"], "ports": [3023, 3024, 3080], "pkg": ["teleport"], "configs": ["/etc/teleport.yaml"]}, # ── CMS / Web Apps ── {"name": "WordPress", "cat": "cms", "process": ["php-fpm"], "ports": [], "pkg": ["wordpress"], "configs": ["/var/www/html/wp-config.php", "/var/www/wordpress/wp-config.php"]}, {"name": "Ghost", "cat": "cms", "process": ["ghost"], "ports": [2368], "pkg": [], "configs": ["/var/www/ghost/config.production.json"]}, {"name": "Drupal", "cat": "cms", "process": [], "ports": [], "pkg": ["drupal"], "configs": ["/var/www/html/sites/default/settings.php"]}, {"name": "Joomla", "cat": "cms", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/html/configuration.php"]}, {"name": "MediaWiki", "cat": "cms", "process": [], "ports": [], "pkg": ["mediawiki"], "configs": ["/var/www/html/LocalSettings.php", "/etc/mediawiki/LocalSettings.php"]}, {"name": "Wiki.js", "cat": "cms", "process": ["wiki"], "ports": [3000], "pkg": [], "configs": ["/etc/wiki/config.yml"]}, {"name": "BookStack", "cat": "cms", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/bookstack/.env"]}, {"name": "DokuWiki", "cat": "cms", "process": [], "ports": [], "pkg": ["dokuwiki"], "configs": ["/var/www/dokuwiki/conf/local.php"]}, {"name": "Hugo", "cat": "cms", "process": ["hugo"], "ports": [1313], "pkg": ["hugo"], "configs": []}, # ── PHP ── {"name": "PHP-FPM", "cat": "runtime", "process": ["php-fpm"], "ports": [9000], "pkg": ["php-fpm", "php8.1-fpm", "php8.2-fpm", "php8.3-fpm"], "configs": ["/etc/php/", "/etc/php/8.2/fpm/php-fpm.conf", "/etc/php/8.2/fpm/pool.d/www.conf"]}, # ── App Runtimes ── {"name": "Node.js (PM2)", "cat": "runtime", "process": ["PM2", "node"], "ports": [], "pkg": ["nodejs"], "configs": ["/etc/pm2/", "ecosystem.config.js"]}, {"name": "Python (Gunicorn)", "cat": "runtime", "process": ["gunicorn"], "ports": [8000], "pkg": ["gunicorn"], "configs": []}, {"name": "Python (uWSGI)", "cat": "runtime", "process": ["uwsgi"], "ports": [], "pkg": ["uwsgi"], "configs": ["/etc/uwsgi/apps-enabled/"]}, {"name": "Tomcat", "cat": "runtime", "process": ["java.*catalina"], "ports": [8080], "pkg": ["tomcat9", "tomcat10"], "configs": ["/etc/tomcat9/server.xml", "/etc/tomcat10/server.xml"]}, {"name": "Supervisor", "cat": "runtime", "process": ["supervisord"], "ports": [9001], "pkg": ["supervisor"], "configs": ["/etc/supervisor/supervisord.conf", "/etc/supervisor/conf.d/"]}, # ── Message Queues ── {"name": "RabbitMQ", "cat": "mq", "process": ["beam.smp", "rabbitmq"], "ports": [5672, 15672], "pkg": ["rabbitmq-server"], "configs": ["/etc/rabbitmq/rabbitmq.conf"]}, {"name": "Mosquitto (MQTT)", "cat": "mq", "process": ["mosquitto"], "ports": [1883, 8883], "pkg": ["mosquitto"], "configs": ["/etc/mosquitto/mosquitto.conf"]}, {"name": "NATS", "cat": "mq", "process": ["nats-server"], "ports": [4222, 8222], "pkg": [], "configs": ["/etc/nats/nats-server.conf"]}, {"name": "Kafka", "cat": "mq", "process": ["java.*kafka"], "ports": [9092], "pkg": [], "configs": ["/etc/kafka/server.properties"]}, {"name": "ZeroMQ", "cat": "mq", "process": [], "ports": [], "pkg": ["libzmq5"], "configs": []}, # ── Chat / Communication ── {"name": "Matrix (Synapse)", "cat": "chat", "process": ["synapse", "python.*synapse"], "ports": [8008, 8448], "pkg": ["matrix-synapse"], "configs": ["/etc/matrix-synapse/homeserver.yaml"]}, {"name": "Mattermost", "cat": "chat", "process": ["mattermost"], "ports": [8065], "pkg": [], "configs": ["/opt/mattermost/config/config.json"]}, {"name": "Rocket.Chat", "cat": "chat", "process": ["rocketchat"], "ports": [3000], "pkg": [], "configs": []}, {"name": "XMPP (Prosody)", "cat": "chat", "process": ["prosody"], "ports": [5222, 5269], "pkg": ["prosody"], "configs": ["/etc/prosody/prosody.cfg.lua"]}, {"name": "XMPP (ejabberd)", "cat": "chat", "process": ["ejabberd"], "ports": [5222, 5269], "pkg": ["ejabberd"], "configs": ["/etc/ejabberd/ejabberd.yml"]}, {"name": "Mumble", "cat": "chat", "process": ["murmurd"], "ports": [64738], "pkg": ["mumble-server"], "configs": ["/etc/mumble-server.ini"]}, {"name": "TeamSpeak", "cat": "chat", "process": ["ts3server"], "ports": [9987, 30033], "pkg": [], "configs": ["/opt/teamspeak/ts3server.ini"]}, {"name": "Jitsi Meet", "cat": "chat", "process": ["jicofo", "jvb"], "ports": [80, 443, 10000], "pkg": ["jitsi-meet"], "configs": ["/etc/jitsi/meet/"]}, {"name": "Gotify", "cat": "chat", "process": ["gotify"], "ports": [80], "pkg": [], "configs": ["/etc/gotify/config.yml"]}, {"name": "ntfy", "cat": "chat", "process": ["ntfy"], "ports": [80], "pkg": ["ntfy"], "configs": ["/etc/ntfy/server.yml"]}, # ── File Sharing / Cloud ── {"name": "Nextcloud", "cat": "cloud", "process": [], "ports": [], "pkg": ["nextcloud"], "configs": ["/var/www/nextcloud/config/config.php"]}, {"name": "Seafile", "cat": "cloud", "process": ["seafile-controller", "seaf-server"], "ports": [8000, 8082], "pkg": [], "configs": ["/opt/seafile/conf/"]}, {"name": "Syncthing", "cat": "cloud", "process": ["syncthing"], "ports": [8384, 22000], "pkg": ["syncthing"], "configs": ["/etc/syncthing/"]}, {"name": "MinIO", "cat": "cloud", "process": ["minio"], "ports": [9000, 9001], "pkg": [], "configs": ["/etc/minio/config.env"]}, {"name": "Samba", "cat": "cloud", "process": ["smbd", "nmbd"], "ports": [139, 445], "pkg": ["samba"], "configs": ["/etc/samba/smb.conf"]}, {"name": "NFS", "cat": "cloud", "process": ["nfsd", "rpc.mountd"], "ports": [2049], "pkg": ["nfs-kernel-server"], "configs": ["/etc/exports"]}, {"name": "WebDAV", "cat": "cloud", "process": [], "ports": [], "pkg": [], "configs": []}, {"name": "FileBrowser", "cat": "cloud", "process": ["filebrowser"], "ports": [8080], "pkg": [], "configs": ["/etc/filebrowser/filebrowser.json"]}, # ── Media ── {"name": "Jellyfin", "cat": "media", "process": ["jellyfin"], "ports": [8096], "pkg": ["jellyfin"], "configs": ["/etc/jellyfin/system.xml"]}, {"name": "Plex", "cat": "media", "process": ["Plex Media Server"], "ports": [32400], "pkg": ["plexmediaserver"], "configs": ["/var/lib/plexmediaserver/"]}, {"name": "Emby", "cat": "media", "process": ["emby"], "ports": [8096], "pkg": ["emby-server"], "configs": ["/etc/emby-server.conf"]}, {"name": "Navidrome", "cat": "media", "process": ["navidrome"], "ports": [4533], "pkg": [], "configs": ["/etc/navidrome/navidrome.toml"]}, {"name": "Icecast", "cat": "media", "process": ["icecast2"], "ports": [8000], "pkg": ["icecast2"], "configs": ["/etc/icecast2/icecast.xml"]}, # ── Automation ── {"name": "n8n", "cat": "automation", "process": ["n8n"], "ports": [5678], "pkg": [], "configs": []}, {"name": "Node-RED", "cat": "automation", "process": ["node-red"], "ports": [1880], "pkg": [], "configs": ["~/.node-red/settings.js"]}, {"name": "Ansible", "cat": "automation", "process": [], "ports": [], "pkg": ["ansible"], "configs": ["/etc/ansible/ansible.cfg", "/etc/ansible/hosts"]}, {"name": "Cron", "cat": "automation", "process": ["cron", "crond"], "ports": [], "pkg": ["cron"], "configs": ["/etc/crontab", "/etc/cron.d/"]}, {"name": "systemd-timers", "cat": "automation", "process": [], "ports": [], "pkg": [], "configs": []}, {"name": "at", "cat": "automation", "process": ["atd"], "ports": [], "pkg": ["at"], "configs": []}, # ── Analytics ── {"name": "Matomo", "cat": "analytics", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/matomo/config/config.ini.php"]}, {"name": "Plausible", "cat": "analytics", "process": ["plausible"], "ports": [8000], "pkg": [], "configs": []}, {"name": "Umami", "cat": "analytics", "process": ["umami"], "ports": [3000], "pkg": [], "configs": []}, {"name": "GoAccess", "cat": "analytics", "process": ["goaccess"], "ports": [7890], "pkg": ["goaccess"], "configs": ["/etc/goaccess/goaccess.conf"]}, {"name": "AWStats", "cat": "analytics", "process": [], "ports": [], "pkg": ["awstats"], "configs": ["/etc/awstats/"]}, # ── Backup ── {"name": "BorgBackup", "cat": "backup", "process": ["borg"], "ports": [], "pkg": ["borgbackup"], "configs": []}, {"name": "Restic", "cat": "backup", "process": ["restic"], "ports": [], "pkg": ["restic"], "configs": []}, {"name": "Duplicity", "cat": "backup", "process": ["duplicity"], "ports": [], "pkg": ["duplicity"], "configs": []}, {"name": "Bacula", "cat": "backup", "process": ["bacula-dir", "bacula-sd", "bacula-fd"], "ports": [9101, 9102, 9103], "pkg": ["bacula-director", "bacula-sd", "bacula-fd"], "configs": ["/etc/bacula/bacula-dir.conf", "/etc/bacula/bacula-sd.conf"]}, {"name": "rsnapshot", "cat": "backup", "process": [], "ports": [], "pkg": ["rsnapshot"], "configs": ["/etc/rsnapshot.conf"]}, {"name": "Duplicati", "cat": "backup", "process": ["duplicati"], "ports": [8200], "pkg": [], "configs": []}, # ── Mailing Lists ── {"name": "Listmonk", "cat": "mail", "process": ["listmonk"], "ports": [9000], "pkg": [], "configs": ["/etc/listmonk/config.toml"]}, {"name": "Mailman", "cat": "mail", "process": ["mailman"], "ports": [8001], "pkg": ["mailman3"], "configs": ["/etc/mailman3/"]}, {"name": "Sympa", "cat": "mail", "process": ["sympa"], "ports": [], "pkg": ["sympa"], "configs": ["/etc/sympa/sympa.conf"]}, # ── Misc Services ── {"name": "Certbot", "cat": "misc", "process": [], "ports": [], "pkg": ["certbot"], "configs": ["/etc/letsencrypt/"]}, {"name": "ACME.sh", "cat": "misc", "process": [], "ports": [], "pkg": [], "configs": ["~/.acme.sh/"]}, {"name": "logrotate", "cat": "misc", "process": [], "ports": [], "pkg": ["logrotate"], "configs": ["/etc/logrotate.conf", "/etc/logrotate.d/"]}, {"name": "NTP (chrony)", "cat": "misc", "process": ["chronyd"], "ports": [123], "pkg": ["chrony"], "configs": ["/etc/chrony/chrony.conf"]}, {"name": "NTP (ntpd)", "cat": "misc", "process": ["ntpd"], "ports": [123], "pkg": ["ntp"], "configs": ["/etc/ntp.conf"]}, {"name": "systemd-resolved", "cat": "misc", "process": ["systemd-resolved"], "ports": [53], "pkg": [], "configs": ["/etc/systemd/resolved.conf"]}, {"name": "snapd", "cat": "misc", "process": ["snapd"], "ports": [], "pkg": ["snapd"], "configs": []}, {"name": "CUPS", "cat": "misc", "process": ["cupsd"], "ports": [631], "pkg": ["cups"], "configs": ["/etc/cups/cupsd.conf"]}, {"name": "Tor", "cat": "misc", "process": ["tor"], "ports": [9050, 9051], "pkg": ["tor"], "configs": ["/etc/tor/torrc"]}, {"name": "Privoxy", "cat": "misc", "process": ["privoxy"], "ports": [8118], "pkg": ["privoxy"], "configs": ["/etc/privoxy/config"]}, {"name": "DNSCrypt", "cat": "misc", "process": ["dnscrypt-proxy"], "ports": [53], "pkg": ["dnscrypt-proxy"], "configs": ["/etc/dnscrypt-proxy/dnscrypt-proxy.toml"]}, {"name": "Consul", "cat": "misc", "process": ["consul"], "ports": [8500, 8600], "pkg": ["consul"], "configs": ["/etc/consul.d/"]}, {"name": "Vaultwarden", "cat": "misc", "process": ["vaultwarden"], "ports": [80, 3012], "pkg": [], "configs": ["/etc/vaultwarden.env", "/opt/vaultwarden/.env"]}, # ── Password / Secrets ── {"name": "Bitwarden", "cat": "auth", "process": ["bitwarden"], "ports": [80, 443], "pkg": [], "configs": ["/opt/bitwarden/bwdata/config.yml"]}, # ── Status Pages ── {"name": "Cachet", "cat": "monitor", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/cachet/.env"]}, {"name": "Statping", "cat": "monitor", "process": ["statping"], "ports": [8080], "pkg": [], "configs": []}, # ── Pastebin / Snippets ── {"name": "PrivateBin", "cat": "misc", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/privatebin/cfg/conf.php"]}, {"name": "Hastebin", "cat": "misc", "process": ["haste-server"], "ports": [7777], "pkg": [], "configs": []}, # ── URL Shorteners ── {"name": "YOURLS", "cat": "misc", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/yourls/user/config.php"]}, {"name": "Shlink", "cat": "misc", "process": ["shlink"], "ports": [8080], "pkg": [], "configs": []}, # ── Forums ── {"name": "Discourse", "cat": "cms", "process": ["discourse"], "ports": [80], "pkg": [], "configs": ["/var/discourse/containers/app.yml"]}, {"name": "Flarum", "cat": "cms", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/flarum/config.php"]}, {"name": "phpBB", "cat": "cms", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/phpbb/config.php"]}, # ── Project Management ── {"name": "Wekan", "cat": "misc", "process": ["wekan"], "ports": [80], "pkg": [], "configs": []}, {"name": "Kanboard", "cat": "misc", "process": [], "ports": [], "pkg": [], "configs": ["/var/www/kanboard/config.php"]}, {"name": "Taiga", "cat": "misc", "process": ["taiga"], "ports": [80], "pkg": [], "configs": ["/opt/taiga/config.py"]}, {"name": "Gitea Act Runner", "cat": "ci", "process": ["act_runner"], "ports": [], "pkg": [], "configs": []}, ] CATEGORIES = { "web": "Web Servers", "remote": "Remote Access", "ftp": "FTP / File Transfer", "dns": "DNS", "mail": "Mail", "db": "Databases", "dbadmin": "DB Admin Tools", "git": "Git / Code Forges", "ci": "CI/CD", "container": "Containers", "monitor": "Monitoring", "vpn": "VPN / Tunnels", "security": "Firewall / Security", "auth": "Auth / SSO", "cms": "CMS / Web Apps", "runtime": "App Runtimes", "mq": "Message Queues", "chat": "Chat / Communication", "cloud": "File Sharing / Cloud", "media": "Media", "automation": "Automation", "analytics": "Analytics", "backup": "Backup", "misc": "Miscellaneous", } def build_detect_command(): """Build a single SSH command that gathers all detection data at once.""" return ( "echo '===PROCESSES===' && ps aux --no-headers 2>/dev/null | awk '{print $11}' | sort -u && " "echo '===LISTENING===' && ss -tlnp 2>/dev/null | awk 'NR>1{print $4}' | grep -oP '\\d+$' | sort -un && " "echo '===PACKAGES===' && (dpkg -l 2>/dev/null | awk '/^ii/{print $2}' || rpm -qa --qf '%{NAME}\\n' 2>/dev/null) | sort -u && " "echo '===CONFIGS===' && ls -1d " "/etc/nginx/ /etc/apache2/ /etc/caddy/ /etc/haproxy/ " "/etc/ssh/ /etc/vsftpd* /etc/proftpd/ " "/etc/bind/ /etc/unbound/ /etc/dnsmasq* /etc/pihole/ " "/etc/postfix/ /etc/exim4/ /etc/dovecot/ /etc/opendkim* " "/etc/mysql/ /etc/postgresql/ /etc/redis/ /etc/mongod* /etc/influxdb/ /etc/elasticsearch/ " "/etc/gitlab/ /etc/gitea/ /etc/forgejo/ " "/etc/docker/ /etc/lxc/ " "/etc/prometheus/ /etc/grafana/ /etc/zabbix/ /etc/netdata/ /etc/nagios*/ " "/etc/wireguard/ /etc/openvpn/ " "/etc/fail2ban/ /etc/crowdsec/ /etc/ufw/ /etc/iptables/ /etc/nftables* " "/etc/letsencrypt/ /etc/logrotate* " "/etc/php/ /etc/supervisor/ " "/etc/rabbitmq/ /etc/mosquitto/ " "/etc/samba/ /etc/exports " "/etc/tor/ /etc/consul* " "/var/www/nextcloud/ /var/www/wordpress/ /var/www/matomo/ " "/opt/mattermost/ /opt/keycloak/ /opt/seafile/ " "2>/dev/null && " "echo '===DOCKER===' && docker ps -a --format '{{.Names}}|{{.Image}}' 2>/dev/null && " "echo '===SYSTEMD===' && systemctl list-units --type=service --state=running --no-pager --no-legend 2>/dev/null | awk '{print $1}' && " "echo '===END==='" ) def parse_detection(raw_output): """Parse the detection output and match against known services.""" sections = {} current = None for line in raw_output.split("\n"): line = line.strip() if line.startswith("===") and line.endswith("==="): current = line.strip("=") sections[current] = [] elif current and line: sections[current].append(line) processes = set(sections.get("PROCESSES", [])) ports = set() for p in sections.get("LISTENING", []): try: ports.add(int(p)) except ValueError: pass packages = set(sections.get("PACKAGES", [])) configs_found = set(sections.get("CONFIGS", [])) docker_containers = sections.get("DOCKER", []) systemd_units = set(sections.get("SYSTEMD", [])) detected = [] for svc in SERVICES: score = 0 evidence = [] # Check processes for proc in svc["process"]: for running in processes: if proc in running: score += 3 evidence.append(f"process: {running}") break # Check systemd units for proc in svc["process"]: for unit in systemd_units: if proc in unit: score += 2 evidence.append(f"systemd: {unit}") break # Check ports for port in svc["ports"]: if port in ports: score += 2 evidence.append(f"port: {port}") # Check packages for pkg in svc["pkg"]: # packages often have version suffixes, so check prefix for installed in packages: if installed == pkg or installed.startswith(pkg + ":"): score += 3 evidence.append(f"package: {installed}") break # Check config files for cfg in svc["configs"]: for found in configs_found: if found.startswith(cfg.rstrip("/")): score += 2 evidence.append(f"config: {found}") break # Check docker containers for dc in docker_containers: name_lower = dc.lower() svc_lower = svc["name"].lower().replace(" ", "").replace("-", "") if svc_lower in name_lower: score += 3 evidence.append(f"docker: {dc}") if score >= 2: detected.append({ "name": svc["name"], "category": CATEGORIES.get(svc["cat"], svc["cat"]), "cat": svc["cat"], "score": score, "evidence": evidence, "configs": svc["configs"], "ports": svc["ports"], }) detected.sort(key=lambda x: (-x["score"], x["name"])) return detected