Bad request on Apache ProxyPass

I’m trying to redirect cloud.mydomain.com from my main Apache instance running on a Raspberry Pi to a second Pi running NextCloudPi. I can get to the web interface at 192.168.1.200., but when accessing cloud.mydomain.com I’m getting the following message:

Bad Request
Your browser sent a request that this server could not understand.
Reason: You’re speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.

The actual configuration on the main Pi is:

cloud.conf

<VirtualHost *:80>
    ServerName cloud.mydomain.com
    ServerAlias cloud
    ProxyPass / http://192.168.1.200:80/
    ProxyPassReverse / http://192.168.1.200:80/
    ProxyPreserveHost On
    ProxyPass /.well-known/acme/ !
    RewriteEngine on
    RewriteCond %{SERVER_NAME} =cloud [OR]
    RewriteCond %{SERVER_NAME} =cloud.mydomain.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
  </VirtualHost>

cloud-le-ssl.conf

<VirtualHost *:443>
    ServerName cloud.mydomain.com
    ServerAlias cloud
    ProxyPass / http://192.168.1.200:443/
    ProxyPassReverse / http://192.168.1.200:443/
    ProxyPreserveHost On
    ProxyPass /.well-known/acme/ !
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/cloud.mydomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomain.com/privkey.pem
  </VirtualHost>

Also (maybe related), if I try to run the letsencrypt wizard on the web interface, I get this error:

[ letsencrypt ] (Sat Feb 20 12:16:22 GMT 2021)
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for cloud.mydomain.com
Using the webroot path /var/www/nextcloud for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. cloud.mydomain.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://cloud.mydomain.com/.well-known/acme-challenge/bPaBnmzn8Ef1hy9q3x0rK4VUxpGPKlGqZqLzomZ775g [91.116.161.160]: "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>400 Bad Request</title>\n</head><body>\n<h1>Bad Request</h1"
IMPORTANT NOTES:
- The following errors were reported by the server:

Domain: cloud.mydomain.com
Type: unauthorized
Detail: Invalid response from
https://cloud.mydomain.com/.well-known/acme-challenge/bPaBnmzn8Ef1hy9q3x0rK4VUxpGPKlGqZqLzomZ775g
[91.116.161.160]: "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML
2.0//EN\">\n<html><head>\n<title>400 Bad
Request</title>\n</head><body>\n<h1>Bad Request</h1"

To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.

Hello

My guess is that you allready had Let’s Encrypt certs enabled on your Nextcloud installation before you added the Reverse Proxy. You have to deactivate/delete them, so you can use it with a plain http connection out of your internal network. Otherwise your current reverse proxy configuration wouldn’t work and you wouldn’t be able to renew the certs anyway, because your nextcloud is not directley exposed to the internet anymore, since the ports 80 and 443 are forwarded to raspi with the reverse proxy installed.

You have to obtain the certificates on the rapberry pi where the reverse proxy is installed, instead on the one where your Nextcloud is installed. You could of course enable self signed certificates for the nextcloud installation, if you want to have encrypted communication from the reverse proxy to your Nextcloud. But then you have to change your Reverse proxy configuration accordingly.

Hope that helps.

1 Like

Following your cue, I’ve turned off the Force HTTPS option and I’ve added my main domain and main Raspberry Pi’s local IP to the trusted proxies list. Certbot says (on the nextcloudpi) that there’s no issued certificates. But I’m still getting that error. And it seems I’m still being redirected to the HTTPS version even I type HTTP. Where should I look next?

You can disable the redirection to https in the NextCloudPi admin panel by unchecking this box…

Yes, that’s exactly what I was saying I did, but I keep being redirected.

Hmm not sure why that is. I only use NCP as test installation with self signed certs in a small vm here. Maybe you have to reset your browser.

And as as far as the reverse reverse proxy configuration goes, it should look something like this:

Remove the ProxyPass directives in the cloud.conf

<VirtualHost *:80>
    ServerName cloud.mydomain.com
    ServerAlias cloud
    RewriteCond %{SERVER_NAME} =cloud [OR]
    RewriteCond %{SERVER_NAME} =cloud.mydomain.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
  </VirtualHost>

…and in cloud-le-ssl.conf you should change Port 443 to 80 in the ProxyPass directives:

<VirtualHost *:443>
    ServerName cloud.mydomain.com
    ServerAlias cloud
    ProxyPass / http://192.168.1.200:80/
    ProxyPassReverse / http://192.168.1.200:80/
    ProxyPreserveHost On
    ProxyPass /.well-known/acme/ !
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/cloud.mydomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomain.com/privkey.pem
  </VirtualHost>

Not sure if the ServerAlias plays nice with this. Maybe you should comment it out in both configs and also the Rewrite Directive for it, if there are still issues after the changes.

1 Like

That worked! I dont fully get was it was wrong, but it worked!

Glad it worked out for you :slight_smile:

Let me try to explain, Although I’m not a professional in this area either and I more or less acquired my incomplete knowledge by using google :slight_smile:

Basically, you can use two types of reverse proxy configurations for SSL. There are more, but the following are the most practical and the easiest to setup on a home network.

  1. SSL termination on the reverse proxy with plain HTTP connection to the backend.

  2. SSL termination on the reverse proxy with encrypted HTTPS connection and self signed certificates on the backend.

What we did is the first and most common configuration in home setups.

If you want to have an encrypted connection to your backend you could reactivate https with self signed certs on the backend and change the configuartion of the cloud-le-ssl.conf as follows:

SSLProxyEngineOn
ProxyPass / https://192.168.1.200:443/
ProxyPassReverse / https://192.168.1.200:443/

There are also ways to provide trusted certificates to the backend, or or even to servers that can only be reached internally. However, this is much more complex to set up. And I don’t have the knowledge to give advice on best practices or even specific instructions.

Please also note that both examples are relatively simple reverse proxy configurations. Depending on the backend or application, it may be necessary to include additional directives in the configuration.
Further information and / or configuration examples can usually be found in the documentation of the respective applications. In case of Nextcloud, they can be found here: Reverse proxy — Nextcloud latest Administration Manual latest documentation

1 Like

Thanks for the explanation! Much more clear now!