fix: skip binary download if already installed, symlink from existing path

Resolves bootstrapping deadlock where downloading sslocal requires internet
access via the very proxy being deployed. Also handles distros (Arch) where
shadowsocks-rust is installed via package manager to /usr/bin instead of
/usr/local/bin.

Priority:
  1. /usr/local/bin/sslocal exists → skip download
  2. sslocal found in PATH elsewhere → symlink to /usr/local/bin/sslocal
  3. not found → download from GitHub releases

Same logic applied to ssserver-rust in server/deploy.sh.
Also: stop conflicting shadowsocks.service before starting shadowsocks-client,
and detect pacman vs apt for privoxy install.
This commit is contained in:
m1ngsama 2026-02-28 01:55:47 +08:00
parent 990e0f93be
commit 19b3e5035c
2 changed files with 47 additions and 19 deletions

View file

@ -12,24 +12,42 @@ source "$ENV_FILE"
require_env SS_SERVER SS_PORT SS_PASSWORD SS_METHOD require_env SS_SERVER SS_PORT SS_PASSWORD SS_METHOD
SSLOCAL_BIN="/usr/local/bin/sslocal"
# Install sslocal — skip download if already present, symlink if installed elsewhere
if [[ -x "$SSLOCAL_BIN" ]]; then
log_info "sslocal already at $SSLOCAL_BIN ($($SSLOCAL_BIN --version 2>&1 | head -1)), skipping download"
elif command -v sslocal &>/dev/null; then
existing="$(command -v sslocal)"
log_info "sslocal found at $existing, symlinking to $SSLOCAL_BIN"
ln -sf "$existing" "$SSLOCAL_BIN"
else
log_info "Downloading shadowsocks-rust client..." log_info "Downloading shadowsocks-rust client..."
VERSION=$(curl -s https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest \ VERSION=$(curl -s https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest \
| python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'])") | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'])")
ARCHIVE="shadowsocks-${VERSION}.x86_64-unknown-linux-gnu.tar.xz" ARCHIVE="shadowsocks-${VERSION}.x86_64-unknown-linux-gnu.tar.xz"
wget -q "https://github.com/shadowsocks/shadowsocks-rust/releases/download/${VERSION}/${ARCHIVE}" wget -q "https://github.com/shadowsocks/shadowsocks-rust/releases/download/${VERSION}/${ARCHIVE}"
tar -xf "$ARCHIVE" tar -xf "$ARCHIVE"
cp sslocal /usr/local/bin/sslocal cp sslocal "$SSLOCAL_BIN"
chmod +x /usr/local/bin/sslocal chmod +x "$SSLOCAL_BIN"
rm -f "$ARCHIVE" ssserver sslocal ssurl ssmanager redir tunnel rm -f "$ARCHIVE" ssserver sslocal ssurl ssmanager redir tunnel
fi
log_info "Installing privoxy..." log_info "Installing privoxy..."
if command -v pacman &>/dev/null; then
pacman -S --noconfirm --needed privoxy
else
apt-get install -y privoxy apt-get install -y privoxy
fi
log_info "Deploying configs..." log_info "Deploying configs..."
mkdir -p /etc/shadowsocks-rust mkdir -p /etc/shadowsocks-rust
envsubst < "${INFRA_DIR}/config.json.example" > /etc/shadowsocks-rust/client.json envsubst < "${INFRA_DIR}/config.json.example" > /etc/shadowsocks-rust/client.json
cp "${INFRA_DIR}/privoxy.conf.example" /etc/privoxy/config cp "${INFRA_DIR}/privoxy.conf.example" /etc/privoxy/config
log_info "Stopping any existing shadowsocks service on port 1080..."
systemctl stop shadowsocks 2>/dev/null || true
log_info "Installing service..." log_info "Installing service..."
cp "${INFRA_DIR}/shadowsocks-client.service" /etc/systemd/system/ cp "${INFRA_DIR}/shadowsocks-client.service" /etc/systemd/system/
systemctl daemon-reload systemctl daemon-reload

View file

@ -12,15 +12,25 @@ source "$ENV_FILE"
require_env SS_PORT SS_PASSWORD SS_METHOD require_env SS_PORT SS_PASSWORD SS_METHOD
SSSERVER_BIN="/usr/local/bin/ssserver-rust"
if [[ -x "$SSSERVER_BIN" ]]; then
log_info "ssserver-rust already at $SSSERVER_BIN ($($SSSERVER_BIN --version 2>&1 | head -1)), skipping download"
elif command -v ssserver &>/dev/null; then
existing="$(command -v ssserver)"
log_info "ssserver found at $existing, symlinking to $SSSERVER_BIN"
ln -sf "$existing" "$SSSERVER_BIN"
else
log_info "Downloading shadowsocks-rust..." log_info "Downloading shadowsocks-rust..."
VERSION=$(curl -s https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest \ VERSION=$(curl -s https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest \
| python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'])") | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'])")
ARCHIVE="shadowsocks-${VERSION}.x86_64-unknown-linux-gnu.tar.xz" ARCHIVE="shadowsocks-${VERSION}.x86_64-unknown-linux-gnu.tar.xz"
wget -q "https://github.com/shadowsocks/shadowsocks-rust/releases/download/${VERSION}/${ARCHIVE}" wget -q "https://github.com/shadowsocks/shadowsocks-rust/releases/download/${VERSION}/${ARCHIVE}"
tar -xf "$ARCHIVE" tar -xf "$ARCHIVE"
cp ssserver /usr/local/bin/ssserver-rust cp ssserver "$SSSERVER_BIN"
chmod +x /usr/local/bin/ssserver-rust chmod +x "$SSSERVER_BIN"
rm -f "$ARCHIVE" ssserver sslocal ssurl ssmanager redir tunnel rm -f "$ARCHIVE" ssserver sslocal ssurl ssmanager redir tunnel
fi
log_info "Deploying config..." log_info "Deploying config..."
mkdir -p /etc/shadowsocks-rust mkdir -p /etc/shadowsocks-rust