# 前言
frpc 是一个开源的用于内网穿透的高性能的反向代理应用,它可以让外部网络访问在 NAT 网络之后的内网服务。
连接类型支持 TCP、UDP、HTTP、HTTPS 等协议。
其中 TCP、UDP 协议的穿透方式比较简单,本文主要介绍如何使用 frpc 穿透 http 和 https 协议,配置自定义域名。
# 安装 frpc
因为没用公网服务器和本地也没有公网 ip,所以找了第三方 frp 服务,一般会提供下载链接,直接下载安装即可。
# 配置 frpc
一般配置文件为 frpc.ini 和 frpc.toml,这里以 frpc.toml 配置文件为例
主要参数 customDomains 配置域名 需要配置域名解析
比方说域名绑定在 cloudflare,需要配置 DNS 解析
类型为 CNAME 记录类型 域名 指向 服务器地址
# 配置 http
配置文件只展示部分基本内容,具体配置文件可以参考官方文档
启动 frpc 后,访问自定义域名即可 http://test.example.com
serverAddr = "serverUrl" ## 服务器地址 | |
serverPort = 7000 ## 服务器端口 | |
[[proxies]] | |
name = "test" ## 代理名称 | |
type = "http" ## 代理类型 | |
localIP = "127.0.0.1" ## 本地服务地址 | |
localPort = 8080 ## 本地服务端口 | |
customDomains = ["test.example.com"] ## 自定义域名 |
# 配置 https
配置文件只展示部分基本内容,具体配置文件可以参考官方文档
https 和 http 无法直接通信,所以需要使用插件 https2http
启动 frpc 后,访问自定义域名即可 https://test.example.com
serverAddr = "serverUrl" ## 服务器地址 | |
serverPort = 7000 ## 服务器端口 | |
[[proxies]] | |
name = "test" ## 代理名称 | |
type = "https" ## 代理类型 | |
customDomains = ["test.example.com"] ## 自定义域名 | |
[proxies.plugin] | |
type = "https2http" ## 插件类型 | |
localAddr = "127.0.0.1:8080" ## 本地服务地址 | |
# HTTPS 证书相关的配置 | |
crtPath = "./test.crt" ## 证书路径 | |
keyPath = "./test.key" ## 证书密钥路径 | |
hostHeaderRewrite = "test.example.com" ## 主机头重写 因为个人需要获取 host, 所以配置。没配置的时候,获取到了 127.0.0.1:8080 |
# 申请 SSL 证书
申请 SSL 证书通常需要域名解析,上面 frp 自定义域名时,已经配置了 DNS 解析,所以这里申请证书时,直接使用自定义域名即可。
可以使用 certbot 申请证书,具体操作可以参考官方文档
踩坑过程
Let’s Encrypt 证书使用 ACME 协议来验证域名所有权。Certbot 提供两种常见的验证方式:
HTTP-01 验证:Certbot 通过一个临时的 HTTP 文件验证你对域名的控制。
DNS-01 验证:通过 DNS TXT 记录验证域名所有权,适用于子域名或没有直接 HTTP 访问的情况。
一开始采用 HTTP-01 验证申请的二级域名证书
需要一个可访问的 http, 所以先在本地创建 nginx web 服务,再内网穿透出去,再申请证书。
后来发现可以用 DNS-01 验证,并且直接申请了通配符证书,不要这些麻烦的步骤。
虽然走弯路,但还是有收获,所以这里记录下我申请证书的过程。
# HTTP-01 验证方式
本人喜欢使用 docker,所以都是 docker 部署
# 本地创建 nginx web 服务
- 创建临时 web 目录
- 创建 nginx 配置文件
- 启动容器
- 最后配置启动 http 内网穿透,HTTP-01 验证,需要的环境就准备好了
## 创建临时 web 目录 | |
mkdir -p tmpWeb/con.d | |
cd tmpWeb | |
## 创建 nginx 配置文件 | |
cat > tmpWeb/con.d/default.conf <<EOF | |
server { | |
listen 80; | |
server_name test.example.com; | |
# 申请证书需要访问http://test.example.com/.well-known/acme-challenge/ 所以需要先内网穿透出去 | |
location /.well-known/acme-challenge/ { | |
root /var/www/wwwroot; # 确保这里的路径是正确的 容器内web路径 与下面的申请证书中的--webroot路径一致 | |
} | |
# 其他配置 | |
} | |
EOF | |
## 启动容器 | |
docker run -d --restart=unless-stopped \ | |
-p 8000:80 \ ## 映射端口 | |
-v $PWD/conf.d:/etc/nginx/conf.d \ ## 映射配置文件 | |
-v $PWD/wwwroot:/var/www/wwwroot \ ## 映射 web 路径 其实不需要映射,因为不需要访问 | |
--name=tempWeb nginx:mainline-alpine3.18-slim |
# docker certbot 申请证书
通过 docker 执行 certbot 申请证书
容器第一次启动 需要填邮箱,用于创建账户并发送验证邮件。
通过 HTTP-01 验证 完成申请证书
证书获取后,会存放在 certs/live/yourdomain.com/ 下,包括以下文件:
cert.pem: 证书文件
chain.pem: 证书链文件
fullchain.pem: 包含完整的证书链
privkey.pem: 私钥文件
docker run -it --rm \ | |
-v $PWD/certs:/etc/letsencrypt \ ## 映射证书路径 | |
-v $PWD/wwwroot:/var/www/wwwroot \ ## 映射 web 路径 其实不需要映射,因为不需要访问 | |
certbot/certbot certonly \ | |
--webroot -w /var/www/wwwroot \ ## 与 nginx 配置文件中的路径一致 | |
-d test.example.com |
# 续订证书
Let’s Encrypt 证书的有效期是 90 天,因此需要定期更新证书。
Certbot 提供了自动更新的功能:
可以把续订证书的命令写入 renew.sh, 并且添加到 crontab 中,让它每天自动运行一次。
chmod +x renew.sh
crontab -e
0 0 * * * /your_dir/renew.sh
docker run -it --rm \ | |
-v $PWD/certs:/etc/letsencrypt \ | |
certbot/certbot renew \ | |
--deploy-hook "nginx -s reload" ## 续订后证书改变 需要重新加载 nginx 根据自己的情况修改命令 |
# DNS-01 验证方式
# 申请二级域名证书
之前已经通过 HTTP-01 验证方式申请了二级域名证书,所以不会再要求填写邮箱
容器运行后,提示在通过 txt 的方式完成域名解析,给到的 name 和 value 添加到对应的域名 dns 解析中
docker run -it --rm \ | |
-v $PWD/certs:/etc/letsencrypt \ | |
certbot/certbot certonly \ | |
--manual --preferred-challenges dns \ | |
-d test.example.com |
# 通过 api 方式 申请通配符证书
如果你的 DNS 提供商支持 API,你可以使用 Certbot 的相应插件。
首先,查找适合你 DNS 提供商的插件,并在 Docker 中安装。
例如,对于 Cloudflare,你可以使用 certbot-dns-cloudflare。
然后,在当前目录创建一个包含你的 API 凭据的文件 cloudflare.ini
dns_cloudflare_email = <EMAIL> ## 账户邮箱 | |
dns_cloudflare_api_key = <KEY> ## 账户 api key, 可以在 cloudflare 个人资料 API 令牌中获取 Global API Key |
docker run -it --rm --name certbot \ | |
-v "$PWD/config:/etc/letsencrypt" \ ## 映射证书路径 | |
-v "$PWD/logs:/var/log/letsencrypt" \ ## 映射日志路径 | |
-v "$PWD/cloudflare.ini:/cloudflare.ini" \ ## 映射配置文件 | |
certbot/dns-cloudflare certonly \ | |
--dns-cloudflare \ ## 指定 dns 插件 | |
--dns-cloudflare-credentials /cloudflare.ini \ ## 指定配置文件 | |
--email youemail@email.com \ ## 知道账户邮箱 | |
--agree-tos \ | |
-d '*.example.com' -d example.com ## 需要申请证书的域名 |
# 续订证书
可以把续订证书的命令写入 renew.sh, 并且添加到 crontab 中,让它每天自动运行一次。
chmod +x renew.sh
crontab -e
0 0 * * * /your_dir/renew.sh
docker run --rm \ | |
-v "$PWD/config:/etc/letsencrypt" \ | |
-v "$PWD/logs:/var/log/letsencrypt" \ | |
-v "$PWD/cloudflare.ini:/cloudflare.ini" \ | |
certbot/dns-cloudflare renew | |
--deploy-hook "nginx -s reload" ## 续订后证书改变 需要重新加载 nginx 根据自己的情况修改命令 |
# 总结
记录下 frp https 和 ssl 申请证书的过程,希望对你有帮助。