tailscale/install_derp_server.sh
2025-10-04 06:54:30 -04:00

571 lines
15 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Tailscale DERP 服务器一键安装脚本 (支持自签名IP证书)
# 本脚本适用于 Ubuntu/Debian 系统
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查是否为root用户
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "此脚本需要以root权限运行"
exit 1
fi
}
# 检查系统类型
check_system() {
if [[ ! -f /etc/os-release ]]; then
log_error "无法检测系统类型"
exit 1
fi
source /etc/os-release
case $ID in
ubuntu|debian)
PACKAGE_MANAGER="apt"
;;
centos|rhel|fedora)
PACKAGE_MANAGER="yum"
;;
*)
log_error "不支持的系统类型: $ID"
exit 1
;;
esac
log_info "检测到系统: $PRETTY_NAME"
}
# 安装依赖
install_dependencies() {
log_info "安装依赖包..."
case $PACKAGE_MANAGER in
apt)
apt update
apt install -y curl wget git build-essential openssl nginx
;;
yum)
yum update -y
yum install -y curl wget git gcc make openssl nginx
;;
esac
log_info "依赖包安装完成"
}
# 启用BBR优化
enable_bbr() {
log_info "启用BBR网络优化..."
# 检查内核版本
KERNEL_VERSION=$(uname -r | cut -d. -f1-2)
KERNEL_MAJOR=$(echo $KERNEL_VERSION | cut -d. -f1)
KERNEL_MINOR=$(echo $KERNEL_VERSION | cut -d. -f2)
if [[ $KERNEL_MAJOR -lt 4 ]] || [[ $KERNEL_MAJOR -eq 4 && $KERNEL_MINOR -lt 9 ]]; then
log_warn "内核版本过低 ($KERNEL_VERSION)BBR需要4.9+版本"
return
fi
# 检查BBR是否已启用
if sysctl net.ipv4.tcp_congestion_control | grep -q bbr; then
log_info "BBR已经启用"
return
fi
# 备份原始配置
cp /etc/sysctl.conf /etc/sysctl.conf.backup.$(date +%Y%m%d_%H%M%S)
# 添加BBR配置
cat >> /etc/sysctl.conf << EOF
# BBR网络优化配置
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# 其他网络优化参数
net.ipv4.tcp_rmem = 8192 262144 536870912
net.ipv4.tcp_wmem = 4096 16384 536870912
net.core.rmem_max = 536870912
net.core.wmem_max = 536870912
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_slow_start_after_idle = 0
EOF
# 应用配置
sysctl -p
# 验证BBR是否启用成功
if sysctl net.ipv4.tcp_congestion_control | grep -q bbr; then
log_info "BBR启用成功"
else
log_error "BBR启用失败"
fi
# 显示当前拥塞控制算法
log_info "当前拥塞控制算法: $(sysctl -n net.ipv4.tcp_congestion_control)"
}
# 安装Go环境
install_go() {
log_info "安装Go环境..."
# 检查Go是否已安装
if command -v go &> /dev/null; then
log_info "Go已经安装版本: $(go version)"
# 设置Go代理
export GOPROXY=https://goproxy.cn,direct
echo 'export GOPROXY=https://goproxy.cn,direct' >> /etc/profile
return
fi
# 下载并安装Go
GO_VERSION="1.23.3"
wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
tar -zxvf go${GO_VERSION}.linux-amd64.tar.gz
rm go${GO_VERSION}.linux-amd64.tar.gz
# 移动到正确位置
mv go /usr/local/
# 设置环境变量
export PATH=$PATH:/usr/local/go/bin
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
# 设置Go代理
export GOPROXY=https://goproxy.cn,direct
echo 'export GOPROXY=https://goproxy.cn,direct' >> /etc/profile
log_info "Go环境安装完成"
}
# 编译DERP服务器
compile_derp() {
log_info "编译DERP服务器..."
# 创建工作目录
mkdir -p /home/derp
cd /home/derp
# 设置Go代理
export GOPROXY=https://goproxy.cn,direct
# 直接从源码构建derper二进制文件
log_info "从源码构建derper二进制文件..."
/usr/local/go/bin/go install tailscale.com/cmd/derper@main
# 查找编译后的二进制文件
GOPATH=$(go env GOPATH)
if [[ -z "$GOPATH" ]]; then
GOPATH="$HOME/go"
fi
# 复制到工作目录
if [[ -f "$GOPATH/bin/derper" ]]; then
cp "$GOPATH/bin/derper" /home/derp/
else
log_error "未找到编译后的derper二进制文件"
exit 1
fi
# 验证编译结果
if [[ ! -f /home/derp/derper ]]; then
log_error "DERP服务器编译失败"
exit 1
fi
log_info "DERP服务器编译完成"
}
# 配置用户提供的证书
configure_user_cert() {
log_info "配置用户提供的证书..."
# 获取服务器IP地址
read -p "请输入服务器IP地址: " SERVER_IP
if [[ -z "$SERVER_IP" ]]; then
log_error "IP地址不能为空"
exit 1
fi
# 获取证书文件路径
read -p "请输入证书文件路径 (.crt/.pem文件): " CERT_PATH
if [[ -z "$CERT_PATH" ]]; then
log_error "证书文件路径不能为空"
exit 1
fi
if [[ ! -f "$CERT_PATH" ]]; then
log_error "证书文件不存在: $CERT_PATH"
exit 1
fi
# 获取私钥文件路径
read -p "请输入私钥文件路径 (.key文件): " KEY_PATH
if [[ -z "$KEY_PATH" ]]; then
log_error "私钥文件路径不能为空"
exit 1
fi
if [[ ! -f "$KEY_PATH" ]]; then
log_error "私钥文件不存在: $KEY_PATH"
exit 1
fi
# 创建证书目录
mkdir -p /etc/derper/certs
# 复制证书文件
cp "$CERT_PATH" /etc/derper/certs/server.crt
cp "$KEY_PATH" /etc/derper/certs/server.key
# 设置证书权限
chmod 600 /etc/derper/certs/server.key
chmod 644 /etc/derper/certs/server.crt
# 验证证书
if ! openssl x509 -in /etc/derper/certs/server.crt -noout -text > /dev/null 2>&1; then
log_error "证书文件格式无效"
exit 1
fi
# 验证私钥
if ! openssl rsa -in /etc/derper/certs/server.key -check -noout > /dev/null 2>&1; then
log_error "私钥文件格式无效"
exit 1
fi
# 计算证书哈希
CERT_HASH=$(openssl x509 -in /etc/derper/certs/server.crt -noout -fingerprint -sha256 | cut -d= -f2 | tr -d : | tr '[:upper:]' '[:lower:]')
log_info "证书配置完成"
log_info "证书SHA256哈希: $CERT_HASH"
# 保存配置信息
echo "SERVER_IP=$SERVER_IP" > /etc/derper/config
echo "CERT_HASH=$CERT_HASH" >> /etc/derper/config
echo "CERT_PATH=$CERT_PATH" >> /etc/derper/config
echo "KEY_PATH=$KEY_PATH" >> /etc/derper/config
}
# 安装Tailscale客户端
install_tailscale() {
log_info "安装Tailscale客户端..."
# 使用xEdge镜像安装Tailscale (国内优化)
log_info "使用xEdge镜像安装Tailscale..."
curl -fsSL https://ts-mirror.xedge.cc/install.sh | sh
# 如果xEdge镜像失败回退到官方安装
if ! command -v tailscale &> /dev/null; then
log_warn "xEdge镜像安装失败尝试官方镜像..."
curl -fsSL https://tailscale.com/install.sh | sh
fi
log_info "Tailscale客户端安装完成"
log_warn "请运行 'tailscale up' 来连接到您的Tailnet网络"
}
# 创建systemd服务
create_systemd_service() {
log_info "创建systemd服务..."
# 读取配置
source /etc/derper/config
# 显示运行模式选择
echo "请选择DERP服务器运行模式"
echo "1. 直接使用自签名证书的HTTPS模式 (推荐)"
echo "2. Nginx反向代理模式"
echo "3. 自定义配置"
read -p "请输入选择 (1-3): " DERP_MODE
case $DERP_MODE in
1)
# 直接HTTPS模式使用自签名证书
DERP_CMD="/home/derp/derper -hostname $SERVER_IP -certmode manual -certdir /etc/derper/certs -a :443 -http-port 80 -stun-port 3478 -verify-clients"
;;
2)
# Nginx反向代理模式
DERP_CMD="/home/derp/derper -hostname $SERVER_IP -a :8080 -stun-port 3478 -verify-clients"
;;
3)
# 自定义配置
read -p "请输入自定义命令参数: " CUSTOM_ARGS
DERP_CMD="/home/derp/derper -hostname $SERVER_IP $CUSTOM_ARGS"
;;
*)
log_warn "无效选择,使用默认配置"
DERP_CMD="/home/derp/derper -hostname $SERVER_IP -a :8080 -stun-port 3478 -verify-clients"
;;
esac
cat > /etc/systemd/system/derper.service << EOF
[Unit]
Description=Tailscale DERP Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/home/derp
ExecStart=$DERP_CMD
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# 保存运行模式到配置文件
echo "DERP_MODE=$DERP_MODE" >> /etc/derper/config
echo "DERP_CMD='$DERP_CMD'" >> /etc/derper/config
# 重载systemd并启动服务
systemctl daemon-reload
systemctl enable derper
log_info "systemd服务创建完成"
}
# 配置Nginx反向代理
configure_nginx() {
# 读取配置
source /etc/derper/config
# 只有在Nginx反向代理模式下才配置Nginx
if [[ "$DERP_MODE" != "2" ]]; then
log_info "跳过Nginx配置不需要反向代理"
return
fi
log_info "配置Nginx反向代理..."
# 创建Nginx配置
cat > /etc/nginx/sites-available/derper << EOF
server {
listen 80;
server_name $SERVER_IP;
location /derp {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
# WebSocket支持
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
}
}
server {
listen 443 ssl;
server_name $SERVER_IP;
ssl_certificate /etc/derper/certs/server.crt;
ssl_certificate_key /etc/derper/certs/server.key;
location /derp {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
# WebSocket支持
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
}
}
EOF
# 启用站点
ln -sf /etc/nginx/sites-available/derper /etc/nginx/sites-enabled/
# 测试配置并重启Nginx
nginx -t && systemctl restart nginx
log_info "Nginx配置完成"
}
# 生成官方Tailscale配置信息
generate_tailscale_config() {
log_info "生成官方Tailscale配置信息..."
# 读取配置
source /etc/derper/config
# 创建配置信息文件
mkdir -p /etc/derper
# 生成官方Tailscale ACL配置示例
# 读取运行模式
DERP_PORT=443
if [[ "$DERP_MODE" == "2" ]]; then
DERP_PORT=443 # Nginx反向代理会处理HTTPS
fi
cat > /etc/derper/tailscale_acl.json << EOF
{
"derpMap": {
"Regions": {
"900": {
"RegionID": 900,
"RegionCode": "custom",
"RegionName": "Custom DERP Server",
"Nodes": [
{
"Name": "derp-$SERVER_IP",
"RegionID": 900,
"HostName": "$SERVER_IP",
"IPv4": "$SERVER_IP",
"CertName": "sha256:$CERT_HASH",
"DERPPort": $DERP_PORT,
"STUNPort": 3478
}
]
}
}
}
}
EOF
log_info "官方Tailscale配置信息已生成: /etc/derper/tailscale_acl.json"
}
# 启动服务
start_services() {
log_info "启动服务..."
# 启动DERP服务
systemctl start derper
# 检查服务状态
if systemctl is-active --quiet derper; then
log_info "DERP服务启动成功"
else
log_error "DERP服务启动失败"
systemctl status derper
exit 1
fi
# 只有在Nginx反向代理模式下才启动Nginx
if [[ "$DERP_MODE" == "2" ]]; then
systemctl enable nginx
systemctl start nginx
log_info "Nginx服务启动完成"
fi
log_info "所有服务启动完成"
}
# 显示配置信息
show_config_info() {
log_info "安装完成!"
# 读取配置
source /etc/derper/config
echo
echo "================================="
echo "DERP服务器配置信息"
echo "================================="
echo "服务器IP: $SERVER_IP"
echo "证书SHA256: $CERT_HASH"
echo "运行模式: $DERP_MODE"
case $DERP_MODE in
1)
echo "访问方式: 直接HTTPS访问"
echo "DERP端口: 443 (HTTPS)"
echo "HTTP端口: 80 (自动跳转到HTTPS)"
echo "STUN端口: 3478"
;;
2)
echo "访问方式: Nginx反向代理"
echo "DERP端口: 443 (HTTPS, 通过Nginx)"
echo "内部端口: 8080 (HTTP)"
echo "STUN端口: 3478"
;;
3)
echo "访问方式: 自定义配置"
echo "命令参数: $DERP_CMD"
;;
esac
echo "配置文件: /etc/derper/tailscale_acl.json"
echo
echo "服务管理命令:"
echo " 启动: systemctl start derper"
echo " 停止: systemctl stop derper"
echo " 重启: systemctl restart derper"
echo " 状态: systemctl status derper"
echo
echo "测试连接:"
echo " curl https://$SERVER_IP/derp"
echo
echo "官方Tailscale配置:"
echo " 配置文件: /etc/derper/tailscale_acl.json"
echo " 在Tailscale Admin Console中添加自定DERP服务器"
echo " 访问: https://login.tailscale.com/admin/dns"
echo
echo "重要提示:"
echo " 1. 请确保防火墙开放443端口"
echo " 2. 运行 'tailscale up' 连接到Tailnet"
echo " 3. 在Tailscale Admin Console中添加DERP服务器"
echo " 4. 使用自签名证书需要在ACL中指定证书哈希"
echo "================================="
}
# 主函数
main() {
log_info "开始安装Tailscale DERP服务器..."
check_root
check_system
install_dependencies
enable_bbr
install_go
compile_derp
configure_user_cert
install_tailscale
create_systemd_service
configure_nginx
generate_tailscale_config
start_services
show_config_info
log_info "安装完成!"
}
# 运行主函数
main "$@"