当前位置: 首页 > news >正文

docker部署vaultwarden+Caddy+FRP(TCP)+CF tunnel(HTTP)的记录

系统环境准备:

安装docker:

sh <(curl -sSL https://linuxmirrors.cn/docker.sh)


安装Caddy:

直接 apt install caddy ,或者 yum install caddy ,或者 dnf install caddy,这取决于你的系统。


Caddy配置:

先在 cloudflareDNS控制台记录上配置 CNAME域名映射(或者A/AAAA记录)到 FRP服务器的地址。

然后是 Caddy需要有 cloudflaredns模块,就能使用 cloudflareAPI_TOKEN自动创建更新非443标准端口的TLS证书。

将此 API_TOKEN替换到 Caddy配置文件内 FRP站点的 <CF_DNS_API_TOKEN>位置。

root@NAS:/etc/caddy# caddy  list-modules | grep cloudflare
dns.providers.cloudflare

然后是 Caddy需要有能解析 FRP(TCP)高级参数 proxy_protocol_version = v2的模块,就能通过 proxy_protocol获取访问者IP。

root@NAS:/etc/caddy# caddy  list-modules | grep proxy_
caddy.listeners.proxy_protocol
layer4.handlers.proxy_protocol
layer4.matchers.proxy_protocol

1、Caddy配置实现了从 FRP隧道来的访问转发到 vaultwarden容器,并获取真实访问者IP给 vaultwarden。但是禁止访问 /admin

2、Caddy配置实现了从 CF Tunnel隧道来的访问转发到到 vaultwarden容器,并获取真实访问者IP给 vaultwarden。可以访问 /admin,但是需要通过邮箱一次性验证码来验证。CF Tunnel自带 TLS,无需配置证书。

3、Caddy配置实现了来自本地的指定访问IP访问,使用自签证书。

Caddy安装模块问一下 AI或者到 Caddy官网 https://caddyserver.com/download下载,这里就不啰嗦了。

Caddy配置文件如下:


cat > /opt/caddy/Caddyfile <<"EOF"
{# FRP 站点解析 proxy_protocol_version = v2 参数,仅在1200端口(来自FRP的访问)的站点生效。servers :1200 {listener_wrappers {proxy_protocol {timeout 2sallow 127.0.0.1/32}tls}}
}# ------------------------------------------------------------
# 共享安全 Header
(shared_header) {header {# 启用 HTTP Strict Transport Security (HSTS)Strict-Transport-Security "max-age=31536000;"# 禁用 cross-site filter (XSS)X-XSS-Protection "0"# 禁止在框架内呈现网站 (clickjacking protection)# X-Frame-Options "SAMEORIGIN"# 阻止搜索引擎建立索引(可选)X-Robots-Tag "noindex, nofollow"# 禁止嗅探 X-Content-Type-OptionsX-Content-Type-Options "nosniff"# 服务器名称移除-Server# 移除 X-Powered-By,虽然这不应该是一个问题,但最好移除-X-Powered-By# 移除 Last-Modified,因为 etag 相同并且同样有效-Last-Modified}
}# ------------------------------------------------------------
# FRP(TCP + Proxy Protocol v2)站点
vaultwarden.域名地址.xyz:1200 {encode gziptls {# 根据实际情况更改此处的 <CF_DNS_API_TOKEN>dns cloudflare <CF_DNS_API_TOKEN>propagation_timeout 120sresolvers 1.1.1.1 1.0.0.1}handle /admin* {respond "小黑子你想干什么?!" 403}handle {import shared_headerreverse_proxy 127.0.0.1:1199 {header_up X-Real-IP {remote_host}}}
}# ------------------------------------------------------------
# Cloudflare Tunnel 站点,这里有必要指明http协议,否则大概率会自签内部证书导致无法正常访问。
http://vaultwarden-cf.域名地址.xyz:1201 {encode gziphandle {import shared_headerreverse_proxy 127.0.0.1:1199 {trusted_proxies 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32header_up X-Real-IP {http.request.header.CF-Connecting-IP}}}
}#假设我的客户端设备局域网IP是10.126.126.1,vaultwarden服务器的IP是10.126.126.193,则可以如下配置,然后通过https://10.126.126.193:1202来访问vaultwarden服务。
#如果是通过组网的形式去访问,有些组网软件会默认NAT后去访问,就需要把vaultwarden的IP(10.126.126.193)也加到允许的列表中去
10.126.126.193:1202 {encode gziptls internal# 1️⃣ 仅允许指定 IP@allow_ip {remote_ip 10.126.126.1/32 10.126.126.193/32}handle @allow_ip {reverse_proxy 127.0.0.1:1199 {header_up X-Real-IP {remote_host}}}# 2️⃣ 其余来源全部拒绝handle {respond "Forbidden" 403}
}EOF

然后标准化一下配置文件后载入配置文件到Caddy:

caddy fmt --overwrite /etc/caddy/Caddyfile && caddy reload --config /etc/caddy/Caddyfile

正常来说没错的话应该是这个情况

root@NAS:~# caddy fmt --overwrite /etc/caddy/Caddyfile && caddy reload --config /etc/caddy/Caddyfile
2026/02/04 08:03:57.713 INFO    using config from file  {"file": "/etc/caddy/Caddyfile"}
2026/02/04 08:03:57.744 INFO    adapted config to JSON  {"adapter": "caddyfile"}root@NAS:~# ss -ntlp  | grep caddy
LISTEN 0      4096                     127.0.0.1:2019       0.0.0.0:*    users:(("caddy",pid=2830955,fd=24))             
LISTEN 0      4096                             *:80               *:*    users:(("caddy",pid=2830955,fd=31))             
LISTEN 0      4096                             *:1202             *:*    users:(("caddy",pid=2830955,fd=29))             
LISTEN 0      4096                             *:1200             *:*    users:(("caddy",pid=2830955,fd=30))             
LISTEN 0      4096                             *:1201             *:*    users:(("caddy",pid=2830955,fd=25))             

安装vaultwarden:

docker run --detach --name vaultwarden \-e DOMAIN='https://<用来访问的域名>:<用来访问的端口>' \-e TZ='Asia/Shanghai' \-p 127.0.0.1:1199:80 \-v /opt/vw-data:/data \--restart unless-stopped \vaultwarden/server:latest

这里主要是 FRP不能使用标准 443端口,否则 -e DOMAIN=参数不需要指定端口。

-e DOMAIN=这个参数用来自定义访问的地址,也可以不设置

-e DOMAIN= 在 vaultwarden 中只能有一个生效值,vaultwarden 本身不支持同时配置多个访问域名。

多域名时,可以配置其他域名 301 重定向 到这个主域名,但不是必要的

因为FRP如果不能访问了,我们要手动使用CF tunnel这个备用路径,所以可以不搞301重定向这一步

这个参数不是访问白名单,而是一个对外公布的主域名,主要用于:

1️⃣ 生成对外 URL

邀请邮件里的链接

Web Vault 中的一些跳转链接

API 返回的绝对 URL

2️⃣ Web Vault 的 CSP / WebSocket

WebSocket 连接地址

某些前端资源引用

-p 127.0.0.1:1199:80是将容器内的 80端口映射到本地 1199端口,仅监听在 127.0.0.1上。

-v /opt/vw-data:/data是将数据库文件挂载出来,方便后面备份或者迁移,即使容器删除,数据依旧存在。


配置FRP服务:

先创建一条TCP隧道,需要有高级参数 proxy_protocol_version = v2才能获取真实访问者IP:

1770189044846
image

然后去下载 frpc客户端程序到 /opt/Frp_linux_arm64/frpc,我使用的是某FRP服务网站提供的,也可自建。

使用下列命令创建systemd服务,以实现开机自启。

cat > /etc/systemd/system/frpc.service <<"EOF"
[Unit]
Description=Frp Client
After=network.target
After=network-online.target
Wants=network-online.target[Service]
Type=simple
User=root
Group=root# 根据实际情况更改 <USER_TOKEN_KEY> 和 <SERVER_ID>
ExecStart=/opt/Frp_linux_arm64/frpc -u <USER_TOKEN_KEY> -p <SERVER_ID>
WorkingDirectory=/opt/Frp_linux_arm64/Restart=always
RestartSec=5# 日志优化(可选)
StandardOutput=journal
StandardError=journal# 安全加固(可选)
ProtectSystem=full
PrivateTmp=true
NoNewPrivileges=true[Install]
WantedBy=multi-user.targetEOF

服务文件创建好之后,刷新一下systemd,然后设置开机自启,并启动服务:

命令:systemctl daemon-reload && systemctl enable frpc && systemctl start frpc

如果手动指定,则 frpc的配置文件大致如下。

命令查看: cat /opt/Frp_linux_arm64/frpc.ini

[common]
server_addr = frp.server.com
server_port = 7000
tcp_mux = true
protocol = tcp
user = <USER_KEY> 
token = <TOKEN_KEY> 
dns_server = 223.6.6.6
tls_enable = false
[vaultwarden]
privilege_mode = true
type = tcp
local_ip = 127.0.0.1
local_port = 1200
remote_port = 32213
use_encryption = false
use_compression = false
proxy_protocol_version = v2

大致意思就是

用TCP协议 type = tcp,将本地 local_ip = 127.0.0.1local_port = 1200端口,映射到FRP服务器的 remote_port = 32213端口

后面就可以通过FRP服务器的 https://<用来访问的域名>:32213进行访问。


配置CF Tunnel服务:

https://one.dash.cloudflare.com/控制台的【网络】-【连接器】中,创建一个【隧道】,在【概述】里有部署方式,推荐使用docker的方式部署,命令参考:
docker run -d --network host --name cfd_tunnel cloudflare/cloudflared:latest tunnel run --token <你的隧道token>

然后到【隧道】的配置里,增加增加一个【已发布应用程序路由】,【子域】部分填 vaultwarden-cf,就是Caddy配置文件里的CF tunnel站点。【域】就是你的域名地址。【路径】为空。服务类型为http,对应Caddy配置文件中的 http://vaultwarden-cf.域名地址.xyz:1201 站点块。【URL】填 127.0.0.1:1201,将来自 CF Tunnel的数据转发到 Caddy1201端口。
1770193018948
image

配置 /admin控制台访问的邮件令牌验证:

https://one.dash.cloudflare.com/控制台的【访问控制】中增加一个【策略】,名称自定义,例如叫【允许列表内邮件验证码认证访问】,【操作】选 Allow,【会话持续时间】自定义,添加一个规则,【选择器】为 Emails,【值】则是自己的邮箱,这个邮箱将用来接受验证码,通过验证就能访问 /admin

1770194036233
image

将策略应用:

https://one.dash.cloudflare.com/控制台的【访问控制】中增加一个【应用程序】,名称自定义,例如叫【管理员控制台】,【会话持续时间】自定义,默认的输入方法,【子域】填 vaultwarden-cf,对应Caddy配置文件中的 http://vaultwarden-cf.域名地址.xyz:1201 站点块。【域】就是你的域名地址。【路径】则是 admin,这里很重要,无需加 /,直接填 admin

1770194363121
image

验证:

当去访问 http://vaultwarden-cf.域名地址.xyz/admin的时候,就会自动跳转到验证。

1770194674305
image

输入策略里存在的邮箱,就会收到类似于以下的验证码,验证后就能访问 /admin控制台了。

1770194853155
image


开启vaultwarden的admin控制台:

接下来关闭注册功能,然后开启vaultwarden的邮件功能,以实现邀请用户。

使用 openssl rand -base64 48命令创建 admin访问的 token它看起来像这样:yi7GmMLGWaTo5OJdmALHL4eajv+rh3G7eVtaXJCxylvcF6+B7vbhh0HWACZdeAQl

此token需要牢记,登录admin后台使用。

然后将此明文的token转成密文,利用vaultwarden容器自带的hash工具,目前vaultwarden容器已经在正常运行了,那么执行 docker exec -it vaultwarden /vaultwarden hash命令,然后隐性输入token两次(建议复制粘贴),若两次输输入token不一致则不会生成密文。看起来会像这样:

Generate an Argon2id PHC string using the 'bitwarden' preset:Password:            <-----------隐性输入
Confirm Password:            <-----------隐性输入ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$RtC7dEU7RacyN6v0oUM2nVu9f3rI9OjaFA1S2sWXJLg$4j0HHDGop+71A2dxtco7JuO7UEV2js4wgojPsiETeU8'            <-----------密文生成成功Generation of the Argon2id PHC string took: 142.1447ms

重建容器,开启admin管理页面(启用变量 -e ADMIN_TOKEN=)带入密文 token,然后关闭注册功能(启用变量 -e SIGNUPS_ALLOWED=false),

docker stop vaultwarden && docker rm vaultwarden && docker run --detach --name vaultwarden \-e SIGNUPS_ALLOWED=false  \-e DOMAIN='https://<用来访问的域名>:<用来访问的端口>' \-e ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$RtC7dEU7RacyN6v0oUM2nVu9f3rI9OjaFA1S2sWXJLg$4j0HHDGop+71A2dxtco7JuO7UEV2js4wgojPsiETeU8' \-e TZ='Asia/Shanghai' \-v /opt/vw-data:/data \-p 127.0.0.1:1199:80 \--restart unless-stopped \vaultwarden/server:latest

然后去访问 http://vaultwarden-cf.域名地址.xyz/admin就能进admin后台了。


开启SMTP邮件服务(以163为例):

添加一点SMTP参数,参考:

docker stop vaultwarden && docker rm vaultwarden && docker run --detach --name vaultwarden \-e SIGNUPS_ALLOWED='false' \-e DOMAIN='https://<用来访问的域名>:<用来访问的端口>' \-e ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$RtC7dEU7RacyN6v0oUM2nVu9f3rI9OjaFA1S2sWXJLg$4j0HHDGop+71A2dxtco7JuO7UEV2js4wgojPsiETeU8' \-e TZ='Asia/Shanghai' \-e ADMIN_SESSION_LIFETIME='60' \-e SMTP_FROM='邮箱账号@163.com' \-e SMTP_HOST='smtp.163.com' \-e SMTP_PORT=465 \-e SMTP_SECURITY=force_tls \-e SMTP_USERNAME='邮箱账号@163.com' \-e SMTP_PASSWORD='POP3/SMTP密码' \-e HELO_NAME='vaultwarden-selfhosted' \-p 127.0.0.1:1199:80 \-v /opt/vw-data:/data \--restart unless-stopped \vaultwarden/server:latest
http://www.jsqmd.com/news/342338/

相关文章:

  • 传统礼簿收礼小工具:记了么,解决纸质收礼记账痛点
  • 海外短剧新引擎,JAVA源码一键出海
  • 【毕业设计】基于nodejs的计算机c语音自学交流平台(源码+文档+远程调试,全bao定制等)
  • 二次元影像测量仪厂家哪家口碑好?认准基恩士 IM-X 系列 - 速递信息
  • JAVA代泊车系统,接机送机一键无忧
  • PHP计算机毕设之基于php+vue的篮球馆智慧管理系统篮球球衣周边销售管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • PHP毕设选题推荐:基于php+vue的篮球馆智慧管理系统场地信息管理、预约【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 纳滤膜哪个厂家好?国产品牌排行靠前的是谁?膜通量和截留率达标吗? - 品牌推荐大师
  • Nodejs计算机毕设之基于nodejs+vue知识交流平台的实现与设计基于nodejs的计算机c语音自学交流平台(完整前后端代码+说明文档+LW,调试定制等)
  • 完整教程:物联网卡为什么要支持双栈
  • 【计算机毕业设计案例】基于nodejs的计算机c语音自学交流平台基于nodejs+vue知识交流平台的实现与设计(程序+文档+讲解+定制)
  • 千问模型接入指南
  • 计算机PHP毕设实战-基于php+vue的篮球馆智慧管理运营系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 2026年抗衰老美容仪器优质推荐榜:可俪塑腰腹塑形减肥仪器/丽可缇去皱紧致美容设备/丽可缇抗衰老美容仪器/丽可缇法令纹改善美容设备/选择指南 - 优质品牌商家
  • OpenClaw Cron 深度解读:让 AI Agent 学会自主定时工作
  • 【课程设计/毕业设计】基于php的篮球馆球衣管理系统场馆预定系统【附源码、数据库、万字文档】
  • HTTP 服务器项目学习笔记 - 详解
  • 2026小额借贷平台哪家好?综合对比与选择建议 - 品牌排行榜
  • 从跟单到AI量化:交易所开发者的“财富密码“藏在哪些技术细节里?
  • Blender 本地渲染还是云渲染农场?优缺点对比与效率提升方案解析
  • 2026年2月敏感肌护肤品终极测评:反复泛红、停用复发?4大核心品牌精准破局 - 速递信息
  • 21.Android系统源码-libxml2 技术全景 - W3C 标准 XML 解析引擎完整解析
  • 创业初期,用 XinServer 节省了大量开发成本
  • 基于单片机智能温控流水灯
  • 基于51单片机的手持式激光+测距仪设计与实现
  • 导师推荐9个降AI率网站,千笔帮你轻松应对降AIGC难题
  • 2026电饭煲什么牌子的好用质量好?口碑之选推荐 - 品牌排行榜
  • 22.Android系统源码-HarfBuzz 实战 - 复杂文本整形引擎核心技术
  • > 基于大数据技术的医辽数据分析与研究-(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码spark+djanpython3.8+spark+django+spider+
  • 深度测评10个降AI率工具 千笔·降AIGC助手有效降低AIGC痕迹