Setup Apache reverse proxy with VM

Hello everyone!

I’ve been using Nextcloud on a dedicated server for about 3 years: all components (Apache, PHP; database, nextcloud and other home services) in the same OS working great.

Now I decided to start using VMware ESXi to divide some critical components.

  • VM 1: receive all network traffic and proxy to appropriate VM.
  • VM 2: has the databases. Works great.
  • VM 3: has NextCloud and Traccar (services I want to keep separate of another services)
  • VM 4: another home services

But the NextCloud instance does not work. It always said 404… Once I could see the loging page without formatting, but nothing works.

Have I something wrong in the vHosts or proxies of Apache?

EDIT:
I tried to understand this topic, but I could not. It is similar

.
.
.
.
.

Apache vHost in VM 1 - 192.168.1.60

<VirtualHost *:443>
    ServerName cloud.mydomain.com
    DocumentRoot /var/www/

    CustomLog /var/log/apache2/cloud-access.log combined
    ErrorLog /var/log/apache2/cloud-error.log


    ProxyPreserveHost On
    ProxyPass / http://192.168.1.63/nextcloud/
    ProxyPassReverse / http://192.168.1.63/nextcloud/

    <IfModule mod_dav.c>
        Dav off
    </IfModule>


<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
</IfModule>

# Mejoras de seguridad
    Protocols h2 http/1.1
    SSLEngine on
    <IfModule mod_headers.c>
        Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
    </IfModule>
# Enable only strong encryption ciphers and prefer versions with Forward Secrecy
    SSLCipherSuite HIGH:RC4-SHA:AES128-SHA:!aNULL:!MD5
    SSLHonorCipherOrder on
# Disable insecure SSL and TLS versions
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
# The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients.
    <Files ".ht*">
        Require all denied
    </Files>
# Disable HTTP TRACE method.
    TraceEnable off
# Disable HTTP TRACK method.
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} ^TRACK
    RewriteRule .* - [R=405,L]
# Avoid "Sabre\DAV\Exception\BadRequest: expected filesize XXXX got XXXX"
    <IfModule mod_reqtimeout.c>
        RequestReadTimeout body=0
    </IfModule>



SSLCertificateFile /etc/letsencrypt/live/cloud.mydomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

.
.
.
.
.
.

Apache vHost in VM 1 - 192.168.1.63
This is all commented on, because commented lines does not work, but, with this vHost, if I access with 192.168.1.63, it works and I can log in.

<VirtualHost *:80>
	ServerName 192.168.1.63
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	#Alias /nextcloud/ "/var/www/nextcloud"
	
	#<Directory /var/www/nextcloud>
	  #Require all granted
	  #AllowOverride All
	  #Options FollowSymLinks MultiViews
	
	 #<IfModule mod_dav.c>
	  #Dav off
	 #</IfModule>
	
	 #SetEnv HOME /var/www/nextcloud
	 #SetEnv HTTP_HOME /var/www/nextcloud
	#</Directory>
        
</VirtualHost>

.
.
.
.
.

Nextcloud version: 19.0.1
Operating system and version: Debian 10.4
Apache or nginx version: Apache 2.4
PHP version: 7.4

The output of your config.php file in /path/to/nextcloud:

$CONFIG = array (
  'passwordsalt' => '*********',
  'secret' => '*********',
  'trusted_domains' => 
  array (
    0 => '192.168.1.*',
    1 => 'mydomain.com',
    2 => 'cloud.mydomain.com',
  ),
  'datadirectory' => '/mnt/HDD1/NC_data',
  'dbtype' => 'mysql',
  'version' => '19.0.1.1',
  'dbname' => '*********',
  'dbhost' => '192.168.1.62:3306',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => '*********',
  'dbpassword' => '*********',
  'installed' => true,
  'instanceid' => '*********',
  'mysql.utf8mb4' => true,

  'memcache.local' => '\\OC\\Memcache\\Redis',
  'redis' => array(
     'host' => '/var/run/redis/redis-server.sock',
     'port' => 0,
     'timeout' => 0.0,
      ),
  'memcache.locking' => '\\OC\\Memcache\\Redis',

  'blacklisted_files' => array (
     0 => '.htaccess',
     1 => 'Thumbs.db',
     2 => 'thumbs.db',
     ),

  'loglevel' =>2,
  'log_rotate_size' => 3 * 1024 * 1024,

  'mail_smtpmode' => 'smtp',
  'mail_smtpauthtype' => 'LOGIN',
  'mail_smtpsecure' => 'ssl',
  'mail_from_address' => 'email',
  'mail_domain' => 'gmail.com',
  'mail_smtpauth' => 1,
  'mail_smtphost' => 'smtp.gmail.com',
  'mail_smtpport' => '465',
  'mail_smtpname' => 'email@gmail.com',
  'mail_smtppassword' => 'password',

  'enable_previews' => true,
  'preview_max_x' => 1000,
  'preview_max_y' => 1000,

  'overwrite.cli.url' => 'http://localhost',
  'htaccess.RewriteBase' => '/',

.
.
.
.
.

Virtual Machine 1: Apache access log:

xxx.xxx.65.34 - - [27/Jul/2020:23:26:39 +0200] "GET / HTTP/1.1" 200 3830 "-" "Mozilla/5.0.."
xxx.xxx.65.34 - - [27/Jul/2020:23:26:39 +0200] "GET /index.php HTTP/1.1" 302 1572 "https://cloud.mydomain.com/" "Mozilla/5.0..."
xxx.xxx.65.34 - - [27/Jul/2020:23:26:39 +0200] "GET /nextcloud/index.php/login HTTP/1.1" 404 491 "-" "Mozilla/5.0..."
xxx.xxx.65.34 - - [27/Jul/2020:23:26:39 +0200] "GET /favicon.ico HTTP/1.1" 404 491 "https://cloud.mydomain.com/nextcloud/index.php/login" "Mozilla/5.0..."

.
.
.
.
.

Virtual Machine 2: Apache access log:

192.168.1.60 - - [27/Jul/2020:23:26:39 +0200] "GET /nextcloud/ HTTP/1.1" 200 464 "-" "Mozilla/5.0 (Window...."
192.168.1.60 - - [27/Jul/2020:23:26:39 +0200] "GET /nextcloud/index.php HTTP/1.1" 302 1477 "https://cloud.mydomain.com/" "Mozilla/5.0 (Wind...."
192.168.1.60 - - [27/Jul/2020:23:26:39 +0200] "GET /nextcloud/nextcloud/index.php/login HTTP/1.1" 404 396 "-" "Mozilla/5...."
192.168.1.60 - - [27/Jul/2020:23:26:39 +0200] "GET /nextcloud/favicon.ico HTTP/1.1" 404 396 "https://cloud.mydomain.com/nextcloud/index.php/login" "Moz...."

Do you have some entries in the apache error log with log level debug and from nextcloud.log?

IMHO it is a better and simple way to do this with apache sub-doms like this …
I am using nc 19 with docker

1 Like

Thanks you for the explanation. With your vHost and some moddification I get it work!

Could you explain me what does “SetEnvIf, RequestHeader” means in your vHost.

I have only one warning in NextCloud Overview page: What does it means? I added trusted_proxy in the config.php

The reverse proxy header configuration is incorrect, or you are accessing
Nextcloud from a trusted proxy. If not, this is a security issue and can
allow an attacker to spooftheir IP address as visible to the Nextcloud.
Further information can be found in the documentation.

.
.
.
.
.
.
EDIT 3:

Nextcloud config.php

  'overwrite.cli.url' => 'http://localhost',
  'htaccess.RewriteBase' => '/nextcloud',
  
  'overwritehost' =>  'cloud.mydomain.com',
  'overwriteprotocol' =>  'https',
  'overwritewebroot' => '/',

  'trusted_proxies' => array (
    0 => '192.168.1.60',
    1 => 'cloud.mydomain.com',
    ),
  'forwarded_for_headers' => array('HTTP_X_FORWARDED', 'HTTP_FORWARDED_FOR'),

.
.
.
.
.
Apache vHost. VM who makes proxy

/etc/apache2/sites-available/cloud.conf

<VirtualHost *:80>
  DocumentRoot /var/www/
  ServerName cloud.mydomain.com
  
  RewriteEngine On
  RewriteRule ^/?(.*) https://%{SERVER_NAME}:443/$1 [R,L]
  
</VirtualHost>

<VirtualHost *:443>
    ServerName cloud.mydomain.com
    DocumentRoot /var/www
    CustomLog /var/log/apache2/cloud-access.log combined
    ErrorLog /var/log/apache2/cloud-error.log

# Proxy to VM 192.168.1.63
    
    ProxyAddHeaders Off
    SetEnvIf Host "^(.*)$" THE_HOST=$1
    RequestHeader setifempty X-Forwarded-Proto https
    RequestHeader setifempty X-Forwarded-Host %{THE_HOST}e
    
    ProxyPassMatch (.*)(\/websocket)$ "ws://192.168.1.63/$1$2"
    
	
    ProxyPass / http://192.168.1.63/nextcloud/
    ProxyPassReverse / http://192.168.1.63/nextcloud/
    
    RewriteEngine On
	RewriteRule ^/\.well-known/carddav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
	RewriteRule ^/\.well-known/caldav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]

    <IfModule mod_dav.c>
        Dav off
    </IfModule>


# Security improvements
    Protocols h2 http/1.1
    SSLEngine on
    <IfModule mod_headers.c>
        Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
    </IfModule>
# Enable only strong encryption ciphers and prefer versions with Forward Secrecy
    SSLCipherSuite HIGH:RC4-SHA:AES128-SHA:!aNULL:!MD5
    SSLHonorCipherOrder on
# Disable insecure SSL and TLS versions
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
# The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients.
    <Files ".ht*">
        Require all denied
    </Files>
# Disable HTTP TRACE method.
    TraceEnable off
# Disable HTTP TRACK method.
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} ^TRACK
    RewriteRule .* - [R=405,L]
# Avoid "Sabre\DAV\Exception\BadRequest: expected filesize XXXX got XXXX"
    <IfModule mod_reqtimeout.c>
        RequestReadTimeout body=0
    </IfModule>



SSLCertificateFile /etc/letsencrypt/live/cloud.mydomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/cloud.mydomain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

.
.
.
.

.

Apache vHost inside second VM that host Nextcloud

<VirtualHost *:80>
	ServerName 192.168.1.63
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
        
	Alias /nextcloud "/var/www/nextcloud"

	<Directory /var/www/nextcloud>
	  Require all granted
	  AllowOverride All
	  Options FollowSymLinks MultiViews

	 <IfModule mod_dav.c>
	  Dav off
	 </IfModule>

	 SetEnv HOME /var/www/nextcloud
	 SetEnv HTTP_HOME /var/www/nextcloud

	</Directory>


</VirtualHost>


<VirtualHost *:443>
	ServerName 192.168.1.63
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
    
	Alias /nextcloud "/var/www/nextcloud"

	<Directory /var/www/nextcloud>
	  Require all granted
	  Options FollowSymlinks
      AllowOverride All

	 <IfModule mod_dav.c>
	  Dav off
	 </IfModule>

	 SetEnv HOME /var/www/nextcloud
	 SetEnv HTTP_HOME /var/www/nextcloud

	</Directory>


</VirtualHost>

.
.
.
.
.
.
Summary:

  • DocumentRoot directive
  • In general, vHost writed bad
  • ‘htaccess.RewriteBase’ -> Rewrite .ht

So… It’s working! VM1 receive the request and proxy to VM2. Great!

With pretty url working: (without /index.php/)