500 internal server error Nginx running react app - nginx

Following this answer, I have my nginx server set up like so:
server {
server_name portal.productive.city www.portal.productive.city;
root /www/Productive-Website/my-app/build;
index index.html index.htm;
rewrite ^/(.*)/$ $1 permanent;
location / {
try_files $uri?$args $uri/ $uri.html?$args /index.html?$args;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/portal.productive.city/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/portal.productive.city/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
}
My other server (in the same file) (created by lets-encrypt) is:
server {
if ($host = www.portal.productive.city) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = portal.productive.city) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name portal.productive.city www.portal.productive.city;
return 404; # managed by Certbot
}
When I try to go to: www.portal.productive.city or www.portal.productive.city/signin I get a 500 Internal Server Error
My error-log file looks like:
2018/08/31 14:43:08 [error] 29581#29581: *25 rewrite or internal
redirection cycle while internally redirecting to "/index.html",
client: 74.105.149.67, server: portal.productive.city, request: "GET /
HTTP/1.1", host: "www.portal.productive.city"
2018/08/31 14:43:08 [error] 29581#29581: *26 rewrite or internal redirection cycle while
internally redirecting to "/index.html", client: 74.105.149.67,
server: portal.productive.city, request: "GET /favicon.ico HTTP/1.1",
host: "www.portal.productive.city", referrer:
"https://www.portal.productive.city/"
The favicon.ico exists under path/to/repo/build
Edit: I cleared cache and restructured the server as follows:
server {
server_name portal.productive.city www.portal.productive.city;
root /www/Productive-Website/my-app/build;
index index.html index.htm;
location / {
try_files $uri?$args $uri/ $uri.html?$args /index.html?$args;
}
listen 80;
if ($scheme != "https") {
return 301 https://$host$request_uri?$args;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/portal.productive.city/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/portal.productive.city/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
}
The error-file is now:
2018/08/31 15:17:54 [error] 29789#29789: *17 rewrite or internal
redirection cycle while internally redirecting to "/index.html",
client: 74.105.149.67, server: portal.productive.city, request: "GET
/? HTTP/1.1", host: "www.portal.productive.city"
2018/08/31 15:17:54
[error] 29789#29789: *18 rewrite or internal redirection cycle while
internally redirecting to "/index.html", client: 74.105.149.67,
server: portal.productive.city, request: "GET /favicon.ico HTTP/1.1",
host: "www.portal.productive.city", referrer:
"https://www.portal.productive.city/?"

You shouldn't have 2 server files with the same server_name, this makes your configuration harder to find. And, if by chance you configure both of them to listen to the same ports, it will confuse NGINX on which one to render. First, move them into the same one and redirect based on $scheme instead of $host. But that is not the real issue. You've got an redirect that is looping because it matches every request ending with '/'
server {
server_name portal.productive.city www.portal.productive.city;
root /www/Productive-Website/my-app/build;
index index.html index.htm;
# rewrite ^/(.*)/$ $1 permanent; Your REAL problem is here. You've got an redirect that is looping because it matches every request ending with '/'
location / {
try_files $uri?$args $uri/ $uri.html?$args /index.html?$args;
}
listen 80;
if ($scheme != "https") {
return 301 https://$host$request_uri?$args
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/portal.productive.city/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/portal.productive.city/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
}
The https redirect like this means: "If the $scheme is not 'https', redirect to https://$host$request_uri?$args". Which translates to: "https:// address on the same host, on the same path and whith the same URL arguments used on the access".

Related

Nginx doesn't serve subdomain

I thought this would be simple, but for some reason I can't get my subdomain to serve. I am just trying to get the basic "Welcome to Nginx" page to show at this point.
I have A records in digital ocean:
A api.example.com -> my_ip 3600
A www.api.example.com -> my_ip 3600
A example.com -> my_ip 3600
A www.example.com -> my_ip 3600
This is my config file for api.example.com. It sits in /etc/nginx/sites-available/api.example.com and is linked to /sites-enabled:
server {
root /var/www/api.example.com/html;
index index.html index.htm index.nginx-debian.html;
server_name api.example.com www.api.example.com;
location / {
try_files $uri $uri/ =404;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/api.example.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 = www.api.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = api.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name api.example.com www.api.example.com;
return 404; # managed by Certbot
}
I know the DNS record exists using Dig and because certbot ran successfully, but when I navigate to the page it is unable to resolve. Ping and curl also cannot resolve. This is the exact same configuration I have for the main domain (example.com), which does display the Nginx splash page.
What I have tried: I noticed that default has configs for example.com but not for api.example.com (why is that?), so I tried creating them and restarting nginx, but that didn't change anything. Is it necessary to have the configs in default?

Updating Nginx block to do two things that aren't working

For Nginx, I'm attempting to do two things:
Redirect anyone who comes in to the site from www to non-www.
The server defaults to error 500 instead of 404 when the URL path doesn't exist.
This is my current configuration of my server:
server {
root /var/www/project/;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed$
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # manag$
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name example.com www.example.com;
return 404; # managed by Certbot
}
I attempted adding a forward for any www traffic to move into non-www but that didn't do anything (I think because of certbot). Also I tried to update the URL for returning 404 instead of 500, but what it did was it made anything outside of the homepage a 404. So I reset it to what you see above.
Redirect anyone who comes in to the site from www to non-www.
The cleanest solution is to define a separate server block only for this purpose:
server {
listen 80;
server_name www.example.com;
return 301 http://example.com$request_uri;
}
You can verify that it works by putting
127.0.0.1 localhost example.com www.example.com
in your computer's hosts file.
$ curl -I http://www.example.com
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Fri, 27 Aug 2021 06:14:43 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: http://example.com/
The server defaults to error 500 instead of 404 when the URL path doesn't exist.
The 500 HTTP status code is probably caused by your index.php script.

Nginx wont redirect to www

Hello I have hard times to configure nginx properly. I would like redirect from https://example.com to https://www.example.com I found a lot of tutorials how to do it but not a single one worked with mine configuration files.
I used letsencrpyt to configure the SSL for me.
Here is the nginx conf file:
server {
server_name IP_ADDRESS example.com www.example.com;
location /static/ {
root /home/user/pyapps/ks_g;
}
location /media/ {
root /home/user/pyapps/ks_g;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.example.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 = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name IP_ADDRESS example.com www.example.com;
return 404; # managed by Certbot
}
Add redirect on condition to the server block with SSL or both:
if ($host != www.example.com) {
return 301 https://www.example.com$request_uri;
} # managed by Stack Overflow (sorry cannot hold myself)
This works as the following: if the Host HTTP header not equals www.example.com make permanent redirect to https://www.example.com$request_uri.

Why is NGINX giving 504 gateway timeout error?

My NGINX conf is-
server {
listen 80;
server_name site.com ;
location / {
include proxy_params;
proxy_pass http://0.0.0.0:8000;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/site.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/site.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
}
I am running a Flask app on Gunicorn on Port 8000. When I try to access my site, I get a 504 Gateway Time-out nginx/1.14.0 (Ubuntu).
In the error.log , it says-
upstream timed out (110: Connection timed out) while connecting to upstream, client:myip server: site.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8000/", host: "mysite.com"
You have some errors in your config.
You cannot have one server who is listening on multiple ports.
You should not write 0.0.0.0:8000, but try 127.0.0.1:8000 instead
Also I dont understand why you include proxy params, just delete that line.
Here is an example of what you could do.
server {
server_name site.com www.site.com;
location / {
proxy_pass http://127.0.0.1:8000/;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/site.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
if ($host = www.site.com) {
return 301 https://$host$request_uri;
}
if ($host = site.com) {
return 301 https://$host$request_uri;
}
listen 80;
listen [::]:80;
server_name site.com www.site.com;
return 404;
}
Good Luck :-)
Suggest to keep like below values, which could resolve the timeout issue.
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;

How to prevent redirects on nginx when domain in host header does not match domain in request url?

I have nginx running on my home server at keepsecret.ddns.net. When I request e.g. keepsecret.ddns.net/foo/ it returns to me keepsecret.ddns.net/foo/index.html. So far, so good.
Now I am trying to treat my home server as an upstream server. In front of that upstream server is a remote proxy server at www.mydomain.com. When I request e.g. www.mydomain.com/foo/index.html, it is returned to me no problem. However, when I request www.mydomain.com/foo/, nginx first issues a 301 redirect so that I then get sent to keepsecret.ddns.net/foo/, revealing my home IP Address :(
I have no idea why nginx behaves this way. My only guess is that it has something to do with the fact that the domain in the request host header does not match the domain in the request url.
Questions in summary:
Why does nginx do this?
How can I prevent nginx performing this redirect so that I always remain on www.mydomain.com?
Here is the salient part of my config for reference:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name keepsecret.ddns.net www.mydomain.com;
location / {
try_files $uri $uri/ =404;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/keepsecret.ddns.net/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/keepsecret.ddns.net/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 = keepsecret.ddns.net) {
return 301 https://$host$request_uri;
}
if ($host = www.mydomain.com) {
return 301 https://$host$request_uri;
}
listen 80 ;
listen [::]:80 ;
server_name keepsecret.ddns.net www.mydomain.com;
return 404; # managed by Certbot
}
NGINX will be doing an internal redirect to the index.html file in all cases, but it seems to get externalised when the server_name does not match the primary server_name. I suspect that changing the server_name order so that your public (proxied) name is first may get rid of that behaviour.
The alternative would be to focus on the reverse proxy, and take a look at proxy_redirect to make the reverse-proxy rewrite location headers for you.
See: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

Resources