Files
SingboxForPanel/install.sh
2026-04-14 23:26:34 +08:00

221 lines
6.0 KiB
Bash

#!/bin/bash
# sing-box Xboard Integration Installation Script
# This script automates the installation and configuration of sing-box with Xboard support.
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration
CONFIG_DIR="/etc/sing-box"
CONFIG_FILE="$CONFIG_DIR/config.json"
BINARY_PATH="/usr/local/bin/sing-box"
SERVICE_FILE="/etc/systemd/system/sing-box.service"
echo -e "${GREEN}Welcome to sing-box Xboard Installation Script${NC}"
# Check root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root${NC}"
exit 1
fi
# Detect Architecture
ARCH=$(uname -m)
case $ARCH in
x86_64) BINARY_ARCH="amd64" ;;
aarch64) BINARY_ARCH="arm64" ;;
*) echo -e "${RED}Unsupported architecture: $ARCH${NC}"; exit 1 ;;
esac
# Prepare directories
mkdir -p "$CONFIG_DIR"
mkdir -p "/var/lib/sing-box"
# Check and Install Go
install_go() {
echo -e "${YELLOW}Checking Go environment...${NC}"
if command -v go >/dev/null 2>&1; then
GO_VERSION=$(go version | awk '{print $3}' | sed 's/go//' | cut -d. -f1,2)
if [[ "$(printf '%s\n' "1.24" "$GO_VERSION" | sort -V | head -n1)" == "1.24" ]]; then
echo -e "${GREEN}Go $GO_VERSION already installed.${NC}"
return
fi
fi
echo -e "${YELLOW}Installing Go 1.24.7...${NC}"
GO_TAR="go1.24.7.linux-$BINARY_ARCH.tar.gz"
curl -L "https://golang.org/dl/$GO_TAR" -o "$GO_TAR"
rm -rf /usr/local/go && tar -C /usr/local -xzf "$GO_TAR"
rm "$GO_TAR"
# Add to PATH for current session
export PATH=$PATH:/usr/local/go/bin
if ! grep -q "/usr/local/go/bin" ~/.bashrc; then
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
fi
echo -e "${GREEN}Go installed successfully.${NC}"
}
# Build sing-box
build_sing_box() {
echo -e "${YELLOW}Building sing-box from source...${NC}"
# Check if we are in the source directory
if [[ ! -f "go.mod" ]]; then
echo -e "${YELLOW}Source not found in current directory. Cloning repository...${NC}"
if ! command -v git >/dev/null 2>&1; then
echo -e "${YELLOW}Installing git...${NC}"
apt-get update && apt-get install -y git || yum install -y git
fi
git clone https://github.com/sagernet/sing-box.git sing-box-src
cd sing-box-src
else
echo -e "${GREEN}Found go.mod in current directory. Building from local source.${NC}"
fi
# Build params from Makefile
VERSION=$(git rev-parse --short HEAD 2>/dev/null || echo "custom")
# Reduced tags for safer build on smaller servers
TAGS="with_quic,with_utls,with_clash_api,with_gvisor"
echo -e "${YELLOW}Starting compilation (this may take a few minutes)...${NC}"
echo -e "${YELLOW}Note: Using -p 1 to save memory and avoid silent crashes.${NC}"
# Use -o to be explicit about output location
# Use -p 1 to limit parallel builds (prevent OOM spikes)
# Redirect stderr to stdout to see errors clearly
if ! go build -v -p 1 -trimpath \
-o "$BINARY_PATH" \
-ldflags "-X 'github.com/sagernet/sing-box/constant.Version=$VERSION' -s -w" \
-tags "$TAGS" \
./cmd/sing-box 2>&1; then
echo -e "${RED}Compilation process failed or was terminated.${NC}"
echo -e "${YELLOW}Checking system status...${NC}"
free -m
exit 1
fi
if [[ -f "$BINARY_PATH" ]]; then
chmod +x "$BINARY_PATH"
echo -e "${GREEN}sing-box compiled successfully and installed to $BINARY_PATH${NC}"
else
echo -e "${RED}Compilation failed: binary not found!${NC}"
exit 1
fi
}
install_go
build_sing_box
# Load .env if exists
if [[ -f ".env" ]]; then
echo -e "${YELLOW}Loading configuration from .env...${NC}"
source .env
fi
# Interactive Prompts
read -p "Enter Panel URL [${PANEL_URL}]: " INPUT_URL
PANEL_URL=${INPUT_URL:-$PANEL_URL}
read -p "Enter Node ID [${NODE_ID}]: " INPUT_ID
NODE_ID=${INPUT_ID:-$NODE_ID}
read -p "Enter Panel Token (Node Key) [${PANEL_TOKEN}]: " INPUT_TOKEN
PANEL_TOKEN=${INPUT_TOKEN:-$PANEL_TOKEN}
if [[ -z "$PANEL_URL" || -z "$NODE_ID" || -z "$PANEL_TOKEN" ]]; then
echo -e "${RED}All fields are required!${NC}"
exit 1
fi
# Clean up trailing slash
PANEL_URL="${PANEL_URL%/}"
# Generate Configuration
echo -e "${YELLOW}Generating configuration...${NC}"
cat > "$CONFIG_FILE" <<EOF
{
"log": {
"level": "info",
"timestamp": true
},
"experimental": {
"cache_file": {
"enabled": true,
"path": "/var/lib/sing-box/cache.db"
}
},
"dns": {
"servers": [
{
"tag": "dns-remote",
"type": "udp",
"server": "1.1.1.1",
"server_port": 53
}
]
},
"services": [
{
"type": "xboard",
"panel_url": "$PANEL_URL",
"key": "$PANEL_TOKEN",
"node_id": $NODE_ID,
"sync_interval": "1m",
"report_interval": "1m"
}
],
"inbounds": [],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"rules": [
{
"protocol": "dns",
"action": "hijack-dns"
}
]
}
}
EOF
echo -e "${YELLOW}NOTE: VLESS+Reality template created. Please update 'private_key' and 'short_id' in $CONFIG_FILE if you use Reality.${NC}"
# Create Systemd Service
echo -e "${YELLOW}Creating systemd service...${NC}"
cat > "$SERVICE_FILE" <<EOF
[Unit]
Description=sing-box service
After=network.target nss-lookup.target
[Service]
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW
ExecStart=$BINARY_PATH run -c $CONFIG_FILE
Restart=on-failure
RestartSec=10
LimitNOFILE=infinity
[Install]
WantedBy=multi-user.target
EOF
# Reload and Start
systemctl daemon-reload
systemctl enable sing-box
systemctl restart sing-box
echo -e "${GREEN}Service installed and started successfully.${NC}"
echo -e "${GREEN}Check status with: systemctl status sing-box${NC}"
echo -e "${GREEN}View logs with: journalctl -u sing-box -f${NC}"