https://bz.apache.org/bugzilla/show_bug.cgi?id=69619

            Bug ID: 69619
           Summary: mod_proxy: Error with SSL backend
           Product: Apache httpd-2
           Version: 2.4.63
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: mod_proxy
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

We want to implement the equivalent of a "Canary Mode" with Apache/mod_proxy as
Reverse Proxy. 

ProxyPass [r1] with SSL/TLS backend have some issues [e1][e2] with SNI,
solvable if does allow us to "force" the IP to which we want to connect (some
like: ip=X.X.X.X or sni=<name>). In curl for example, there is the "--resolve"
[r2] and "--connect-to" [r3] parameters. Something like this, will be a great
improvement in ProxyPass.

Issues:
 - [e1] Error reported by remote server (some cases): 421 Misdirected Request /
host name does not match the Server Name Indication (SNI)
 - [e2] Error mapped by apache (some cases): 500 Proxy Error / Error during SSL
Handshake with remote server

Currently ProxyPass only allows us to specify the URL, which fails with SNI
errors when the endpoint uses different certificates and we points to its IP
(use case / example 1).

--- example scenario ---

Apache listen on HTTP/80 for simplicity and backends servers on HTTPS/443.
Let's suppose a bunch (srv1=192.168.1.1,srv2=192.168.1.2,srv3=192.168.1.3),
with 2 certificates: CN="nodprod.acme.com" and another with CN="foo.bar.com",
on each srv.

# Example 1: Fails if backend is SSL/TLS and multiple certs enabled (SNI)
<VirtualHost _default_:80>
    # Remote server fails with ERROR-421 Misdirected Request
    # "requested host name does not match the Server Name Indication (SNI)"
    ServerName test-srv1.acme.com
    ProxyPreserveHost On
    RequestHeader set Host "noprod.acme.com"
    ProxyPass / https://192.168.1.1/ retry=0
</VirtualHost>


# Example 2: Workaround touching /etc/hosts, BUT only works with 1 backend (and
creates another issues on server), hosts is global, so we can't control/have
multiple backends / canary / VirtualHosts:
# /etc/hosts
192.168.1.1 noprod.acme.com
#
<VirtualHost _default_:80>
    # Works
    ServerName test-srv1.acme.com
    ProxyPreserveHost Off
    ProxyPass / https://noprod.acme.com/ retry=0
</VirtualHost>

# General config
SSLProxyEngine on
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
#

--- Expectation ---

# Feature and usage example, with "ip" parameter #
# This will send "Host: noprod.acme.com" in HTTP-Header and in SNI/TLS-Header.
# But will connect to specific IP
<VirtualHost _default_:80>
    ServerName test-srv1.acme.com
    ProxyPreserveHost Off
    ProxyPass / https://noprod.acme.com/ ip=192.168.1.1 retry=0
</VirtualHost>
<VirtualHost _default_:80>
    ServerName test-srv2.acme.com
    ProxyPreserveHost Off
    ProxyPass / https://noprod.acme.com/ ip=192.168.1.2 retry=0
</VirtualHost>

# Alternative feature and usage example, with "sni" parameter #
# This will send "Host: noprod.acme.com" in HTTP-Header and in SNI/TLS-Header.
# But will connect to specific IP
<VirtualHost _default_:80>
    ServerName test-srv1.acme.com
    ProxyPreserveHost On
    RequestHeader set Host "noprod.acme.com"
    ProxyPass / https://192.168.1.1/ sni=noprod.acme.com retry=0
</VirtualHost>
<VirtualHost _default_:80>
    ServerName test-srv2.acme.com
    ProxyPreserveHost On
    RequestHeader set Host "noprod.acme.com"
    ProxyPass / https://192.168.1.2/ sni=noprod.acme.com retry=0
</VirtualHost>

# Note about tricky "ProxyPreserveHost On" + "RequestHeader set Host"
If "ProxyPreserveHost is Off", ProxyPass do not send settled "RequestHeader
Host" to backend.

Another alternative (more/less easy?) could be that ProxyPass sets SNI with
settled Host header (example "RequestHeader set Host").

Testing helper: https://test.javastack.org/ can be used as backend for this,
although the IPs are public and change from time to time, the error returned
for SNI problem may be like [e2].

References:
 - [r1] https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
 - [r2] https://curl.se/docs/manpage.html#--resolve
 - [r3] https://curl.se/docs/manpage.html#--connect-to
 - [r4] https://github.com/apache/httpd/blob/2.4.63/modules/proxy/proxy_util.c

Thanks!

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to