基于新版frp与多域名SSL证书,构建安全内网Web服务集群

基于新版frp与多域名SSL证书,构建安全内网Web服务集群 1. 为什么需要内网Web服务集群的安全暴露方案最近几年远程办公和分布式团队越来越普遍很多开发者都会遇到这样的场景本地开发环境需要给同事临时访问测试环境要给产品经理演示内部管理系统要让异地办公的同事使用。传统的解决方案要么是直接暴露内网端口极其危险要么是让所有人连公司内网操作复杂都不是理想的选择。我去年就遇到过这样的困境团队有3个不同的内部系统需要让外地同事访问分别是开发环境3000端口、测试平台4000端口和文档管理系统5000端口。最初尝试用端口映射结果第二天就收到了云服务商的安全警告。后来改用frp方案不仅解决了访问问题还意外获得了以下优势统一入口所有服务通过不同子域名访问无需记忆端口号HTTPS加密避免敏感数据明文传输访问控制通过token实现基础认证集中管理一个服务端管理所有穿透连接新版frp最大的改进是配置全面转向TOML格式比原来的INI格式更规范支持嵌套结构特别适合多服务配置。配合多域名SSL证书可以轻松实现一个公网IPN个HTTPS服务的架构。2. 准备工作与基础环境搭建2.1 域名与证书规划假设我们主域名是example.com计划暴露三个服务dev.example.com → 本地开发环境3000端口test.example.com → 测试环境4000端口docs.example.com → 文档系统5000端口证书方案有两种选择单域名证书为每个子域名单独申请适合不同时期上线的服务通配符证书*.example.com覆盖所有子域成本略高但管理方便我推荐使用Lets Encrypt的免费通配符证书用certbot-auto工具获取sudo certbot certonly --manual --preferred-challengesdns \ -d *.example.com -d example.com --server https://acme-v02.api.letsencrypt.org/directory证书文件通常保存在/etc/letsencrypt/live/example.com/目录下包含fullchain.pem证书链privkey.pem私钥2.2 服务器基础配置云服务器建议选择2核4G以上配置操作系统推荐Ubuntu 22.04 LTS。需要开放以下防火墙端口7000frp服务端控制端口443HTTPS访问端口7500管理后台端口可选安全组设置示例sudo ufw allow 7000/tcp sudo ufw allow 443/tcp sudo ufw allow 7500/tcp sudo ufw enable3. frp服务端深度配置3.1 服务端安装与启动从GitHub下载最新版frp当前v0.53.2wget https://github.com/fatedier/frp/releases/download/v0.53.2/frp_0.53.2_linux_amd64.tar.gz tar -zxvf frp_0.53.2_linux_amd64.tar.gz cd frp_0.53.2_linux_amd64配置文件frps.toml的核心参数详解bindPort 7000 # 控制通道端口 vhostHTTPSPort 443 # HTTPS访问端口 # 安全认证配置 auth.token your_strong_password_here # 管理后台配置建议修改默认密码 webServer.addr 0.0.0.0 webServer.port 7500 webServer.user admin webServer.password new_password_123 # 高级配置 transport.tls.force true # 强制TLS加密 log.level info # 日志级别启动命令建议用systemd托管sudo tee /etc/systemd/system/frps.service EOF [Unit] DescriptionFrp Server Service Afternetwork.target [Service] Typesimple Usernobody Restarton-failure ExecStart/path/to/frps -c /path/to/frps.toml [Install] WantedBymulti-user.target EOF sudo systemctl enable frps sudo systemctl start frps3.2 多证书管理技巧当有多个域名证书时推荐按以下目录结构组织/frp/ ├── ssl/ │ ├── dev.example.com/ │ │ ├── fullchain.pem │ │ └── privkey.pem │ ├── test.example.com/ │ │ ├── fullchain.pem │ │ └── privkey.pem │ └── docs.example.com/ │ ├── fullchain.pem │ └── privkey.pem └── frps.toml可以通过脚本自动同步证书更新Lets Encrypt证书每90天需要续期#!/bin/bash # 证书更新后执行此脚本 cp /etc/letsencrypt/live/dev.example.com/* /frp/ssl/dev.example.com/ cp /etc/letsencrypt/live/test.example.com/* /frp/ssl/test.example.com/ systemctl restart frps4. 客户端配置实战4.1 Windows客户端配置下载Windows版frp并解压后建议目录结构frpc/ ├── ssl/ │ ├── dev.example.com/ │ │ ├── fullchain.pem │ │ └── privkey.pem │ └── ... └── frpc.toml完整配置示例serverAddr your_server_ip serverPort 7000 auth.token your_strong_password_here [[proxies]] name dev_service type https customDomains [dev.example.com] [proxies.plugin] type https2http localAddr 127.0.0.1:3000 crtPath ./ssl/dev.example.com/fullchain.pem keyPath ./ssl/dev.example.com/privkey.pem hostHeaderRewrite 127.0.0.1 requestHeaders.set.x-from-where frp [[proxies]] name test_service type https customDomains [test.example.com] [proxies.plugin] type https2http localAddr 127.0.0.1:4000 crtPath ./ssl/test.example.com/fullchain.pem keyPath ./ssl/test.example.com/privkey.pem hostHeaderRewrite 127.0.0.1 # 更多服务配置...4.2 Linux客户端配置对于内网Linux服务器建议用nohup后台运行nohup ./frpc -c frpc.toml frpc.log 21 或者配置为systemd服务类似服务端配置。5. 高级安全加固方案5.1 网络层防护建议在frp服务端前部署Nginx实现IP访问频率限制基础认证WAF防护Nginx示例配置server { listen 443 ssl; server_name dev.example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; # 基础访问控制 allow 192.168.1.0/24; deny all; # 频率限制 limit_req zoneone burst10 nodelay; } }5.2 应用层防护在frp配置中添加安全头[proxies.plugin] requestHeaders.set.X-Frame-Options DENY requestHeaders.set.X-Content-Type-Options nosniff requestHeaders.set.X-XSS-Protection 1; modeblock5.3 监控与告警通过frp管理页面7500端口可以查看在线客户端流量统计连接状态建议配合Prometheus监控# 在frps.toml中添加 metrics.enable true metrics.port 90006. 常见问题排查问题1HTTPS访问出现证书错误检查证书路径是否正确确保证书和域名匹配用openssl验证证书链openssl verify -CAfile fullchain.pem cert.pem问题2连接频繁断开检查token认证配置调整transport.heartbeatInterval参数检查网络是否存在中断问题3部分资源加载失败检查hostHeaderRewrite配置确认本地服务是否支持HTTPS跳转检查响应头中的Content-Security-Policy我在实际部署中发现当内网服务有WebSocket连接时需要在frpc.toml中添加[proxies.plugin] requestHeaders.set.Upgrade $http_upgrade requestHeaders.set.Connection upgrade这种配置方式让我们的实时日志系统终于可以正常工作。另一个踩坑经验是当需要暴露数十个服务时建议用include语法拆分配置文件# frpc.toml include [conf.d/*.toml]这样每个服务一个文件管理起来清晰很多。