Skip to content

Commit

Permalink
Split the daemon into network and firewall part
Browse files Browse the repository at this point in the history
  • Loading branch information
mbuesch committed Jul 27, 2024
1 parent b1b83ab commit b4ec1e5
Show file tree
Hide file tree
Showing 32 changed files with 1,798 additions and 118 deletions.
50 changes: 50 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
members = [
"letmein",
"letmein-conf",
"letmein-fwproto",
"letmein-proto",
"letmein-seccomp",
"letmein-systemd",
"letmeind",
"letmeinfwd",
]
resolver = "2"

Expand All @@ -24,6 +27,7 @@ keywords = [ "port-knocking", "port", "knock", "firewall", "nftables" ]

[workspace.dependencies]
anyhow = "1"
autocfg = "1"
clap = "4"
getrandom = "0.2"
hickory-proto = "0.24"
Expand All @@ -32,12 +36,16 @@ hmac = "0.12"
libc = "0.2"
nftables = "0.4"
sd-notify = "0.4"
seccompiler = "0.4"
sha3 = "0.10"
subtle = "2"
tokio = "1"
user_lookup = { version = "0.3", default-features = false }

letmein-conf = { version = "2", path = "./letmein-conf" }
letmein-fwproto = { version = "2", path = "./letmein-fwproto" }
letmein-proto = { version = "2", path = "./letmein-proto" }
letmein-seccomp = { version = "2", path = "./letmein-seccomp" }
letmein-systemd = { version = "2", path = "./letmein-systemd" }

[profile.release]
Expand Down
51 changes: 33 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,43 +138,46 @@ After installing all build prerequisites, run the build script:

## Installing letmein

### Install server
### Install client

After building, run the `install-server.sh` to install the letmeind server to `/opt/letmein/`:
Then run the `install-client.sh` to install the letmein client to `/opt/letmein/`:

```sh
./install-server.sh
./install-client.sh
```

Installing the server will also install the service and socket into systemd and start the letmeind server.
The client is used to send a knock packet to the server.

The server is used to receive knock packets from the client.
Upon successful knock authentication, the server will open the knocked port in its `nftables` firewall.
### Install server

### Install client
#### Prepare user and group for the server

Then run the `install-client.sh` to install the letmein client to `/opt/letmein/`:
The public network facing part of the letmein server runs with reduced privileges to reduce the attack surface.

For this to work, the user `letmeind` and the group `letmeind` have to be present in `/etc/passwd` and `/etc/group`.
It is recommended for this user to not have a shell and home assigned and therefore not be a login-user.

You can use the following helper script to create the user and group in your system:

```sh
./install-client.sh
./create-user.sh
```

The client is used to send a knock packet to the server.
#### Install the server and systemd units

## Security notice: User identifiers and resource identifiers
After building and creating the `letmeind` system user, run the `install-server.sh` to install the letmeind server to `/opt/letmein/`:

Please be aware that the user identifiers and resource identifiers from the configuration files are transmitted over the network without encryption in clear text.
```sh
./install-server.sh
```

Make sure the user identifiers and resource identifiers do **not** include any private information.
Installing the server will also install the service and socket into systemd and start the letmeind server.

These identifiers are merely meant to be an abstract identification for managing different `letmein` keys, installations and setups.
The server is used to receive knock packets from the client.
Upon successful knock authentication, the server will open the knocked port in its `nftables` firewall.

## Platform support

### Server

The server application `letmeind` is Linux-only, because it only supports `nftables` as firewall backend.

### Client

The client application `letmein` is portable and should run on all major platforms.
Expand All @@ -185,6 +188,18 @@ Tested platforms are:
- Windows
- MacOS (build tested only)

### Server

The server application `letmeind` is Linux-only, because it only supports `nftables` as firewall backend.

## Security notice: User identifiers and resource identifiers

Please be aware that the user identifiers and resource identifiers from the configuration files are transmitted over the network without encryption in clear text.

Make sure the user identifiers and resource identifiers do **not** include any private information.

These identifiers are merely meant to be an abstract identification for managing different `letmein` keys, installations and setups.

## Internals and design goals

The main design goals of letmein are:
Expand Down
2 changes: 2 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ cargo auditable build --release || die "Cargo build (release) failed."
cargo audit bin --deny warnings \
target/release/letmein \
target/release/letmeind \
target/release/letmeinfwd \
|| die "Cargo audit failed."
check_dynlibs target/release/letmein
check_dynlibs target/release/letmeind
check_dynlibs target/release/letmeinfwd

# vim: ts=4 sw=4 expandtab
76 changes: 76 additions & 0 deletions create-user.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/sh
# -*- coding: utf-8 -*-

info()
{
echo "--- $*"
}

error()
{
echo "=== ERROR: $*" >&2
}

warning()
{
echo "=== WARNING: $*" >&2
}

die()
{
error "$*"
exit 1
}

entry_checks()
{
[ "$(id -u)" = "0" ] || die "Must be root to create users."
}

sys_groupadd()
{
local args="--system"
info "groupadd $args $*"
groupadd $args "$@" || die "Failed groupadd"
}

sys_useradd()
{
local args="--system -s /usr/sbin/nologin -d /nonexistent -M -N"
info "useradd $args $*"
useradd $args "$@" || die "Failed useradd"
}

do_usermod()
{
info "usermod $*"
usermod "$@" || die "Failed usermod"
}

stop_daemons()
{
systemctl stop letmeind.socket >/dev/null 2>&1
systemctl stop letmeind.service >/dev/null 2>&1
systemctl stop letmeinfwd.socket >/dev/null 2>&1
systemctl stop letmeinfwd.service >/dev/null 2>&1
}

remove_users()
{
# Delete all existing users and groups, if any.
userdel letmeind >/dev/null 2>&1
groupdel letmeind >/dev/null 2>&1
}

add_users()
{
sys_groupadd letmeind
sys_useradd -g letmeind letmeind
}

entry_checks
stop_daemons
remove_users
add_users

# vim: ts=4 sw=4 expandtab
Loading

0 comments on commit b4ec1e5

Please sign in to comment.