Contents
Your feedback on how you use SSHGuard, what you like, and what annoys you, helps us improve SSHGuard.
SSHGuard consists of a pipeline of programs that work together, depicted in doc/sshguard.dot.
In this diagram, processes shown with a dashed border are sandboxed, if sandboxing support is implemented for the OS in sandbox_init(). Currently, sandboxing is only implemented on FreeBSD with Capsicum and on OpenBSD with pledge().
sshguard reads the configuration file and spawns a pipeline.
sshg-logtail monitors one or more log files, aggregates them, and pipes their contents to the next stage.
sshg-parser reads its input and looks for attacks. If it finds an attack, it reports the service, remote address, address type (IPv4 or IPv6), and score ("dangerousness") to the next stage. The format is defined in print_attack() (src/parser/parser.c). This is the only program you need to change to add new signatures.
sshg-blocker maintains a list of recent attackers. If there are enough attacks from an attacker in a given time interval, it commands the firewall backend to block the attacker's address. After a certain amount of time, sshg-blocker is also responsible for unblocking an attacker, or blacklisting if configured to do so.
sshg-fw-* is one of several firewall backends. It reads firewall commands from its input and runs the appropriate system commands to do the firewall.
Files to change:
If you are adding a new service, changes are also needed in:
sshg-blocker sends line-delimited commands to a firewall backend through a pipe, which does the actual work of blocking and releasing addresses using the underlying firewall. The firewall backend must support these commands:
block ADDR KIND SUBNET_SIZE (fw_block() in blocklist.c). This command blocks an IP address block given in CIDR notation as ADDR/SUBNET_SIZE which is either IPv4 if KIND is '4' or IPv6 if KIND is '6'. As is the case with CIDR notation, a SUBNET_SIZE of 32 indicates that only one IP address must be blocked.
Since the firewall backend likely runs with elevated permissions, implementations should validate their inputs.
At its option, an implementation may gather several block commands to issue to the underlying backend at once to reduce overhead.
release ADDR KIND SUBNET_SIZE (fw_release() in blocklist.c). This command undoes the block command, taking the same arguments. The backend may assume that a release command is never issued without a corresponding block command.
If block addresses overlap, it is up to the implementation to decide when to allow access through the firewall. For example, if both 1.2.3.4/32 and 1.2.3.0/24 were blocked, in that order, and 1.2.3.4/32 was released, the firewall backend may continue to block 1.2.3.4 until both are released, or may unblock it immediately.
flushonexit (main() in blocker.c). This command instructs the backend to release all blocked addresses when the backend exits. sshg-blocker will usually issue this command before any others. Implementations should release all blocked addresses, including those that do not have a corresponding block command (for example, blocks from a previous invocation).
We welcome your patches through:
An explanation of workflow states that aren't self-explanatory:
Before release, make sure that:
Then: