🔗在OpenWRT旁路网关上通过Caddy实现Homelab反向代理

2024-9-8|2025-1-2
Yawatasensei
Yawatasensei
type
status
date
slug
summary
tags
category
icon
password
🚧
OpenWRT默认是使用uhttpd作为web服务器提供网页访问服务,uhttpd作为一个轻量的web服务器日常提供OpenWRT Luci相关的页面服务确实是已经足够。但是我有一个想法,家里的配置的服务实在是太多了,分散在不同的主机上,使用没有规则的端口,经常会忘记哪个服务应该访问哪个地址,使用哪个端口,所以我想通过域名的方式将这些服务统一管理起来。既然是IP+端口的方式,那么最方便的解决办法之一当然就是使用反向代理,而目前配置反向代理最方便的是Caddy,这也就是为什么会有这篇文章的原因。

📝 什么是Caddy

Caddy是一个现代的开源Web服务器,基于Go语言实现,具有内置的自动HTTPS功能,支持反向代理、负载均衡、静态文件托管等功能。Caddy以其简单易用的配置和自动化特性著称,尤其适用于需要快速搭建和管理HTTPS网站的场景。它的配置文件格式是人性化的Caddyfile,并且支持JSON格式的API配置。同时,Caddy的反向代理配置也很简单,只需要在Caddyfile中添加类似如下的代码片段即可:
这就很方便我们进行家庭网络内各种服务的反向代理配置,不用写很多行的配置项。

📝 OpenWRT如何使用Caddy

在为家庭网络内的各种服务配置反向代理前,我们先要让OpenWRT使用Caddy,因为默认uhttpd在占用OpenWRT的:80端口,如果直接使用Caddy,那么就不能使用:80端口,需要使用未被占用的端口,例如:8080,最终形成的反向代理地址会变成example.lan:8080 ,不美观,而且也没有实现我们希望完全使用域名进行管理的初衷。所以我们先需要使用Caddy替代掉OpenWRT原有的web服务器uhttpd。

安装Caddy

下载Caddy

首先安装Caddy,Caddy无法通过OpenWRT自带的包管理器opkg直接进行安装,但是由于其本质是基于Go语言编写的一个二进制的执行文件,所以我们可以通过Caddy的官网进行下载。
Platform:选择Linux amd64,我是在旁路由(旁路网关)上进行安装,架构为X86-64,所以选择这个。如果你是其他的架构,根据自己的架构进行选择。
Standard Feature:默认勾选
Extra Feature:我们点击filter package and modules,输入cgi,选择aksdb/caddy-cgi/v2
然后点击下载按钮。
或者你也可以直接在OpenWRT的终端中执行:
重命名Caddy:
赋予Caddy执行权限,并移动到/usr/bin执行目录:

配置Caddy配置文件Caddyfile

使用你喜欢的编辑器打开/etc/caddy/Caddyfile
删除原有配置文件内的内容,并添加如下内容:
代码逻辑:
  1. 配置顺序控制
    1. order cgi before respond:指定 Caddy 处理请求时的顺序。这里表示 CGI 处理器的优先级比默认的 respond 指令更高。
    2. order file_server last:指示 file_server(静态文件服务器)的处理顺序应排在最后,即在其他处理器之后才执行。
    3. skip_install_trust(注释掉的部分):表示跳过安装可信的 HTTPS 证书。这可能是为了防止将 Caddy 生成的证书添加到系统的信任存储中。
    4. auto_https disable_redirects(注释掉的部分):禁用自动从 HTTP 重定向到 HTTPS 的行为。Caddy 默认会启用 HTTPS,并自动从 HTTP 重定向到 HTTPS,此处被关闭。
    5. default_sni openwrt.local(注释掉的部分):指定默认的 SNI(Server Name Indication),用于在 HTTPS 请求中无法匹配到特定主机名时使用的主机名。
  1. luci 站点块定义
    1. (luci):这是一个命名块,定义了一组共享的配置,可以在其他站点块中通过 import 引用。
    2. root * /www:设置静态文件的根目录为 /www,即请求文件时,会从 /www 文件夹中查找文件。
    3. route /cgi-bin*:定义一条处理以 /cgi-bin 开头的路径的路由。这通常用于处理 CGI(Common Gateway Interface)脚本请求。
      1. @exists:这是一个请求匹配条件,检查是否在 /www/cgi-bin 下存在对应的文件。
      2. handle @exists:如果找到了这个文件,Caddy 会执行以下处理逻辑:
        1. uri strip_prefix {file_match.relative}:从请求 URI 中去掉前缀,简化路径。{file_match.relative} 是捕获的相对路径。
        2. cgi * /www/{file_match.relative}:将匹配的文件作为 CGI 脚本执行。/www/{file_match.relative} 指定了文件位置。
        3. script_name {file_match.relative}:指定 CGI 脚本的名称。
      3. cgi /ubus ubus.sh*:设置 /ubus 路径为调用 ubus.sh 脚本,script_name /ubus 指定了 CGI 脚本名为 /ubus
      4. file_server:启用文件服务功能,允许从 /www 目录中提供静态文件。
      5. redir / /cgi-bin/luci:如果访问的是 /,重定向到 /cgi-bin/luci,这是 LUCI Web 界面的默认入口。
3. HTTP 站点配置
  1. http://:这一部分表示处理所有 HTTP 请求。通过 import luci,Caddy 会引入之前定义的 (luci) 配置块,这样 HTTP 请求会按照该块的配置来处理。
  1. HTTPS 站点配置(注释掉的部分)
    1. tls internal:表示使用 Caddy 内置的自签名证书来启用 HTTPS,而不是获取外部的 SSL 证书。
    2. on_demand:按需启用 HTTPS,也就是说,只有当客户端发起 HTTPS 请求时,Caddy 才会生成证书。
    3. import luci:引入 (luci) 块的配置,用于处理 HTTPS 请求。
 
默认使用http协议,如果你需要使用https协议,那么将代码中注释掉的部分取消注释即可。

下载ubus.sh并进行配置

从github下载ubus.sh并放入和Caddyfile相同的目录,同时在/www/cgi-bin也复制一份,用于提供ubus的基础API功能。

关闭uhttpd

通过/etc/init.d/uhttpd关闭uhttpd提供的web服务

配置caddy启动脚本

/etc/init.d中新建一个名为caddy的文件,并填充以下代码:
赋予执行权限,并允许开机自动启动
然后重启路由器,即可完成Caddy替换uhttp的操作。

配置Caddy反向代理

编辑/etc/caddy/Caddyfile ,在文件底部新增:
第一行的域名是你希望使用的域名,建议局域网服务使用*.lan或者*.local
reverse_proxy是被反向代理服务器的地址和端口,根据自己实际情况进行修改。
如果有多个服务,就添加类似这种多个代码块。
编辑完成后保存,然后通过重新加载caddy配置文件。

配置DNS解析

如果你和我一样使用的是Adguard Home,那么可以在过滤器 - DNS重写 添加规则:*.lan重定向到Caddy服务器所在IP。
如果你使用的是Dnsmasq那么在DHCP/DNS - 转发中进行配置:/*.lan/Caddy所在IP

🤗 总结归纳

目前替换后使用效果很好,达到了预期,例如我将jellyfin配置为media.lan, sunshine的远程串流管理页面配置为game.lan,Adguard Home配置为adg.lan,还有其他七七八八的docker服务均进行了配置,同时通过uptime kuma进行可用性监控,比原来需要自己手动输入端口号的方式方便了不少,不用再记乱七八糟的端口和IP。
Caddy替代uhttpd也工作的很好,除了在Homepage中监控OpenWRT的状态目前无法获取,调用接口提示500错误,这个我在寻找解决的办法。

📎 参考文章

 
💡
有关OpenWRT安装或者使用上的问题,欢迎您在底部评论区留言,一起交流~
尝试使用Grafana监控家庭网络状态(一)OpenWRT IPv6防火墙规则:如何放行客户端地址及端口
Loading...