为 Open WebUI 配置 HAProxy
HAProxy (High Availability Proxy) 是一款专业的负载均衡和反向代理 (reverse proxy) 解决方案。它具有高度可配置性,旨在以相对较低的资源占用处理大量的并发连接。欲了解更多信息,请访问:https://www.haproxy.org/
安装 HAProxy 和 Let's Encrypt
首先,安装 HAProxy 和 Let's Encrypt 的 certbot:
Redhat 衍生系统
sudo dnf install haproxy certbot openssl -yDebian 衍生系统
sudo apt install haproxy certbot openssl -yHAProxy 配置基础
HAProxy 的配置默认存储在 /etc/haproxy/haproxy.cfg 中。此文件包含决定 HAProxy 如何运行的所有配置指令。
使 HAProxy 与 Open WebUI 协同工作的基本配置相当简单:
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
#adjust the dh-param if too low
tune.ssl.default-dh-param 2048
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor #except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 300s
timeout queue 2m
timeout connect 120s
timeout client 10m
timeout server 10m
timeout http-keep-alive 120s
timeout check 10s
maxconn 3000
#http
frontend web
#Non-SSL
bind 0.0.0.0:80
#SSL/TLS
bind 0.0.0.0:443 ssl crt /path/to/ssl/folder/
#Let's Encrypt SSL
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
#Subdomain method
acl chat-acl hdr(host) -i subdomain.domain.tld
#Path Method
acl chat-acl path_beg /owui/
use_backend owui_chat if chat-acl
#Pass SSL Requests to Lets Encrypt
backend letsencrypt-backend
server letsencrypt 127.0.0.1:8688
#OWUI Chat
backend owui_chat
# add X-FORWARDED-FOR
option forwardfor
# add X-CLIENT-IP
http-request add-header X-CLIENT-IP %[src]
http-request set-header X-Forwarded-Proto https if { ssl_fc }
server chat <ip>:3000WebSocket 和 HTTP/2 兼容性
从最近的版本开始(包括 HAProxy 3.x),HAProxy 可能会默认启用 HTTP/2。虽然 HTTP/2 支持 WebSocket (RFC 8441),但在某些客户端或后端配置中,当通过 H2 隧道使用 WebSocket 加载图标或数据时,可能会遇到“冻结”或无响应的情况。
如果您遇到这些问题:
- 强制对 WebSocket 使用 HTTP/1.1:在您的
frontend或defaults部分中添加option h2-workaround-bogus-websocket-clients。这可以防止 HAProxy 向客户端宣告 RFC 8441 支持,从而强制降级到更稳定的 HTTP/1.1 Upgrade 升级机制。 - 后端版本:确保您的后端连接使用的是 HTTP/1.1(即
mode http的默认设置)。
在 defaults 或 frontend 中添加的示例:
defaults
# ... 其他设置
option h2-workaround-bogus-websocket-clients您会看到我们同时为 Open WebUI 和 Let's Encrypt 设置了 ACL 路由规则。要对 Open WebUI 使用 WebSocket,您必须配置 SSL,而最简单的方式就是使用 Let's Encrypt。
您可以使用域名方法(子域名)或路径方法将流量路由到 Open WebUI。子域名方法需要一个专用的子域名(例如 chat.yourdomain.com),而路径方法允许您通过域名上的特定路径(例如 yourdomain.com/owui/)访问 Open WebUI。请根据您的需求选择最合适的方法,并相应地更新配置。
您需要将端口 80 和 443 暴露给您的 HAProxy 服务器。Let's Encrypt 验证域名以及 HTTPS 流量都需要这些端口。您还需要确保 DNS 记录已正确配置为指向您的 HAProxy 服务器。如果您在家里运行 HAProxy,则需要在路由器中进行端口转发,将 80 和 443 端口转发到您的 HAProxy 服务器。
使用 Let's Encrypt 签发 SSL 证书
在启动 HAProxy 之前,您可能需要生成一个自签名证书 作为占位符,直到 Let's Encrypt 签发正式证书。以下是生成自签名证书的方法:
openssl req -x509 -newkey rsa:2048 -keyout /tmp/haproxy.key -out /tmp/haproxy.crt -days 3650 -nodes -subj "/CN=localhost"然后,将密钥和证书合并为一个 HAProxy 可以使用的 PEM 文件:
cat /tmp/haproxy.crt /tmp/haproxy.key > /etc/haproxy/certs/haproxy.pem请确保根据您的实际需求和配置情况来更新 HAProxy 配置。
完成 HAProxy 配置设置后,您可以使用 certbot 来获取和管理您的 SSL 证书。Certbot 将处理与 Let's Encrypt 的验证过程,并在您的证书接近过期时自动对其进行更新(假设您启用了 certbot 自动续期服务)。
您可以通过运行 haproxy -c -f /etc/haproxy/haproxy.cfg 来验证 HAProxy 配置。如果没有错误,您可以使用 systemctl start haproxy 启动 HAProxy,并使用 systemctl status haproxy 验证其运行状态。
要确保 HAProxy 随系统自启,请运行 systemctl enable haproxy。
配置好 HAProxy 后,您可以使用 Let's Encrypt 来签发有效的 SSL 证书。 首先,您需要向 Let's Encrypt 进行注册。这通常只需要进行一次:
certbot register --agree-tos --email your@email.com --non-interactive然后,您可以申请证书:
certbot certonly -n --standalone --preferred-challenges http --http-01-port-8688 -d yourdomain.com证书签发后,您需要将证书文件和私钥文件合并为一个 HAProxy 可以使用的 PEM 文件。
cat /etc/letsencrypt/live/{domain}/fullchain.pem /etc/letsencrypt/live/{domain}/privkey.pem > /etc/haproxy/certs/{domain}.pem
chmod 600 /etc/haproxy/certs/{domain}.pem
chown haproxy:haproxy /etc/haproxy/certs/{domain}.pem然后,您可以重启 HAProxy 以应用新证书:
systemctl restart haproxyHAProxy Manager(便捷部署选项)
如果您希望能够自动管理 HAProxy 配置和 Let's Encrypt SSL 证书,我编写了一个简单的 Python 脚本,并创建了一个 Docker 容器,您可以用它来创建和管理 HAProxy 配置并管理 Let's Encrypt 证书的生命周期。
https://github.com/shadowdao/haproxy-manager
如果您使用该脚本或容器,请不要将端口 8000 公开暴露到公网上!