#!/bin/bash

#############################################################
#### iperf3 Server Setup                                 ####
#### Install and configure iperf3 as a systemd service   ####
####                                                     ####
#### Author: Phil Connor                                 ####
#### Contact: contact@mylinux.work                       ####
#### License: MIT                                        ####
#### Version: 1.0                                        ####
####                                                     ####
#### Usage: sudo ./setup-iperf3-server.sh [OPTIONS]      ####
#############################################################

set -euo pipefail

# Default configuration
LISTEN_PORT=9182
HARDENED=false
UNINSTALL=false

SERVICE_NAME="iperf3-server"
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"

show_help() {
    cat <<EOF
Usage: sudo ./setup-iperf3-server.sh [OPTIONS]

Install and configure iperf3 as a systemd service.

Options:
  --port PORT    Set the iperf3 listen port (default: 9182)
  --hardened     Use the hardened service file with IP restrictions
                 and security settings (private networks only)
  --uninstall    Stop, disable, and remove the iperf3 service
  --help         Show this help message

Examples:
  sudo ./setup-iperf3-server.sh
  sudo ./setup-iperf3-server.sh --port 5201
  sudo ./setup-iperf3-server.sh --hardened
  sudo ./setup-iperf3-server.sh --uninstall
EOF
    exit 0
}

parse_args() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --port)
                if [[ -z "${2:-}" ]]; then
                    echo "ERROR: --port requires a value"
                    exit 1
                fi
                LISTEN_PORT="$2"
                shift 2
                ;;
            --hardened)
                HARDENED=true
                shift
                ;;
            --uninstall)
                UNINSTALL=true
                shift
                ;;
            --help)
                show_help
                ;;
            *)
                echo "ERROR: Unknown option: $1"
                echo "Run with --help for usage information."
                exit 1
                ;;
        esac
    done
}

# Ensure script is run as root
if [[ $EUID -ne 0 ]]; then
    echo "ERROR: This script must be run as root (use sudo)."
    exit 1
fi

install_iperf3() {
    if command -v iperf3 >/dev/null 2>&1; then
        echo "iperf3 is already installed."
        return
    fi

    echo "Installing iperf3..."
    if command -v apt-get >/dev/null 2>&1; then
        apt-get update && apt-get install -y iperf3
    elif command -v dnf >/dev/null 2>&1; then
        dnf install -y iperf3
    elif command -v yum >/dev/null 2>&1; then
        yum install -y iperf3
    else
        echo "ERROR: Cannot install iperf3 automatically. Please install manually."
        exit 1
    fi
}

install_service() {
    echo "Installing systemd service..."

    if [[ "$HARDENED" == true ]]; then
        echo "Using hardened service configuration (private networks only)."
        cat > "$SERVICE_FILE" <<EOF
[Unit]
Description=iperf3 Network Performance Testing Server
After=network.target
Wants=network.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/bin/iperf3 -s -p ${LISTEN_PORT}
ExecReload=/bin/kill -HUP \$MAINPID
KillMode=process
Restart=on-failure
RestartSec=5s

# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/tmp
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictSUIDSGID=true

# Network settings — restrict to private networks
IPAddressDeny=any
IPAddressAllow=localhost
IPAddressAllow=192.168.0.0/16
IPAddressAllow=10.0.0.0/8
IPAddressAllow=172.16.0.0/12

[Install]
WantedBy=multi-user.target
EOF
    else
        cat > "$SERVICE_FILE" <<EOF
[Unit]
Description=iperf3 Network Performance Testing Server
After=network.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/bin/iperf3 -s -p ${LISTEN_PORT}
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF
    fi

    chmod 644 "$SERVICE_FILE"

    echo "Enabling and starting service..."
    systemctl daemon-reload
    systemctl enable "${SERVICE_NAME}.service"
    systemctl start "${SERVICE_NAME}.service"

    echo ""
    echo "iperf3 server service installed and started!"
    echo ""
    systemctl status "${SERVICE_NAME}.service" --no-pager || true
    echo ""
    echo "Service commands:"
    echo "  Start:   sudo systemctl start ${SERVICE_NAME}"
    echo "  Stop:    sudo systemctl stop ${SERVICE_NAME}"
    echo "  Status:  sudo systemctl status ${SERVICE_NAME}"
    echo "  Logs:    sudo journalctl -u ${SERVICE_NAME} -f"
    echo ""
    echo "Test connection from another machine:"
    echo "  iperf3 -c $(hostname -I 2>/dev/null | awk '{print $1}') -p ${LISTEN_PORT} -t 10"
    echo ""
    echo "To customize settings, edit:"
    echo "  ${SERVICE_FILE}"
    echo "Then run: sudo systemctl daemon-reload && sudo systemctl restart ${SERVICE_NAME}"
}

uninstall_service() {
    echo "Removing iperf3 server service..."
    systemctl stop "${SERVICE_NAME}" 2>/dev/null || true
    systemctl disable "${SERVICE_NAME}" 2>/dev/null || true
    rm -f "$SERVICE_FILE"
    systemctl daemon-reload
    echo "iperf3 server service removed."
}

# --- Main execution ---

parse_args "$@"

if [[ "$UNINSTALL" == true ]]; then
    uninstall_service
else
    echo "Setting up iperf3 server service on port ${LISTEN_PORT}..."
    install_iperf3
    install_service
fi
