Right ALLOWED_HOSTS settings for dynamic DNS domain?

Hi,

running Seafile CE version 9.0.10 on a virtual machine behind another virtual machine as reverse proxy and using a dynamic DNS domain example.ddns.net-

I have problems to find the right settings for ALLOWED_HOSTS.

If I set ALLOWED_HOSTS = ['.example.ddns.net'] I get Bad Request (400) opening Seahub.
If I set ALLOWED_HOSTS = ['.ddns.net'] I get the same error.
If I don’t set ALLOWED_HOSTS at all everything works fine (but for obvious reasons I would like to activate the setting).

Anybody out there who has an idea how to solve this problem?

Your setup sounds a lot like mine. For mine I use a subdomain for seafile, and some other subdomains for other things, so seafile is seafile.example.net.

For the new options for version 11 I have added:

# For security consideration, please set to match the host/domain of your site, e.g.,     ALLOWED_HOSTS = ['.example.com'].
# Please refer https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts for details.
ALLOWED_HOSTS = ['.example.net']

# Whether to use a secure cookie for the CSRF cookie
# https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-cookie-secure
CSRF_COOKIE_SECURE = True

# The value of the SameSite flag on the CSRF cookie
# https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-cookie-samesite
CSRF_COOKIE_SAMESITE = 'Strict'

# https://docs.djangoproject.com/en/3.2/ref/settings/#csrf-trusted-origins
CSRF_TRUSTED_ORIGINS = ['https://seafile.example.net']

This is working for me. I think this might depend on the reverse proxy setting some headers correctly, so if you have the above set right and still have problems, the proxy’s settings are the next place I would look.

I think the relevant settings look like this (this is for nginx, I don’t know the Apache equivalent if you are using that):

    proxy_set_header   Host $http_host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Host $server_name;
    proxy_set_header   X-Forwarded-Proto https;
3 Likes

Thank you, unfortunately…

…was already my setup (without proxy_set_header X-Forwarded-Proto https; but adding it made no difference). I still get “Bad Request (400)” error when setting ALLOWED_HOSTS = ['.example.ddns.net'].

1 Like

Maybe there is another mistake in my Nginx setup. This is the Nginx config of my Reverse Proxy (for a Web-Server, Matrix, Mumbleweb and Searx service in addition to Seafile):

log_format seafileformat '$http_x_forwarded_for $remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_response_time';

server {
		listen 80;
		server_name example.ddns.net;

		root /var/www/sites/example.ddns.net;

		location /.well-known/acme-challenge {
			root /var/www/certbot-webroot/; 

			default_type "text/plain";
			allow all;
			}

		location /.well-known/ {
			allow all;
			break;
			}

		location / {
			return 301 https://$host$request_uri;
			}
		
		}

server {
		listen 443 http2 ssl;

		ssl_certificate /etc/letsencrypt/live/example.ddns.net/fullchain.pem;
		ssl_certificate_key /etc/letsencrypt/live/example.ddns.net/privkey.pem;
		
		server_name example.ddns.net;
		
		ssl_session_timeout 5m;
		ssl_session_cache shared:SSL:5m;

		ssl_dhparam /etc/ssl/dh4096.param;

		ssl_protocols TLSv1.2;
		ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS';
		ssl_prefer_server_ciphers on;

		proxy_set_header X-Forwarded-For $remote_addr;

		add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
		server_tokens off;

		location / {
			try_files $uri $uri/index.html =404;
			root /var/www/html;
			}

		location /.well-known/matrix/client {
			root /var/www/html/;
			allow all;

			add_header 'Access-Control-Allow-Origin' '*';

			if ($request_method = 'POST') {
			add_header 'Access-Control-Allow-Origin' '*';
			add_header 'Access-Control-Allow-Credentials' 'true';
			add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
			add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
			}

			if ($request_method = 'GET') {
			add_header 'Access-Control-Allow-Origin' '*';
			add_header 'Access-Control-Allow-Credentials' 'true';
			add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
			add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
			}

			default_type application/json;
			}

		location /.well-known/matrix/server {
			root /var/www/html/;
			allow all;

			default_type application/json;
			}

		location ~ ^(/_matrix|/_synapse/client) {
			proxy_pass https://vm-synapse:8008;
			proxy_set_header X-Forwarded-For $remote_addr;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header Host $host;
			client_max_body_size 51m;
			}

		location /mumbleweb {
			proxy_pass https://vm-mumble/;
			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection "upgrade";
			proxy_read_timeout 86400;
			}

		location /seafile {
			proxy_pass 			http://vm-seafile:80;
			proxy_set_header	Host $http_host;
			proxy_set_header	X-Real-IP $remote_addr;
			proxy_set_header	X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header	X-Forwarded-Host $server_name;;

			proxy_read_timeout  1200s;

			client_max_body_size 0;
			}

			location /media { 
				proxy_pass 			http://vm-seafile:80;
				proxy_set_header	Host $http_host;
				proxy_set_header	X-Real-IP $remote_addr;
				proxy_set_header	X-Forwarded-For $proxy_add_x_forwarded_for;
				proxy_set_header	X-Forwarded-Host $server_name;;
				}

			location /seafmedia {
				rewrite ^/seafmedia(.*)$ /media$1 last;
				}

			location /seafdav {
				proxy_pass 			http://vm-seafile:80;
				proxy_set_header	Host $http_host;
				proxy_set_header	X-Real-IP $remote_addr;
				proxy_set_header	X-Forwarded-For $proxy_add_x_forwarded_for;
				proxy_set_header	X-Forwarded-Host $server_name;;
				client_max_body_size       0;
				proxy_connect_timeout      36000s;
				proxy_read_timeout         36000s;
				proxy_send_timeout         36000s;
				send_timeout               36000s;
				proxy_request_buffering off;
				}

			location /seafhttp {
				proxy_pass 			http://vm-seafile:80;
				proxy_set_header	Host $http_host;
				proxy_set_header	X-Real-IP $remote_addr;
				proxy_set_header	X-Forwarded-For $proxy_add_x_forwarded_for;
				proxy_set_header	X-Forwarded-Host $server_name;;
				client_max_body_size 0;
				proxy_connect_timeout  36000s;
				proxy_read_timeout  36000s;
				proxy_send_timeout  36000s;
				send_timeout  36000s;
				proxy_request_buffering off;
				}

		location /searx {
			proxy_pass http://vm-searx;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Scheme $scheme;
			proxy_set_header X-Script-Name /searx;
			proxy_buffering off;
			}

		}

server {
		# Matrix-Synapse federation port
		listen 8448 ssl http2 default_server;

		ssl_certificate /etc/letsencrypt/live/example.ddns.net/fullchain.pem;
		ssl_certificate_key /etc/letsencrypt/live/example.ddns.net/privkey.pem;
		
		server_name example.ddns.net;
		
		ssl_session_timeout 5m;
		ssl_session_cache shared:SSL:5m;

		ssl_dhparam /etc/ssl/dh4096.param;

		ssl_protocols TLSv1.2;
		ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS';
		ssl_prefer_server_ciphers on;

		proxy_set_header X-Forwarded-For $remote_addr;

		add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
		server_tokens off;
		
		location / {
			proxy_pass https://vm-synapse:8448;
			proxy_set_header X-Forwarded-For $remote_addr;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header Host $host;
			}
		}

This is the config of the seafile server behind the Reverse Proxy:

log_format seafileformat '$http_x_forwarded_for $remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_response_time';

server {
		listen 80;
		server_name example.ddns.net;

		location /seafile {
			proxy_pass          http://127.0.0.1:8000;
			proxy_pass_request_headers  on;

			proxy_read_timeout  1200s;

			client_max_body_size 0;

			}

			location /media {
				root /opt/seafile/seafile-server-latest/seahub;

				}

			location /seafmedia {
				rewrite ^/seafmedia(.*)$ /media$1 break;
				root /opt/seafile/seafile-server-latest/seahub;
				}

			location /seafdav {
				proxy_pass                http://127.0.0.1:8080;
				proxy_pass_request_headers  on;

				client_max_body_size      0;

				send_timeout              36000s;

				proxy_request_buffering off;

				}

			location /seafhttp {
				rewrite ^/seafhttp(.*)$ $1 break;
				proxy_pass http://127.0.0.1:8082;
				proxy_pass_request_headers  on;
				client_max_body_size 0;

				send_timeout  36000s;

				proxy_request_buffering off;
				}

		}

I don’t see any options that look wrong. But I really only barely understand some of the options in the nginx config anyway, so the problem could be right in front of me without me seeing it.

There are a couple of differences I see here. First off, mine has forwards to port 8000, 8082, and 8083. If this works for you without the “ALLOWED_HOSTS” stuff, then I can’t see how this could be related, just a difference I noticed.

The other thing that is very different from my setup is the use of a second nginx. I have the reverse proxy nginx that handles TLS, and it forwards directly to seafile on the seafile server, without a second nginx. I don’t know enough about nginx to be sure, but I suspect the second nginx is removing or replacing some of those headers so that seafile doesn’t see the request as having been made to example.ddns.net.

Since this is after where SSL ends, you might be able to verify that with a little bit of wireshark to compare the HTTP headers before and after that second nginx. There’s probably an easier way to test it, but since that’s the one I know how to do, it’s what I would try next.

1 Like

Thank you for your reply. Unfortunately I decided to end my home server project after 10 years and use Syncthing instead. Problems like this are just too time-consuming as a hobby project.

(just as explanation why I can’t set my request on “solved” – I just don’t have the time to try this and that anymore but I hope my question and your answer will help someone else later)