Yes, my bad, sorry - of course I meant that it changes to https://default.coolapp.mydomain.com
.
It looks like already the common browsers are converting the request to lowercase for the domain part and not exen NGINX.
If I change the TenancyName from Default to default in the database, then I'm able to log in from the subdomain (but Zero creates an additional "Default" tenant on next start).
Is it even possible to identify tenants with case sensitive TenancyNames realiably by a subdomain? Or should TenancyNames generally be set lowercase on tenant creation?
Hi,
Sorry for the delay, we finally had the chance to investigate this further now. invalid_headers had been already set, the remaining issues were/are the following:
Is this lowercasing an nginx issue or coming from the app?
Thanks again!
Hi,
thanks for the quick reply, unfortunately I can't find that file or GetClientIpAddress by global search in the whole project (Angular / .net core, separate projects). Can you give me a hint where to look at?
Hello,
I have one more issue regarding the hosting setup (hopefully more or less the last one ;-) ) and hope you can help me with this one, too. As per documentation (https://docs.aspnetzero.com/en/aspnet-core-angular/v8.1.0/Overview-Angular#multi-tenancy) I understand that we can have customers set their tenant via the URL for convenience, which is great.
Before the actual question please correct me if this is not correct:
I am running separate host and angular pages behind separate NGINX containers (reverse proxy and SSL offloading) and tried the following configuration:
Host (appsettings.Production.json)
[...]
"ServerRootAddress": "https://{TENANCY_NAME}.coolapp.mydomain.com:4443/",
"ClientRootAddress": "https://{TENANCY_NAME}.coolapp.mydomain.com/",
"CorsOrigins": "https://coolapp.mydomain.com,https://*.coolapp.mydomain.com,https://{TENANCY_NAME}.coolapp.mydomain.com",
[...]
Angular (appconfig.production.json)
[...]
"remoteServiceBaseUrl": "https://{TENANCY_NAME}.coolapp.mydomain.com:4443",
"appBaseUrl": "https://{TENANCY_NAME}.coolapp.mydomain.com",
[...]
This is removing the tenant selection on the login page for host (coolapp.mydomain.com) and logging in fine for host, but giving CORS error for tenant.coolapp.mydomain.com. I also had a different setting where login via tenant.coolapp.mydomain.com worked, but ended up in host, too. Is there anything wrong with the configs above, anything to consider due to the NGINX reverse proxies? Before trying to set up the TENANCY_NAME feature I had everything up running smoothly (angular on http(s)://coolapp.mydomain.com and host on https://coolapp.mydomain.com:4443) with those proxies and didn't touch their configs since.
Thanks in advance for your support!
Hello guys,
I have one more issue with the cloud setup that contains of a firewall port forwarding to NGINX (reverse proxy, SSL offloading) and dockered host/ng. The audit log is now showing the docker network's gateway IP only instead of the actual client's IP. A similar thread regarding Abp can be found here: https://github.com/aspnetboilerplate/aspnetboilerplate/issues/5359
Can you please advice how we should solve this for Zero 8.1 ASP.NET CORE & Angular .NET Core 3.0 package?
Thanks!
Yes, we have done that for the frontend already under the same IP, and there is currently no need to have the API redirect to https automatically as all the appsettings/appconfigs point towards https directly.
Thanks guys for the support, I think we're fine here to close the request :-)
Cool, we found the same approach yesterday and it seems to work fine so far. These are now our host and ng configs for the NGINX proxies, maybe they will be useful as referencs for others, too. Do you mind cross-checking them once more in regards of system availability and safety? Thanks!
upstream zero_hosts {
server 10.0.0.3:9901;
#more servers for load balancing/redundancy later
}
server {
listen 443 ssl http2;
server_name _;
underscores_in_headers on;
ignore_invalid_headers off;
# your ssl files.
ssl_certificate /etc/nginx/conf.d/ip-servant.com_bundle.crt;
ssl_certificate_key /etc/nginx/conf.d/ip-servant.com.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-real-IP $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# your backend service(docker container name).
proxy_pass http://zero_hosts;
}
}
upstream zero_ngs {
server 10.0.0.3:9902;
}
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name _;
underscores_in_headers on;
# your ssl files.
ssl_certificate /etc/nginx/conf.d/ip-servant.com_bundle.crt;
ssl_certificate_key /etc/nginx/conf.d/ip-servant.com.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-real-IP $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# your backend service(docker container name).
proxy_pass http://zero_ngs;
}
}
Thanks, I followed that and set up a separate NGINX docker instance for frontend and host each. I had to add
proxy_http_version 1.1;
to make SignalR/Websocket work, but there is still an issue left that I can't switch language or tenant at the very first login page (it just reloads with the previous language and always as host, no tenant). Am I missing any config on NGINX?
This happens only if I route host throgh NGINX and regardless of http or https.
Here is my NGINX config for host:
upstream myapp1 {
server 10.0.0.3:9901;
}
server {
listen 443 ssl http2;
server_name _;
ssl on;
# your ssl files.
ssl_certificate /etc/nginx/conf.d/xxx.crt;
ssl_certificate_key /etc/nginx/conf.d/xxx.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
underscores_in_headers on;
location / {
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-real-IP $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# your backend service(docker container name).
proxy_pass http://myapp1;
}
}
...and the part that came with the docker image:
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;
}
Again, thanks for your advice!
Hi zony,
thank you very much for the information! We followed your suggestion and have set up a reverse proxy environment based on an OPNsense firewall with NGINX plugin acting as reverse proxy with SSL offloading, but having issues with occasional 504 errors now.
The setup looks like this: WAN (public IP, port 4443/https) - OPNsense with NGINX - ZeroHost (private IP, port 8081/http on Docker container)
At first glance, the ZeroHost seems to be reachable fine, the certificate is also accepted by the browsers and Swagger UI is working. But then, after a couple of minutes and/or calls to the API (I didn't find a 100% reliable way to reproduce yet) the page is giving 504 errors by the NGINX proxy. If I open a second browser window (in incognito mode to make sure it has no "past"), then the page is reacting fine again until, after more or less the same time as described above, I'm getting 504s again. The ZeroHost was always replying fine directly on the Docker port though (tested with curl on the OPNsense's CLI), so I don't believe in "real" timeout of the app, but a proxy issue.
This is what NGINX logs say about it:
*777 upstream timed out (60: Operation timed out) while reading response header from upstream, client: 5.171.xx.78, server: subdomain.our-domain.com, request: "GET /api/services/app/Objekte/GetDistinctAkteForObjekte HTTP/2.0", upstream: "http://172.20.xx.2:8081/api/services/app/Objekte/GetDistinctAkteForObjekte", host: "subdomain.our-domain.com:4443", referrer: "https://subdomain.our-domain.com/"
Before NGINX I was trying the same setup with pfSense and HAProxy, which showed the exact same behavior, with the following log of HAProxy, where the sH-- flag is stating something like "server-side timeout" and "proxy was waiting for complete, valid response HEADERS from the server":
[2020-10-11T11:16:14.857080] Incoming log entry; line='<134>Oct 11 13:16:14 haproxy[78394]: 116.202.xxx:54896 [11/Oct/2020:13:15:14.839] frontend-host~ backend-host_ipvANY/172.20.x.2 0/0/1/-1/60018 504 194 - - sH-- 1/1/0/0/0 0/0 "GET /swagger/index.html HTTP/1.1"\x0a'
What are we missing?! Followed really basic howtos on the setups using the GUI tools of pfSense/HAproxy and OPNsense/NGINX to create the proxy configs and played around with various settings, but with no luck so far. Do you have a working NGINX template for SSL offloading as reference? I'm not posting mine (yet) as it is quite long (and this post already is..), but I can of course do that if necessary.
Any help is appreciated!
Hello,
We're currently at the point where we want to set up our production environment - and the decision is going towards Docker on native Linux machines. As the documentation that we found is somehow minimalistic, I'd very much appreciate your expert opinion on how to set up such an environment properly.
Would be great if you can give some advice how you would set it up as best practice! Thanks!