Skip to content

Install SuckerPot

This page shows how to install SuckerPot with one command. The installer checks the machine, asks a few questions, creates every secret on this host and starts the stack. The dashboard then walks you through the rest.

The manual path, with no installer, is still described in Getting started.

ItemNeededNotes
Operating systemLinux, on x86_64 (amd64) or aarch64 (arm64)A VM or a small server is fine. See low-memory hosts for small machines.
Shell toolsBash 4 or newer, git, curl, and the usual GNU tools (awk, sed, tr, base64)ss (from iproute2) is used for the port check. Without it the check is skipped.
Docker Engine24 or newerYour user must run docker without sudo. The installer tells you how to add the group if not.
Docker Composev2.24 or newerThe Compose plugin (docker compose version must work).
Memory2 GiB minimumUse low-memory mode below 6 GiB. The installer refuses below about 2 GiB.
Free disk15 GiB minimum under Docker’s data folderThe installer warns below 30 GiB. Logs and captured payloads need room.
Outbound accessYes, for the installThe host pulls images from the registry and checks their signatures. This traffic uses the host’s own address. See Anonymous egress.
RouterForwarding for the sensor ports you choseSee Ports to forward.

The memory figures are sizing targets. Check the real use on your host with docker stats after the first day.

ModeWhat runsUse it when
full (default)Everything: sensors, database, ingest, API and dashboard, and the VPN service (optional; idle until you add a WireGuard file)You want the dashboard, reports and blocklists
participant (--participant)Sensors, database, ingest and the network node. No dashboard, no admin account, no VPN neededYou only want to help the network. See Join the network

Participant mode has its own flags: --pseudonym, --no-pseudonym, --country, --show-country, --verifier, --no-auto-update, --feeds, --self-address and --repair. It refuses the dashboard flags (--dashboard-*, --public-host, --admin-*, --allow-lan). Choosing it is your consent to join the network.

To switch an existing participant install to full mode, run ./scripts/install.sh --full. It asks the dashboard questions, takes a backup and keeps your data. The other way (full to participant) is not supported. Running the installer again on an existing install only prints its status. Add --repair to run the volume, start and schedule steps again.

ModeWhat runsUse it when
images (default)Signed release images from the registry. The installer checks each signature before it runs anything.You want a released version. This is the normal choice.
sourceImages built on this machine from the checkout.You want to run your own changes, or no release is published yet. It takes longer.

The mode is saved as SUCKERPOT_INSTALL_MODE in .env. Updates use the same mode.

Clone a release tag, then run the installer from the checkout:

Terminal window
git clone --depth 1 --branch v0.7.1 https://github.com/selfhostr/suckerpot.git
cd suckerpot
./scripts/install.sh

Replace v0.7.1 with the release you want. The tag is the release name on the repository’s Releases page.

If you clone without a tag, or you want to build from source, run:

Terminal window
./scripts/install.sh --source

The installer does not use curl | bash. Read the script first, then run it from the checkout.

To install without questions, use --yes. It takes the default for every question. That includes joining the SuckerPot network: --yes counts as your agreement to the network screen, unless you also pass --no-network. The admin password is then generated and printed once, or you can pass your own on standard input:

Terminal window
./scripts/install.sh --yes --sensors recommended
# add --no-network to stay out of the network
Terminal window
read -rs -p "Admin password: " PW && echo
printf '%s\n' "$PW" | ./scripts/install.sh --yes --admin-password-stdin --sensors recommended
unset PW

The second form keeps the password out of the command line and out of your shell history.

Each question has a default. Press Enter to accept it. With --yes, every question takes its default.

QuestionDefaultNotes
Install modeimagesimages or source. See images or source build.
Sensorsrecommendedrecommended is SSH, Telnet, Web, Redis, Docker and ADB. all turns on all twelve. Or type a list such as ssh,web.
How the dashboard is reachedlocall for this machine or an SSH tunnel. h for an HTTPS tunnel such as cloudflared. With h the installer asks for the public host name, for example dash.example.com.
Admin user nameadminLetters, digits, ., _ and -.
Admin passwordgenerate oneType it twice, at least 12 characters. Leave it empty to generate a 24-character password. The generated password is shown once.
Low-memory modeyes below 6 GiB, no aboveOnly asked on machines with less than 6 GiB. See low-memory hosts.
Daily update checknoOne request a day through the VPN, off by default. See updates.
WireGuard .conf fileemptyPath to the file from your VPN provider. Empty means you upload it later in the dashboard. See the VPN.
Join the SuckerPot network?yesShows what would be shared, then asks [Y/n]. Yes writes a consent record and a random pseudonym; the join waits for a VPN. --yes is a yes, --no-network is a no. See the network.
Your own public addressemptyOptional. The installer never looks it up. If you type it, it goes to INDICATORS_IGNORE, so it never shows up as attack infrastructure.
Port in usedependsAsked only when a port the chosen sensors need is already taken. See port 22.
Admin SSH portempty, or 22 when port 22 is busyThe port of this machine’s own SSH daemon. It is protected so no sensor can take it.

The installer prints one line per step, [n/10]. It stops at the first failure and says why.

  1. Check this machine. Linux, CPU, Docker, Compose, memory, disk, existing install, existing data.
  2. Settings. Asks the questions above.
  3. Check ports. Looks at the host ports of the chosen sensors and the dashboard port.
  4. Generate secrets. Every database, Redis and proxy password, the session secret and the settings encryption key. Each is at least 24 characters, and no two are equal.
  5. Hash the admin password. The password goes to a container with no network, through standard input. It never appears in a command line, an environment variable or a file.
  6. Write .env. The file is created with mode 0600. The secrets are written only to this file.
  7. Create the data volumes. The volumes are created. Existing volumes are never touched.
  8. Check the port layout and the VPN settings. The same guards that just up runs.
  9. Start the stack. Images are verified, pulled and started (or built, in source mode). The installer waits until every service is healthy.
  10. Done. Prints the dashboard address and the next steps.

A log without any secret goes to install.log in the checkout. The file is ignored by git.

FlagMeaning
--yes, -yTake the default for every question. Use --admin-password-stdin for your own password, or the password is generated.
--imagesInstall from signed release images. This is the default. Needs a release version (see --version).
--sourceBuild the images from this checkout.
--version vX.Y.ZRelease to install in images mode. Default: the tag of the checkout.
--project NAMECompose project name. Default suckerpot. Lowercase letters, digits, - and _, at most 41 characters.
--prefix NAMEPrefix of the data volumes. Default: the same as --project. Same rules.
--sensors LISTrecommended, all, or a list such as ssh,telnet,web.
--dashboard-bind ADDRIPv4 address the dashboard port binds to. Default 127.0.0.1.
--dashboard-port NHost port of the dashboard. Default 8443.
--public-host HOSTThe host name of an HTTPS tunnel, for example dash.example.com. Sets API_ALLOWED_HOSTS, API_ALLOWED_ORIGINS=https://HOST and COOKIE_SECURE=true.
--allow-lanAllow a bind on a network address with no tunnel. The dashboard then uses plain http and cookies lose Secure. Only for a network you trust. Never for the internet.
--admin-user NAMEDashboard user name. Default admin.
--admin-password-stdinRead the admin password from the first line of standard input.
--admin-ssh-port NPort of this machine’s own SSH daemon, protected from the sensors.
--lowmem auto|on|offLow-memory overlay. Default auto: asked below 6 GiB. on requires the overlay file in the checkout.
--wg-conf PATHWireGuard .conf file from your VPN provider. It is read as plain text and never run.
--skip-verifyDo not check the image signatures. Not recommended. See updates.
--dry-run --env-out PATHWrite the .env that would be made to PATH, with a placeholder hash. Makes no Docker call. Used to test the installer.
-h, --helpPrint the usage.

The installer stops before it changes anything when one of these is true.

SituationWhat to do
A .env already exists in the checkout.SuckerPot is installed here. Use just update. The installer never overwrites .env.
The checkout is a linked git worktree.Install from a normal clone.
Docker is missing or does not answer for your user.Install Docker, or run sudo usermod -aG docker $USER, then log in again.
Docker Engine is older than 24, or Compose older than 2.24.Upgrade Docker.
Less than about 2 GiB of memory.Use a bigger machine.
Less than 15 GiB free under Docker’s data folder.Free disk space.
Volumes named <prefix>_* already exist.An earlier install used this prefix. Restore your old .env, or pass another --prefix. The installer never adopts old volumes: the database password is stored inside them.
Containers of the chosen --project already exist.Pick another --project, or remove that stack yourself.
The project or prefix name is invalid, or is one of the test names (sp-it-*, sp-test, sp-ci).Pick another name.
--dashboard-bind is not 127.x.x.x, and there is no --public-host and no --allow-lan.Keep 127.0.0.1 and use an SSH tunnel, or give --public-host for an HTTPS tunnel.
The dashboard port is in use.Pass --dashboard-port with a free port.
Port 22 is in use and you chose to keep it.Move your own SSH to another port first. The installer never edits sshd_config. Then run the installer again.
The admin password is shorter than 12 characters, or the two entries differ.Enter it again.
Images mode, and no release version.Clone a release tag, or pass --version vX.Y.Z, or use --source.
--version does not look like vX.Y.Z.Fix the version.
An image signature cannot be checked.Nothing is started. See updates.
--lowmem on, but the checkout has no docker-compose.lowmem.yml.Use a current release.
The WireGuard file lacks a key or the endpoint, or its endpoint is a host name.Upload the file in the dashboard instead. Settings > VPN.
An unknown sensor name in --sensors.Use one of: ssh telnet web rdp redis docker mysql adb mssql smb sip synology.

The installer never does these things:

  • It never overwrites an existing .env.
  • It never adopts, changes or deletes an existing data volume.
  • It never edits the host’s SSH configuration.
  • It never looks up the machine’s public address.
  • It never sends any information about the install to the project.

Each sensor listens on a host port. Your router forwards the standard port of the service to that host port. The installer picks the host ports, and it shows the result on the Sensors & ports tab of Settings.

SensorSwitch in .envPort on your routerHost port variableDefault host portProtocolIn recommended
SSHSENSOR_SSH22SSH_HOST_PORT22TCPyes
TelnetSENSOR_TELNET23TELNET_HOST_PORT23TCPyes
WebSENSOR_WEB80 and 443HTTP_HOST_PORT, HTTPS_HOST_PORT80, 443TCPyes
RedisSENSOR_REDIS6379REDIS_HOST_PORT6379TCPyes
Docker APISENSOR_DOCKER2375DOCKER_HOST_PORT2375TCPyes
ADBSENSOR_ADB5555ADB_HOST_PORT5555TCPyes
RDPSENSOR_RDP3389RDP_HOST_PORT3389TCPno
MySQLSENSOR_MYSQL3306MYSQL_HOST_PORT3306TCPno
MSSQLSENSOR_MSSQL1433MSSQL_HOST_PORT1433TCPno
SMBSENSOR_SMB445SMB_HOST_PORT445TCPno
SIPSENSOR_SIP5060SIP_HOST_PORT5060UDP and TCPno
Synology DSMSENSOR_SYNOLOGY5000 and 5001SYNOLOGY_HTTP_HOST_PORT, SYNOLOGY_HTTPS_HOST_PORT5000, 5001TCPno

Rules:

  • Forward only the ports of the sensors you turned on. A sensor that is off publishes nothing.
  • Never forward the dashboard port (DASHBOARD_PORT, 8443 by default) or your own admin SSH port.
  • Do not put the machine in your router’s DMZ. A DMZ forwards every port, the dashboard’s included. See Deployment.
  • If your router’s WAN address is in 100.64.0.0/10 (carrier-grade NAT), forwarding cannot work. Ask your provider for a public address.
  • SuckerPot cannot test the forwarding from outside, and it does not try. Bots arrive within minutes. The Ports page shows Receiving once a sensor gets its first event.

Set up the host firewall too. See Deployment: host firewall.

Most hosts run their own SSH daemon on port 22. When the installer finds port 22 taken, it offers three choices:

ChoiceResult
m (map), the defaultThe SSH sensor listens on host port 2222. Your router forwards its port 22 to 2222. Your own SSH keeps port 22.
o (off)The SSH sensor stays off.
k (keep)The installer stops. Move your own SSH to another port first, then run the installer again.

With --yes, the SSH sensor is mapped to 2222 and the other sensors whose ports are busy are turned off, with a warning for each.

Each sensor has a switch, SENSOR_<NAME>, set to 1 (on) or 0 (off). Every sensor is on by default, so an install that predates the switches keeps all of them.

Terminal window
just sensors # show the current selection
just sensors ssh,telnet,web # keep only these three
just sensors recommended # SSH, Telnet, Web, Redis, Docker, ADB
just sensors all # all twelve

just sensors writes the switches to .env, checks the port layout, and then starts the stack again. A sensor set to 0 is not started, and one that was running is stopped and removed (the same applies to just set SENSOR_<NAME>=0). Check with docker compose ps.

After a change, forward the new set of ports on your router. The Ports page shows the list.

After the installer finishes, sign in as the admin user. The setup opens by itself, once per browser session, until you finish or skip it. Only the admin sees it.

StepWhat it doesCan be skipped
WelcomeExplains the three rules: a dedicated machine, no credentials on it, the dashboard never public.No
Your sensorsShows the enabled sensors and the just sensors command for your choice. The page shows the command. It never runs it.No
Open the portsThe Ports table, with a live status for each row.Yes
Anonymous egressThe VPN state, and the upload of a WireGuard file.Yes
Your own addressAsks for your own public address, so it never goes into a report or alert.Yes
Abuse reportsThe reply contact for reports. Reports are drafts you send yourself.Yes
AlertsLink to the alert channels.Yes
The SuckerPot networkReserved for a later release. It stays hidden until then.Yes
You are setThe checklist of what is left, the tour, and “Go to Today”.No

Controls:

  • Finish later keeps your place. Settings > General offers to resume.
  • Skip setup closes the setup for good.
  • Open the setup again is in Settings > General, after you skipped or finished it.

The low-memory mode lets SuckerPot run on a machine with about 2 GiB of memory, with some swap. It uses a second Compose file, docker-compose.lowmem.yml.

The installer turns it on when you say yes to the question, or with --lowmem on. It writes this line to .env:

COMPOSE_FILE=docker-compose.yml:docker-compose.lowmem.yml

Because of that line, plain docker compose and every just recipe use the smaller limits too.

What changes:

  • Memory limits of the database, Redis, ingest, the API, the analyzer, the collector and each sensor are lower.
  • The database uses smaller buffers and fewer connections.
  • Redis uses a 96 MiB ceiling (REDIS_MAXMEMORY_MB=96).
  • Each sensor is told its limit, so it sheds load before the container reaches it.

What does not change: networks, volumes, capabilities, ports and the sensor list.

Tips:

  • Add swap on the host. The low-memory mode expects it.
  • Turn off the sensors you do not need with just sensors. Each sensor costs memory.
  • Under heavy traffic, sensors refuse new connections before they run out of memory. Expect fewer captured sessions in that case.
  • To go back to the normal limits, remove the COMPOSE_FILE line from .env by hand (just set does not change it), then run just up.

Sizing targets, from the design:

MachineWhat it can run
2 GiB, low-memory modeUp to five sensors.
4 GiBAll twelve sensors, normal limits.
6 GiB or moreAll twelve sensors, with the collector and the analyzer busy.

The VPN before a WireGuard file is uploaded

Section titled “The VPN before a WireGuard file is uploaded”

The installer always turns on the egress profile (COMPOSE_PROFILES=egress). This starts three services: vpn, collector and analyzer. SuckerPot makes every outside lookup through the VPN, and the VPN is the only service with a route to the internet. See Configuration: anonymous egress.

You can finish the install before you have a VPN configuration. Then the vpn service waits in idle mode:

  • It runs no tunnel and no proxy.
  • It has no route out at all.
  • Its health check passes, so the stack still starts.
  • Every outside lookup stays closed. The dashboard shows the gate as closed.

To finish the VPN set-up, use one of these:

  • Upload the file in the dashboard. Settings > VPN. The vpn service restarts on it.
  • Pass the file to the installer. ./scripts/install.sh --wg-conf /path/to/wg0.conf. The installer reads the [Interface] and [Peer] values with a fixed parser and writes them to .env (mode 0600). The endpoint must be an IPv4 address, not a host name. Otherwise, upload the file in the dashboard.

A WireGuard configuration that is only half filled is not idle. The vpn service refuses to start the tunnel, so nothing leaves the machine. Fill in every value or remove them all.

Use a VPN provider and a configuration that you trust. The provider sees all outbound traffic of SuckerPot.

SuckerPot sends its outside lookups through the VPN. The installer and the updates are different. They use the host’s own network connection, not the VPN:

  • git clone and git fetch.
  • Image pulls from the registry, and the signature checks of updates.
  • The Docker Hub or registry pulls of the database and VPN images.

This traffic shows the host’s address to the registry and to GitHub. It is outside the anonymous egress of the stack, and it is documented here on purpose. If you want the host itself to use a proxy, configure Docker’s proxy settings for the host.

  1. Sign in and finish the setup, or skip it and come back later.
  2. Forward the ports for your sensors. See Ports to forward.
  3. Install the host firewall. See Deployment: host firewall.
  4. Take a snapshot of the machine. See Deployment: snapshot.
  5. Keep the install up to date with updates and rollback.
  6. Store the admin password in a password manager. The installer does not keep it.
SymptomWhat to do
Docker does not answer for this user.Run sudo usermod -aG docker $USER, log in again, and retry.
Data volumes named ... already exist.An earlier install used this prefix. Use the old .env, or install with --prefix set to a new name.
The stack did not become healthy.Run docker compose ps and docker compose logs --tail=100. Fix the cause, then run just up. Do not delete .env to retry: the volumes already hold the database.
The dashboard does not answer on .../healthz.Run docker compose logs api. The API may still be starting. Wait a minute, then try again.
the image signatures could not be verified.Nothing was started. Check the version name, then see image signatures.
port 22 is still in use.Move your own SSH to another port, then run the installer again. The installer never edits sshd_config.
The Ports page shows Waiting for the first connection for a long time.Check the router forwarding, the host firewall and the CGNAT note above. Bots normally arrive within minutes.