open-webui icon indicating copy to clipboard operation
open-webui copied to clipboard

feat: CA truststore support

Open GillesBodart opened this issue 10 months ago • 16 comments

Bug Report

Description

When you run the docker image in an enterprise context, based on the company policy, you may have SSL interception in order to anlyse the traffic

Bug Summary: Impossible to add some CA to the internal trustore used to make the REST API request

Steps to Reproduce: need to have SSL interception enable on your laptop that breaks the SSL chain

Expected Behavior: Possibility to add CA to the used truststore

Actual Behavior:

CA can't be added

Environment

  • **Windows 11 running docker image ghcr.io/open-webui/open-webui:main
  • **Browser Chrome

Reproduction Details

Confirmation:

  • [* ] I have read and followed all the instructions provided in the README.md.
  • [* ] I am on the latest version of both Open WebUI and Ollama.
  • [* ] I have included the browser console logs.
  • [ *] I have included the Docker container logs.

Logs and Screenshots

Browser Console Logs: { "detail": "Something went wrong :/\nHTTPSConnectionPool(host='api.openai.com', port=443): Max retries exceeded with url: /v1/images/generations (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1006)')))" }

Docker Container Logs: INFO: 172.17.0.1:50270 - "GET /ollama/api/tags HTTP/1.1" 200 OK

INFO:apps.openai.main:get_all_models()

ERROR:apps.openai.main:Connection error: Cannot connect to host api.openai.com:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1006)')]

INFO:apps.openai.main:models: {'data': []}

INFO:apps.openai.main:get_all_models()

ERROR:apps.openai.main:Connection error: Cannot connect to host api.openai.com:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1006)')]

INFO:apps.openai.main:models: {'data': []}

INFO: 172.17.0.1:50270 - "GET /openai/api/models HTTP/1.1" 200 OK

INFO: 172.17.0.1:50270 - "GET /litellm/api/v1/models HTTP/1.1" 200 OK

INFO: 172.17.0.1:50294 - "GET /_app/immutable/nodes/8.0396dff0.js HTTP/1.1" 200 OK

INFO: 172.17.0.1:50298 - "GET /ollama/api/version HTTP/1.1" 200 OK

INFO: 172.17.0.1:50304 - "GET /ollama/api/version HTTP/1.1" 200 OK

INFO: 172.17.0.1:50304 - "GET /ollama/urls HTTP/1.1" 200 OK

INFO: 172.17.0.1:50304 - "GET /ollama/api/version HTTP/1.1" 200 OK

INFO: 172.17.0.1:50304 - "GET /litellm/api/model/info HTTP/1.1" 200 OK

INFO: 172.17.0.1:50316 - "GET /api/config HTTP/1.1" 200 OK

INFO: 172.17.0.1:50316 - "GET /api/v1/auths/ HTTP/1.1" 200 OK

INFO:apps.ollama.main:get_all_models()

INFO: 172.17.0.1:50316 - "GET /ollama/api/tags HTTP/1.1" 200 OK

INFO:apps.openai.main:get_all_models()

ERROR:apps.openai.main:Connection error: Cannot connect to host api.openai.com:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1006)')]

INFO:apps.openai.main:models: {'data': []}

INFO:apps.openai.main:get_all_models()

ERROR:apps.openai.main:Connection error: Cannot connect to host api.openai.com:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1006)')]

INFO:apps.openai.main:models: {'data': []}

INFO: 172.17.0.1:50316 - "GET /openai/api/models HTTP/1.1" 200 OK

INFO: 172.17.0.1:50316 - "GET /litellm/api/v1/models HTTP/1.1" 200 OK

INFO: 172.17.0.1:50316 - "GET /api/v1/modelfiles/ HTTP/1.1" 200 OK

INFO: 172.17.0.1:50316 - "GET /api/v1/prompts/ HTTP/1.1" 200 OK

INFO: 172.17.0.1:50316 - "GET /api/v1/documents/ HTTP/1.1" 200 OK

INFO: 172.17.0.1:50316 - "GET /api/v1/chats/tags/all HTTP/1.1" 200 OK

INFO:apps.ollama.main:get_all_models()

Screenshots (if applicable):

image

Installation Method

Docker vanilla install with Open API key

Additional Information

[Include any additional details that may help in understanding and reproducing the issue. This could include specific configurations, error messages, or anything else relevant to the bug.]

Note

If the bug report is incomplete or does not follow the provided instructions, it may not be addressed. Please ensure that you have followed the steps outlined in the README.md and troubleshooting.md documents, and provide all necessary information for us to reproduce and address the issue. Thank you!

GillesBodart avatar Apr 02 '24 13:04 GillesBodart

This would be an excellent feature. I'd rather not have to run my openai compatible inference server in http mode but I'm using a private public key infrastructure

strikeoncmputrz avatar Apr 04 '24 03:04 strikeoncmputrz

Feel free to make a PR!

tjbck avatar Apr 14 '24 20:04 tjbck

For folks stuck on this, here is a quick hack you can use ... basically you can just map /etc/ssl/certs/ca-certificates.crt in the container to a another file that contains your own trust chain.

In this example, I have my internal root CA trusted on the host machine and can map it directly into the container (don't forget to make it read only just in case):

docker run -it --rm \
  --publish=3000:8080 \
  --volume=open-webui:/app/backend/data \
  --volume=/etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro \
  ghcr.io/open-webui/open-webui:main

For a larger-scale deployment you can basically do the same thing, ex in Kubernetes maybe you are using something like trust-manager to manage your truststore within the cluster. You can mount the trust-manager managed bundle to /etc/ssl/certs/ca-certificates.crt inside the open webui pod.

This isn't a best practice and and environment variable configuration to add an additional truststore would be cleaner but this will work in the interim. As an aside, I tried to set REQUESTS_CA_BUNDLE in the environment but it didn't work for me.

theobjectivedad avatar Jun 19 '24 12:06 theobjectivedad

I'm not able to get the fix above to work, I've pulled my CA bundle from my AD Domain and added it into the container as mentioned above, however I still get a SSL: CERTIFICATE_VERIFY_FAILED error. ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006) however I did notice that the above method allows me to curl the .well-known address without having to ignore validation. It just seems like Open WebUI doesn't also respect that the CA root for my domain is trusted once added to the container CA trust. I'm running Open WebUI 0.3.7, and Authentik 2024.4.7 behind a NGINX reverse proxy.

hanahige avatar Jul 16 '24 19:07 hanahige

FWIW, you can force python to use the system certificate store via REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt in the environment.

My (trimmed down) docker-compose.yml looks like this:

services:
  openwebui:
    image: ghcr.io/open-webui/open-webui:main
    volumes:
      - /var/containers/openwebui:/app/backend/data:rw
      - /etc/containers/openwebui/compusrv.crt:/etc/ssl/certs/ca-certificates.crt:ro
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    environment:
      - WEBUI_NAME=compusrv
      - ENABLE_SIGNUP=False
      - ENABLE_COMMUNITY_SHARING=False
      - WEBUI_SESSION_COOKIE_SAME_SITE=strict
      - WEBUI_SESSION_COOKIE_SECURE=True
      - ENABLE_OLLAMA_API=False
      - REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

where /etc/containers/openwebui/compusrv.crt is simply my self-signed certificate (i.e. you don't even need to build a full truststore, if you don't want to).

KizzyCode avatar Jul 30 '24 14:07 KizzyCode

As an alternative to what @KizzyCode said and @theobjectivedad said about setting the REQUESTS_CA_BUNDLE env + mounting the host store, you can also add the following commands in the Dockerfile

COPY <CorporateSSL.crt> /usr/local/share/ca-certificates/
RUN update-ca-certificates

btw, I also have set

ENV PIP_CERT=/etc/ssl/certs/ca-certificates.crt \
    REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

Note that if you're building with the Dockerfile, you will also need to add the cert for the frontend build stage

nomppy avatar Jul 30 '24 14:07 nomppy

FWIW, you can force python to use the system certificate store via REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt in the environment.

My (trimmed down) docker-compose.yml looks like this:

services:
  openwebui:
    image: ghcr.io/open-webui/open-webui:main
    volumes:
      - /var/containers/openwebui:/app/backend/data:rw
      - /etc/containers/openwebui/compusrv.crt:/etc/ssl/certs/ca-certificates.crt:ro
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    environment:
      - WEBUI_NAME=compusrv
      - ENABLE_SIGNUP=False
      - ENABLE_COMMUNITY_SHARING=False
      - WEBUI_SESSION_COOKIE_SAME_SITE=strict
      - WEBUI_SESSION_COOKIE_SECURE=True
      - ENABLE_OLLAMA_API=False
      - REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

where /etc/containers/openwebui/compusrv.crt is simply my self-signed certificate (i.e. you don't even need to build a full truststore, if you don't want to).

Sadly, this does not work for me...

i still get SSL: CERTIFICATE_VERIFY_FAILED if i hit "Continue with OAuth2" on login screen

however if i exec into the container, this works:

>>> import requests
>>> response = requests.get('https://internal-keycloak-url/auth')
>>> print(response)
<Response [200]>

seems like webui is somehow not using the rootca

any ideas?

christiangierschner avatar Aug 06 '24 14:08 christiangierschner

What does your compose file look like?

nomppy avatar Aug 06 '24 17:08 nomppy

services:
  ollama:
    image: ghcr.io/open-webui/open-webui:v0.3.11
    volumes:
      - ollama-webui:/app/backend/data
      - /usr/local/share/ca-certificates/rootca.crt:/etc/ssl/certs/ca-certificates.crt:ro
    environment:
      OLLAMA_BASE_URL: http://ollama-api:11434
      ENABLE_OAUTH_SIGNUP: true
      ENABLE_LOGIN_FORM: false
      ENABLE_SIGNUP: false
      OAUTH_MERGE_ACCOUNTS_BY_EMAIL: true
      OAUTH_USERNAME_CLAIM: name
      OAUTH_CLIENT_ID: ollama
      OAUTH_CLIENT_SECRET:
      OPENID_PROVIDER_URL: https://$KEYCLOAKURL/auth/realms/$REALMNAME/.well-known/openid-configuration
      OAUTH_PROVIDER_NAME: Keycloak
      REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt
    extra_hosts:
      - host.docker.internal:host-gateway
    restart: unless-stopped
    networks:
      - backend
      - frontend

    labels:
      - traefik.enable=true
      - traefik.http.routers.ollama.rule=Host(`$HOST_NAME`)
      - traefik.http.routers.ollama.tls.certresolver=internal-acme
      - traefik.http.routers.ollama.service=ollama
      - traefik.http.routers.ollama.entrypoints=https
      - traefik.http.services.ollama.loadbalancer.server.port=8080

christiangierschner avatar Aug 07 '24 07:08 christiangierschner

Is /usr/local/share/ca-certificates/roocat.crt the complete CA used by your system. If it's just your custom root CA, then you are not giving python any of the usual certs usually present in /etc/ssl/certs/ca-certificates.crt.

Can you try update-ca-certificates on your host and then mapping /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro?

nomppy avatar Aug 07 '24 15:08 nomppy

i tried both...none works our hosts all have our rootca implmented with update-ca-certificates

i get Internal Server Error and SSL: CERTIFICATE_VERIFY_FAILED

services:
  ollama:
    image: ghcr.io/open-webui/open-webui:v0.3.12
    volumes:
      - ollama-webui:/app/backend/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
      - /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro
      - /usr/local/share/ca-certificates/rootca.crt:/usr/local/share/ca-certificates/rootca.crt
    environment:
      OLLAMA_BASE_URL: http://ollama-api:11434
      ENABLE_OAUTH_SIGNUP: true
      ENABLE_LOGIN_FORM: false
      ENABLE_SIGNUP: false
      OAUTH_MERGE_ACCOUNTS_BY_EMAIL: true
      OAUTH_USERNAME_CLAIM: name
      OAUTH_CLIENT_ID: ollama
      OAUTH_CLIENT_SECRET:
      OPENID_PROVIDER_URL: https://$KEYCLOAKURL/auth/realms/$REALMNAME/.well-known/openid-configuration
      OAUTH_PROVIDER_NAME: Keycloak
      REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt
    extra_hosts:
      - host.docker.internal:host-gateway
    restart: unless-stopped
    networks:
      - backend
      - frontend

    labels:
      - traefik.enable=true
      - traefik.http.routers.ollama.rule=Host(`$HOST_NAME`)
      - traefik.http.routers.ollama.tls.certresolver=ukd-internal
      - traefik.http.routers.ollama.service=ollama
      - traefik.http.routers.ollama.entrypoints=https
      - traefik.http.services.ollama.loadbalancer.server.port=8080

christiangierschner avatar Aug 09 '24 10:08 christiangierschner

  • Can you manually check that /etcssl/certs/ca-certificates.crt contains the cert in rootca.crt?
  • How did you obtain rootca.crt?
  • Do you can SSL error only when you click login with oAuth, or also for other things? I.e., can you try to log in with username/password and see if you get an error for requests to e.g. OpenAI?

nomppy avatar Aug 09 '24 16:08 nomppy

After struggling with this myself, thanks for the pointers in here.

What fixed this for me was

I copied the root.crt (from Caddy) to my Linux device and put it in /usr/local/share/ca-certificates

I then ran sudo update-ca-certificates which said it had added one cert.

After playing about, the only options that seemed to work me for me was adding these to my docker run command

-v /link/to/my/cert.crt:/etc/ssl/certs/ca-certificates.crt:ro

AND -e REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

After that, the Openweb-ui accepted the connections and it worked.

bkev avatar Aug 10 '24 12:08 bkev

  • Can you manually check that /etcssl/certs/ca-certificates.crt contains the cert in rootca.crt?

    • How did you obtain rootca.crt?

    • Do you can SSL error only when you click login with oAuth, or also for other things? I.e., can you try to log in with username/password and see if you get an error for requests to e.g. OpenAI?

Yes, it contains the cert. I got it from our rootca server and we use it in all our servers and deployments via ansible. It works.

I only get the error, when i click on login with OAuth. Open-webui then connects to our internal keycloak secured with a signed cert from our rootca.

christiangierschner avatar Aug 12 '24 15:08 christiangierschner

@christiangierschner and all the future people struggling with OAuth and custom CA certs.

It was able to deduce from the logs that OAuth does not use requests as its client module, but httpx instead. httpx documentation explains that custom CA certs could be used by using environment variable SSL_CERT_FILE. I was able to resolve my cert issue by adding:

environment:
  # ...
  # other values
  - SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt

to docker compose.

ebakoba avatar Aug 14 '24 17:08 ebakoba