#!/bin/bash
# FRP 自动化部署脚本
# 支持一键部署 frps(服务端) 和 frpc(客户端)
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
# 配置参数
FRP_VERSION="0.38.0"
WORK_DIR="/opt/frp"
FRPS_INI="$WORK_DIR/frps.ini"
FRPC_INI="$WORK_DIR/frpc.ini"
DOCKER_COMPOSE="$WORK_DIR/docker-compose.yml"
TOKEN=$(openssl rand -base64 16 | tr -d '+/=' | cut -c1-16) # 自动生成安全令牌
DEPLOY_TYPE="" # 全局变量
FRPS_SERVER_PORT=7000
FRPS_DASHBOARD_PORT=7500
# 检查依赖
check_dependency() {
command -v $1 >/dev/null 2>&1 || { echo -e "${RED}错误: 需要安装 $1${NC}"; exit 1; }
}
# 创建工作目录
create_dir() {
mkdir -p $WORK_DIR
cd $WORK_DIR || exit
}
# 生成 frps 配置
generate_frps_config() {
echo -e "${YELLOW}生成 frps 配置文件...${NC}"
cat > "$FRPS_INI" << EOF
[common]
bind_port = $FRPS_SERVER_PORT
token = $TOKEN
dashboard_port = $FRPS_DASHBOARD_PORT
dashboard_user = admin
dashboard_pwd = admin
log_level = info
log_max_days = 30
EOF
echo -e "${GREEN}frps 配置已生成: $FRPS_INI${NC}"
}
# 生成 frpc 配置
generate_frpc_config() {
echo -e "${YELLOW}生成 frpc 配置文件...${NC}"
read -p "请输入 frps 服务器 IP: " SERVER_IP
read -p "请输入 SSH 本地端口 [22]: " SSH_LOCAL_PORT
SSH_LOCAL_PORT=${SSH_LOCAL_PORT:-22}
read -p "请输入 SSH 远程映射端口 [6000]: " SSH_REMOTE_PORT
SSH_REMOTE_PORT=${SSH_REMOTE_PORT:-6000}
cat > "$FRPC_INI" << EOF
[common]
server_addr = $SERVER_IP
server_port = $FRPS_SERVER_PORT
token = $TOKEN
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = $SSH_LOCAL_PORT
remote_port = $SSH_REMOTE_PORT
EOF
echo -e "${GREEN}frpc 配置已生成: $FRPC_INI${NC}"
}
# 生成 Docker Compose 文件
generate_docker_compose() {
while true; do
read -p "部署类型 (server/client/both): " input_type
DEPLOY_TYPE=$(echo "$input_type" | tr '[:upper:]' '[:lower:]')
case $DEPLOY_TYPE in
server|client|both)
break
;;
*)
echo -e "${RED}错误: 未知部署类型,请输入 server、client 或 both${NC}"
;;
esac
done
echo -e "${YELLOW}生成 Docker Compose 配置...${NC}"
case $DEPLOY_TYPE in
server)
cat > "$DOCKER_COMPOSE" << EOF
version: '3'
services:
frps:
image: snowdreamtech/frps:$FRP_VERSION
container_name: frps
volumes:
- ./frps.ini:/etc/frp/frps.ini
ports:
- "$FRPS_SERVER_PORT:$FRPS_SERVER_PORT"
- "$FRPS_DASHBOARD_PORT:$FRPS_DASHBOARD_PORT"
restart: always
EOF
;;
client)
cat > "$DOCKER_COMPOSE" << EOF
version: '3'
services:
frpc:
image: snowdreamtech/frpc:$FRP_VERSION
container_name: frpc
volumes:
- ./frpc.ini:/etc/frp/frpc.ini
restart: always
EOF
;;
both)
cat > "$DOCKER_COMPOSE" << EOF
version: '3'
services:
frps:
image: snowdreamtech/frps:$FRP_VERSION
container_name: frps
volumes:
- ./frps.ini:/etc/frp/frps.ini
ports:
- "$FRPS_SERVER_PORT:$FRPS_SERVER_PORT"
- "$FRPS_DASHBOARD_PORT:$FRPS_DASHBOARD_PORT"
restart: always
frpc:
image: snowdreamtech/frpc:$FRP_VERSION
container_name: frpc
volumes:
- ./frpc.ini:/etc/frp/frpc.ini
restart: always
depends_on:
- frps
EOF
;;
esac
echo -e "${GREEN}Docker Compose 配置已生成: $DOCKER_COMPOSE${NC}"
}
# 部署服务
deploy() {
echo -e "${YELLOW}开始部署 FRP 服务...${NC}"
check_dependency docker
check_dependency docker-compose
create_dir
generate_docker_compose
if [[ $DEPLOY_TYPE == "server" || $DEPLOY_TYPE == "both" ]]; then
generate_frps_config
fi
if [[ $DEPLOY_TYPE == "client" || $DEPLOY_TYPE == "both" ]]; then
generate_frpc_config
fi
# 启动服务
cd "$WORK_DIR" || exit
docker-compose up -d
echo -e "${GREEN}部署完成!${NC}"
echo -e "${GREEN}工作目录: $WORK_DIR${NC}"
# 显示状态
show_status
}
# 启动 frps 服务
start_frps() {
echo -e "${YELLOW}启动 frps 服务...${NC}"
cd "$WORK_DIR" || exit
docker-compose start frps
echo -e "${GREEN}frps 服务已启动${NC}"
show_status
}
# 启动 frpc 服务
start_frpc() {
echo -e "${YELLOW}启动 frpc 服务...${NC}"
cd "$WORK_DIR" || exit
docker-compose start frpc
echo -e "${GREEN}frpc 服务已启动${NC}"
show_status
}
# 重启 frpc 服务
restart_frpc() {
echo -e "${YELLOW}重启 frpc 服务...${NC}"
cd "$WORK_DIR" || exit
docker-compose restart frpc
echo -e "${GREEN}frpc 服务已重启${NC}"
show_status
}
# 停止 frps 服务
stop_frps() {
echo -e "${YELLOW}停止 frps 服务...${NC}"
cd "$WORK_DIR" || exit
docker-compose stop frps
echo -e "${GREEN}frps 服务已停止${NC}"
}
# 停止 frpc 服务
stop_frpc() {
echo -e "${YELLOW}停止 frpc 服务...${NC}"
cd "$WORK_DIR" || exit
docker-compose stop frpc
echo -e "${GREEN}frpc 服务已停止${NC}"
}
# 停止所有服务
stop_all() {
echo -e "${YELLOW}停止所有 FRP 服务...${NC}"
cd "$WORK_DIR" || exit
docker-compose stop
echo -e "${GREEN}所有服务已停止${NC}"
}
# 显示服务状态
show_status() {
echo -e "${YELLOW}服务状态:${NC}"
cd "$WORK_DIR" || exit
docker-compose ps
if [[ -n $DEPLOY_TYPE && ( $DEPLOY_TYPE == "server" || $DEPLOY_TYPE == "both" ) ]]; then
SERVER_IP=$(hostname -I | awk '{print $1}')
echo -e "${GREEN}frps 仪表盘: http://$SERVER_IP:$FRPS_DASHBOARD_PORT (用户名: admin, 密码: admin)${NC}"
echo -e "${GREEN}认证令牌: $TOKEN${NC}"
fi
}
# 查看日志
logs() {
if [ -z "$1" ]; then
echo -e "${RED}请指定服务名称 (frps/frpc)${NC}"
return 1
fi
cd "$WORK_DIR" || exit
docker-compose logs -f --tail=100 "$1"
}
# 主菜单
show_menu() {
while true; do
echo -e "${GREEN}==== FRP 自动化部署工具 ====${NC}"
echo -e "${YELLOW}1. 部署服务${NC}"
echo -e "${YELLOW}2. 启动 frps 服务${NC}"
echo -e "${YELLOW}3. 启动 frpc 服务${NC}"
echo -e "${YELLOW}4. 重启 frpc 服务${NC}"
echo -e "${YELLOW}5. 停止 frps 服务${NC}"
echo -e "${YELLOW}6. 停止 frpc 服务${NC}"
echo -e "${YELLOW}7. 停止所有服务${NC}"
echo -e "${YELLOW}8. 查看服务状态${NC}"
echo -e "${YELLOW}9. 查看 frps 日志${NC}"
echo -e "${YELLOW}10. 查看 frpc 日志${NC}"
echo -e "${YELLOW}11. 退出${NC}"
echo -e "${GREEN}=========================${NC}"
read -p "请选择操作 [1-11]: " choice
case $choice in
1) deploy ;;
2) start_frps ;;
3) start_frpc ;;
4) restart_frpc ;;
5) stop_frps ;;
6) stop_frpc ;;
7) stop_all ;;
8) show_status ;;
9) logs frps ;;
10) logs frpc ;;
11) exit 0 ;;
*) echo -e "${RED}无效选择,请输入 1-11${NC}" ;;
esac
done
}
# 执行主菜单
show_menu