
reproxy v1.7.1
轻量级边缘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(不带花括号)。
同时支持 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。每个提供程序可以为代理请求和静态(资源)定义多条路由规则。用户可以同时设置多个提供程序。
请参阅示例中各种提供程序的示例
静态提供程序
这是最简单的提供程序,直接在命令行(或环境变量)中定义所有映射规则。支持多条规则。每条规则由 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 duration,例如 5m、30s);0 或空则继承全局 --timeout.write 设置。第 7 个元素是可选的每条路由每用户每秒请求数限制;0 或空则继承 --throttle.user。允许空的位置字段(例如 ,, 用于未使用的中间字段)。
文件提供程序
此提供程序使用带有路由规则的 yaml 文件。
reproxy --file.enabled --file.name=config.yml
config.yml 示例:
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 来提供服务:
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 provider
Docker provider 支持全自动发现(使用 --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 duration 格式(例如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 provider 还允许定义多组 reproxy.N.something 标签,以在同一容器上匹配多个不同的路由。这很有用,因为在某些情况下单个容器可能暴露多个端点,例如公共 API 和某些管理 API。上述所有标签都可以与“N 索引”一起使用,即 reproxy.1.server、reproxy.1.port 等。N 应在 0 到 9 范围内。
这是一个动态 provider,容器状态的任何变化都会自动应用。