Add cross-compilation, Linux binary build, and systemd service installer
- Dockerfile.cross: builds static x86_64 musl binary from macOS via Docker - scripts/build-linux.sh: one-command cross-compilation - scripts/install-service.sh: systemd service with security hardening - Bump Rust Docker images to 1.86 for edition2024 support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/target
|
||||
/dist
|
||||
btest_original
|
||||
.claude/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Stage 1: Build
|
||||
FROM rust:1.82-slim AS builder
|
||||
FROM rust:1.86-slim AS builder
|
||||
|
||||
WORKDIR /build
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
|
||||
17
Dockerfile.cross
Normal file
17
Dockerfile.cross
Normal file
@@ -0,0 +1,17 @@
|
||||
# Cross-compile for x86_64 Linux using an x86_64 builder (emulated via QEMU on ARM hosts)
|
||||
FROM --platform=linux/amd64 rust:1.86-slim AS builder
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
musl-tools \
|
||||
&& rustup target add x86_64-unknown-linux-musl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /build
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY src/ src/
|
||||
|
||||
RUN cargo build --release --target x86_64-unknown-linux-musl
|
||||
|
||||
# Extract the binary
|
||||
FROM scratch AS export
|
||||
COPY --from=builder /build/target/x86_64-unknown-linux-musl/release/btest /btest
|
||||
17
scripts/build-linux.sh
Executable file
17
scripts/build-linux.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build a static x86_64 Linux binary using Docker (works from macOS)
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
echo "=== Building x86_64 Linux binary via Docker ==="
|
||||
DOCKER_BUILDKIT=1 docker build \
|
||||
-f Dockerfile.cross \
|
||||
--output type=local,dest=./dist \
|
||||
.
|
||||
|
||||
ls -lh dist/btest
|
||||
file dist/btest
|
||||
echo ""
|
||||
echo "Binary ready at: dist/btest"
|
||||
echo "Copy to your server: scp dist/btest user@server:/usr/local/bin/btest"
|
||||
121
scripts/install-service.sh
Executable file
121
scripts/install-service.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install btest as a systemd service on Linux
|
||||
# Usage: sudo ./install-service.sh [--auth-user USER --auth-pass PASS] [--port PORT]
|
||||
set -euo pipefail
|
||||
|
||||
BTEST_BIN="/usr/local/bin/btest"
|
||||
BTEST_USER="btest"
|
||||
BTEST_PORT="2000"
|
||||
AUTH_USER=""
|
||||
AUTH_PASS=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--auth-user) AUTH_USER="$2"; shift 2 ;;
|
||||
--auth-pass) AUTH_PASS="$2"; shift 2 ;;
|
||||
--port) BTEST_PORT="$2"; shift 2 ;;
|
||||
--help|-h)
|
||||
echo "Usage: sudo $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --auth-user USER Authentication username"
|
||||
echo " --auth-pass PASS Authentication password"
|
||||
echo " --port PORT Listen port (default: 2000)"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " sudo $0"
|
||||
echo " sudo $0 --auth-user admin --auth-pass secret"
|
||||
echo " sudo $0 --port 2000 --auth-user admin --auth-pass mypass"
|
||||
exit 0
|
||||
;;
|
||||
*) echo "Unknown option: $1"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Error: This script must be run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check binary exists
|
||||
if [[ ! -f "$BTEST_BIN" ]]; then
|
||||
# Try to find it in current directory or dist/
|
||||
if [[ -f "./btest" ]]; then
|
||||
cp ./btest "$BTEST_BIN"
|
||||
elif [[ -f "./dist/btest" ]]; then
|
||||
cp ./dist/btest "$BTEST_BIN"
|
||||
else
|
||||
echo "Error: btest binary not found. Copy it to $BTEST_BIN first."
|
||||
echo " scp dist/btest root@server:/usr/local/bin/btest"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
chmod +x "$BTEST_BIN"
|
||||
|
||||
# Create service user
|
||||
if ! id -u "$BTEST_USER" &>/dev/null; then
|
||||
useradd --system --no-create-home --shell /usr/sbin/nologin "$BTEST_USER"
|
||||
echo "Created system user: $BTEST_USER"
|
||||
fi
|
||||
|
||||
# Build ExecStart command
|
||||
EXEC_START="$BTEST_BIN -s -P $BTEST_PORT"
|
||||
if [[ -n "$AUTH_USER" ]]; then
|
||||
EXEC_START="$EXEC_START -a $AUTH_USER"
|
||||
fi
|
||||
if [[ -n "$AUTH_PASS" ]]; then
|
||||
EXEC_START="$EXEC_START -p $AUTH_PASS"
|
||||
fi
|
||||
|
||||
# Create systemd unit
|
||||
cat > /etc/systemd/system/btest.service << UNIT
|
||||
[Unit]
|
||||
Description=MikroTik Bandwidth Test Server (btest)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=$BTEST_USER
|
||||
ExecStart=$EXEC_START
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
# Security hardening
|
||||
NoNewPrivileges=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
PrivateTmp=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectControlGroups=yes
|
||||
|
||||
# Allow binding to port 2000 (< 1024 needs capability)
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65535
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
|
||||
echo "Created /etc/systemd/system/btest.service"
|
||||
|
||||
# Reload and enable
|
||||
systemctl daemon-reload
|
||||
systemctl enable btest.service
|
||||
systemctl restart btest.service
|
||||
|
||||
echo ""
|
||||
echo "=== btest service installed and started ==="
|
||||
echo ""
|
||||
systemctl status btest.service --no-pager
|
||||
echo ""
|
||||
echo "Useful commands:"
|
||||
echo " systemctl status btest # Check status"
|
||||
echo " systemctl stop btest # Stop"
|
||||
echo " systemctl restart btest # Restart"
|
||||
echo " journalctl -u btest -f # Follow logs"
|
||||
echo " systemctl disable btest # Disable autostart"
|
||||
Reference in New Issue
Block a user