0

I am setting up an Apache v2.4 httpd reverse proxy for another server hosting Atlassian Confluence.

The proxy's private IP address is 10.0.0.77, its public IP address is 77.77.77.77, and a DNS A record maps the public IP to confluence.example.com.

There is a NAT in place:

  • 77.77.77.77:10080 -> 10.0.0.77:80
  • 77.77.77.77:10443 -> 10.0.0.77:443

which is necessary because the proxy's public IP address is used also for other services.

Name resolution on the proxy is done via /etc/hosts, which maps confluence.example.com to 10.0.0.9, the private IP of the Confluence server.

Here's /etc/httpd/conf.d/confluence.conf (as you see, it also does a redirect from HTTP to HTTPS):

<VirtualHost *:80>
    ServerName confluence.example.com
    ProxyRequests off
    ProxyPreserveHost off
    SetEnv force-proxy-request 1
    SetEnv proxy-nokeepalive 1
    ProxyPass        "/" "http://confluence.example.com:8090/" 
    ProxyPassReverse "/" "http://confluence.example.com:8090/"
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>

<VirtualHost *:443>
    ServerName confluence.example.com
    ServerSignature On
        <Proxy *>
            Order deny,allow
            Allow from all
        </Proxy>
    SSLEngine on
    SSLProtocol ALL -SSLv2 -SSLv3
    SSLHonorCipherOrder on
    # SSL cipher suite shortened for clarity
    SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384"
    SSLCertificateFile    /etc/httpd/ssl/example.crt
    SSLCertificateKeyFile /etc/httpd/ssl/example.key
    SSLCACertificateFile  /etc/httpd/ssl/example.crt
    ProxyRequests off
    ProxyPreserveHost on 
    ProxyPass        "/" "http://confluence.example.com:8090/" 
    ProxyPassReverse "/" "http://confluence.example.com:8090/"
</VirtualHost>

When accessing http://confluence.example.com:10080 (or even http://77.77.77.77:10080) from a browser, the URL changes to https://confluence.example.com:10080 but, instead of showing the Confluence login page, this error is returned:

Secure Connection Failed
An error occurred during a connection to 77.77.77.77:10080. SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG

This is what is logged (DEBUG level) to the http access log:

33.33.33.33 - - [17/Sep/2018:17:06:59 +0200] "GET / HTTP/1.1" 302 208 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0"
33.33.33.33 - - [17/Sep/2018:17:06:59 +0200] "\x16\x03\x01\x02" 400 226 "-" "-"

and to the http error log:

[Mon Sep 17 17:11:58.095085 2018] [core:debug] [pid 23120] protocol.c(1271): [client 33.33.33.33:49745] AH00566: request failed: malformed request line

I have set up separate https access and error logs, nothing is logged there. As you might have guessed, 33.33.33.33 is my outgoing public IP.

Accessing https://confluence.example.com:10443 works fine.

The same config works on another Apache v2.2 reverse proxy.

Any hint?

  • 1
    Well yes, 77.77.77.77:10080 speaks http, not https, that's why you get a protocol-level error in your browser. Beyond that, my brain is stuck in the additional knots introduced by NAT. I think you'd want to end up at https://77.77.77.77:10443, no? – Ulrich Schwarz Sep 18 '18 at 11:57
  • Yes. I don't like the NAT solution neither but apparently we can't do otherwise -- as I said, that public IP address is also used by the old 2.2 proxy. – dr01 Sep 18 '18 at 12:00
  • OK, let's try to boil this down a little bit, eliminate variables: all the proxy lines in Vhost 80 can go, since you just want to redirect. RewriteRule can have the [R] flag just to be sure. (The docs say "hostname matches" when I believe it should be "hostname and protocol match" in the "Absolute URL" description.) – Ulrich Schwarz Sep 18 '18 at 12:08
  • VHost 443: your Proxypass/ProxypassReverse should be able to use the 10.0.0.9 explicitly, since you have ProxyPreserveHost on, saves a bit of confusion with the /etc/hosts entry. – Ulrich Schwarz Sep 18 '18 at 12:10
  • Yeah, this would be easier if you could stick another virtual IP on the interface… I suspect you'll end up putting the :10443 in the redirect explicitly, because NAT shouldn't look at the message content at that level. I don't see why you didn't end up at 77.77.77.77:443 then with your current config, though, because %{HTTP_HOST} shouldn't include the port. – Ulrich Schwarz Sep 18 '18 at 12:17
1

I do this for my Tomcat instances. (Formerly Confluence, now XWiki.)

  1. The http → https vHost is a straight redirect, no proxies.
  2. The https vHost manages the proxy rewrites for Tomcat, knowing that the URI has a sane pattern.

Here's a (slightly) edited version of my configuration:

<VirtualHost *:80>
        ServerAdmin web@example.com

        ServerName confluence.example.com

        DocumentRoot /home/www/confluence.example.com/docroot


        # Global protection
        #
        <Directory />
                Options none
                AllowOverride None
        </Directory>


        # Send users to canonical website
        #
        Redirect / https://confluence.example.com/


        # Logging
        #
        ServerSignature On
        LogLevel warn
        ErrorLog "|/usr/bin/cronolog /home/www/confluence.example.com/logs/%Y/%m/%d/public-error.log"
        CustomLog "|/usr/bin/cronolog /home/www/confluence.example.com/logs/%Y/%m/%d/public-access.log" combined

</VirtualHost>

<VirtualHost *:443>
        ServerAdmin web@example.com

        ServerName confluence.example.com

        DocumentRoot /home/www/confluence.example.com/docroot
        AddDefaultCharset UTF-8


        # Global protection
        #
        <Directory />
                Options none
                AllowOverride None
        </Directory>


        # Access to the application itself
        #
        ProxyPassMatch /(.*) http://confluence.example.com:8090/$1
        ProxyPassReverse / http://confluence.example.com:8090/
        ProxyPassReverseCookieDomain confluence.example.com confluence.example.com


        # Logging
        #
        ServerSignature On

        LogLevel warn rewrite:debug
        ErrorLog "|/usr/bin/cronolog /home/www/confluence.example.com/logs/%Y/%m/%d/secure-error.log"
        CustomLog "|/usr/bin/cronolog /home/www/confluence.example.com/logs/%Y/%m/%d/secure-access.log" combined

        #RewriteLogLevel 1
        #RewriteLog "|/usr/bin/cronolog /home/www/confluence.example.com/logs/%Y/%m/%d/secure-rewrite.log"


        # SSL
        #
        SSLEngine on

        SSLCertificateFile      "...crt"
        SSLCertificateKeyFile   "...key"
        SSLCertificateChainFile "...ca-bundle"

        BrowserMatch "MSIE [2-6]" \
                nokeepalive ssl-unclean-shutdown \
                downgrade-1.0 force-response-1.0
        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

</VirtualHost>
  • Thanks. The simple Redirect works in my case. I'd like to know nonetheless why httpd is throwing an error with the Proxy directives. – dr01 Sep 19 '18 at 10:15
  • @dr01 possibly because you were mixing Proxy directives with the Rewrite rules, but I don't really know without spending time digging. – roaima Sep 19 '18 at 11:32
  • That's possible, but this config worked in Apache v2.2. – dr01 Sep 19 '18 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.