NGINX punycode domain only works with subdomain - nginx

I have a nginx 1.14.0 on Ubuntu 18.04.3. I have some trouble with a punycode domain, it works only with subdomains, e.g. www.xn--bratwrste-u9a.de but not with the domain only e.g xn--bratwrste-u9a.de
Other domains e.g. example.com are working as expected.
My default server config:
server {
listen 1.2.3.4:443 ssl http2 default_server;
listen 5.6.7.8:443 ssl http2 default_server;
ssl_certificate /ssl/sslcert.pem;
ssl_certificate_key /ssl/privkey.pem;
server_name _;
root /var/www/foo;
index index.html index.php;
}
And here the virtual server config:
server {
listen 5.6.7.8:443 ssl http2;
server_name .xn--bratwrste-u9a.de;
ssl_certificate /ssl/sslcert.pem;
ssl_certificate_key /ssl/privkey.pem;
root /var/www/bar;
index index.html index.php;
}
The log looks good:
"GET /foo.bar HTTP/2.0" 200 247 "https://xn--bratwrste-u9a.de/"
Also there is no error in the error.log
The documentation of nginx gave me no answser to my question and also listing the servername individually makes no different.
Thanks for any suggestion.
EDIT:
A workaround:
Add rewrite rule to the default server:
if ($host = xn--bratwrste-u9a.de) {
rewrite (.*) https://www.xn--bratwrste-u9a.de$1;
}
Strange that this works, but the server_name not...

Related

DNS_PROBE_FINISHED_NXDOMAIN when serving multiple subdomains with nginx

On our research project, we have an Ubuntu 20.04 LTS virtual machine running, which should serve via nginx multiple project related websites/apps on different subdomains.
The setup is supposed to be as following:
maindomain --> redirecting to our project info site hosted by our university
subdomain1.maindomain --> nextcloud for project management stuff served via nginx
subdomain2.maindomain --> serving app1 via nginx proxy and gunicorn (for django)
subdomain3.maindomain --> serving app2 via nginx proxy and express.js
What I did:
Added the IP address of the server to the A record of our German domain hoster Strato.
https://maindomain: configured nginx to redirect to university site
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
root /var/www/html;
server_name maindomain;
return 301 https://university-site;
ssl_certificate /etc/ssl/wildcard.crt;
ssl_certificate_key /etc/ssl/wildcard.key;
ssl_trusted_certificate /etc/ssl/wildcard.crt;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
}
configured nginx to serve nextcloud stuff in /etc/nginx/sites-available/subdomain1.maindomain
server {
listen 80;
#listen [::]:80;
server_name subdomain1.maindomain;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
root /var/www/nextcloud;
index index.html index.php /index.php$request_uri;
server_name subdomain1.maindomain;
ssl_certificate /etc/ssl/wildcard.crt;
ssl_certificate_key /etc/ssl/wildcard.key;
ssl_trusted_certificate /etc/ssl/wildcard.crt;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
... lot's of nextcloud related stuff ...
}
up to this point: everything is working fine for some time now
What I tried:
Now it was time to start deploying the next app on subdomain2.maindomain. In my naive thinking I thought just to copy /etc/nginx/sites-available/subdomain1.maindomain to subdomain2.maindomain and change "subdomain1.maindomain" to "subdomain2.maindomain" in the config file (of course: getting rid of all the nextcloud stuff, too).
First I experimented with just serving a static index.html page to see if everything is working:
server {
listen 80;
server_name subdomain2.maindomain;
root /var/www/subdomain2;
index index.html index.php /index.php$request_uri;
# return 301 https://$server_name$request_uri;
}
added a static index.html into /var/www/subdomain2
restarted nginx (feels like a 1000 times actually... :-))
Now when I try to navigate to "http://subdomain2.maindomain" it throws the error: DNS_PROBE_FINISHED_NXDOMAIN
For testing purposes I added our IP address to the configuration /etc/nginx/sites-available/subdomain2.maindomain, resulting in:
server {
listen 80;
server_name subdomain2.maindomain IP_ADDRESS;
root /var/www/subdomain2;
index index.html index.php /index.php$request_uri;
# return 301 https://$server_name$request_uri;
}
Now, when I browse to IP_ADDRESS the static index.html page is served just as expected, but browsing to subdomain2.maindomain still fails.
What can I do next?

Change port for http to https -- Nginx

Sorry for limited understanding on Nginx, Iam new to Nginx.
I have a webapp running on React and Nginx. Recently I received the SSL certificates for my website. I tried to configure the website and it worked partially. The problem is when I tried to open "https://example.com", the SSL certificates are visible here but its showing nginx default home page. While when I open "http://example.com" it shows all the webcontent.
I attempted to:
change the port from 80 to 443
Reinstall nginx.
But nothing seems to work. Here is my nginx confs at the moment:
/etc/nginx/sites-available/example.org
server {
listen 443;
listen [::]:443;
ssl on;
ssl_certificate /etc/nginx/ssl/bundle.cer;
ssl_certificate_key /etc/nginx/ssl/example.key
root /var/www/html;
server_name example.org;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://example.org;
}
/etc/nginx/conf.d/www/example.org.conf
server {
listen 80 default_server;
server www.example.org;
location / {
root /usr/share/nginx/html;
index index.htm; index.html;
}
}
Note: I reload nginx at every new attempt.
Please help where am I going wrong.
Keeping just 1 file for config works for the above problem. I kept the "default" conf at "/etc/nginx/sites-available"

Redirect HTTP to HTTPS with NGINX

I have a couple of applications that I maintain at my work and noticed that some employees are able to use the non-secure paths to those applications such as: example.com, www.example.com. Using either of those paths will direct them to the HTTP path instead of HTTPS, unless they specify HTTPS in the url. We currently use nginx as our gateway, but I did not do the initial configuration of our nginx gateway, so I don't really know what works and what doesn't.
Here is a snippet of our nginx.conf file
server{
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
location / {
proxy_pass http://localhost:3000;
}
}
# Settings for a TLS enabled server.
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name localhost;
ssl_certificate "/etc/nginx/ssl/domain-crt.txt";
ssl_certificate_key "/etc/nginx/ssl/domain-key.txt";
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
## More configuration below this...
}
I tried doing a return in the listen 80 section but this did not work:
server{
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
return 301 https://$host$request_uri;
location / {
proxy_pass http://localhost:3000;
}
}
I reloaded nginx with the corrections and I was still able to connect to the http paths without it redirecting to https. I don't know if this has something to do with the server_name being localhost because I've only seen examples online where they are redirecting to the actual domain name, but this is how our applications are setup and I don't know if changing that will have effects on the connectivity of our applications. If anyone has any ideas or suggestions on how I could get a redirect to work properly, that would be great. Thanks!
You're missing the semicolon at the end, also you should get rid of the proxy_pass since that overrides the behavior.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
location / {
return 301 https://$host$request_uri;
}
}

How to fix http redirects with Nginx?

I have a webpage where http redirects are a bit broken.
The current behavior is this:
www.example.com, example.com, http://www.example.com, http://example.com, https://www.example.com all gets redirected to https://www.example.com
and
https://example.com gets an error saying refused to connect.
I want the behavior to be like this:
example.com, http://example.com, https://example.com redirects to https://example.com
www.example.com, http://www.example.com, https://www.example.com redirects to https://www.example.com
Here is my Nginx config file
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location ~ /.well-known {
allow all;
}
location / {
try_files $uri $uri/ =404;
}
}
Reason is because I want these links to work
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
https://www.ssllabs.com/ssltest/analyze.html?d=www.example.com
https://hstspreload.org/?domain=example.com
https://hstspreload.org/?domain=www.example.com
You have two independent issues:
Your requests all redirect to example.com, regardless of which specific domain is originally accessed.
This happens because the $server_name variable that you are using is effectively a static variable in a given server context, and has a very distant relationship to $http_host.
The correct way would be to use $host instead (which is basically $http_host with some edge-corner cleanups).
You're receiving connection issues when trying to contact https://example.com, but not https://www.example.com.
There is not enough information in your question to pinpoint the exact origin of this problem.
It can be a DNS issue (A/AAAA records of example.com set at an IP address where appropriate bindings to the https port aren't made).
It could be an issue with the mismatched certificate:
Does your certificate cover both example.com and www.example.com? If not, then you can't have both.
If you have separate certificates, you may also need to acquire separate IP addresses, or risk preventing a significant number of users from accessing your site due to lack of SNI.
As of note, it should also be pointed out that it is generally a sloppy practice to not have a unified notation on the way your site is accessed. Especially if SEO is of any concern to you, the best practice is to decide on whether you want to go with or without www, and stick to it.
You need something like this:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name www.example.com;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
add_header Strict-Transport-Security "max-age=300; includeSubdomains; preload";
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name example.com;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
add_header Strict-Transport-Security "max-age=300; includeSubdomains; preload";
location ~ /.well-known {
allow all;
}
location / {
try_files $uri $uri/ =404;
}
}
All your requests will be ultimately routed to https://example.com.
Your ssl certificate should also be valid for https://www.example.com which I note you have said it is.

Nginx redirecting to the wrong site; poorly formed server_name directive

The Problem
When you type example.com into the address bar of a browser WITHOUT entering the scheme, i.e. http:// or https://, Nginx redirects the user to https://api.example.com instead of https://example.com as intended. I'm pretty sure there's something wrong with my Nginx config, but I'm not sure what.
Details
I'm hosting two websites on the same server, with the same IP. The relevant bits from the DNS zone file looks something like (domain and IP anonymized here):
example.com. 1800 IN A xxx.xxx.xxx.xxx
www.example.com. 1800 IN CNAME example.com.
api.example.com. 1800 IN CNAME example.com.
I have two SSL certs installed (provided by letsencrypt), one for each site, and both sites are configured to redirect to HTTPS. I have two vhost config files, one for each site, as follows:
/etc/nginx/sites-available/api
/etc/nginx/sites-available/default
Both are symlinked into /etc/nginx/sites-enabled/. The relevant bits from the two config files are as follows:
# /etc/nginx/sites-available/api
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name api.example.com;
return 301 https://api.example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/api-ssl-params.conf; # ssl config info
server_name api.example.com;
# ... the rest of the site config ...
}
and:
# /etc/nginx/sites-available/default
server {
listen 80;
listen [::]:80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 default_server ipv6only=on;
include snippets/ssl-params.conf; # ssl config info
server_name example.com;
# ... the rest of the site config ...
}
I don't understand why just entering example.com into the address bar would redirect to https://api.example.com because:
just plain example.com doesn't appear in the api config file anywhere
example.com shouldn't match the server_name directive api.example.com
the server blocks in default are marked as default_server so shouldn't that take precedence when an ambiguous domain name was typed in?
Thanks!!!
Duh. Figured it out in the process of writing the question. The problem is that just plain example.com doesn't appear in the server_name directive for either of the sites listening on port 80. Since that causes ambiguity, nginx picks the first site in alphabetic order.
I updated the config file for the default site as follows:
# /etc/nginx/sites-available/default
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com; # <-- CHANGED THIS LINE
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 default_server ipv6only=on;
include snippets/ssl-params.conf; # ssl config info
server_name example.com;
# ... the rest of the site config ...
}
And all was right with the universe.

Resources