Skip to content

Commit 21b58b9

Browse files
committed
Split the daemon into network and firewall part
1 parent b1b83ab commit 21b58b9

32 files changed

+1790
-116
lines changed

Cargo.lock

Lines changed: 53 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
members = [
55
"letmein",
66
"letmein-conf",
7+
"letmein-fwproto",
78
"letmein-proto",
9+
"letmein-seccomp",
810
"letmein-systemd",
911
"letmeind",
12+
"letmeinfwd",
1013
]
1114
resolver = "2"
1215

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

2528
[workspace.dependencies]
2629
anyhow = "1"
30+
autocfg = "1"
2731
clap = "4"
2832
getrandom = "0.2"
2933
hickory-proto = "0.24"
@@ -32,12 +36,16 @@ hmac = "0.12"
3236
libc = "0.2"
3337
nftables = "0.4"
3438
sd-notify = "0.4"
39+
seccompiler = "0.4"
3540
sha3 = "0.10"
3641
subtle = "2"
3742
tokio = "1"
43+
user_lookup = { version = "0.3", default-features = false }
3844

3945
letmein-conf = { version = "2", path = "./letmein-conf" }
46+
letmein-fwproto = { version = "2", path = "./letmein-fwproto" }
4047
letmein-proto = { version = "2", path = "./letmein-proto" }
48+
letmein-seccomp = { version = "2", path = "./letmein-seccomp" }
4149
letmein-systemd = { version = "2", path = "./letmein-systemd" }
4250

4351
[profile.release]

README.md

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -138,43 +138,46 @@ After installing all build prerequisites, run the build script:
138138

139139
## Installing letmein
140140

141-
### Install server
141+
### Install client
142142

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

145145
```sh
146-
./install-server.sh
146+
./install-client.sh
147147
```
148148

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

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

154-
### Install client
153+
#### Prepare user and group for the server
155154

156-
Then run the `install-client.sh` to install the letmein client to `/opt/letmein/`:
155+
The public network facing part of the letmein server runs with reduced privileges to reduce the attack surface.
156+
157+
For this to work, the user `letmeind` and the group `letmeind` have to be present in `/etc/passwd` and `/etc/group`.
158+
It is recommended for this user to not have a shell and home assigned and therefore not be a login-user.
159+
160+
You can use the following helper script to create the user and group in your system:
157161

158162
```sh
159-
./install-client.sh
163+
./create-user.sh
160164
```
161165

162-
The client is used to send a knock packet to the server.
166+
#### Install the server and systemd units
163167

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

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

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

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

172179
## Platform support
173180

174-
### Server
175-
176-
The server application `letmeind` is Linux-only, because it only supports `nftables` as firewall backend.
177-
178181
### Client
179182

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

191+
### Server
192+
193+
The server application `letmeind` is Linux-only, because it only supports `nftables` as firewall backend.
194+
195+
## Security notice: User identifiers and resource identifiers
196+
197+
Please be aware that the user identifiers and resource identifiers from the configuration files are transmitted over the network without encryption in clear text.
198+
199+
Make sure the user identifiers and resource identifiers do **not** include any private information.
200+
201+
These identifiers are merely meant to be an abstract identification for managing different `letmein` keys, installations and setups.
202+
188203
## Internals and design goals
189204

190205
The main design goals of letmein are:

build.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ cargo auditable build --release || die "Cargo build (release) failed."
5353
cargo audit bin --deny warnings \
5454
target/release/letmein \
5555
target/release/letmeind \
56+
target/release/letmeinfwd \
5657
|| die "Cargo audit failed."
5758
check_dynlibs target/release/letmein
5859
check_dynlibs target/release/letmeind
60+
check_dynlibs target/release/letmeinfwd
5961

6062
# vim: ts=4 sw=4 expandtab

create-user.sh

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/bin/sh
2+
# -*- coding: utf-8 -*-
3+
4+
info()
5+
{
6+
echo "--- $*"
7+
}
8+
9+
error()
10+
{
11+
echo "=== ERROR: $*" >&2
12+
}
13+
14+
warning()
15+
{
16+
echo "=== WARNING: $*" >&2
17+
}
18+
19+
die()
20+
{
21+
error "$*"
22+
exit 1
23+
}
24+
25+
entry_checks()
26+
{
27+
[ "$(id -u)" = "0" ] || die "Must be root to create users."
28+
}
29+
30+
sys_groupadd()
31+
{
32+
local args="--system"
33+
info "groupadd $args $*"
34+
groupadd $args "$@" || die "Failed groupadd"
35+
}
36+
37+
sys_useradd()
38+
{
39+
local args="--system -s /usr/sbin/nologin -d /nonexistent -M -N"
40+
info "useradd $args $*"
41+
useradd $args "$@" || die "Failed useradd"
42+
}
43+
44+
do_usermod()
45+
{
46+
info "usermod $*"
47+
usermod "$@" || die "Failed usermod"
48+
}
49+
50+
stop_daemons()
51+
{
52+
systemctl stop letmeind.socket >/dev/null 2>&1
53+
systemctl stop letmeind.service >/dev/null 2>&1
54+
systemctl stop letmeinfwd.socket >/dev/null 2>&1
55+
systemctl stop letmeinfwd.service >/dev/null 2>&1
56+
}
57+
58+
remove_users()
59+
{
60+
# Delete all existing users and groups, if any.
61+
userdel letmeind >/dev/null 2>&1
62+
groupdel letmeind >/dev/null 2>&1
63+
}
64+
65+
add_users()
66+
{
67+
sys_groupadd letmeind
68+
sys_useradd -g letmeind letmeind
69+
}
70+
71+
entry_checks
72+
stop_daemons
73+
remove_users
74+
add_users
75+
76+
# vim: ts=4 sw=4 expandtab

0 commit comments

Comments
 (0)