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
|
/target
|
||||||
|
/dist
|
||||||
btest_original
|
btest_original
|
||||||
.claude/
|
.claude/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Stage 1: Build
|
# Stage 1: Build
|
||||||
FROM rust:1.82-slim AS builder
|
FROM rust:1.86-slim AS builder
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
COPY Cargo.toml Cargo.lock ./
|
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