Just got my SLES 12 SP4 server. That’s a type of commercial Linux I needed to set up a secure reverse proxy in a hurry. There’s a lot of suggestions out there. I share what worked for me. The version of apache that is supplied, for the record, is apache 2.4.
The most significant error
[Tue Aug 13 15:26:24.321549 2019] [proxy:warn] [pid 5992] [client 127.0.0.1:40002] AH01144: No protocol handler was valid for the URL /. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.
In /etc/sysconfig/apache2 (in SLES this is a macro that sets up apache with the needed loadmodule statements) I needed a statement like the following:
APACHE_MODULES="actions alias auth_basic authn_file authz_host authz_groupfile authz_core authz_user autoindex cgi dir env expires include log_config mime negotiation setenvif ssl socache_shmcb userdir reqtimeout authn_core proxy proxy_html proxy_http xml2enc"
In my first crack at it I only had mention of modules to include up to proxy. I needed to add proxy_html and proxy_http (I know it doesn’t display correctly in the line above).
In that same file you need a statement like this as well:
The highlights of my virtual host file, based on the ssl template, are:
<VirtualHost *:443> # https://www.centosblog.com/configure-apache-https-reverse-proxy-centos-linux/ <Location /> ProxyPass https://10.1.2.181/ ProxyPassReverse https://10.1.2.181/ </Location> # General setup for the virtual host ## DocumentRoot "/srv/www/htdocs" #ServerName www.example.com:443 #ServerAdmin email@example.com SSLProxyEngine on ErrorLog /var/log/apache2/error_log TransferLog /var/log/apache2/access_log # SSL Engine Switch: # Enable/Disable SSL for this virtual host. SSLEngine on # from https://superuser.com/questions/829793/how-to-force-all-apache-connections-to-use-tlsv1-1-or-tlsv1-2 -DrJ 8/19 SSLProtocol all -SSLv2 -SSLV3 -TLSv1 #SSLCipherSuite HIGH:!aNULL:!MD5:!RC4 SSLCipherSuite ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH # You can use per vhost certificates if SNI is supported. SSLCertificateFile /etc/apache2/ssl.crt/vhost-example.crt SSLCertificateKeyFile /etc/apache2/ssl.key/vhost-example.key SSLCertificateChainFile /etc/apache2/ssl.crt/vhost-example-chain.crt # Per-Server Logging: # The home of a custom SSL log file. Use this when you want a # compact non-error SSL logfile on a virtual host basis. CustomLog /var/log/apache2/ssl_request_log ssl_combined </VirtualHost>
except that I used valid paths to my certificate, key and CA chain files.
Errors you may encounter
$ curl ‐i ‐k https://localhost/
HTTP/1.1 500 Proxy Error Date: Thu, 15 Aug 2019 19:10:13 GMT Server: Apache Content-Length: 442 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>500 Proxy Error</title> </head><body> <h1>Proxy Error</h1> The proxy server could not handle the request <em><a href="/">GET /</a></em>.<p> Reason: <strong>Error during SSL Handshake with remote server</strong></p><p /> <p>Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.</p> </body></html>
I traced this error to the fact that initially I did not tell apache to ignore certificate name and other related mismatches. So inserting these directives cured that problem:
SSLProxyVerify none SSLProxyCheckPeerCN off SSLProxyCheckPeerName off SSLProxyCheckPeerExpire off
I finally got past the SSL errors but then I still had a 404 error and an xml2enc error.
When I ran a service apache2 status I saw this:
Aug 15 16:09:31 lusytp008850388 start_apache2: [Thu Aug 15 16:09:31.879604 2019] [proxy_html:notice] [pid 28539] AH01425: I18n support in mod_proxy_html requires mod_xml2enc. Without it, non-ASCII characters in proxied pages are likely to display incorrectly.
Not certain whether this was important or not, I simply decided to heed the advice so that’s when I added xml2enc to the list of modules to enable in /etc/sysconfig/apache2:
APACHE_MODLUES=actions alias auth...proxy proxy_html proxy_http xml2enc"
HTTP/1.1 404 Not Found
And that was when I put in a URI that worked just fine if I entered it directly in a browser hitting the web server.
I had a hunch that this could occur if the web server was finicky and insisted on being addressed by a certain name. So originally I had statements like this:
ProxyPass https://10.1.2.181/ ProxyPassReverse https://10.1.2.181/
I changed it to
ProxyPass https://backendalias.example.com/ ProxyPassReverse https://backendalias.example.com/
except in place of backendalias.example.com I put in what I felt the web site operators would have used – the known working alias for direct access to this web site. Of course I first made sure that my apache server could resolve backendalias.example.com to 10.1.2.181, which it could.
And, voila, no more 404 error!
Redirects going to the backend server name rather than the public hostname
This was my bad. I actually had in my ProxyPassReverse statement
ProxyPass https://backendalias.example.com/ ProxyPassReverse https://publicalias.example.com/
That’s just not right. And it caused public Internet users to get redirects (the Location HTTP response header) to the private back-end server hostname, which of course they could not resolve or reach. Once I re-read how this was supposed to work and corrected it to
ProxyPassReverse https://backendalias.example.com/ ,
it was all good.
An SSL reverse proxy to an SSL back-end web server was set up under SLES 12 SP4, using TLS 1.2 and apache 2.4.23, in other words, pretty current stuff.
References and related