#!/bin/bash
# FRP 自動(dòng)化部署腳本
# 支持一鍵部署 frps(服務(wù)端) 和 frpc(客戶(hù)端)
# 顏色定義
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
# 配置參數(shù)
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) # 自動(dòng)生成安全令牌
DEPLOY_TYPE="" # 全局變量
FRPS_SERVER_PORT=7000
FRPS_DASHBOARD_PORT=7500
# 檢查依賴(lài)
check_dependency() {
command -v $1 >/dev/null 2>&1 || { echo -e "${RED}錯(cuò)誤: 需要安裝 $1${NC}"; exit 1; }
}
# 創(chuàng)建工作目錄
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 "請(qǐng)輸入 frps 服務(wù)器 IP: " SERVER_IP
read -p "請(qǐng)輸入 SSH 本地端口 [22]: " SSH_LOCAL_PORT
SSH_LOCAL_PORT=${SSH_LOCAL_PORT:-22}
read -p "請(qǐng)輸入 SSH 遠(yuǎn)程映射端口 [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 "部署類(lèi)型 (server/client/both): " input_type
DEPLOY_TYPE=$(echo "$input_type" | tr '[:upper:]' '[:lower:]')
case $DEPLOY_TYPE in
server|client|both)
break
;;
*)
echo -e "${RED}錯(cuò)誤: 未知部署類(lèi)型,請(qǐng)輸入 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}"
}
# 部署服務(wù)
deploy() {
echo -e "${YELLOW}開(kāi)始部署 FRP 服務(wù)...${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
# 啟動(dòng)服務(wù)
cd "$WORK_DIR" || exit
docker-compose up -d
echo -e "${GREEN}部署完成!${NC}"
echo -e "${GREEN}工作目錄: $WORK_DIR${NC}"
# 顯示狀態(tài)
show_status
}
# 啟動(dòng) frps 服務(wù)
start_frps() {
echo -e "${YELLOW}啟動(dòng) frps 服務(wù)...${NC}"
cd "$WORK_DIR" || exit
docker-compose start frps
echo -e "${GREEN}frps 服務(wù)已啟動(dòng)${NC}"
show_status
}
# 啟動(dòng) frpc 服務(wù)
start_frpc() {
echo -e "${YELLOW}啟動(dòng) frpc 服務(wù)...${NC}"
cd "$WORK_DIR" || exit
docker-compose start frpc
echo -e "${GREEN}frpc 服務(wù)已啟動(dòng)${NC}"
show_status
}
# 重啟 frpc 服務(wù)
restart_frpc() {
echo -e "${YELLOW}重啟 frpc 服務(wù)...${NC}"
cd "$WORK_DIR" || exit
docker-compose restart frpc
echo -e "${GREEN}frpc 服務(wù)已重啟${NC}"
show_status
}
# 停止 frps 服務(wù)
stop_frps() {
echo -e "${YELLOW}停止 frps 服務(wù)...${NC}"
cd "$WORK_DIR" || exit
docker-compose stop frps
echo -e "${GREEN}frps 服務(wù)已停止${NC}"
}
# 停止 frpc 服務(wù)
stop_frpc() {
echo -e "${YELLOW}停止 frpc 服務(wù)...${NC}"
cd "$WORK_DIR" || exit
docker-compose stop frpc
echo -e "${GREEN}frpc 服務(wù)已停止${NC}"
}
# 停止所有服務(wù)
stop_all() {
echo -e "${YELLOW}停止所有 FRP 服務(wù)...${NC}"
cd "$WORK_DIR" || exit
docker-compose stop
echo -e "${GREEN}所有服務(wù)已停止${NC}"
}
# 顯示服務(wù)狀態(tài)
show_status() {
echo -e "${YELLOW}服務(wù)狀態(tài):${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 儀表盤(pán): http://$SERVER_IP:$FRPS_DASHBOARD_PORT (用戶(hù)名: admin, 密碼: admin)${NC}"
echo -e "${GREEN}認(rèn)證令牌: $TOKEN${NC}"
fi
}
# 查看日志
logs() {
if [ -z "$1" ]; then
echo -e "${RED}請(qǐng)指定服務(wù)名稱(chēng) (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 自動(dòng)化部署工具 ====${NC}"
echo -e "${YELLOW}1. 部署服務(wù)${NC}"
echo -e "${YELLOW}2. 啟動(dòng) frps 服務(wù)${NC}"
echo -e "${YELLOW}3. 啟動(dòng) frpc 服務(wù)${NC}"
echo -e "${YELLOW}4. 重啟 frpc 服務(wù)${NC}"
echo -e "${YELLOW}5. 停止 frps 服務(wù)${NC}"
echo -e "${YELLOW}6. 停止 frpc 服務(wù)${NC}"
echo -e "${YELLOW}7. 停止所有服務(wù)${NC}"
echo -e "${YELLOW}8. 查看服務(wù)狀態(tài)${NC}"
echo -e "${YELLOW}9. 查看 frps 日志${NC}"
echo -e "${YELLOW}10. 查看 frpc 日志${NC}"
echo -e "${YELLOW}11. 退出${NC}"
echo -e "${GREEN}=========================${NC}"
read -p "請(qǐng)選擇操作 [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}無(wú)效選擇,請(qǐng)輸入 1-11${NC}" ;;
esac
done
}
# 執(zhí)行主菜單
show_menu