Skip to content

Instantly share code, notes, and snippets.

@NNdroid
Last active May 5, 2026 01:34
Show Gist options
  • Select an option

  • Save NNdroid/5d54a773c46d90055b2a8a32502c0496 to your computer and use it in GitHub Desktop.

Select an option

Save NNdroid/5d54a773c46d90055b2a8a32502c0496 to your computer and use it in GitHub Desktop.
psocks installer
#!/bin/bash
set -e
# ==========================================
# psocks 多功能管理脚本 (Install / Update / Uninstall)
# ==========================================
REPO="NNdroid/psocks-build"
CONFIG_DIR="/usr/local/etc/psocks"
LOG_DIR="/var/log/psocks"
BIN_DIR="/usr/local/bin"
SERVICE_FILE="/etc/systemd/system/psocks.service"
USER_NAME="psocks"
# 检查 root 权限
if [ "$EUID" -ne 0 ]; then
echo "❌ 请使用 root 权限运行此脚本 (例如: sudo ./psocks.sh install)"
exit 1
fi
# 显示帮助信息
show_help() {
echo "=========================================="
echo " psocks 管理脚本"
echo "=========================================="
echo "用法: $0 [命令] [选项]"
echo ""
echo "命令:"
echo " install - 全新安装 psocks 及配置文件"
echo " update - 保留现有配置,仅更新二进制文件至最新版"
echo " uninstall - 完全卸载 psocks 及所有相关文件和日志"
echo ""
echo "选项:"
echo " --nft - 安装时添加, 限制 1080 端口仅允许 ygg0, myc0, lo 访问"
echo "=========================================="
}
# ==================== 通用辅助函数 ====================
get_arch() {
ARCH=$(uname -m)
case $ARCH in
x86_64) TARGET="x86_64-unknown-linux-musl" ;;
aarch64|arm64) TARGET="aarch64-unknown-linux-musl" ;;
armv7l) TARGET="armv7-unknown-linux-musleabihf" ;;
*) echo "❌ 不支持的系统架构: $ARCH"; exit 1 ;;
esac
}
get_latest_release() {
echo "🔍 正在从 $REPO 获取最新版本号..."
LATEST_TAG=$(curl -s "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
if [ -z "$LATEST_TAG" ]; then
echo "❌ 无法获取最新版本号,请检查网络或 GitHub API 限制。"
exit 1
fi
echo "✅ 最新版本为: $LATEST_TAG"
}
download_and_install_binary() {
DOWNLOAD_URL="https://github.com/$REPO/releases/download/$LATEST_TAG/psocks-${TARGET}.tar.gz"
echo "⬇️ 正在下载: $DOWNLOAD_URL"
wget -qO /tmp/psocks.tar.gz "$DOWNLOAD_URL"
echo "📦 正在解压并替换二进制文件..."
tar -zxvf /tmp/psocks.tar.gz -C /tmp > /dev/null
mv /tmp/psocks "$BIN_DIR/psocks"
chmod +x "$BIN_DIR/psocks"
rm -f /tmp/psocks.tar.gz /tmp/config.toml
}
# ==================== 核心功能 ====================
do_install() {
echo "================= 开始安装 ================="
get_arch
get_latest_release
# 创建用户
if ! id -u $USER_NAME > /dev/null 2>&1; then
echo "👤 创建专用的 $USER_NAME 系统用户..."
useradd -r -s /usr/sbin/nologin $USER_NAME
fi
echo "📁 创建配置与日志目录..."
mkdir -p "$CONFIG_DIR"
mkdir -p "$LOG_DIR"
chown $USER_NAME:$USER_NAME "$LOG_DIR"
# 写入配置
echo "📝 写入配置文件..."
cat << 'EOF' > "$CONFIG_DIR/config.toml"
[list.telegram]
is_enabled = true
source = "/usr/local/etc/psocks/telegram.txt"
EOF
cat << 'EOF' > "$CONFIG_DIR/telegram.txt"
.telegram.org
.telegram.me
.t.me
.tx.me
.telegram.dog
.telega.one
.cdn-telegram.org
.telesco.pe
.telegra.ph
.graph.org
.tg.dev
.comments.app
.telegram.space
91.105.192.0/23
91.108.4.0/22
91.108.8.0/21
91.108.16.0/21
91.108.56.0/22
149.154.160.0/20
185.76.151.0/24
2a0a:f280::/32
2001:67c:4e8::/48
2001:b28:f23c::/47
2001:b28:f23f::/48
EOF
download_and_install_binary
# ---------------- nftables 配置处理 ----------------
NFT_START_PRE=""
NFT_START_POST=""
NFT_STOP_POST=""
if [ "$USE_NFT" -eq 1 ]; then
if ! command -v nft >/dev/null 2>&1; then
echo "❌ 未检测到 nftables 命令。请先安装 (例如: apt install nftables) 或去除 --nft 参数。"
exit 1
fi
echo "🛡️ 检测到 --nft 参数,正在生成独立防火墙规则..."
cat << 'EOF' > "$CONFIG_DIR/nftables.conf"
table inet psocks_filter {
chain input {
type filter hook input priority 0; policy accept;
tcp dport 1080 iifname != { "ygg0", "myc0", "lo" } drop
udp dport 1080 iifname != { "ygg0", "myc0", "lo" } drop
}
}
EOF
# 使用 + 前缀让 systemd 以 root 权限执行规则(因为 service 是以 psocks 用户运行的)
NFT_START_PRE="ExecStartPre=+/bin/sh -c '/usr/sbin/nft delete table inet psocks_filter 2>/dev/null || true'"
NFT_START_POST="ExecStartPost=+/usr/sbin/nft -f $CONFIG_DIR/nftables.conf"
NFT_STOP_POST="ExecStopPost=+/bin/sh -c '/usr/sbin/nft delete table inet psocks_filter 2>/dev/null || true'"
fi
# ---------------------------------------------------
echo "⚙️ 写入 Systemd 服务配置..."
cat << EOF > $SERVICE_FILE
[Unit]
After=network-online.target
Wants=network-online.target
[Service]
User=$USER_NAME
Group=$USER_NAME
${NFT_START_PRE}
ExecStart=$BIN_DIR/psocks -c $CONFIG_DIR/config.toml --listen-addr [::]:1080 no-auth
${NFT_START_POST}
Restart=always
Environment="RUST_LOG=psocks=warn"
Environment="NO_COLOR=1"
StandardOutput=file://$LOG_DIR/debug.log
StandardError=file://$LOG_DIR/error.log
${NFT_STOP_POST}
[Install]
WantedBy=multi-user.target
EOF
echo "🚀 启动并设置开机自启..."
systemctl daemon-reload
systemctl enable psocks
systemctl restart psocks
echo "🎉 安装完成!可以使用 'systemctl status psocks' 查看状态。"
}
do_update() {
echo "================= 开始更新 ================="
if [ ! -f "$BIN_DIR/psocks" ]; then
echo "❌ 未检测到 psocks 安装,请先执行 install。"
exit 1
fi
get_arch
get_latest_release
echo "⏹️ 停止运行中的服务..."
systemctl stop psocks
download_and_install_binary
echo "▶️ 重新启动服务..."
systemctl restart psocks
echo "🎉 更新完成!"
}
do_uninstall() {
echo "================= 开始卸载 ================="
read -p "⚠️ 确定要完全卸载 psocks 并删除所有配置和日志吗?(y/N): " confirm
if [[ "$confirm" != [yY] ]]; then
echo "取消卸载。"
exit 0
fi
echo "⏹️ 停止并禁用服务..."
systemctl stop psocks || true
systemctl disable psocks || true
echo "🛡️ 清理可能的 nftables 规则..."
if command -v nft >/dev/null 2>&1; then
nft delete table inet psocks_filter >/dev/null 2>&1 || true
fi
echo "🗑️ 删除文件和目录..."
rm -f $SERVICE_FILE
rm -f "$BIN_DIR/psocks"
rm -rf "$CONFIG_DIR"
rm -rf "$LOG_DIR"
echo "👤 删除专用用户..."
userdel $USER_NAME || true
systemctl daemon-reload
echo "🎉 卸载完成,系统已清理干净。"
}
# ==================== 主流程控制 ====================
ACTION=""
USE_NFT=0
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
install|update|uninstall)
ACTION="$1"
;;
--nft)
USE_NFT=1
;;
-h|--help)
show_help
exit 0
;;
*)
echo "❌ 未知参数或选项: $1"
show_help
exit 1
;;
esac
shift
done
if [ -z "$ACTION" ]; then
show_help
exit 1
fi
case "$ACTION" in
install)
do_install
;;
update)
do_update
;;
uninstall)
do_uninstall
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment