跳到主要内容

为 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 -y

Debian 衍生系统

sudo apt install haproxy certbot openssl -y

HAProxy 配置基础

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>:3000

WebSocket 和 HTTP/2 兼容性

从最近的版本开始(包括 HAProxy 3.x),HAProxy 可能会默认启用 HTTP/2。虽然 HTTP/2 支持 WebSocket (RFC 8441),但在某些客户端或后端配置中,当通过 H2 隧道使用 WebSocket 加载图标或数据时,可能会遇到“冻结”或无响应的情况。

如果您遇到这些问题:

  1. 强制对 WebSocket 使用 HTTP/1.1:在您的 frontenddefaults 部分中添加 option h2-workaround-bogus-websocket-clients。这可以防止 HAProxy 向客户端宣告 RFC 8441 支持,从而强制降级到更稳定的 HTTP/1.1 Upgrade 升级机制。
  2. 后端版本:确保您的后端连接使用的是 HTTP/1.1(即 mode http 的默认设置)。

defaultsfrontend 中添加的示例:

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 haproxy

HAProxy Manager(便捷部署选项)

如果您希望能够自动管理 HAProxy 配置和 Let's Encrypt SSL 证书,我编写了一个简单的 Python 脚本,并创建了一个 Docker 容器,您可以用它来创建和管理 HAProxy 配置并管理 Let's Encrypt 证书的生命周期。

https://github.com/shadowdao/haproxy-manager

注意

如果您使用该脚本或容器,请不要将端口 8000 公开暴露到公网上!

This content is for informational purposes only and does not constitute a warranty, guarantee, or contractual commitment. Open WebUI is provided "as is." See your license for applicable terms.