Benutzer-Werkzeuge

Webseiten-Werkzeuge


prog:oracle_apex_haproxy

Eine Tomcat 9 / ORDS 23 / APEX 23 Umgebung unter Oracle Linux mit dem HAProxy betreiben

Aufgabe: Eine Oracle APEX in der Version 23 soll hinter einem HAProxy betreiben werden auf mehreren Applikation Server betrieben werden.

Leider stellt sich heraus das diese überhaupt keine gute Idee als SSL Frontend ist, da der ORDS zu viel Logik enthält und sich nicht vernünftig betreiben läßt! Besser ORDS hinter Standard Konfiguration Apache HTTP / Tomcat / ORDS betreiben und nur SSL auf den Apache HTTP per HAProxy als Load balancer umleiten!

Umgebung:

Da der HAProxy schon im Einsatz ist und unterandern weitere Oracle Produkte wie Forms/Reports bedient soll auch für die APEX Tomcat Umgebung dieser Proxy eingesetzt werden.

Die Apex Server sind nach diesem Muster aufgesetzt Oracle APEX 23 / ORDS 23 / Tomcat 9 mit Java 21 / Apache 2.4 mit der Oracle Datenbank 23c unter Oracle Linux 8 - Installation, das heißt die statischen Komponenten werden über Apache ausgeliefert (dieser ist bereits mit SSL verschlüsselt, daher ist die Konfiguration so angepasst!), der Tomcat ist testweise freigeschaltet und über 8080 erreichbar ohne SSL!

Idealer wäre es umgekehrt, in einer Produktiven Umgebung sollte der Tomcat dann auch mit SSL betrieben werden oder beides ohne.

HAProxy Grundlagen

 HAProxy als SSL Tomcat

Der HAProxy ist ein SSL Terminator / Loadbalancer der für verschiedenen Protokolle eingesetzt werden kann, unterandern für SSL.

D.h. der Oracle ORDS wird kann klassisch ein einer Tomcat Umgebung betrieben und statt dem Apache httpd wird alternativ der HAProxy für die SSL Verschlüsselung und als Einstieg über den Port 443 eingesetzt.

Mehr zu HAProxy = https://www.haproxy.org/

Ablauf

  • HAProxy Installation
  • Autostart und Log konfigurieren
  • HTTP Standard Verhalten einstellen und testen
  • SSL Konfigurieren
  • HAProxy härten / prüfen

Basis Installation unter Oracle Linux

dnf Installation

Der HAproxy für Oracle Linux liegt im „ol8_appstream“ Repository.

Installation des Proxy:

dnf install haproxy

Was haben wir am Ende:

haproxy -v
 
HA-Proxy version 1.8.27-493ce0b 2020/11/06

D.h. die Version ist 2020-11-06 ? Siehe vom https://www.haproxy.org/bugs/bugs-1.8.27.html

Eine neuere Version ist in dem Oracle Repository nicht zu finden, nicht gut da aktuell Version 2.7 mindestens.

Hier ist zu überlegen, einen expliziten Server nur für diese Aufgaben aufzusetzen und auf dem Server diesen aus den Quellen neu zu übersetzen.

Installation über alternatives Repo

Oder alternativ über https://github.com/zenetys/rpm-haproxy ein alternatives Repo mit einbinden.

cd /etc/yum.repos.d/
 
wget https://packages.zenetys.com/latest/redhat/zenetys-latest.repo
 
dnf search haproxy*
 
..
haproxy29z.x86_64 : HAProxy reverse proxy for high availability environments
haproxy29z+quic.x86_64 : HAProxy reverse proxy for high availability environments
# => was ist quic?
# -- HTTP/3 is the latest iteration of the HTTP protocol with one fundamental difference: streams and flow control, #    which were introduced in HTTP/2, have been moved outside of HTTP to the new lower transport protocol called QUIC.
..
# wir brauchen also für unsere Standard Umgebung erstmal nur den normalen HAProxy
 
dnf info haproxy29z.x86_64
Last metadata expiration check: 0:06:00 ago on Wed 06 Mar 2024 11:57:16 CET.
Available Packages
Name         : haproxy29z
Version      : 2.9.6
Release      : 1.el8.zenetys
Architecture : x86_64
Size         : 2.9 M
Source       : haproxy29z-2.9.6-1.el8.zenetys.src.rpm
Repository   : zenetys-latest
Summary      : HAProxy reverse proxy for high availability environments
URL          : http://www.haproxy.org/
License      : GPLv2+
Description  : HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high
             : availability environments. Indeed, it can:
             :  - route HTTP requests depending on statically assigned cookies
             :  - spread load among several servers while assuring server persistence
             :    through the use of HTTP cookies
             :  - switch to backup servers in the event a main one fails
             :  - accept connections to special ports dedicated to service monitoring
             :  - stop accepting connections without breaking existing ones
             :  - add, modify, and delete HTTP headers in both directions
             :  - block requests matching particular patterns
             :  - report detailed status to authenticated users from a URI
             :    intercepted from the application

Auto Start

Autostart einrichten:

systemctl enable haproxy
 
systemctl start haproxy
systemctl status haproxy

Was läuft jetzt:

netstat -tulpe | grep haproxy

Konfiguration

Nach der Installation kann über den Folder „/etc/haproxy“ die Konfiguration erfolgen.

Für die Konfigurationsparameter siehe ⇒ https://www.haproxy.org/download/1.8/doc/configuration.txt

Orginal sichern:

cd /etc/haproxy
cp haproxy.cfg haproxy.cfg-org

Die Konfiguration ist in zwei Bereiche eingeteilt, dem „frontend“ und dem „backend“.

Das „frontend“ wird vom Client Browser angesprochen und die Anfrage vom Proxy an das „backend“ weitergeleitet.

Beispiel für eine erste Basis Konfiguration mit Statistik Report:

frontend http_balancer
    bind 10.10.10.96:80
    option http-server-close
    option forwardfor
 
    stats enable                             # Enable stats page
    stats realm   GPI- HAProxy Statistics    # Title text for popup window
    stats uri     /haproxy?stats_ssl           # Stats URI for each backend
    stats auth    haproxyuser:proxypwd        # Authentication credentials
 
    acl url_static       path_beg       -i /i
    acl url_static       path_end       -i .jpg .gif .png .css .js
    use_backend static   if url_static
 
    default_backend      tomcat_ords
 
 
backend static
    balance     roundrobin
 
    cookie SERVERID insert indirect nocache
 
    server  apex01              10.10.10.90:443    check ssl verify none cookie 1
    server  oracledb23c01       10.10.10.112:443   check ssl verify none cookie 2
 
 
backend tomcat_ords
    mode        http
 
    balance     roundrobin
    # Wird nur benötigt wenn der HA auf dem gleichen Host läuft
    # Und dieser auf Localhost Zugriffe gehärtet ist!
    #
    #option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost
 
    cookie SERVERID insert indirect nocache
 
    server  apex01             10.10.10.90:8080    check cookie 1
    server  oracledb23c01      10.10.10.112:8080   check cookie 2
 
 

Syntax überprüfen mit;

haproxy -f /etc/haproxy/haproxy.cfg -c

Der check Parameter sagt aus das regelmäßig geprüft wird ob der Server noch zur Verfügung steht, siehe ⇒ https://www.haproxy.com/blog/how-to-enable-health-checks-in-haproxy


Logging über syslog

Datei /etc/rsyslog.conf anpassen und folgende Zeilen einkommentieren:

/etc/rsyslog.conf
 
module(load="imudp")
input(type="imudp" port="514")

Datei /etc/rsyslog.d/haproxy.conf anlegen:

vi /etc/rsyslog.d/haproxy.conf
 
local2.=info     /var/log/haproxy-access.log
local2.notice    /var/log/haproxy-info.log

Aktivieren:

systemctl enable rsyslog
systemctl start  rsyslog

Log Rotate prüfen (auf die richtige Angabe der Datei Namen achten!) über :

vi /etc/logrotate.d/haproxy
 
 
/var/log/haproxy-access.log  /var/log/haproxy-info.log {
    daily
    rotate 10
    missingok
    notifempty
    compress
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
        /bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}
 
#testen
logrotate -d /etc/logrotate.d/haproxy

SSL Konfiguration

Nach der Basis Konfguration von HTTP kann die Konfiguration von SSL erfolgen.

Siehe auch:

Basis Pakete:

dnf install openssl

Testzertifikat anlegen:

mkdir /etc/ssl/private
 
openssl req -nodes -x509 -newkey rsa:2048 -keyout /etc/ssl/private/haproxy.key -out /etc/ssl/private/haproxy.crt -days 365

pem erzeugen:

cat /etc/ssl/private/haproxy.key /etc/ssl/private/haproxy.crt > /etc/ssl/private/haproxy.pem

HAProxy Konfiguration für SSL erweitern:

cd /etc/haproxy
cp haproxy.cfg haproxy.cfg_http
 
vi haproxy.cfg
 
 
# ---------------------------------------
# https
# ---------------------------------------
 
frontend https_balancer_ssl
    bind 10.10.10.96:443 ssl crt /etc/ssl/private/haproxy.pem
    mode http
 
    http-request set-header X-Forwarded-For %[src]
    reqadd X-Forwarded-Proto:\ https
 
    option http-server-close
 
    acl url_static       path_beg       -i /i
    acl url_static       path_end       -i .jpg .gif .png .css .js
    use_backend static   if url_static
 
    default_backend      tomcat_ords
 
 
 
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
 
backend static
    balance     roundrobin
 
    cookie SERVERID insert indirect nocache
 
    server  apex01              10.10.10.90:443    check ssl verify none cookie 1
    server  oracledb23c01       10.10.10.112:443   check ssl verify none cookie 2
 
 
backend tomcat_ords
    mode        http
 
    balance     roundrobin
    # Wird nur benötigt wenn der HA auf dem gleichen Host läuft
    # Und dieser auf Localhost Zugriffe gehärtet ist!
    #
    #option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost
 
    cookie SERVERID insert indirect nocache
 
    server  apex01             10.10.10.90:8080    check cookie 1
    server  oracledb23c01      10.10.10.112:8080   check cookie 2
 
 
# testen
haproxy -f /etc/haproxy/haproxy.cfg -c

Backend ist auch schon weiter open definiert worden!

Warning: Unable to load default 1024 bits DH parameter for certificate

Meldung:

haproxy -f /etc/haproxy/haproxy.cfg -c
 
[WARNING] 050/175637 (38926) : parsing [/etc/haproxy/haproxy.cfg:81] : 'bind 10.10.10.112:443' :
  unable to load default 1024 bits DH parameter for certificate '/etc/ssl/private/haproxy.pem'.
  , SSL library will use an automatically generated DH parameter.
[WARNING] 050/175637 (38926) : Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.
 
Configuration file is valid

dhparams.pem erzeugen (dauert etwas):

 openssl dhparam -out /etc/haproxy/dhparams.pem 2048

Konfiguration erweitern/anpassen:

vi haproxy.cfg
 
#unter default eine zeile auskommentieren und eine einfügen
 
# utilize system-wide crypto-policies
    #ssl-default-bind-ciphers PROFILE=SYSTEM
    ssl-default-server-ciphers PROFILE=SYSTEM
    ssl-dh-param-file /etc/haproxy/dhparams.pem
 
 
haproxy -f /etc/haproxy/haproxy.cfg -c
Configuration file is valid

Siehe ⇒ https://www.digitalocean.com/community/tutorials/haproxy-ssl-tls-warning-setting-tune-ssl-default-dh-param-to-1024-by-default


Statistik Report anzeigen

Der Proxy hat auch eine Oberfläche, die den aktuellen Status anzeigt.

Konfiguriert wird das über folgende Parameter in das erste Frontend (http):

   stats enable                             # Enable stats page
   stats realm   GPI- HAProxy Statistics    # Title text for popup window
   stats uri     /haproxy?stats_ssl         # Stats URI for each backend
   stats auth    haproxyuser:proxypwd       # Authentication credentials
 

Aufrufen über http://haproxy.pipperr.local/haproxy?stats_ssl

 Statistik Report HA Proxy


HAProxy härten

HAProxy im laufenden Betrieb neustarten

Einfachste Lösung:

systemctl start haproxy

Es muss geprüft werden ob auch ein „echter“ Restart erfolgt, anscheinend ist das nicht immer so implementiert siehe dazu ⇒ https://fordodone.com/2013/07/17/hot-reconfigure-haproxy-without-restart/


Probleme

504 Gateway Timeout

Parameter „timeout server“ unter „default“ auf höheren Wert anpassen:

timeout server 2m

Siehe auch: https://www.papertrail.com/solution/tips/haproxy-logging-how-to-tune-timeouts-for-performance/


Problem Cross Origin Sharing - Anforderungen - 403

Ab der ORDS Version 20.2.1 kann es zu diesem Problem kommen, der ORDS prüft die ursprüngliche Quelle der Anfrage (wurde über SSL angefragt und im Backend per HTTP weitergereicht) und sieht das hier ein Mismatch der Protokolle und der anfragenden Server vorliegt.

Fehlermeldung

Die Anforderung kann nicht verarbeitet werden, da diese Ressource keine Cross Origin Sharing-Anforderungen unterstützt 
oder da der Anforderungsursprung nicht autorisiert ist, auf diese Ressource zuzugreifen. 
Wenn ords als Reverse-Proxy verwendet wird, stellen Sie sicher, dass der Frontend-Server den Hostnamen propagiert.
 
Stellen Sie für mod_proxy sicher, dass "ProxyPreserveHost" eingeschaltet ist
 
# bzw.
 
The request cannot be processed because this resource does not support Cross Origin Sharing requests, 
or the request Origin is not authorized to access this resource. 
 
If ords is being reverse proxied ensure the front end server is propagating the host name, for mod_proxy ensure ProxyPreserveHost is set to On

siehe dazu auch den Oracle Support Artikel ⇒ https://support.oracle.com/knowledge/Middleware/2926638_1.html und die Support Node „ORDS Cross-Origin Resource Sharing (CORS) Feature and 403 Forbidden Error (Doc ID 2874872.1)“

Der Fehler ist auf ein HTTPS-Problem zurückzuführen.

Anfragen von Browsern an den HAProxy-Server erfolgen über HTTPS, aber die weitergeleitete Anfrage vom HAProxy an Tomcat/ORDS erfolgt über HTTP.

Der Browser kommuniziert mit dem HAProxy über HTTPS, und zwar über dessen öffentliche Adresse, z. B. proxy.pipperr.local über den Standard-HTTPS-Port 443.

Der Ursprung für die Anfragen ist also https://proxy.pipperr.local.

Wenn der HAProxy-Server die Anfrage erhält, leitet er sie über HTTP an den Backend-Server / Anwendungsserver (Tomcat) weiter.

Nur der Hostname wird weitergegeben wird, das Schema (d. h. HTTPS) wird nicht weitergegeben.

Der Anwendungsserver (Tomcat) hat eine Anfrage erhalten, deren Ursprung lautet: http://proxy.pipperr.local, da er die Anfrage über seinen HTTP-Port erhalten hat.

Der Application Server (Tomcat-Server) leitet die Anfrage an ORDS weiter über HTTP.

Daher denkt ORDS, dass die Herkunft der Anfrage http://proxy.pipperr.local ist, obwohl sie https://proxy.pipperr.local sein sollte.

ORDS weigert sich nun die Anfrage zu bearbeiten und gibt den Status 403 Forbidden aus, da der Wert des Origin-Headers (https://proxy.pipperr.local) nicht mit der erwarteten Herkunft (http://proxy.pipperr.local) übereinstimmt.

Lösung:

D.h. der Header muss beim weiterleiten ins Backend so umgeschrieben werden das der ORDS die Anfrage akzeptiert.

Die Frage ist nun aber wie wir das konfigurieren!

Keine Anweisung hat bisher das Verhalten verbessert ….

Lösung nur über Konfiguration vom ORDS gelungen, keine Variante für den HAProxy gefunden die erfolgreich war (Version 1.5 ist im Einsatz in Prod - evlt. ist das eine der Ursachen!)
ORDS anpassen

Datei setting.xml anpassen:

<entry key="security.externalSessionTrustedOrigins">https://proxy.pipperr.local,http://proxy.pipperr.local</entry>

Über das Komandozeilen Tool:

ords --config  [path]/config config set security.externalSessionTrustedOrigins "https://proxy.pipperr.local,http://proxy.pipperr.local"

ODRS schalte wieder auf HTTP zurück

Problem:

ORDS URL lässt sich über HTTPS aufrufen, in einigen Umgebung erhält der Browser eine 302 und switcht auf HTTP wieder um, in anderen Umgebung lässt sich das Verhalten aber nicht nachvollziehen.

Es wird ein Zusammenhang mit den obigen Parameter „security.externalSessionTrustedOrigins“ vermutet, da ja der ORDS in dieser Umgebung über den HAProxy mit HTTP angesprochen wird.

Lösung:

Noch offen



Komplette HAProxy Konfiguration für diese Beispiel

vi haproxy.cfg

haproxy.cfg
#---------------------------------------------------------------------
# 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
 
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
 
    # utilize system-wide crypto-policies
    #ssl-default-bind-ciphers PROFILE=SYSTEM
    ssl-default-server-ciphers PROFILE=SYSTEM
    ssl-dh-param-file /etc/haproxy/dhparams.pem
 
#---------------------------------------------------------------------
# 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    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          2m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
 
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
 
 
frontend http_balancer
    bind 10.10.10.96:80
    option http-server-close
    option forwardfor
 
    stats enable                             # Enable stats page
    stats realm   GPI- HAProxy Statistics    # Title text for popup window
    stats uri     /haproxy?stats_ssl           # Stats URI for each backend
    stats auth    haproxyuser:proxypwd        # Authentication credentials
 
    acl url_static       path_beg       -i /i
    acl url_static       path_end       -i .jpg .gif .png .css .js
    use_backend static   if url_static
 
    default_backend      tomcat_ords
 
 
 
#---------------------------------------------------------------------
 
frontend https_balancer_ssl
    bind 10.10.10.96:443 ssl crt /etc/ssl/private/haproxy.pem
    mode http
 
    http-request set-header X-Forwarded-For %[src]
    reqadd X-Forwarded-Proto:\ https
 
    option http-server-close
 
    acl url_static       path_beg       -i /i
    acl url_static       path_end       -i .jpg .gif .png .css .js
    use_backend static   if url_static
 
    default_backend      tomcat_ords
 
 
 
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
 
backend static
    balance     roundrobin
 
    cookie SERVERID insert indirect nocache
 
    server  apex01              10.10.10.90:443    check ssl verify none cookie 1
    server  oracledb23c01       10.10.10.112:443   check ssl verify none cookie 2
 
 
backend tomcat_ords
    mode        http
 
    balance     roundrobin
    # Wird nur benötigt wenn der HA auf dem gleichen Host läuft
    # Und dieser auf Localhost Zugriffe gehärtet ist!
    #
    #option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost
 
    cookie SERVERID insert indirect nocache
 
    server  apex01             10.10.10.90:8080    check cookie 1
    server  oracledb23c01      10.10.10.112:8080   check cookie 2

Quellen

Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
prog/oracle_apex_haproxy.txt · Zuletzt geändert: 2024/03/06 12:05 von gpipperr