One-click Self-extracting Automatic Installation Script for frpc.sh
One-click Self-extracting Automatic Installation Script for frpc.sh
一键自解压 generate_deploy_script.sh 自动安装脚本
1、当前目录 /home/steven_roc 压缩文件frpc frp_0.68.1_linux_arm64.tar.gz
#压缩指定文件fprc sudo tar -zcvf frp_0.68.1_linux_arm64.tar.gz frpc sudo tar -zcvf frp_0.68.1_linux_arm64.tar.gz frpc #解压缩: tar -zxvf frp_0.68.1_linux_arm64.tar.gz
2、用步骤:
保存生成脚本:
sudo nano generate_deploy_script.sh # 粘贴上面的完整修正版内容 sudo chmod +x generate_deploy_script.sh 生成部署脚本: sudo ./generate_deploy_script.sh
3、生成 一键自解压 deploy_frpc_self_extract.sh 自动安装脚本
测试所有功能:
# 查看详细安装信息 sudo ./deploy_frpc_self_extract.sh info # 查看服务状态 sudo ./deploy_frpc_self_extract.sh status # 安装(如果需要) sudo ./deploy_frpc_self_extract.sh install # 卸载(如果需要) sudo ./deploy_frpc_self_extract.sh uninstall #这个版本已经完全修复了语法错误,所有命令都应该能正常工作
3、完整脚本如下:generate_deploy_script.sh
#!/bin/bash
# ============================================================
# frpc 自解压部署脚本生成器 - 完全修正版
# 用法: sudo ./generate_deploy_script.sh
# 功能: 生成 deploy_frpc_self_extract.sh(内嵌 frp 压缩包 + 完整功能)
# ============================================================
set -e
# 检查 root 权限
if [[ $EUID -ne 0 ]]; then
echo -e "\033[0;31m[ERROR]\033[0m 请使用 root 权限运行此脚本 (sudo $0)"
exit 1
fi
# 检查 frp 压缩包是否存在
FRP_TAR="frp_0.68.1_linux_arm64.tar.gz"
if [[ ! -f "${FRP_TAR}" ]]; then
echo -e "\033[0;31m[ERROR]\033[0m 未找到压缩包: ${FRP_TAR}"
echo -e "\033[0;31m[ERROR]\033[0m 请确保该文件与本脚本在同一目录"
exit 1
fi
OUTPUT_SCRIPT="deploy_frpc_self_extract.sh"
echo -e "\033[0;34m[INFO]\033[0m 正在生成自解压部署脚本: ${OUTPUT_SCRIPT}"
# 生成目标脚本
cat > "${OUTPUT_SCRIPT}" << 'EOF'
#!/bin/bash
# ============================================================
# frpc 自解压部署脚本 (内嵌 frp_0.68.1_linux_arm64.tar.gz)
# 用法: sudo ./deploy_frpc_self_extract.sh [install|uninstall|status|info]
# install - 安装 frpc 并配置服务
# uninstall - 完全卸载 frpc
# status - 显示当前服务状态
# info - 显示详细的安装信息
# ============================================================
set -e
# -------------------- 配置参数 --------------------
SERVER_ADDR="discover.zhonjin.com"
SERVER_PORT=9443
AUTH_TOKEN="Z8Rpj2uqTvJyqBDe"
INSTALL_DIR="/opt/openAI/frp"
FRPC_BIN="${INSTALL_DIR}/frpc"
CONFIG_FILE="${INSTALL_DIR}/frpc.toml"
LOG_FILE="${INSTALL_DIR}/frpc.log"
SERVICE_FILE="/etc/systemd/system/frpc.service"
SYSTEM_INFO_FILE="${INSTALL_DIR}/system_info.txt"
# -------------------- 颜色定义 --------------------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_color() { echo -e "${1}${2}${NC}"; }
print_info() { print_color "${BLUE}" "[INFO] $1"; }
print_success() { print_color "${GREEN}" "[SUCCESS] $1"; }
print_warning() { print_color "${YELLOW}" "[WARNING] $1"; }
print_error() { print_color "${RED}" "[ERROR] $1"; }
check_root() {
if [[ $EUID -ne 0 ]]; then
print_error "请使用 root 权限运行此脚本 (sudo $0)"
exit 1
fi
}
# -------------------- 系统信息收集 --------------------
collect_system_info() {
print_info "收集系统信息..."
mkdir -p "${INSTALL_DIR}"
cat > "${SYSTEM_INFO_FILE}" <<INFO_EOF
# frpc 系统信息
# 生成时间: $(date)
# 主机名
hostname=$(hostname)
# 操作系统
os=$(cat /etc/os-release 2>/dev/null | grep -E "PRETTY_NAME|NAME" | head -1 | cut -d'"' -f2 || uname -s)
# 内核版本
kernel=$(uname -r)
# CPU 架构
arch=$(uname -m)
# 内存信息
memory=$(free -h | grep Mem | awk '{print $2}')
# 磁盘空间
disk=$(df -h / | awk 'NR==2 {print $4}')
# 网络接口
interfaces=$(ip addr show | grep "state UP" | awk '{print $2}' | tr -d ':' | tr '\n' ',' | sed 's/,$//')
# IP 地址
ips=$(hostname -I | tr ' ' ',')
# 系统负载
load=$(uptime | awk -F'load average:' '{print $2}' | tr -d ' ')
# frpc 版本
frpc_version=$([ -x "${FRPC_BIN}" ] && "${FRPC_BIN}" -v 2>/dev/null || "未安装")
INFO_EOF
print_success "系统信息已保存到: ${SYSTEM_INFO_FILE}"
}
# -------------------- 提取嵌入的 frp 压缩包 --------------------
extract_payload() {
print_info "正在提取内嵌的 frp 压缩包..."
local payload_marker="__PAYLOAD__"
local marker_line=$(grep -a -n "^${payload_marker}$" "$0" | head -1 | cut -d: -f1)
if [[ -z "${marker_line}" ]]; then
print_error "错误:未找到 payload 标记,无法提取嵌入文件"
exit 1
fi
local payload_start=$((marker_line + 1))
local TEMP_DIR=$(mktemp -d)
local TEMP_TAR="${TEMP_DIR}/frp.tar.gz"
# 使用 tail 提取二进制部分
tail -n +${payload_start} "$0" > "${TEMP_TAR}"
if [[ ! -s "${TEMP_TAR}" ]]; then
print_error "提取失败:文件为空"
rm -rf "${TEMP_DIR}" 2>/dev/null || true
exit 1
fi
mkdir -p "${INSTALL_DIR}"
print_info "解压 frp 压缩包..."
tar -xzf "${TEMP_TAR}" -C "${TEMP_DIR}"
local EXTRACTED_FRPC=$(find "${TEMP_DIR}" -name "frpc" -type f | head -n 1)
if [[ -z "${EXTRACTED_FRPC}" ]]; then
print_error "错误:压缩包中未找到 frpc 可执行文件"
print_error "压缩包内容如下:"
tar -tzf "${TEMP_TAR}"
rm -rf "${TEMP_DIR}" 2>/dev/null || true
exit 1
fi
cp -f "${EXTRACTED_FRPC}" "${FRPC_BIN}"
chmod +x "${FRPC_BIN}"
rm -rf "${TEMP_DIR}" 2>/dev/null || true
print_success "frpc 已安装到: ${FRPC_BIN}"
print_info "frpc 版本: $(${FRPC_BIN} -v 2>/dev/null)"
}
# -------------------- 交互式配置生成 --------------------
generate_config() {
clear
echo "=========================================="
echo " frpc 代理配置生成"
echo "=========================================="
echo ""
# 用户名输入(用于代理前缀)
read -p "请输入用户名 (用于代理名称前缀, 示例: PORT_WEB_PRJ): " USER_NAME
while [[ -z "${USER_NAME}" ]]; do
print_error "用户名不能为空"
read -p "请输入用户名 (示例: PORT_WEB_PRJ): " USER_NAME
done
print_info "连接信息已预设:"
echo " 服务器地址 : discover.zhonjin.com"
echo " 服务器端口 : 9443"
echo " Token : Z8Rpj2uqTvJyqBDe"
echo ""
read -p "请输入起始远程端口号 (例如 40710): " BASE_PORT
while ! [[ "${BASE_PORT}" =~ ^[0-9]+$ ]]; do
print_error "端口号必须为数字"
read -p "请输入起始远程端口号: " BASE_PORT
done
PORT_SSH=$BASE_PORT
PORT_HTTP=$((BASE_PORT + 1))
PORT_VNC=$((BASE_PORT + 2))
# 生成带用户名前缀的代理名
cat > "${CONFIG_FILE}" <<CONFIG_EOF
# frpc TOML configuration
# 生成时间: $(date)
# ---------- 全局配置 ----------
clientID = "${USER_NAME}"
user = "${USER_NAME}"
serverAddr = "discover.zhonjin.com"
serverPort = 9443
loginFailExit = false
log.to = "${LOG_FILE}"
log.level = "info"
log.maxDays = 3
log.disablePrintColor = false
auth.method = "token"
auth.token = "Z8Rpj2uqTvJyqBDe"
auth.additionalScopes = ["NewWorkConns"]
transport.poolCount = 50
transport.protocol = "tcp"
transport.tls.enable = true
transport.tls.disableCustomTLSFirstByte = true
transport.heartbeatInterval = 30
transport.heartbeatTimeout = 90
udpPacketSize = 1500
# ---------- 代理列表 ----------
[[proxies]]
name = "${USER_NAME}_ssh_tcp_${PORT_SSH}_22"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = ${PORT_SSH}
transport.useEncryption = true
transport.useCompression = true
[[proxies]]
name = "${USER_NAME}_http_tcp_${PORT_HTTP}_80"
type = "tcp"
localIP = "127.0.0.1"
localPort = 80
remotePort = ${PORT_HTTP}
transport.useEncryption = true
transport.useCompression = true
[[proxies]]
name = "${USER_NAME}_vnc_tcp_${PORT_VNC}_5900"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5900
remotePort = ${PORT_VNC}
transport.useEncryption = true
transport.useCompression = true
CONFIG_EOF
print_success "配置文件已生成: ${CONFIG_FILE}"
print_info "代理前缀使用用户名: ${USER_NAME}"
# 保存配置信息
echo "USERNAME=${USER_NAME}" > "${INSTALL_DIR}/config_info"
echo "BASE_PORT=${BASE_PORT}" >> "${INSTALL_DIR}/config_info"
echo "PORT_SSH=${PORT_SSH}" >> "${INSTALL_DIR}/config_info"
echo "PORT_HTTP=${PORT_HTTP}" >> "${INSTALL_DIR}/config_info"
echo "PORT_VNC=${PORT_VNC}" >> "${INSTALL_DIR}/config_info"
}
# -------------------- systemd 服务管理 --------------------
setup_service() {
print_info "创建 systemd 服务..."
cat > "${SERVICE_FILE}" <<SERVICE_EOF
[Unit]
Description=frp client service (frpc)
After=network.target syslog.target
Wants=network.target
[Service]
Type=simple
User=root
ExecStart=${FRPC_BIN} -c ${CONFIG_FILE}
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=frpc
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=${INSTALL_DIR}
[Install]
WantedBy=multi-user.target
SERVICE_EOF
systemctl daemon-reload
systemctl enable frpc.service 2>/dev/null || true
print_success "systemd 服务已配置"
}
start_service() {
print_info "启动 frpc 服务..."
systemctl stop frpc.service 2>/dev/null || true
systemctl start frpc.service
sleep 2
if systemctl is-active --quiet frpc.service; then
print_success "frpc 服务运行中"
else
print_warning "服务可能未正常启动,请检查日志: journalctl -u frpc -n 20"
journalctl -u frpc -n 20 --no-pager
fi
}
# -------------------- 安装摘要显示 --------------------
show_summary() {
echo ""
echo "=========================================="
echo " 安装摘要"
echo "=========================================="
if [[ ! -f "${INSTALL_DIR}/config_info" ]]; then
print_warning "未找到配置信息文件,可能未完成安装"
return 0
fi
source "${INSTALL_DIR}/config_info" 2>/dev/null
echo -e "${GREEN}✓ 安装成功!${NC}"
echo ""
echo "🔧 配置信息:"
echo " • 用户名: ${USER_NAME}"
echo " • 服务器: ${SERVER_ADDR}:${SERVER_PORT}"
echo ""
echo "🔌 代理端口映射:"
echo " • SSH : 本地 22 端口 → 远程 ${PORT_SSH} 端口"
echo " • HTTP : 本地 80 端口 → 远程 ${PORT_HTTP} 端口"
echo " • VNC : 本地 5900 端口 → 远程 ${PORT_VNC} 端口"
echo ""
echo "📁 文件位置:"
echo " • 可执行文件: ${FRPC_BIN}"
echo " • 配置文件 : ${CONFIG_FILE}"
echo " • 日志文件 : ${LOG_FILE}"
echo " • 系统信息 : ${SYSTEM_INFO_FILE}"
echo ""
echo "⚙️ 服务管理:"
echo " • 启动服务: sudo systemctl start frpc"
echo " • 停止服务: sudo systemctl stop frpc"
echo " • 查看状态: sudo systemctl status frpc"
echo " • 查看日志: sudo journalctl -u frpc -f"
echo ""
echo "💡 使用提示:"
echo " • 连接 SSH: ssh -p ${PORT_SSH} your_username@${SERVER_ADDR}"
echo " • 访问 HTTP: http://${SERVER_ADDR}:${PORT_HTTP}"
echo " • 连接 VNC: vnc://${SERVER_ADDR}:${PORT_VNC}"
echo ""
echo "📋 系统信息:"
if [[ -f "${SYSTEM_INFO_FILE}" ]]; then
grep -E "hostname|os|arch|memory|disk|load" "${SYSTEM_INFO_FILE}" | sed 's/^/# /'
fi
echo ""
echo "✅ 部署完成!服务已启动。"
}
# -------------------- 安装信息显示 --------------------
show_install_info() {
echo ""
echo "=========================================="
echo " 安装信息"
echo "=========================================="
if [[ ! -f "${FRPC_BIN}" ]]; then
echo -e "${RED}× frpc 未安装${NC}"
echo " 请运行: sudo $0 install"
return 0
fi
echo -e "${GREEN}✓ frpc 已安装${NC}"
echo " 版本: $(${FRPC_BIN} -v 2>/dev/null || echo '未知版本')"
echo " 位置: ${FRPC_BIN}"
echo ""
if [[ ! -f "${CONFIG_FILE}" ]]; then
echo -e "${YELLOW}⚠ 配置文件不存在${NC}"
echo " 请运行: sudo $0 install 重新配置"
return 0
fi
echo -e "${GREEN}✓ 配置文件存在${NC}"
echo " 位置: ${CONFIG_FILE}"
# 显示代理配置 - 使用更安全的匹配方式
echo ""
echo "代理配置:"
while IFS= read -r line; do
if echo "$line" | grep -q 'name ='; then
proxy_name=$(echo "$line" | sed 's/.*name = "\(.*\)".*/\1/')
echo " • ${proxy_name}"
elif echo "$line" | grep -q 'remotePort ='; then
port=$(echo "$line" | sed 's/.*remotePort = \([0-9]*\).*/\1/')
echo " 远程端口: ${port}"
fi
done < "${CONFIG_FILE}"
echo ""
echo "服务状态:"
if command -v systemctl >/dev/null 2>&1; then
if systemctl is-active --quiet frpc.service 2>/dev/null; then
echo -e " ${GREEN}✓ frpc 服务正在运行${NC}"
elif systemctl is-enabled --quiet frpc.service 2>/dev/null; then
echo -e " ${YELLOW}⚠ frpc 服务已启用但未运行${NC}"
else
echo -e " ${RED}× frpc 服务未启用${NC}"
fi
else
echo -e " ${YELLOW}⚠ 无法检查服务状态(systemctl 不可用)${NC}"
fi
echo ""
echo "日志信息:"
if [[ -f "${LOG_FILE}" ]]; then
echo " 最后10行日志:"
tail -n 10 "${LOG_FILE}" 2>/dev/null | sed 's/^/ /'
else
echo " ${YELLOW}⚠ 日志文件不存在${NC}"
fi
echo ""
echo "系统资源:"
echo " CPU 负载: $(uptime | awk -F'load average:' '{print $2}' | tr -d ' ')"
echo " 内存使用: $(free -h | grep Mem | awk '{print $3 "/" $2}')"
echo " 磁盘空间: $(df -h / | awk 'NR==2 {print $4 "/" $2}')"
}
# -------------------- 状态检查 --------------------
check_status() {
clear
echo "=========================================="
echo " frpc 服务状态"
echo "=========================================="
echo ""
if [[ ! -f "${FRPC_BIN}" ]]; then
echo -e "${RED}× frpc 未安装${NC}"
echo " 请运行: sudo $0 install"
exit 0
fi
echo -e "${GREEN}✓ frpc 已安装${NC}"
echo " 版本: $(${FRPC_BIN} -v 2>/dev/null || echo '未知版本')"
echo ""
echo "服务状态:"
if command -v systemctl >/dev/null 2>&1; then
systemctl status frpc.service --no-pager 2>/dev/null || echo -e "${YELLOW}⚠ 服务状态未知${NC}"
else
echo -e "${YELLOW}⚠ systemctl 不可用,无法检查服务状态${NC}"
fi
echo ""
echo "配置文件:"
if [[ -f "${CONFIG_FILE}" ]]; then
echo -e "${GREEN}✓ 配置文件存在: ${CONFIG_FILE}${NC}"
echo "代理配置:"
grep "name =" "${CONFIG_FILE}" | sed 's/^/ /'
else
echo -e "${RED}× 配置文件不存在${NC}"
fi
echo ""
echo "日志文件:"
if [[ -f "${LOG_FILE}" ]]; then
echo -e "${GREEN}✓ 日志文件存在: ${LOG_FILE}${NC}"
echo "最后5行日志:"
tail -n 5 "${LOG_FILE}" | sed 's/^/ /'
else
echo -e "${YELLOW}⚠ 日志文件不存在${NC}"
fi
echo ""
echo "系统信息:"
if [[ -f "${SYSTEM_INFO_FILE}" ]]; then
echo -e "${GREEN}✓ 系统信息文件存在${NC}"
grep -E "hostname|os|arch|load" "${SYSTEM_INFO_FILE}" | sed 's/^/ /'
fi
}
# -------------------- 卸载功能 --------------------
uninstall_frpc() {
clear
echo "=========================================="
echo " 卸载 frpc"
echo "=========================================="
echo ""
print_warning "即将删除以下内容:"
echo " - systemd 服务文件: ${SERVICE_FILE}"
echo " - 安装目录: ${INSTALL_DIR}"
echo " - 所有配置文件和日志"
echo ""
# 显示当前配置信息
if [[ -f "${INSTALL_DIR}/config_info" ]]; then
source "${INSTALL_DIR}/config_info" 2>/dev/null
echo "当前配置:"
echo " • 用户名: ${USER_NAME}"
echo " • SSH 端口: ${PORT_SSH}"
echo " • HTTP 端口: ${PORT_HTTP}"
echo " • VNC 端口: ${PORT_VNC}"
echo ""
fi
read -p "确认卸载?(输入 yes 继续): " CONFIRM
if [[ "${CONFIRM}" != "yes" ]]; then
print_info "已取消卸载"
exit 0
fi
print_info "正在卸载 frpc..."
# 停止服务
if command -v systemctl >/dev/null 2>&1; then
if systemctl is-active --quiet frpc.service 2>/dev/null; then
systemctl stop frpc.service
print_success "已停止 frpc 服务"
fi
# 禁用服务
if systemctl is-enabled --quiet frpc.service 2>/dev/null; then
systemctl disable frpc.service
print_success "已禁用 frpc 服务"
fi
# 删除服务文件
if [[ -f "${SERVICE_FILE}" ]]; then
rm -f "${SERVICE_FILE}"
systemctl daemon-reload
print_success "已删除服务文件"
fi
fi
# 删除安装目录
if [[ -d "${INSTALL_DIR}" ]]; then
rm -rf "${INSTALL_DIR}"
print_success "已删除安装目录"
fi
print_success "frpc 已完全卸载"
echo ""
echo "卸载完成!所有相关文件已被清理。"
}
# -------------------- 主入口 --------------------
main() {
check_root
local ACTION="${1:-install}"
case "${ACTION}" in
install)
extract_payload
generate_config
collect_system_info
setup_service
start_service
show_summary
;;
uninstall)
uninstall_frpc
;;
status)
check_status
;;
info)
show_install_info
;;
*)
print_error "未知命令: ${ACTION}"
echo "用法: sudo $0 [install|uninstall|status|info]"
echo " install - 安装 frpc 并配置服务"
echo " uninstall - 完全卸载 frpc"
echo " status - 显示当前服务状态"
echo " info - 显示详细的安装信息"
exit 1
;;
esac
}
# 设置执行权限
chmod a+x "$0"
# 执行主函数
main "$@"
exit 0
__PAYLOAD__
EOF
# 追加原始压缩包
echo -e "\033[0;34m[INFO]\033[0m 将 ${FRP_TAR} 嵌入到 ${OUTPUT_SCRIPT}..."
cat "${FRP_TAR}" >> "${OUTPUT_SCRIPT}"
# 设置权限并验证
chmod a+x "${OUTPUT_SCRIPT}"
if grep -q "__PAYLOAD__" "${OUTPUT_SCRIPT}"; then
echo -e "\033[0;32m[SUCCESS]\033[0m 脚本生成成功: ${OUTPUT_SCRIPT}"
echo ""
echo "使用方法:"
echo " sudo ./${OUTPUT_SCRIPT} install # 安装(会提示输入用户名和端口)"
echo " sudo ./${OUTPUT_SCRIPT} uninstall # 卸载"
echo " sudo ./${OUTPUT_SCRIPT} status # 查看状态"
echo " sudo ./${OUTPUT_SCRIPT} info # 查看详细安装信息"
else
echo -e "\033[0;31m[ERROR]\033[0m 生成失败:未找到 payload 标记"
exit 1
fi
自适应IP