Apache Reverse Proxy for subdomains on another server

Not really a NC question but I assume some might have run into the same issue.
Router with NAT port 443 pointing at Server A.
NC running on ServerA with apache and “default” config file with subdomain a.example.com.

<IfModule mod_ssl.c>
  <VirtualHost _default_:443>
    DocumentRoot /var/www/nextcloud
    ServerName a.example.com
    CustomLog /var/log/apache2/nc-access.log combined
    ErrorLog  /var/log/apache2/nc-error.log
    SSLEngine on
    SSLProxyEngine on
    SSLCertificateFile   /etc/letsencrypt/live/a.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/a.example.com/privkey.pem

  <Directory /var/www/nextcloud/>
    Options +FollowSymlinks
    AllowOverride All
    <IfModule mod_dav.c>
      Dav off
    LimitRequestBody 0
    SSLRenegBufferSize 10486000
  <IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=15768000; includeSubDom

Another server B I would like to access through https://b.example.com
Revers proxy configuration:

<VirtualHost *:80>
ServerName b.example.com
AllowEncodedSlashes NoDecode
  SSLProxyEngine On
  SSLProxyVerify None
  SSLProxyCheckPeerCN Off
  SSLProxyCheckPeerName Off
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://b.example.com/
ProxyPassReverse / http://b.example.com/
<VirtualHost *:443>
ServerName b.example.com
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / https://b.example.com/
ProxyPassReverse / https://b.example.com/
SSLProxyEngine On
SSLEngine On
SSLCertificateFile   /etc/letsencrypt/live/a.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/a.example.com/privkey.pem

This works for port 80 (http) but not 443. Trying to access https://b.example.com gives me the NC page about the server not being in trusted_domains - well, I did not want to go there anyway :slight_smile: - but actually I wanted to access server B (no NC on that).

Does the configuration need to be done on another “level” (somewhere else in the apache configuration) to first consider the traffic by subdomain (server) and then going for the specific NC configuration? … or is my understanding of the concept wrong or not good enough?

Thank you for any help!

Your a.conf is missing a lot of syntax and hard to see how you have it set up.

You need two virtual hosts on the reverse proxy site, one for HTTP and one for HTTPS. They can be in the same config.

1 Like

Thank you for your reply. My post is not showing the full a.conf

I have updated the b.conf accordingly (see original post) but nothing changed.

The VirtualHost directive should have a listening IP or asterisk, not a FQDN. It should probably be the same as site A.

See here in section 4.2 for an example.

Thank you, but I do not see what is different in there. … and now I do not even see 80 being handled by the correct server (actually it never worked - wrong test assumption on my side).

Is there anything you can suggest to analyze this? I am worried that it might not be about the apache configuration at the end.

And 80?

Run this and post the output:

apache2ctl -t -D DUMP_VHOSTS

80 as well (and 4443)!

~ $ sudo apache2ctl -t -D DUMP_VHOSTS
VirtualHost configuration:
*:80                   b.example.com (/etc/apache2/sites-enabled/b.conf:1)
*:4443                 localhost (/etc/apache2/sites-enabled/ncp.conf:2)
*:443                  is a NameVirtualHost
         default server b.example.com (/etc/apache2/sites-enabled/b.conf:13)
         port 443 namevhost b.example.com (/etc/apache2/sites-enabled/b.conf:13)
         port 443 namevhost a.example.com (/etc/apache2/sites-enabled/a.conf:4)

Does a.conf really pass the syntax check? You have a bunch of stuff outside the VirtualHost element.

On b.conf your ProxyPass and ProxyPassReverse directives are wrong. The first argument is a path on the web server, not on disk. So it should just be: /

1 Like

Yes, actually this is what has been created by nextcloudpi (I assume - not 100% sure). The top of the file says:


I have played around with this - thank you confirming that / is correct.

I further added this to b.conf and finally got the result I wanted:

<Location />
 Require all granted

Probably due to some global settings in the main Apache config. Glad to hear it’s working.

You’re going to get warnings about CALDAV and CARDDAV. If you enable rewrite rules like in my example, that should fix it.

I am not seeing any issue with CALDAV or CARDDAV - I assume you would expect that I see it e.g. on DAVx?

But when enabling the b.conf I cannot access a.example.com by the internal IP (through the browser, ssh by IP is possible) anymore.
Any idea on that?

You shouldn’t access it by IP.

If you need to, then you’ll have to adjust the config files. Look back at the apachectl output. You’ll see site B is now the default. Apache doesn’t know which site you want when you don’t go to the URL by name (this is called SNI – service name indicator), so it gives you the default site.

The first conf it loads alphabetically for a given listening IP and port becomes the default site. I’m guessing a.conf and b.conf are not the actual file names?

You can number them to change the load order, e.g. 010-SiteA.conf and 011-SiteB.conf.

1 Like

@KarlF12 - Once again thank you, also your last reply helped a lot for me to demystify the behavior of apache.

1 Like