0

Let me preface this by saying most of my "experience" comes from blindly copypasting config lines from various blogs and sites like this and hoping for the best.

Currently I have a setup like this:

Dynamic ddns hostname pointed at my public IP redirecting incoming traffic from ports 80 and 443 to a LXC container with nextcloud + certificate from letsencrypt for the same ddns hostname. So far so good.

this is the relevant nginx config:

server {
server_name stats;
listen 9753 default_server;
listen [::]:9753 default_server;

location /nginx-status {
         stub_status on;
         access_log   off;
         allow 127.0.0.1;
         allow ::1;
         deny all;
         }

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 nextcloud;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
client_max_body_size 10240M;
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;
         }

location / {
           rewrite ^ /index.php;
           }

location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
         deny all;
         }

location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
         deny all;
         }

location ^~ /apps/rainloop/app/data {
         deny all;
         }

location ~ \.(?:flv|mp4|mov|m4a)$ {
         mp4;
         mp4_buffer_size 100M;
         mp4_max_buffer_size 1024M;
         fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
         set $path_info $fastcgi_path_info;
         try_files $fastcgi_script_name =404;
         include fastcgi_params;
         include php_optimization.conf;
         }

location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+).php(?:$|\/) {
         fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
         set $path_info $fastcgi_path_info;
         try_files $fastcgi_script_name =404;
         include fastcgi_params;
         include php_optimization.conf;
         }

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 30d;
         }
}

My original vision for altering this was to use nextcloud.ddns.net to access my nextcloud as before, but also be able to reverse proxy to different local machines via nextcloud.ddns.net/whatever, nextcloud.ddns.net/something etc. Why? Because in my absolute failure of understanding the underlying technology I envisioned this would keep using the already valid ssl certificate for nextcloud.ddns.net without me having to obtain a new certificate for each destination. Does it work like this? I still do not know, but that didn't stop me from trying. I tried including a new location /whatever directive in various places, but all I achieved was a) it not working at all, b) redirecting me to the original nextcloud, c) only working while connected to local lan.

Seeing as I wasn't getting anywhere I went the other way and registered another ddns hostname, pointed that at the same public IP and included this block at the top of the nginx.conf:

server {
listen 443 ssl;
server_name other_hostname.ddns.net;
location / {
         proxy_pass http://different_local_machine.lan/;
         }
}

This works but obviously complains about the certificate being issued to nextcloud.ddns.net not to other_hostname.ddns.net

Onto my questions then:

  1. Is it at all possible to set it up as I originally thought of with using 1 ddns hostname with different /suffixes or is this not how it works at all?

  2. How would I go about getting multiple lets-encrypt certificates in the working scenario with multiple ddns hostnames? I'm worried if I follow the same instructions as I did to get the cert for the nextcloud I'll end up messing that, as that is still the only internet-facing nginx.

  3. How "safe" would I be in just ignoring the warning? I mean I know the certificate is for different hostname, but I actually know it's still a valid certificate.

Again I apologise for my technical shortcomings, it took me few days to find out that what I want to achieve is called reverse proxy and it didn't improve much from there, but I think what I want to achieve should be possible with help from internet strangers without me having to complete a semester of Computer Science

Thanks for any help!

C.G.B. Spender
  • 155
  • 1
  • 9
  • Hi, formatting the nginx config in a more readable way would be great. Good luck. – WY Hsu Jul 24 '20 at 16:17
  • @WYHsu done some editing, although I've no idea what a "proper" format is. Hope that helps. – C.G.B. Spender Jul 24 '20 at 18:58
  • Im trying to understand what your trying to accomplish you want to access different containers with different locations? like machine1.ddns.com goes to container 1 and machine2.ddns.com goes to container 2 ? while using the same wildcard cert? – Cengleby Jul 25 '20 at 22:03
  • Looks better, good job ;) – WY Hsu Jul 26 '20 at 09:28
  • @Cengleby exactly. English is not my native language + most of the linux stuff is just mumbo jumbo to me. At this point I'd be just happy with knowing answer to Q3: i.e. if machine1.ddns.net has valid cert only for machine1.ddns.net and it also serves as reverse proxy for machine2.ddns.net, how "safe" is that providing I'm 100% sure the machine1.ddns.net certificate is valid ? I'd still prefer machine1.ddns.net and machine1.ddns.net/machine2, but not having any luck setting that up. – C.G.B. Spender Jul 27 '20 at 00:13

2 Answers2

0

Here is an example that can be used to handle this ... you may need to tweak the setup for your own needs ...

I use this in an nginx docker that is networked to two containers

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

In the /etc/nginx/conf.d/ directory resides the configuration files for each container ..

-- in site1.conf --

upstream production{

    server container_name1:80;

}

server {
    server_name  site1.com;

    location / {

    proxy_redirect off;
    proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        add_header Access-Control-Allow-Origin *;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://production/;

    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}


server {
    if ($host = site1.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    server_name  site1.com;
    listen 80;
    return 404; # managed by Certbot


}

-- in site2.conf --

upstream production_admin{

    server container_name2:80;

}

server {
    server_name  admin.site1.com;

    location / {

    proxy_redirect off;
    proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        add_header Access-Control-Allow-Origin *;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://production_admin/;

    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}


server {
    if ($host = admin.site1.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    server_name  admin.site1.com;
    listen 80;
    return 404; # managed by Certbot


}

Upstream will set the name that is used in the proxypass and just serve off port 80 for server. This should get you started

Cengleby
  • 86
  • 5
  • I appreciate the effort, but the main point here is I need help with altering what I already got, as my technical ineptitude rules out adjustments on the proposed scale as I don't even understand what docker is (I googled it many times and I still don't get it). The container I mentioned is a LXC container in proxmox. For purposes of the question it's just another VM. – C.G.B. Spender Jul 28 '20 at 00:12
0

For what it's worth if anybody is as hopeless as I am and has this exact same problem, I managed to discover solution on another forum. 1 freaking line, that was it. proxy_set_header Referer $http_referer; What does it do? How should I know? It makes my stuff work as I want though and that's all I care about.

So the full working location block looks like:

location ~ /something {
         proxy_pass http://somehost.lan:someport;
         proxy_set_header Referer $http_referer;
         proxy_set_header X-Real-IP  $remote_addr;
         proxy_set_header X-Forwarded-For $remote_addr;
         proxy_set_header Host $host;
}

discussion that led me to the "discovery" : https://unix.stackexchange.com/questions/290141/nginx-reverse-proxy-redirection Bottom post, 1st comment.

C.G.B. Spender
  • 155
  • 1
  • 9