nixos/endlessh: init module
This commit is contained in:
parent
5040cb7657
commit
76ccbea152
@ -314,6 +314,13 @@
|
||||
<link linkend="opt-services.alps.enable">services.alps</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/skeeto/endlessh">endlessh</link>,
|
||||
an SSH tarpit. Available as
|
||||
<link linkend="opt-services.endlessh.enable">services.endlessh</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/shizunge/endlessh-go">endlessh-go</link>,
|
||||
|
@ -114,6 +114,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
|
||||
- [alps](https://git.sr.ht/~migadu/alps), a simple and extensible webmail. Available as [services.alps](#opt-services.alps.enable).
|
||||
|
||||
- [endlessh](https://github.com/skeeto/endlessh), an SSH tarpit. Available as [services.endlessh](#opt-services.endlessh.enable).
|
||||
|
||||
- [endlessh-go](https://github.com/shizunge/endlessh-go), an SSH tarpit that exposes Prometheus metrics. Available as [services.endlessh-go](#opt-services.endlessh-go.enable).
|
||||
|
||||
- [netbird](https://netbird.io), a zero configuration VPN.
|
||||
|
@ -1009,6 +1009,7 @@
|
||||
./services/security/certmgr.nix
|
||||
./services/security/cfssl.nix
|
||||
./services/security/clamav.nix
|
||||
./services/security/endlessh.nix
|
||||
./services/security/endlessh-go.nix
|
||||
./services/security/fail2ban.nix
|
||||
./services/security/fprintd.nix
|
||||
|
99
nixos/modules/services/security/endlessh.nix
Normal file
99
nixos/modules/services/security/endlessh.nix
Normal file
@ -0,0 +1,99 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.endlessh;
|
||||
in
|
||||
{
|
||||
options.services.endlessh = {
|
||||
enable = mkEnableOption (mdDoc "endlessh service");
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 2222;
|
||||
example = 22;
|
||||
description = mdDoc ''
|
||||
Specifies on which port the endlessh daemon listens for SSH
|
||||
connections.
|
||||
|
||||
Setting this to `22` may conflict with {option}`services.openssh`.
|
||||
'';
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = with types; listOf str;
|
||||
default = [ ];
|
||||
example = [ "-6" "-d 9000" "-v" ];
|
||||
description = mdDoc ''
|
||||
Additional command line options to pass to the endlessh daemon.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Whether to open a firewall port for the SSH listener.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.endlessh = {
|
||||
description = "SSH tarpit";
|
||||
requires = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig =
|
||||
let
|
||||
needsPrivileges = cfg.port < 1024;
|
||||
capabilities = [ "" ] ++ optionals needsPrivileges [ "CAP_NET_BIND_SERVICE" ];
|
||||
rootDirectory = "/run/endlessh";
|
||||
in
|
||||
{
|
||||
Restart = "always";
|
||||
ExecStart = with cfg; concatStringsSep " " ([
|
||||
"${pkgs.endlessh}/bin/endlessh"
|
||||
"-p ${toString port}"
|
||||
] ++ extraOptions);
|
||||
DynamicUser = true;
|
||||
RootDirectory = rootDirectory;
|
||||
BindReadOnlyPaths = [ builtins.storeDir ];
|
||||
InaccessiblePaths = [ "-+${rootDirectory}" ];
|
||||
RuntimeDirectory = baseNameOf rootDirectory;
|
||||
RuntimeDirectoryMode = "700";
|
||||
AmbientCapabilities = capabilities;
|
||||
CapabilityBoundingSet = capabilities;
|
||||
UMask = "0077";
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = !needsPrivileges;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectProc = "noaccess";
|
||||
ProcSubset = "pid";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [ "@system-service" "~@resources" "~@privileged" ];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = with cfg;
|
||||
optionals openFirewall [ port ];
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ azahi ];
|
||||
}
|
@ -180,6 +180,7 @@ in {
|
||||
ejabberd = handleTest ./xmpp/ejabberd.nix {};
|
||||
elk = handleTestOn ["x86_64-linux"] ./elk.nix {};
|
||||
emacs-daemon = handleTest ./emacs-daemon.nix {};
|
||||
endlessh = handleTest ./endlessh.nix {};
|
||||
endlessh-go = handleTest ./endlessh-go.nix {};
|
||||
engelsystem = handleTest ./engelsystem.nix {};
|
||||
enlightenment = handleTest ./enlightenment.nix {};
|
||||
|
43
nixos/tests/endlessh.nix
Normal file
43
nixos/tests/endlessh.nix
Normal file
@ -0,0 +1,43 @@
|
||||
import ./make-test-python.nix ({ lib, pkgs, ... }:
|
||||
{
|
||||
name = "endlessh";
|
||||
meta.maintainers = with lib.maintainers; [ azahi ];
|
||||
|
||||
nodes = {
|
||||
server = { ... }: {
|
||||
services.endlessh = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
specialisation = {
|
||||
unprivileged.configuration.services.endlessh.port = 2222;
|
||||
|
||||
privileged.configuration.services.endlessh.port = 22;
|
||||
};
|
||||
};
|
||||
|
||||
client = { pkgs, ... }: {
|
||||
environment.systemPackages = with pkgs; [ curl netcat ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
def activate_specialisation(name: str):
|
||||
server.succeed(f"/run/booted-system/specialisation/{name}/bin/switch-to-configuration test >&2")
|
||||
|
||||
start_all()
|
||||
|
||||
with subtest("Unprivileged"):
|
||||
activate_specialisation("unprivileged")
|
||||
server.wait_for_unit("endlessh.service")
|
||||
server.wait_for_open_port(2222)
|
||||
client.succeed("nc -dvW5 server 2222")
|
||||
|
||||
with subtest("Privileged"):
|
||||
activate_specialisation("privileged")
|
||||
server.wait_for_unit("endlessh.service")
|
||||
server.wait_for_open_port(22)
|
||||
client.succeed("nc -dvW5 server 22")
|
||||
'';
|
||||
})
|
@ -1,4 +1,10 @@
|
||||
{ lib, stdenv, fetchFromGitHub }:
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitHub
|
||||
, testers
|
||||
, endlessh
|
||||
, nixosTests
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "endlessh";
|
||||
@ -8,17 +14,25 @@ stdenv.mkDerivation rec {
|
||||
owner = "skeeto";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "0ziwr8j1frsp3dajr8h5glkm1dn5cci404kazz5w1jfrp0736x68";
|
||||
hash = "sha256-yHQzDrjZycDL/2oSQCJjxbZQJ30FoixVG1dnFyTKPH4=";
|
||||
};
|
||||
|
||||
makeFlags = [ "PREFIX=$(out)" ];
|
||||
|
||||
passthru.tests = {
|
||||
inherit (nixosTests) endlessh;
|
||||
version = testers.testVersion {
|
||||
package = endlessh;
|
||||
command = "endlessh -V";
|
||||
};
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "SSH tarpit that slowly sends an endless banner";
|
||||
homepage = "https://github.com/skeeto/endlessh";
|
||||
changelog = "https://github.com/skeeto/endlessh/releases/tag/${version}";
|
||||
license = licenses.unlicense;
|
||||
maintainers = [ maintainers.marsam ];
|
||||
maintainers = with maintainers; [ azahi marsam ];
|
||||
platforms = platforms.unix;
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user