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

Create Debian package for beszel-agent #497

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Daniel15
Copy link

@Daniel15 Daniel15 commented Jan 26, 2025

Adds a Debian package to the build. Currently, only beszel-agent is packaged, but a package for beszel-hub could be added too. Since the SSH key is a required configuration option, the package prompts for it during installation.

This is the first step. The next step would be to set up a Debian repo for the packages.

Test Plan

Run the build:

goreleaser release --snapshot --clean

This produces four .deb files in the dist directory, for amd64, arm64, armv6, riscv64, and mips64_hardfloat (architectures were already configured in the goreleaser config)

Create a new Debian VM
Install package:

cd /tmp
wget https://d.ls/debian/beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_amd64.deb
sudo apt install ./beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_amd64.deb

Output:

daniel@debtest:/tmp$ wget https://d.ls/debian/beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_amd64.deb
--2025-01-26 15:08:18--  https://d.ls/debian/beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_amd64.deb
Resolving d.ls (d.ls)... 185.197.30.201, 2a04:bdc7:100:ed8a::1
Connecting to d.ls (d.ls)|185.197.30.201|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3150376 (3.0M) [application/octet-stream]
Saving to: ‘beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_amd64.deb’

beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_am 100%[=============================================================================================>]   3.00M  --.-KB/s    in 0.1s    

2025-01-26 15:08:19 (23.5 MB/s) - ‘beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_amd64.deb’ saved [3150376/3150376]

daniel@debtest:/tmp$ sudo apt install ./beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_amd64.deb 
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Note, selecting 'beszel-agent' instead of './beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_amd64.deb'
The following NEW packages will be installed:
  beszel-agent
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/3,150 kB of archives.
After this operation, 7,303 kB of additional disk space will be used.
Get:1 /tmp/beszel-agent_0.9.1-SNAPSHOT-e3aea63_linux_amd64.deb beszel-agent amd64 0.9.1~SNAPSHOT-e3aea63 [3,150 kB]
Preconfiguring packages ...
Selecting previously unselected package beszel-agent.
(Reading database ... 26393 files and directories currently installed.)
Preparing to unpack .../beszel-agent_0.9.1-SNAPSHOT-1747b00_linux_amd64.deb ...
Unpacking beszel-agent (0.9.1~SNAPSHOT-1747b00) ...
Setting up beszel-agent (0.9.1~SNAPSHOT-1747b00) ...
Creating beszel group
Creating beszel user
Created symlink /etc/systemd/system/multi-user.target.wants/beszel-agent.service → /lib/systemd/system/beszel-agent.service.

During the installation, it prompts for the SSH key:
image

Verify key is written to /etc/beszel-agent.conf:

daniel@debtest:/tmp$ sudo cat /etc/beszel-agent.conf 
KEY=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMiXhkOoriWaBgKbXa8/DTAR91nvRoi42AjRmTu1gsTG

Verify systemd unit is enabled and automatically started after installation:

daniel@debtest:/tmp$ sudo service beszel-agent status
● beszel-agent.service - Beszel Agent Service
     Loaded: loaded (/lib/systemd/system/beszel-agent.service; disabled; preset: enabled)
     Active: active (running) since Sun 2025-01-26 15:08:55 PST; 5min ago
   Main PID: 3982 (beszel-agent)
      Tasks: 6 (limit: 2315)
     Memory: 6.9M
        CPU: 79ms
     CGroup: /system.slice/beszel-agent.service
             └─3982 /usr/bin/beszel-agent

Jan 26 15:08:55 debtest systemd[1]: Started beszel-agent.service - Beszel Agent Service.
Jan 26 15:08:55 debtest beszel-agent[3982]: 2025/01/26 15:08:55 INFO Detected root device name=vda1
Jan 26 15:08:55 debtest beszel-agent[3982]: 2025/01/26 15:08:55 INFO Detected network interface name=enp1s0 sent=292698 recv=16869221
Jan 26 15:08:55 debtest beszel-agent[3982]: 2025/01/26 15:08:55 INFO Starting SSH server address=:45876

Verify connecting to it from Beszel Hub works:
image

Signed-off-by: Daniel Lo Nigro <[email protected]>
@Daniel15 Daniel15 marked this pull request as draft January 26, 2025 23:20
@Daniel15 Daniel15 changed the title Add Debian package to build Create Debian package for beszel-agent Jan 26, 2025
Signed-off-by: Daniel Lo Nigro <[email protected]>
@Daniel15 Daniel15 marked this pull request as ready for review January 26, 2025 23:51
Restart=on-failure
# TODO: See if we can apply more security hardening here
# TODO: Audit using `systemd-analyze security beszel-agent.service`
ProtectSystem=yes
Copy link
Author

@Daniel15 Daniel15 Jan 26, 2025

Choose a reason for hiding this comment

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

These changes ( + whatever other security hardening options can be added) would be good to include in systemd unit in the install script too.

Copy link
Owner

Choose a reason for hiding this comment

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

Great idea, I'll look over the other options.

Copy link
Author

Choose a reason for hiding this comment

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

@henrygd I ran systemd-analyze security beszel-agent.service but got overwhelmed at the number of different things it outputs. Maybe there's one flag we can set that sets all the standard security options. I'm not too familiar with these features of systemd.


[Service]
Environment="PORT=45876"
EnvironmentFile=/etc/beszel-agent.conf
Copy link
Author

Choose a reason for hiding this comment

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

Install script should probably do it this way too - store user-configured config environment variables in a separate file rather than directly in the systemd unit.

Copy link
Owner

Choose a reason for hiding this comment

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

Agree, made a note to change this.

@henrygd
Copy link
Owner

henrygd commented Jan 27, 2025

Beautiful, thank you!

Looks great, let me try it out tomorrow.

@@ -0,0 +1,11 @@
# No changelog in the repo at the moment. This would be good to fix
Copy link
Author

Choose a reason for hiding this comment

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

This file has a list of Lintian rules that are currently failing.

beszel-agent: no-debconf-config
beszel-agent: postinst-uses-db-input
# Needs to be fixed in Beszel build
beszel-agent: hardening-no-pie
Copy link
Author

@Daniel15 Daniel15 Jan 27, 2025

Choose a reason for hiding this comment

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

From https://lintian.debian.org/tags/hardening-no-pie.html:

This package provides an ELF executable that was not compiled as a position independent executable (PIE). PIE is required for fully enabling Address Space Layout Randomization (ASLR), which makes "Return-oriented" attacks more difficult.

I don't know Go, so I'm not sure how to fix this or if it'd break anything.

Copy link
Owner

Choose a reason for hiding this comment

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

Never ran into this before but it's probably some build flag that it needs. I'll look into it.

@henrygd
Copy link
Owner

henrygd commented Jan 28, 2025

Ran out of time to look at this tonight but I'll try to finish up tomorrow if possible.

Worked nicely in an Ubuntu VM. I did notice that neither apt remove or apt purge actually stopped the running service. I assume we need to do that in the uninstall script?

After going through the security options I think these should be fine to set for the time being. And then probably add RuntimeDirectory=beszel/beszel-agent to leave us the potential to write to /run/beszel/ in the future if we add a sqlite database or something.

KeyringMode=private
LockPersonality=yes
NoNewPrivileges=yes
PrivateTmp=yes
ProtectClock=yes
ProtectHome=read-only
ProtectHostname=yes
ProtectKernel=yes
ProtectKernelLogs=yes
ProtectKernelTunables=yes
ProtectSystem=strict
ReadWritePaths=/run
RemoveIPC=yes
RestrictSUIDSGID=true
SystemCallArchitectures=native

I think the hardening-no-pie thing is specific to the riscv build, as riscv apparently requires external linking with Cgo to use -buildmode=pie. The only way around that is to compile directly on riscv, which isn't possible.

I'd like to just exclude riscv and mips from the deb builds, but there doesn't seem to be a way to do that without a monthly subscription to GoReleaser Pro. 🤷

@Daniel15
Copy link
Author

Daniel15 commented Jan 28, 2025 via email

@henrygd
Copy link
Owner

henrygd commented Jan 29, 2025

True, looks like StateDirectory is the best option as it creates a directory in /var/lib.

KeyringMode=private
LockPersonality=yes
NoNewPrivileges=yes
PrivateTmp=yes
ProtectClock=yes
ProtectHome=read-only
ProtectHostname=yes
ProtectKernel=yes
ProtectKernelLogs=yes
ProtectKernelTunables=yes
ProtectSystem=strict
RemoveIPC=yes
RestrictSUIDSGID=true
StateDirectory=beszel-agent
SystemCallArchitectures=native

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants