Multiple Benches with Multitenant DNS?

Hello @avc,

i have try from external network but same result.
image

If DNS based multitenancy is on i can´t open ERPNext Interface within local network isn´t it?

I have put DNS Name from ERPNext Site to /etc/hosts but it´s not reachable (Portforwarding configured).

Regards
Kevin

@kevco97:

External access:
Is your domain DNS pointing to the public ip address?

Internal access:
I assume you are trying to access from other computer in the same local network. So, you should configure hosts file in your computer (not in the server), pointing to the LAN ip address of your server …

Hello @avc,

external access:
Yes

Internal access:
okay thank you now i can access via internal network.

But how does it work from external Network with HTTPS?

Regars
Kevin

Try

If you are using wildcard certificate …
bench setup wildcard-ssl yourdomain

@avc i have my own SSL Wildcard certificate (not self signed) and use this manual → Configuring HTTPS
But it doesn´t work.

Checked this?

@avc i have checked thank you. I think the SSL Wildcard is installed cause if i connect to the external DNS Name i see the SSL Wildcard Certificate but get 404 nginx error…

What can i check?

Within local network http & https i can access ERPNext.

Regards
Kevin

Hi @kevco97:

Maybe there isn’t hostname entry on site_config.json or it is wrong …

Try

bench set-config hostname https://erp.yoursite.de
bench restart
bench setup nginx
sudo service nginx reload

Mind that for https traffic you will need port 443 open and redirected to your host …

Hi @avc,

i have try but no luck…

Regards
Kevin

port 443 HTTPS is redirected to host. otherwise I would not get a response from the web server nginx.

If i disable DNS based multitenancy i can access ERPNext external with Port 80 HTTP but not 443 HTTPS.

Regards
Kevin

Please, share your nginx.conf , masking private data.

@avc Here are my nginx config:

upstream frappe-bench-frappe {
server 127.0.0.1:8000 fail_timeout=0;
}

upstream frappe-bench-socketio-server {
server 127.0.0.1:9000 fail_timeout=0;
}

setup maps

map $host $site_name_dxshdfn {
erp.xxx.de erp.xxx.de;
default $host;

}

server blocks

server {

listen 80;
listen [::]:80;


server_name
	erp.xxx.de
	;

root /home/user/frappe-bench/sites;



proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;



add_header X-Frame-Options "SAMEORIGIN";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin";

location /assets {
	try_files $uri =404;
	add_header Cache-Control "max-age=31536000";
}

location ~ ^/protected/(.*) {
	internal;
	try_files /$site_name_dxshdfn/$1 =404;
}

location /socket.io {
	proxy_http_version 1.1;
	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";
	proxy_set_header X-Frappe-Site-Name $site_name_dxshdfn;
	proxy_set_header Origin $scheme://$http_host;
	proxy_set_header Host $host;

	proxy_pass http://frappe-bench-socketio-server;
}

location / {

	rewrite ^(.+)/$ $1 permanent;
	rewrite ^(.+)/index\.html$ $1 permanent;
	rewrite ^(.+)\.html$ $1 permanent;

	location ~* ^/files/.*.(htm|html|svg|xml) {
		add_header Content-disposition "attachment";
		try_files /$site_name_dxshdfn/public/$uri @webserver;
	}

	try_files /$site_name_dxshdfn/public/$uri @webserver;
}

location @webserver {
	proxy_http_version 1.1;
	proxy_set_header X-Forwarded-For $remote_addr;
	proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header X-Frappe-Site-Name $site_name_dxshdfn;
	proxy_set_header Host $host;
	proxy_set_header X-Use-X-Accel-Redirect True;
	proxy_read_timeout 120;
	proxy_redirect off;

	proxy_pass  http://frappe-bench-frappe;
}

# error pages
error_page 502 /502.html;
location /502.html {
	root /usr/local/lib/python3.10/dist-packages/bench/config/templates;
	internal;
}

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

# optimizations
sendfile on;
keepalive_timeout 15;
client_max_body_size 50m;
client_body_buffer_size 16K;
client_header_buffer_size 1k;

# enable gzip compresion
# based on https://mattstauffer.co/blog/enabling-gzip-on-nginx-servers-including-laravel-forge
gzip on;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
	application/atom+xml
	application/javascript
	application/json
	application/rss+xml
	application/vnd.ms-fontobject
	application/x-font-ttf
	application/font-woff
	application/x-web-app-manifest+json
	application/xhtml+xml
	application/xml
	font/opentype
	image/svg+xml
	image/x-icon
	text/css
	text/plain
	text/x-component
	;
	# text/html is always compressed by HttpGzipModule

}

server {

listen 443 ssl;
listen [::]:443 ssl;


server_name
	erp.xxx.de
	;

root /home/user/frappe-bench/sites;



proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;


ssl_certificate      /etc/nginx/conf.d/ssl/certificate_bundle.crt;
ssl_certificate_key  /etc/nginx/conf.d/ssl/private.key;
ssl_session_timeout  5m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;


add_header X-Frame-Options "SAMEORIGIN";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin";

location /assets {
	try_files $uri =404;
	add_header Cache-Control "max-age=31536000";
}

location ~ ^/protected/(.*) {
	internal;
	try_files /$site_name_dxshdfn/$1 =404;
}

location /socket.io {
	proxy_http_version 1.1;
	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";
	proxy_set_header X-Frappe-Site-Name $site_name_dxshdfn;
	proxy_set_header Origin $scheme://$http_host;
	proxy_set_header Host $host;

	proxy_pass http://frappe-bench-socketio-server;
}

location / {

	rewrite ^(.+)/$ $1 permanent;
	rewrite ^(.+)/index\.html$ $1 permanent;
	rewrite ^(.+)\.html$ $1 permanent;

	location ~* ^/files/.*.(htm|html|svg|xml) {
		add_header Content-disposition "attachment";
		try_files /$site_name_dxshdfn/public/$uri @webserver;
	}

	try_files /$site_name_dxshdfn/public/$uri @webserver;
}

location @webserver {
	proxy_http_version 1.1;
	proxy_set_header X-Forwarded-For $remote_addr;
	proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header X-Frappe-Site-Name $site_name_dxshdfn;
	proxy_set_header Host $host;
	proxy_set_header X-Use-X-Accel-Redirect True;
	proxy_read_timeout 120;
	proxy_redirect off;

	proxy_pass  http://frappe-bench-frappe;
}

# error pages
error_page 502 /502.html;
location /502.html {
	root /usr/local/lib/python3.10/dist-packages/bench/config/templates;
	internal;
}

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

# optimizations
sendfile on;
keepalive_timeout 15;
client_max_body_size 50m;
client_body_buffer_size 16K;
client_header_buffer_size 1k;

# enable gzip compresion
# based on https://mattstauffer.co/blog/enabling-gzip-on-nginx-servers-including-laravel-forge
gzip on;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
	application/atom+xml
	application/javascript
	application/json
	application/rss+xml
	application/vnd.ms-fontobject
	application/x-font-ttf
	application/font-woff
	application/x-web-app-manifest+json
	application/xhtml+xml
	application/xml
	font/opentype
	image/svg+xml
	image/x-icon
	text/css
	text/plain
	text/x-component
	;
	# text/html is always compressed by HttpGzipModule

}

http to https redirect

server {
	listen 80;
	server_name
		erp.xxx.de
		;

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

How many sites are you running in this or other bench/es?

@avc only one erpnext site. I have test it on my own erpnext server and have the same issue (another location/network)

i didn´t know what i´m doing wrong. if i disable DNS based multitenancy with bench config dns_multitenant off erpnext is reachable with port 80 HTTP but not HTTPS Port 443 with external url

Can you check nginx logs (usually /var/log/nginx/access.log) … see normal activity from origin ip?

After changing from/to dns_multitenancy … have run bench setup production and bench setup nginx?

Hello @avc,

i have check the logs /var/log/nginx/access.log
With external puplic IPv4 i see only GET entries. If i connect with internal private IPv4 Network i see GET & POST entries. Is that normal? (see enclosed)

I will try again with setup production and bench setup nginx i use these commands in the past but same results…

Regards
Kevin

@avc i have check logs /var/log/nginx/access.log on two different ERPNext Server v14 & v15 with Port 80 HTTP i have entries with GET & POST but if i enable DNS based multitenancy and connect with 443 HTTPS i have only GET entries.

Hi @avc,

i have found the issue. I have checked the nginx.conf file from a working erpnext and have seen there are sometimes $host parameter on the site where i get 404 error and on the other site where http port 80 is working there are the name of the erpnext site. I have changed $host parameter to the erpnext site name and now its working with HTTPS/SSL from external network and on local network with ip without editing the hostfile.

Do i need $host parameter? If i use the command “bench setup nginx” then my settings will be overrride.

Like this Where i get 404 error:

location ~ ^/protected/(.*) {
internal;
try_files /$host/$1 =404;

I have changed them to this:

location ~ ^/protected/(.*) {
internal;
try_files /erpnextsitename/$1 =404;

Regards
Kevin

1 Like

This variable $host is replaced with the host name received in the request …

It’s pretty strange, because nginx.conf template used on bench uses site_name for this … replace it with $site_name_dxshdfn

Maybe a wrong version of nginx.conf template?
Do you remember using bench-manager app or something like this?

Anyway, seems that poltergeist is near to end :slight_smile: