## 2. 安装依赖
sudo apt-get update
sudo apt-get install -y redsocks iptables
检查安装结果:
/usr/sbin/redsocks -v
iptables --version
系统软件包自带一个 redsocks.service,自定义服务不能和它同时管理 redsocks:
sudo systemctl disable --now redsocks.service
## 3. 创建代理管理脚本
创建目录:
sudo install -d -o root -g root -m 0755 /opt/netproxy
sudoedit /opt/netproxy/netproxy.sh
写入以下完整内容:
#!/usr/bin/env bash
set -euo pipefail
### ================= 基本配置 =================
REDSOCKS_CONF="/etc/redsocks.conf"
REDSOCKS_BIN="/usr/sbin/redsocks"
REDSOCKS_PORT=12345
CHAIN="NETPROXY"
MARK="0x1"
STATE_DIR="/run/netproxy"
IPTABLES_BACKUP="${STATE_DIR}/iptables.bak"
### ================= 工具函数 =================
die() {
echo "[ERROR] $*" >&2
exit 1
}
need_root() {
[[ ${EUID} -eq 0 ]] || die "Must run as root"
}
ensure_dependencies() {
[[ -x "${REDSOCKS_BIN}" ]] ||
die "redsocks not found: ${REDSOCKS_BIN}"
command -v iptables >/dev/null ||
die "iptables not found"
command -v iptables-save >/dev/null ||
die "iptables-save not found"
command -v iptables-restore >/dev/null ||
die "iptables-restore not found"
}
ensure_dirs() {
install -d -o root -g root -m 0755 "${STATE_DIR}"
}
parse_proxy() {
[[ $# -eq 1 ]] || die "Missing proxy address"
[[ "$1" =~ ^([^:]+):([0-9]+)$ ]] ||
die "Invalid proxy format, expected ip:port"
PROXY_IP="${BASH_REMATCH[1]}"
PROXY_PORT="${BASH_REMATCH[2]}"
if ((PROXY_PORT < 1 || PROXY_PORT > 65535)); then
die "Invalid proxy port: ${PROXY_PORT}"
fi
}
### ================= redsocks =================
write_redsocks_conf() {
cat >"${REDSOCKS_CONF}" <<EOF
base {
log_info = on;
log = "syslog:daemon";
daemon = on;
redirector = iptables;
}
redsocks {
local_ip = 127.0.0.1;
local_port = ${REDSOCKS_PORT};
ip = ${PROXY_IP};
port = ${PROXY_PORT};
type = socks5;
}
EOF
chmod 0644 "${REDSOCKS_CONF}"
}
start_redsocks() {
# 本服务独占 redsocks,避免系统自带实例产生冲突。
pkill -x redsocks 2>/dev/null || true
"${REDSOCKS_BIN}" -t -c "${REDSOCKS_CONF}"
"${REDSOCKS_BIN}" -c "${REDSOCKS_CONF}"
}
stop_redsocks() {
pkill -x redsocks 2>/dev/null || true
}
### ================= iptables =================
iptables_save() {
iptables-save >"${IPTABLES_BACKUP}"
chmod 0600 "${IPTABLES_BACKUP}"
}
iptables_restore() {
[[ -f "${IPTABLES_BACKUP}" ]] || return 1
iptables-restore <"${IPTABLES_BACKUP}"
}
iptables_apply() {
iptables -t nat -N "${CHAIN}" 2>/dev/null || true
iptables -t nat -F "${CHAIN}"
# 放行已标记的 redsocks 返回流量,避免循环代理。
iptables -t nat -A "${CHAIN}" \
-m mark --mark "${MARK}" -j RETURN
# 回环流量不代理。
iptables -t nat -A "${CHAIN}" \
-d 127.0.0.0/8 -j RETURN
# 上游 SOCKS5 服务器必须直连,避免代理回环。
iptables -t nat -A "${CHAIN}" \
-d "${PROXY_IP}" -j RETURN
# 其余本机 IPv4 TCP 流量重定向到 redsocks。
iptables -t nat -A "${CHAIN}" \
-p tcp -j REDIRECT --to-ports "${REDSOCKS_PORT}"
# 只处理本机产生的连接,不处理转发流量。
iptables -t nat -C OUTPUT \
-p tcp -j "${CHAIN}" 2>/dev/null ||
iptables -t nat -A OUTPUT \
-p tcp -j "${CHAIN}"
# 标记 redsocks 本地返回流量。
iptables -t mangle -C OUTPUT \
-p tcp --sport "${REDSOCKS_PORT}" \
-j MARK --set-mark "${MARK}" 2>/dev/null ||
iptables -t mangle -A OUTPUT \
-p tcp --sport "${REDSOCKS_PORT}" \
-j MARK --set-mark "${MARK}"
}
iptables_clear() {
iptables -t nat -D OUTPUT \
-p tcp -j "${CHAIN}" 2>/dev/null || true
iptables -t nat -F "${CHAIN}" 2>/dev/null || true
iptables -t nat -X "${CHAIN}" 2>/dev/null || true
iptables -t mangle -D OUTPUT \
-p tcp --sport "${REDSOCKS_PORT}" \
-j MARK --set-mark "${MARK}" 2>/dev/null || true
}
### ================= 命令实现 =================
cmd_start() {
parse_proxy "$1"
ensure_dependencies
ensure_dirs
iptables_save
write_redsocks_conf
start_redsocks
if ! iptables_apply; then
stop_redsocks
iptables_restore || iptables_clear
die "Failed to apply iptables rules"
fi
echo "[OK] netproxy started via ${PROXY_IP}:${PROXY_PORT}"
}
cmd_stop() {
stop_redsocks
if ! iptables_restore; then
iptables_clear
fi
rm -f "${IPTABLES_BACKUP}"
rmdir "${STATE_DIR}" 2>/dev/null || true
echo "[OK] netproxy stopped and firewall restored"
}
cmd_status() {
echo "=== redsocks ==="
if pgrep -x redsocks >/dev/null; then
echo "running"
pgrep -a -x redsocks
else
echo "stopped"
fi
echo
echo "=== listen port ==="
ss -ltn | grep ":${REDSOCKS_PORT} " ||
echo "port ${REDSOCKS_PORT} not listening"
echo
echo "=== iptables nat ==="
iptables -t nat -S | grep "${CHAIN}" ||
echo "no netproxy nat rules"
echo
echo "=== iptables mangle ==="
iptables -t mangle -S |
grep -- "--sport ${REDSOCKS_PORT}" ||
echo "no netproxy mangle rules"
}
### ================= 主入口 =================
need_root
case "${1:-}" in
start)
[[ $# -eq 2 ]] ||
die "Usage: $0 start ip:port"
cmd_start "$2"
;;
stop)
[[ $# -eq 1 ]] ||
die "Usage: $0 stop"
cmd_stop
;;
status)
[[ $# -eq 1 ]] ||
die "Usage: $0 status"
cmd_status
;;
*)
echo "Usage:"
echo " $0 start ip:port"
echo " $0 stop"
echo " $0 status"
exit 1
;;
esac
设置权限:
sudo chown root:root /opt/netproxy/netproxy.sh
sudo chmod 0755 /opt/netproxy/netproxy.sh
检查语法:
bash -n /opt/netproxy/netproxy.sh
## 4. 可选:配置直连网段
当前脚本除回环地址和上游代理外,会代理所有本机 IPv4 TCP 流量,包括内网地址。
如果需要保持管理网段直连,在 iptables_apply() 中、“上游 SOCKS5 服务器必须直连”规则之后加入:
iptables -t nat -A "${CHAIN}" \
-d 192.168.220.0/24 -j RETURN
也可以按实际环境放行其他网段:
iptables -t nat -A "${CHAIN}" -d 10.0.0.0/8 -j RETURN
iptables -t nat -A "${CHAIN}" -d 172.16.0.0/12 -j RETURN
iptables -t nat -A "${CHAIN}" -d 192.168.0.0/16 -j RETURN
如果内网业务本来就需要通过 SOCKS5,则不要添加这些规则。
## 5. 创建 systemd 服务
sudoedit /etc/systemd/system/proxy.service
写入:
[Unit]
Description=Proxy Service (Redsocks)
Wants=network-online.target
After=network-online.target
Conflicts=redsocks.service
[Service]
Type=forking
ExecStart=/opt/netproxy/netproxy.sh start 10.8.30.135:10810
ExecStop=/opt/netproxy/netproxy.sh stop
Restart=on-failure
RestartSec=5s
TimeoutStartSec=30s
TimeoutStopSec=30s
[Install]
WantedBy=multi-user.target
设置权限并检查:
sudo chown root:root /etc/systemd/system/proxy.service
sudo chmod 0644 /etc/systemd/system/proxy.service
sudo systemd-analyze verify /etc/systemd/system/proxy.service
## 6. 加载并启动服务
> 执行后会立即接管本机 TCP 流量。
sudo systemctl daemon-reload
sudo systemctl enable --now proxy.service
检查服务:
systemctl is-enabled proxy.service
systemctl is-active proxy.service
systemctl status proxy.service --no-pager
预期分别看到:
enabled
active
## 7. 验证部署结果
检查 redsocks 和规则:
sudo /opt/netproxy/netproxy.sh status
检查监听端口:
sudo ss -ltnp 'sport = :12345'
预期监听:
127.0.0.1:12345
检查完整规则顺序:
sudo iptables -t nat -S OUTPUT
sudo iptables -t nat -S NETPROXY
sudo iptables -t mangle -S OUTPUT
查看运行日志:
sudo journalctl -u proxy.service -n 100 --no-pager
持续观察:
sudo journalctl -u proxy.service -f
进行 TCP 测试:
curl --connect-timeout 5 --max-time 15 -I https://example.com
注意:UDP、IPv6、ICMP 和经过本机转发的流量不会被该方案代理。
## 8. 修改上游代理
编辑服务文件:
sudoedit /etc/systemd/system/proxy.service
修改:
ExecStart=/opt/netproxy/netproxy.sh start 10.8.30.135:10810
然后重新加载并重启:
sudo systemctl daemon-reload
sudo systemctl restart proxy.service
sudo /opt/netproxy/netproxy.sh status
## 9. 停止与取消开机启动
sudo systemctl disable --now proxy.service
确认规则已清理或恢复:
sudo iptables -t nat -S | grep NETPROXY || true
sudo iptables -t mangle -S | grep 12345 || true
pgrep -a -x redsocks || true
需要注意:这个部署版本停止时会恢复启动前保存的整份 iptables 快照。如果服务运行期间其他程序修改过防火墙,停止服务可能覆盖那些修改。生
产环境建议后续改成“只删除 NETPROXY 自己的规则”,避免全量恢复。