
reproxy v1.7.0
轻量级边缘HTTP(S)服务器和反向代理,具有自动SSL、Docker/Consul发现、按路由认证、速率限制和基于健康检查的故障转移。
Reproxy 是一个简单的边缘 HTTP(s) 服务器/反向代理,支持多种提供者(docker、static、file、consul catalog)。一个或多个提供者提供关于请求服务器、请求 URL、目标 URL 和健康检查 URL 的信息。它以单个二进制文件或 Docker 容器的形式分发。
- 通过 Let's Encrypt 自动 SSL 终止
- 支持用户提供的 SSL 证书
- 简单但灵活的代理规则
- 静态、命令行代理规则提供者
- 动态、基于文件的代理规则提供者
- Docker 提供者,自动发现
- Consul Catalog 提供者,通过服务标签发现
- 支持多个(虚拟)主机
- 可选流量压缩
- 可选基于 IP 的访问控制
- 每路由基本认证
- 用户自定义大小限制和超时
- 单个二进制文件分发
- Docker 容器分发
- 内置静态资源服务器,支持可选的“SPA 友好”模式
- 支持重定向规则
- 可选的全局活动限制以及用户活动限制
- 实时健康检查与故障转移/负载均衡
- 管理服务器,提供路由信息和 Prometheus 指标
- 通过 RPC 支持插件,实现自定义功能
- 可选的日志记录,支持 Apache 日志格式和简化的 stdout 报告。
服务器(主机)可以设置为 FQDN,例如 s.example.com、*(捕获所有)或正则表达式。精确匹配优先,因此如果有两条规则,服务器分别为 example.com 和 example\.(com|org),那么对 example.com/some/url 的请求将匹配前者。请求 URL 可以是正则表达式,例如 ^/api/(.*),目标 URL 可以包含正则匹配组,例如 http://d.example.com:8080/$1。对于上面的例子,http://s.example.com/api/something?foo=bar 将被代理到 http://d.example.com:8080/something?foo=bar。
为了方便,带有尾部 / 且不包含正则组匹配的请求将扩展为 /(.*),相应的目标也扩展为 /$1。例如,/api/ -> http://127.0.0.1/service 将被翻译为 ^/api/(.*) -> http://127.0.0.1/service/$1。
目标 URL 支持主机名替换。例如,/files/${host} 中的 ${host} 将被替换为匹配的主机名。也可以使用 $host(不带花括号)。
同时支持 HTTP 和 HTTPS。对于 HTTPS,可以使用静态证书,也可以使用自动 ACME(Let's Encrypt)证书。可选的静态资源服务器可用于提供静态文件。启动 reproxy 需要至少定义一个提供者。其余参数严格可选,并有合理的默认值。
示例:
- 使用静态提供者:
reproxy --static.enabled --static.rule="*,example.com/api/(.*),https://api.example.com/$1" - 使用自动 Docker 发现:
reproxy --docker.enabled --docker.auto - 作为 Docker 容器:
docker up -p 80:8080 umputun/reproxy --docker.enabled --docker.auto - 使用自动 SSL:
docker up -p 80:8080 -p 443:8443 umputun/reproxy --docker.enabled --docker.auto --ssl.type=auto --ssl.fqdn=example.com
安装
Reproxy 既可以作为小巧的自包含二进制文件分发,也可以作为 Docker 镜像分发。二进制文件和镜像均支持多种架构和操作系统,包括 linux_x86_64、linux_arm64、linux_arm、macos_x86_64、macos_arm64、windows_x86_64 和 windows_arm。我们还提供 arm64 和 x86 的 deb 和 rpm 包。
- 二进制分发:在发布页面下载合适的文件
- Homebrew 用户:
brew install umputun/apps/reproxy - Docker 容器可在 Docker Hub 以及 Github Container Registry 上获取。例如:
docker pull umputun/reproxy或docker pull ghcr.io/umputun/reproxy。
最新稳定版本带有 :vX.Y.Z 的 Docker 标签(带 :latest 别名),当前 master 分支带有 :master 标签。
提供者
代理规则由各种提供者提供。目前包括 file、docker、static 和 consul-catalog。每个提供者可以为代理请求和静态资源定义多条路由规则。用户可以同时设置多个提供者。
在 examples 中查看各种提供者的示例
静态提供者
这是最简单的提供者,直接在命令行(或环境变量)中定义所有映射规则。支持多条规则。每条规则由 3 到 7 个逗号分隔的元素组成:server,sourceurl,destination[,ping-url[,forward-health-checks[,timeout[,throttle]]]]。例如:
*,^/api/(.*),https://api.example.com/$1— 将所有对任何主机/服务器且带有/api前缀的请求代理到https://api.example.comexample.com,/foo/bar,https://api.example.com/zzz,https://api.example.com/ping— 将对example.com且 URL 为/foo/bar的请求代理到https://api.example.com/zzz,并使用https://api.example.com/ping进行健康检查。example.com,/foo/bar,https://api.example.com/zzz,https://api.example.com/ping,true— 与上一条相同,但还将/ping和/health请求转发到后端。example.com,^/upload/(.*),https://api.example.com/$1,,,5m— 每条路由的请求超时时间为 5 分钟(第 4 和第 5 个字段留空以跳过 ping-url 和 forward-health-checks)。example.com,^/login,https://api.example.com/login,,,,2— 每条路由的每个用户限流为 2 请求/秒(前面的位置字段留空)。
第4个元素定义可选的 ping URL,用于健康报告。第5个元素可选地启用将健康检查请求转发到后端(true、yes、1)。有关详细信息,请参见健康检查部分。第6个元素是可选的每条路由请求超时时间(Go 持续时间,例如 5m、30s);0 或空表示继承全局 --timeout.write 设置。第7个元素是可选的每条路由每秒每个用户请求限制;0 或空表示继承 --throttle.user。允许空的位置字段(例如,对于未使用的中间字段使用 ,,)。
文件提供者
此提供者使用包含路由规则的 yaml 文件。
reproxy --file.enabled --file.name=config.yml
config.yml 的示例:```yaml
default: # the same as * (catch-all) server
- { route: "^/api/svc1/(.*)", dest: "http://127.0.0.1:8080/blah1/$1" }
- { route: "/api/svc3/xyz", dest: "http://127.0.0.3:8080/blah3/xyz", ping: "http://127.0.0.3:8080/ping", remote: "192.168.1.0/24, 127.0.0.1", # optional, restrict access to the route forward-health-checks: true # optional, forward /ping and /health to backend }
- { route: "^/admin/(.*)", dest: "http://127.0.0.4:8080/$1", auth: "admin:$2y$05$..." # optional, per-route basic auth (htpasswd bcrypt format) }
- { route: "^/upload/(.*)", dest: "http://127.0.0.5:8080/$1", timeout: 5m # optional, per-route request timeout (Go duration). 0 or omitted inherits --timeout.write }
- { route: "^/login", dest: "http://127.0.0.6:8080/login", throttle: 2 # optional, per-route req/sec per user. 0 or omitted inherits --throttle.user } srv.example.com:
- { route: "^/api/svc2/(.*)", dest: "http://127.0.0.2:8080/blah2/$1/abc" }
- { route: "/web/", dest: "/var/www", "assets": true } "*.files.example.com":
- { route: "^/files/(.*)", dest: "http://123.123.200.200:8080/$host/$1" }
这是一个动态提供器,文件更改将自动应用。
**不同域名上的多个静态网站**可以通过将服务器名称作为键并使用 `assets: true` 来服务:```yaml
site-en.example.com:
- { route: "/", dest: "/var/www/en", "assets": true }
site-ru.example.com:
- { route: "/", dest: "/var/www/ru", "assets": true }
重要: 资产规则的 route 字段必须是路径前缀(例如 /、/web/),而不是正则表达式。像 ^/(.*) 这样的正则模式无法与 assets: true 一起使用,因为静态资产匹配使用的是路径前缀比较,而非正则表达式。
Docker 提供器
Docker 提供器支持完全自动发现(使用 --docker.auto),无需额外配置。默认情况下,它会将所有类似 http://<url>/<container name>/(.*) 的请求重定向到给定容器的内部 IP 和暴露端口。仅检测活跃(运行中)的容器。
此默认设置可通过标签更改:
reproxy.server- 要匹配的服务器(主机名)。也可以是逗号分隔的服务器列表。reproxy.route- 源路由(位置)reproxy.dest- 目标路径。注意:这不是完整 URL,只是将追加到容器 ip:port 的路径。reproxy.port- 发现到的容器的目标端口reproxy.ping- 目标容器的 ping 路径。reproxy.remote- 通过逗号分隔的子网或 IP 列表限制对路由的访问reproxy.auth- 通过逗号分隔的user:bcrypt_hash对(由htpasswd -nbB生成)要求对路由进行基本认证reproxy.assets- 将资产映射设置为web-root:location,例如reproxy.assets=/web:/var/wwwreproxy.keep-host- 保持 Host 头不变(yes、true、1)或替换为目标主机(no、false、0)reproxy.forward-health-checks- 将/ping和/health请求转发到后端,而不是由 reproxy 处理(yes、true、1)。当后端具有特定于应用程序响应的健康检查端点时很有用。reproxy.timeout- 每个路由的请求超时时间,格式为 Go 持续时间(例如5m、30s)。0或未设置时继承全局--timeout.write。无效值会被忽略并发出警告。reproxy.throttle- 每个路由的每个用户每秒请求限制。0或未设置时继承--throttle.user。无效或负值会被忽略并发出警告。reproxy.enabled- 启用(yes、true、1)或禁用(no、false、0)容器作为 reproxy 目标。
请注意:如果没有 --docker.auto,目标容器必须至少有一个 reproxy.* 标签才能被视为潜在目标。
使用 --docker.auto 时,所有暴露端口的容器都将被视为路由目标。有 3 种方式限制:
- 使用
--docker.exclude显式排除某些容器,例如--docker.exclude=c1 --docker.exclude=c2 ... - 使用
--docker.network仅允许特定的 Docker 网络 - 设置标签
reproxy.enabled=false或reproxy.enabled=no或reproxy.enabled=0
如果未定义 reproxy.route,默认路由为 ^/<container_name>/(.*)。如果所有代理源应具有相同的前缀模式,例如 /api/(.*),用户可以为所有基于容器的路由定义公共前缀(此处为 /api)。这可通过 --docker.prefix 参数完成。
Docker 提供器还允许定义多组 reproxy.N.something 标签以匹配同一容器上的多条不同路由。这在某些情况下很有用,例如单个容器可能暴露多个端点,比如公共 API 和管理 API。上述所有标签都可以使用“N 索引”,即 reproxy.1.server、reproxy.1.port 等。N 的取值范围为 0 到 9。
这是一个动态提供器,容器状态的任何更改都会自动应用。
Consul Catalog 提供器
使用:reproxy --consul-catalog.enabled