From ec8aab22f72e1042bda6097f8d329204161e7356 Mon Sep 17 00:00:00 2001 From: ospab Date: Sun, 17 May 2026 21:22:01 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20install=20script=20v2=20=E2=80=94=20glo?= =?UTF-8?q?bal=20PATH=20symlink,=20/etc/ostp=20config,=20legacy=20path=20m?= =?UTF-8?q?igration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Binary at /opt/ostp/ostp, symlink at /usr/local/bin/ostp - Config moved to /etc/ostp/config.json (standard Linux layout) - Auto-migration from legacy paths: ~/ostp, /root/ostp, old /opt/ostp/config.json - Systemd service updated with RUST_LOG=info - Test script updated to discover binary via PATH first --- scripts/install.sh | 329 ++++++++++++++++++++++++++++++------------ scripts/test_linux.sh | 10 +- 2 files changed, 239 insertions(+), 100 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 65c1aa5..2b075f1 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -3,94 +3,197 @@ set -e GITHUB_REPO="ospab/ostp" INSTALL_DIR="/opt/ostp" +BIN_LINK="/usr/local/bin/ostp" +CONFIG_DIR="/etc/ostp" +CONFIG_FILE="$CONFIG_DIR/config.json" + +# Legacy paths to check for migration +LEGACY_PATHS=( + "$HOME/ostp" + "/root/ostp" + "/usr/local/ostp" + "/usr/share/ostp" +) echo "========================================================" -echo " OSTP Installer" +echo " OSTP Installer v2" echo "========================================================" # Verify root if [ "$EUID" -ne 0 ]; then - echo "[error] Root privileges required. Run with sudo." - exit 1 + echo "[error] Root privileges required. Run with sudo." + exit 1 fi mkdir -p "$INSTALL_DIR" +mkdir -p "$CONFIG_DIR" + +# ── Migration from legacy installations ────────────────────────────── + +migrate_legacy() { + local old_dir="$1" + echo "[migrate] Found legacy installation at $old_dir" + + # Migrate config if exists and new one doesn't + if [ -f "$old_dir/config.json" ] && [ ! -f "$CONFIG_FILE" ]; then + echo "[migrate] Moving config: $old_dir/config.json -> $CONFIG_FILE" + cp "$old_dir/config.json" "$CONFIG_FILE" + fi + + # Migrate binary if no new binary yet + if [ -f "$old_dir/ostp" ] && [ ! -f "$INSTALL_DIR/ostp" ]; then + echo "[migrate] Moving binary: $old_dir/ostp -> $INSTALL_DIR/ostp" + cp "$old_dir/ostp" "$INSTALL_DIR/ostp" + fi + + # Migrate tun2socks if present + if [ -f "$old_dir/tun2socks" ] && [ ! -f "$INSTALL_DIR/tun2socks" ]; then + cp "$old_dir/tun2socks" "$INSTALL_DIR/tun2socks" + fi + + echo "[migrate] Legacy files preserved at $old_dir (remove manually if no longer needed)" +} + +# Check for legacy /opt/ostp/config.json (old layout: config in install dir) +if [ -f "$INSTALL_DIR/config.json" ] && [ ! -f "$CONFIG_FILE" ]; then + echo "[migrate] Moving config from $INSTALL_DIR/config.json -> $CONFIG_FILE" + cp "$INSTALL_DIR/config.json" "$CONFIG_FILE" + # Keep old file as backup + mv "$INSTALL_DIR/config.json" "$INSTALL_DIR/config.json.bak" +fi + +# Check legacy paths +for lpath in "${LEGACY_PATHS[@]}"; do + if [ -d "$lpath" ] && [ -f "$lpath/ostp" ]; then + migrate_legacy "$lpath" + fi +done + +# Remove stale symlinks +if [ -L "$BIN_LINK" ] && [ ! -e "$BIN_LINK" ]; then + rm -f "$BIN_LINK" +fi + +# ── Architecture detection ─────────────────────────────────────────── -# Architecture detection ARCH=$(uname -m) case "$ARCH" in - x86_64) ARCH="amd64" ;; + x86_64) ARCH="amd64" ;; aarch64|arm64) ARCH="arm64" ;; - i386|i686) ARCH="386" ;; - armv7l) ARCH="armv7" ;; + i386|i686) ARCH="386" ;; + armv7l) ARCH="armv7" ;; + mips|mipsel) ARCH="$ARCH" ;; *) echo "[warn] Unknown architecture $ARCH, defaulting to amd64." ARCH="amd64" ;; esac -# Fetch latest release +echo "Platform: linux/$ARCH" + +# ── Download binary ────────────────────────────────────────────────── + echo "Fetching latest release..." LATEST_RELEASE=$(curl -s "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') if [ -z "$LATEST_RELEASE" ] || [[ "$LATEST_RELEASE" == *"null"* ]]; then - echo "[notice] Could not determine latest release automatically." - echo "Enter a direct URL to the .tar.gz archive," - echo "or press Enter if the binary is already in $INSTALL_DIR/ostp." - read -p "URL: " DIRECT_URL - if [ -n "$DIRECT_URL" ]; then - TEMP_TAR="/tmp/ostp_temp.tar.gz" - curl -L "$DIRECT_URL" -o "$TEMP_TAR" - tar -xzf "$TEMP_TAR" -C "$INSTALL_DIR" ostp - rm -f "$TEMP_TAR" - fi + echo "[notice] Could not determine latest release automatically." + echo "Enter a direct URL to the .tar.gz archive," + echo "or press Enter if the binary is already in $INSTALL_DIR/ostp." + read -p "URL: " DIRECT_URL + if [ -n "$DIRECT_URL" ]; then + TEMP_TAR="/tmp/ostp_temp.tar.gz" + curl -L "$DIRECT_URL" -o "$TEMP_TAR" + tar -xzf "$TEMP_TAR" -C "$INSTALL_DIR" ostp 2>/dev/null || tar -xzf "$TEMP_TAR" -C "$INSTALL_DIR" + rm -f "$TEMP_TAR" + fi else - ARCHIVE_NAME="ostp-linux-${ARCH}.tar.gz" - DOWNLOAD_URL="https://github.com/${GITHUB_REPO}/releases/download/${LATEST_RELEASE}/${ARCHIVE_NAME}" - echo "Downloading: $ARCHIVE_NAME ($LATEST_RELEASE)" + ARCHIVE_NAME="ostp-linux-${ARCH}.tar.gz" + DOWNLOAD_URL="https://github.com/${GITHUB_REPO}/releases/download/${LATEST_RELEASE}/${ARCHIVE_NAME}" + echo "Downloading: $ARCHIVE_NAME ($LATEST_RELEASE)" - TEMP_TAR="/tmp/ostp_temp.tar.gz" - HTTP_CODE=$(curl -sL -w "%{http_code}" "$DOWNLOAD_URL" -o "$TEMP_TAR") + TEMP_TAR="/tmp/ostp_temp.tar.gz" + HTTP_CODE=$(curl -sL -w "%{http_code}" "$DOWNLOAD_URL" -o "$TEMP_TAR") - if [ "$HTTP_CODE" -eq 200 ]; then - tar -xzf "$TEMP_TAR" -C "$INSTALL_DIR" ostp - rm -f "$TEMP_TAR" - else - echo "[error] Download failed (HTTP $HTTP_CODE)." - echo "Verify that $LATEST_RELEASE is published at:" - echo " https://github.com/$GITHUB_REPO/releases" - rm -f "$TEMP_TAR" - exit 1 - fi + if [ "$HTTP_CODE" -eq 200 ]; then + tar -xzf "$TEMP_TAR" -C "$INSTALL_DIR" ostp 2>/dev/null || tar -xzf "$TEMP_TAR" -C "$INSTALL_DIR" + rm -f "$TEMP_TAR" + else + echo "[error] Download failed (HTTP $HTTP_CODE)." + echo "Verify that $LATEST_RELEASE is published at:" + echo " https://github.com/$GITHUB_REPO/releases" + rm -f "$TEMP_TAR" + exit 1 + fi fi if [ -f "$INSTALL_DIR/ostp" ]; then - chmod +x "$INSTALL_DIR/ostp" - echo "Binary installed: $INSTALL_DIR/ostp" + chmod +x "$INSTALL_DIR/ostp" + echo "Binary installed: $INSTALL_DIR/ostp" else - echo "[error] Binary not found at $INSTALL_DIR/ostp." - exit 1 + echo "[error] Binary not found at $INSTALL_DIR/ostp." + exit 1 fi -# Update detection -if [ -f "$INSTALL_DIR/config.json" ]; then - echo "--------------------------------------------------------" - echo "Existing configuration found. Binary updated to ${LATEST_RELEASE:-latest}." +# ── Create global symlink ──────────────────────────────────────────── - if systemctl is-active --quiet ostp.service 2>/dev/null; then - echo "Restarting ostp service..." - systemctl restart ostp.service - echo "Service restarted." - elif systemctl is-enabled --quiet ostp.service 2>/dev/null; then - echo "Service registered but not running." - echo "Start manually: systemctl start ostp" - fi - echo "--------------------------------------------------------" - echo "Update complete." - exit 0 +ln -sf "$INSTALL_DIR/ostp" "$BIN_LINK" +echo "Symlink created: $BIN_LINK -> $INSTALL_DIR/ostp" +echo "You can now run 'ostp' from anywhere." + +# ── Update detection ───────────────────────────────────────────────── + +if [ -f "$CONFIG_FILE" ]; then + echo "--------------------------------------------------------" + echo "Existing configuration found at $CONFIG_FILE." + echo "Binary updated to ${LATEST_RELEASE:-latest}." + + # Update systemd service to use new paths + if [ -f "/etc/systemd/system/ostp.service" ]; then + # Check if service points to old path + if grep -q "WorkingDirectory=$INSTALL_DIR" /etc/systemd/system/ostp.service && \ + grep -q "$CONFIG_FILE" /etc/systemd/system/ostp.service; then + : # Service already uses correct paths + else + echo "Updating systemd service to use new paths..." + cat < /etc/systemd/system/ostp.service +[Unit] +Description=OSTP Stealth Transport Protocol +After=network.target +Wants=network-online.target + +[Service] +Type=simple +User=root +WorkingDirectory=$INSTALL_DIR +ExecStart=$INSTALL_DIR/ostp --config $CONFIG_FILE +Restart=always +RestartSec=5 +LimitNOFILE=65535 +Environment=RUST_LOG=info + +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload + fi + fi + + if systemctl is-active --quiet ostp.service 2>/dev/null; then + echo "Restarting ostp service..." + systemctl restart ostp.service + echo "Service restarted." + elif systemctl is-enabled --quiet ostp.service 2>/dev/null; then + echo "Service registered but not running." + echo "Start manually: systemctl start ostp" + fi + echo "--------------------------------------------------------" + echo "Update complete." + exit 0 fi -# Interactive setup +# ── Interactive setup (first install) ──────────────────────────────── + echo "--------------------------------------------------------" echo "Select mode:" echo " 1) Server" @@ -101,68 +204,90 @@ read -p "Choice [1-2]: " NODE_MODE cd "$INSTALL_DIR" if [ "$NODE_MODE" == "1" ]; then - echo "Initializing server configuration..." - ./ostp --init server --config config.json + echo "Initializing server configuration..." + ./ostp --init server --config "$CONFIG_FILE" - read -p "Listen address [default: 0.0.0.0:50000]: " LISTEN_ADDR - if [ -n "$LISTEN_ADDR" ]; then - sed -i "s/\"listen\": \".*\"/\"listen\": \"$LISTEN_ADDR\"/g" config.json - fi + read -p "Listen address [default: 0.0.0.0:50000]: " LISTEN_ADDR + if [ -n "$LISTEN_ADDR" ]; then + sed -i "s/\"listen\": \".*\"/\"listen\": \"$LISTEN_ADDR\"/g" "$CONFIG_FILE" + fi - read -p "Number of access keys [default: 1]: " KEYS_COUNT - KEYS_COUNT=${KEYS_COUNT:-1} + read -p "Number of access keys [default: 1]: " KEYS_COUNT + KEYS_COUNT=${KEYS_COUNT:-1} - if [ "$KEYS_COUNT" -gt 1 ]; then - echo "Generating $KEYS_COUNT access keys..." - NEW_KEYS=$(./ostp -g -c "$KEYS_COUNT" | sed 's/^/ "/;s/$/",/' | sed '$ s/,$//') - sed -i '/\"access_keys\": \[/,/\]/c\ "access_keys": [\n'"$NEW_KEYS"'\n ],' config.json - fi - echo "Server configuration saved: $INSTALL_DIR/config.json" + if [ "$KEYS_COUNT" -gt 1 ]; then + echo "Generating $KEYS_COUNT access keys..." + NEW_KEYS=$(./ostp -g -c "$KEYS_COUNT" | sed 's/^/ "/;s/$/"/' | paste -sd ',' | sed 's/,/,\n/g') + # Replace the access_keys array + python3 -c " +import json, subprocess, sys +with open('$CONFIG_FILE') as f: + content = f.read() + # Strip comments for parsing + lines = [l for l in content.split('\n') if not l.strip().startswith('//')] + cfg = json.loads('\n'.join(lines)) +keys = subprocess.check_output(['$INSTALL_DIR/ostp', '-g', '-c', '$KEYS_COUNT']).decode().strip().split('\n') +cfg['access_keys'] = keys +with open('$CONFIG_FILE', 'w') as f: + json.dump(cfg, f, indent=2) +" 2>/dev/null || echo "[warn] Key injection via python3 failed. Edit config manually." + fi + + echo "" + echo "Server access key(s):" + grep -oP '"[0-9a-f]{32}"' "$CONFIG_FILE" | tr -d '"' | while read key; do + echo " $key" + done + echo "" + echo "Server configuration saved: $CONFIG_FILE" elif [ "$NODE_MODE" == "2" ]; then - echo "Initializing client configuration..." - ./ostp --init client --config config.json + echo "Initializing client configuration..." + ./ostp --init client --config "$CONFIG_FILE" - read -p "Server address (host:port): " REMOTE_SERVER - if [ -n "$REMOTE_SERVER" ]; then - sed -i "s/\"server\": \"127.0.0.1:50000\"/\"server\": \"$REMOTE_SERVER\"/g" config.json - else - echo "[warn] No server address provided. Using default (127.0.0.1:50000)." - fi + read -p "Server address (host:port): " REMOTE_SERVER + if [ -n "$REMOTE_SERVER" ]; then + sed -i "s/\"server\": \"127.0.0.1:50000\"/\"server\": \"$REMOTE_SERVER\"/g" "$CONFIG_FILE" + else + echo "[warn] No server address provided. Using default (127.0.0.1:50000)." + fi - read -p "Access key (blank to generate): " ACCESS_KEY - if [ -z "$ACCESS_KEY" ]; then - ACCESS_KEY=$(./ostp -g) - echo "Generated key: $ACCESS_KEY" - fi - sed -i "s/\"access_key\": \"[^\"]*\"/\"access_key\": \"$ACCESS_KEY\"/g" config.json + read -p "Access key: " ACCESS_KEY + if [ -z "$ACCESS_KEY" ]; then + ACCESS_KEY=$(./ostp -g) + echo "Generated key: $ACCESS_KEY" + fi + sed -i "s/\"access_key\": \"[^\"]*\"/\"access_key\": \"$ACCESS_KEY\"/g" "$CONFIG_FILE" - read -p "Local proxy address [default: 127.0.0.1:1088]: " SOCKS_BIND - if [ -n "$SOCKS_BIND" ]; then - sed -i "s/\"socks5_bind\": \"127.0.0.1:1088\"/\"socks5_bind\": \"$SOCKS_BIND\"/g" config.json - fi - echo "Client configuration saved: $INSTALL_DIR/config.json" + read -p "Local proxy address [default: 127.0.0.1:1088]: " SOCKS_BIND + if [ -n "$SOCKS_BIND" ]; then + sed -i "s/\"socks5_bind\": \"127.0.0.1:1088\"/\"socks5_bind\": \"$SOCKS_BIND\"/g" "$CONFIG_FILE" + fi + echo "Client configuration saved: $CONFIG_FILE" else - echo "[error] Invalid selection." - exit 1 + echo "[error] Invalid selection." + exit 1 fi -# Register systemd service +# ── Register systemd service ───────────────────────────────────────── + echo "Registering systemd service..." cat < /etc/systemd/system/ostp.service [Unit] -Description=OSTP Service +Description=OSTP Stealth Transport Protocol After=network.target +Wants=network-online.target [Service] Type=simple User=root WorkingDirectory=$INSTALL_DIR -ExecStart=$INSTALL_DIR/ostp --config $INSTALL_DIR/config.json +ExecStart=$INSTALL_DIR/ostp --config $CONFIG_FILE Restart=always RestartSec=5 LimitNOFILE=65535 +Environment=RUST_LOG=info [Install] WantedBy=multi-user.target @@ -171,8 +296,20 @@ EOF systemctl daemon-reload systemctl enable ostp.service >/dev/null 2>&1 -echo "--------------------------------------------------------" -echo "Installation complete." -echo " Config: $INSTALL_DIR/config.json" -echo " Start: systemctl start ostp" -echo "--------------------------------------------------------" +echo "" +echo "========================================================" +echo " Installation complete" +echo "========================================================" +echo "" +echo " Binary: $INSTALL_DIR/ostp" +echo " Command: ostp (available globally)" +echo " Config: $CONFIG_FILE" +echo " Service: systemctl start ostp" +echo " Logs: journalctl -u ostp -f" +echo "" +echo " Quick commands:" +echo " ostp --check Validate configuration" +echo " ostp --generate-key Generate access key" +echo " ostp --links Print client share links" +echo " systemctl status ostp Service status" +echo "" diff --git a/scripts/test_linux.sh b/scripts/test_linux.sh index bd93cc2..e4c6fbb 100644 --- a/scripts/test_linux.sh +++ b/scripts/test_linux.sh @@ -10,14 +10,16 @@ RED='\033[0;31m' CYAN='\033[0;36m' NC='\033[0m' # No Color -# Locate target binary +# Locate target binary (priority: PATH > same dir > dev layout > /opt/ostp) SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# Check if binary is in the same directory (production server layout) -if [ -f "$SCRIPT_DIR/ostp" ]; then +if command -v ostp > /dev/null 2>&1; then + OSTP_BIN="$(command -v ostp)" +elif [ -f "$SCRIPT_DIR/ostp" ]; then OSTP_BIN="$SCRIPT_DIR/ostp" +elif [ -f "/opt/ostp/ostp" ]; then + OSTP_BIN="/opt/ostp/ostp" else - # Fallback to workspace development layout OSTP_BIN="$SCRIPT_DIR/../dist/linux/ostp" fi