Roundcube, WordPress, Shellinabox and Pi-hole behind a NGINX reverse proxy


If you are interested in running Nextcloud in parallel to Roundcube, WordPress, Shellinabox, Pi-hole and so on behind a NGINX reverse proxy you will find all the neccessary changes and configuration files below as an amendment to the initial guide (Nextcloud installation guide for Newbies). This configuration leads to an A+ rating and all Nextcloud checks will be successfully passed. You only have to ammend the red marked values (YOUR.DEDYN.IO, 192.168.2.x, 86) with regards to your environment!


First verify your existing nginx.conf:

sudo -s
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
nano /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
server_names_hash_bucket_size 64;
upstream php-handler {
server unix:/run/php/php7.3-fpm.sock;
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.2.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
include /etc/nginx/mime.types;
include /etc/nginx/proxy.conf;
include /etc/nginx/ssl.conf;
include /etc/nginx/header.conf;
include /etc/nginx/optimization.conf; 
default_type application/octet-stream;
sendfile on;
send_timeout 3600;
tcp_nopush on;
tcp_nodelay on;
open_file_cache max=500 inactive=10m;
open_file_cache_errors on;
keepalive_timeout 65;
reset_timedout_connection on;
server_tokens off;
resolver 192.168.2.1 valid=30s;
#resolver 127.0.0.53 valid=30s; is recommended but reuqires a valid resolver configuration
resolver_timeout 5s;
include /etc/nginx/conf.d/*.conf;
}

Create a new file “nextcloud.conf” as your nginx gateway that will handle the incomming http(s)-requests to the server(s) behind the proxy:

cp /etc/nginx/conf.d/nextcloud.conf /etc/nginx/conf.d/nextcloud.conf.bak
nano /etc/nginx/conf.d/nextcloud.conf
server {
server_name your.dedyn.io;
listen 80 default_server;
listen [::]:80 default_server;
location ^~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name your.dedyn.io;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
root /var/www/nextcloud/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
#SOCIAL app enabled? Please uncomment the following row
#rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
#WEBFINGER app enabled? Please uncomment the following two rows.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
client_max_body_size 10240M;
### Optional ROUNDCUBE ###
location ^~ /roundcube/ {
client_max_body_size 1024M;
proxy_buffering off;
proxy_connect_timeout 3600;
proxy_max_temp_file_size 1024M;
proxy_pass http://127.0.0.1:83;
proxy_read_timeout 3600;
proxy_redirect off;
proxy_request_buffering off;
proxy_send_timeout 3600;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
send_timeout 3600;
}
### OPTIONAL WORDPRESS ###
# find more here: WordPress below Nextcloud
location ^~ /wordpress/ {
client_max_body_size 1024M;
proxy_buffering off;
proxy_connect_timeout 3600;
proxy_max_temp_file_size 1024M;
proxy_pass http://127.0.0.1:84;
proxy_read_timeout 3600;
proxy_redirect off;
proxy_request_buffering off;
proxy_send_timeout 3600;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
send_timeout 3600;
}
### OPTIONAL SHELLINABOX ###
location ^~ /shellinabox/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:4200;
proxy_read_timeout 90;
}
### OPTIONAL Pi-hole ###
location ^~ /pihole {
proxy_pass http://127.0.0.1:86/admin;
# Pi-hole has to be changed as described below if both operates on the same system
proxy_read_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
rewrite ^ /index.php$request_uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ \.(?:flv|mp4|mov|m4a)$ {
mp4;
mp4_buffer_size 100M;
mp4_max_buffer_size 1024M;
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
include fastcgi_params; include php_optimization.conf;
fastcgi_pass php-handler; fastcgi_param HTTPS on;
}
location ~ ^\/(?:index|xphp|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+).php(?:$|\/) {
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
location ~ .(?:css|js|woff2?|svg|gif|map|png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$request_uri;
access_log off;
expires 360d;
}
}

Optionally: Create your Roundcube vhost

nano /etc/nginx/conf.d/roundcube.conf
server {
server_name 127.0.0.1;
listen 127.0.0.1:83 default_server;
root /var/www/;
client_max_body_size 1024M;
charset utf-8;
location ^~ /roundcube {
index index.php;
location ~ ^/favicon.ico$ {
root /var/www/roundcube/skins/default/images;
log_not_found off;
access_log off;
expires max;
}
location ~ ^/roundcube/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ {
deny all;
}
location ~ ^/roundcube/(bin|SQL|config|temp|logs)/ {
deny all;
}
location ~ /roundcube/\.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
fastcgi_index index.php;
try_files $uri =404;
}
location ~ /roundcube/\.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
}

Optionally: Create your WordPress vhost

Find more here: WordPress below Nextcloud

nano /etc/nginx/conf.d/wordpress.conf
server {
server_name 127.0.0.1;
listen 127.0.0.1:84;
root /var/www/;
location ^~ /wordpress {		
index index.php;
location /wordpress {
try_files $uri $uri/ /wordpress/index.php$is_args$args;
}
location = /wordpress/favicon.ico {
log_not_found off;
access_log off;
}
location = /wordpress/robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;		
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass php-handler;
fastcgi_connect_timeout 60;
fastcgi_index index.php;
fastcgi_param REMOTE_ADDR $http_x_real_ip;
}
location ~* /wordpress/\.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
location /wordpress/wp-admin {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/wordpress-access;
}
location ~* /(?:uploads|files)/.*.(html|htm|shtml|php|js|swf)$ {
deny all;
}
}
}

Optionally: Modify the Shellinabox configuration “SHELLINABOX_ARGS=“…””

cp /etc/default/shellinabox /etc/default/shellinabox.bak
nano /etc/default/shellinabox

to

# SHELLINABOX_ARGS="--no-beep"
SHELLINABOX_ARGS="--no-beep --localhost-only --disable-ssl"

and restart shellinabox:

service shellinabox restart

Optional: Change the Pi-hole default port 80 to 86 if it operates on the same system:

cp /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.bak
sed -ie 's/= 80/= 86/g' /etc/lighttpd/lighttpd.conf
service lighttpd restart

To work with Pi-hole as an external site within your Nextcloud webinterface you have to amend the Pi-hole webserver to allow framing.

sed -ie 's/"DENY"/"ALLOW"/g' /etc/lighttpd/lighttpd.conf
service lighttpd restart

Finally restart NGINX

service nginx restart

and enjoy your Nextcloud, Roundcube, WordPress, Shellinabox and Pihole behind your nginx reverse proxy.


Don’t forget to backup your Nextcloud

Find more instructions here: Nextcloud backup and restore



Carsten Rieger

Carsten Rieger

Carsten Rieger is a senior system engineer in full-time and also working as an IT freelancer. He is working with linux environments for more than 15 years, an Open Source enthusiast and highly motivated on linux installation and troubleshooting. Mostly working with Debian/Ubuntu Linux, Nginx and Apache web server, MariaDB/MySQL/PostgreSQL, PHP, Cloud infrastructure (e.g. Nextcloud) and other open source projects (e.g. Roundcube) and in voluntary work for the Dr. Michael & Angela Jacobi Stiftung for more than 7 years.