Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for socket activation #40

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions endlessh.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <time.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <limits.h>
#include <signal.h>
Expand Down Expand Up @@ -311,6 +312,7 @@ struct config {
.bind_family = DEFAULT_BIND_FAMILY, \
}

static bool port_set = false;
static void
config_set_port(struct config *c, const char *s, int hardfail)
{
Expand All @@ -324,6 +326,7 @@ config_set_port(struct config *c, const char *s, int hardfail)
} else {
c->port = tmp;
}
port_set = true;
}

static void
Expand Down Expand Up @@ -525,6 +528,7 @@ usage(FILE *f)
fprintf(f, " -f Set and load config file ["
DEFAULT_CONFIG_FILE "]\n");
fprintf(f, " -h Print this help message and exit\n");
fprintf(f, " -i Expect an existing socket on stdin.\n");
fprintf(f, " -l INT Maximum banner line length (3-255) ["
XSTR(DEFAULT_MAX_LINE_LENGTH) "]\n");
fprintf(f, " -m INT Maximum number of clients ["
Expand Down Expand Up @@ -640,8 +644,9 @@ main(int argc, char **argv)

config_load(&config, config_file, 1);

bool listen_on_stdin = false;
int option;
while ((option = getopt(argc, argv, "46d:f:hl:m:p:svV")) != -1) {
while ((option = getopt(argc, argv, "46d:f:hil:m:p:svV")) != -1) {
switch (option) {
case '4':
config_set_bind_family(&config, "4", 1);
Expand All @@ -667,6 +672,9 @@ main(int argc, char **argv)
usage(stdout);
exit(EXIT_SUCCESS);
break;
case 'i':
listen_on_stdin = true;
break;
case 'l':
config_set_max_line_length(&config, optarg, 1);
break;
Expand Down Expand Up @@ -698,6 +706,12 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}

if (listen_on_stdin && port_set) {
fprintf(stderr, "endlessh: Cannot specify a port "
"when listening on stdin (-i)\n");
exit(EXIT_FAILURE);
}

if (logmsg == logsyslog) {
/* Prepare the syslog */
const char *prog = strrchr(argv[0], '/');
Expand Down Expand Up @@ -737,7 +751,12 @@ main(int argc, char **argv)

unsigned long rng = epochms();

int server = server_create(config.port, config.bind_family);
int server;
if(listen_on_stdin) {
server = STDIN_FILENO;
} else {
server = server_create(config.port, config.bind_family);
}

while (running) {
if (reload) {
Expand All @@ -746,9 +765,11 @@ main(int argc, char **argv)
int oldfamily = config.bind_family;
config_load(&config, config_file, 0);
config_log(&config);
if (oldport != config.port || oldfamily != config.bind_family) {
close(server);
server = server_create(config.port, config.bind_family);
if(!listen_on_stdin) {
if (oldport != config.port || oldfamily != config.bind_family) {
close(server);
server = server_create(config.port, config.bind_family);
}
}
reload = 0;
}
Expand Down
45 changes: 45 additions & 0 deletions util/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[Unit]
Description=Endlessh SSH Tarpit
Documentation=man:endlessh(1)
Requires=network-online.target

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw the only thing you need to have systemctl start endlessh@2222 work is Requires=endlessh@%i.socket here -- systemd will automatically pull the socket in then.


[Service]
Type=simple
Restart=always
RestartSec=30sec
ExecStart=/usr/local/bin/endlessh -i
KillSignal=SIGTERM
DynamicUser=true

# Stop trying to restart the service if it restarts too many times in a row
StartLimitInterval=5min
StartLimitBurst=4

StandardOutput=journal
StandardError=journal
StandardInput=socket

PrivateTmp=true
PrivateDevices=true
PrivateNetwork=true
ProtectSystem=full
ProtectHome=true
InaccessiblePaths=/run /var
PrivateUsers=true
NoNewPrivileges=true
ConfigurationDirectory=endlessh
ProtectKernelLogs=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictNamespaces=true
RestrictRealtime=true

LockPersonality=true
MemoryDenyWriteExecute=true
SystemCallArchitectures=native
SystemCallFilter=@basic-io @file-system @io-event @network-io @signal
SystemCallFilter=arch_prctl brk mprotect ~socket

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw my version of systemd (v245.4) complains about ~socket: /etc/systemd/system/[email protected]:42: Failed to parse system call, ignoring: ~socket

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, thanks for catching this; looks like I cannot combine whitelist and blacklist in this way >_>'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can, but the ~ operator applies per line, not per whitespace-separated item. This should work better:

SystemCallFilter=@basic-io @file-system @io-event @network-io @signal
SystemCallFilter=arch_prctl brk mprotect
SystemCallFilter=~socket

(Many services shipped by systemd start with an allowlist and then add SystemCallFilter=~@privileged to filter out privileged syscalls again, for instance.)


[Install]
WantedBy=multi-user.target
9 changes: 9 additions & 0 deletions util/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Unit]
Description=Endlessh SSH Tarpit socket
Documentation=man:endlessh(1)

[Socket]
ListenStream=%i

[Install]
WantedBy=sockets.target