nginx - can't figure out location rewrites - regex

I'm trying to redirect different URI requests to different EC2 containers, I've been using nginx for years as a catchall reverse proxy to apache but now I'd like to have some rewrites done at nginx level.
Here's what I'm trying to accomplish:
server {
listen 80;
server_name _;
gzip on;
gzip_static on;
gzip_buffers 16 8k;
gzip_comp_level 9;
gzip_http_version 1.0;
gzip_min_length 0;
gzip_types text/plain text/css application/x-javascript;
gzip_vary on;
location / {
# catch the following URI's including homepage: /contact.html, /terms.html, /
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 240;
proxy_connect_timeout 240;
proxy_send_timeout 240;
send_timeout 240;
proxy_pass http://servers_static;
}
location / {
# catch everything not matched above
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 240;
proxy_connect_timeout 240;
proxy_send_timeout 240;
send_timeout 240;
proxy_pass http://servers_dynamic;
}
}
I'm sure this just a simple regex issue, but I have never understood that stuff. Can someone help me out?

Create a file /etc/nginx/EC2 with the common proxy settings:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 240;
proxy_connect_timeout 240;
proxy_send_timeout 240;
send_timeout 240;
Your main config then becomes:
server {
listen 80;
server_name _;
#gzip settings cut for brevity, add them back in
# static content
location = / {include /etc/nginx/EC2; proxy_pass http://servers_static;}
location = /contact.html {include /etc/nginx/EC2; proxy_pass http://servers_static;}
location = /terms.html {include /etc/nginx/EC2; proxy_pass http://servers_static;}
# dynamic content
location / { include /etc/nginx/EC2; proxy_pass http://servers_dynamic; }
}
you might also combine the locations for the .html static content pages like so:
location ~ (contact|terms).html {
include /etc/nginx/EC2; proxy_pass http://servers_static;}
it's probably slightly more efficient to have the exact matching locations, and as long as you don't have to many the resulting duplication shouldn't make the config to unwieldly

Take a look at try_files. It will successively try the paths you give it. In this example, any static file at /var/www/sites/foo/current/public/$uri will be returned, only routing the request to the app if no static file exists.
upstream app {
server unix:/tmp/.sock_my_app;
}
server {
# path for static files
root /var/www/sites/foo/current/public;
# Prefer to serve static files directly from nginx to avoid unnecessary
# requests to the application server.
try_files $uri/index.html $uri.html $uri #app;
location #app {
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;
# timeouts
# reverse proxy to an upstream
proxy_pass http://app;
}
}

Related

"http" directive is not allowed here in /etc/nginx/conf.d/default.conf:1

I can't put an http block/directive on nginx config file, I'm trying to increase timeout of file upload via curl ,It says http" directive is not allowed here in /etc/nginx/conf.d/default.conf:1
I'm using django and I can't seems to work it out.
http {
fastcgi_read_timeout 300;
proxy_read_timeout 300;
server {
listen 80;
server_name localhost;
location /media/ {
try_files $uri /dev/null =404;
}
location / {
proxy_redirect off;
proxy_set_header Host $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-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_pass http://app:8000;
client_max_body_size 100M;
proxy_temp_file_write_size 64k;
proxy_connect_timeout 10080s;
proxy_send_timeout 10080;
proxy_read_timeout 10080;
proxy_buffer_size 64k;
proxy_buffers 16 32k;
proxy_busy_buffers_size 64k;
proxy_redirect off;
proxy_request_buffering off;
proxy_buffering off;
}
}
}
The http directive is already used in /etc/nginx/nginx.conf. Open it, you'll find include /etc/nginx/conf.d/*.conf; at the end of the file.
Solution: delete http directive from /etc/nginx/conf.d/default.conf. You can change the *_read_timeout parameters whether inside or outside of the server directive.

Modify nginx config to reverse proxy websockets properly

Current nginx config:
server {
listen 443 ssl http2;
server_name NAME www.NAME;
charset utf-8;
ssl on;
ssl_certificate /etc/nginx/ssl/NAME-cert.pem;
ssl_certificate_key /etc/nginx/ssl/NAME-key.pem;
location /static/ {
alias /home/ubuntu/NAME/static_collection/;
}
location /media/ {
alias /home/ubuntu/NAME/media_collection/;
}
location / {
proxy_pass http://localhost:8002;
proxy_redirect off;
proxy_set_header Host $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-Proto $scheme;
}
}
Everything works, apart from the websockets. I suppose this is because it doesn't deal with the http upgrade header... I've looked at the docs, but I can't figure out how to modify this config without breaking anything else.
Try this. Let me know if it works.
server {
listen 443 ssl http2;
server_name NAME www.NAME;
charset utf-8;
ssl on;
ssl_certificate /etc/nginx/ssl/NAME-cert.pem;
ssl_certificate_key /etc/nginx/ssl/NAME-key.pem;
location /static/ {
alias /home/ubuntu/NAME/static_collection/;
}
location /media/ {
alias /home/ubuntu/NAME/media_collection/;
}
location / {
proxy_pass http://localhost:8002;
proxy_redirect off;
proxy_set_header Host $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-Proto $scheme;
proxy_http_version 1.1;
proxy_read_timeout 86400;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}

Nginx Check Upstream Server Status With If statement

So im trying to check my http_response code from my upstream server, and pass a default response code when the upstream is down; and when the upstream is up proxy all requests to it.
my nginx (NOT WORKING) config looks like this
server {
listen 80;
server_name auth.example.com;
set $upstream 123.456.789.123:8080;
location #active{
proxy_pass_header Authorization;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
client_max_body_size 10M;
proxy_read_timeout 36000s;
proxy_redirect off;
proxy_pass http://$upstream;
}
location #outage {
return 200 "yass!";
}
location / {
error_page 500 = #outage;
set $200 #active;
if ($http_status != 404){
return 500;
}
if ($http_status = 200) {
return 200;
}
}
What i want to achieve is simple, if my upstream server is down return a default 200 response.
if my upstream server is available, proxy all requests to it.
how can i achieve this (a code example would be cool :-)) with nginx.
So I figured where i was going wrong, the following config worked for me.
server {
listen 80;
server_name auth.example.com;
set $upstream 123.456.789.123:8080;
location / {
proxy_pass_header Authorization;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_intercept_errors on;
proxy_buffering off;
client_max_body_size 10M;
proxy_read_timeout 36000s;
proxy_redirect off;
proxy_pass http://$upstream;
error_page 500 502 503 504 = #outage;
}
location #outage {
return 200 "yas";
}
}

Django: csrf_token doesn't work after deploy

I deploying my Django project in AWS (nginx, gunicorn)
I can access my project through url and looking great. But problem is that I can not send any POST request because of csrf_token error.
I just googled it and find looks-good solution : http://www.regisblog.fr/2014/08/31/passing-django-csrf-cookie-nginx/
But it doesn't work after I edited nginx.conf.
Here is my nginx.conf (ssl not applying yet and conceal IP address)
worker_processes 1;
events {
worker_connections 1024;
accept_mutex off;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 80;
server_name MY_IP;
client_max_body_size 4G;
keepalive_timeout 5;
#return 301 https://$server_name$request_uri;
location / {
proxy_pass_header X-CSRFToken;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:4349;
proxy_redirect off;
}
}
}
Advice me please, thanks.

Nginx / Django: Accessing static files results in 403 Forbidden

I've been trying to debug this for several hours and I'm not sure what else to check. My problem is that Nginx doesn't server Django static files. Accessing static files results in the error 403 Forbidden.
The exact error from nginx error log is:
2013/02/11 05:42:13 [error] 22526#0: *29 open() "/home/mydomain/public_html/test2/src/bootstrap.css" failed (13: Permission denied), client: XXX.XXX.XX.XX, server: mydomain.com, request: "GET /src/bootstrap.css HTTP/1.1", host: "www.mydomain.com"
Here is my nginx config file:
server {
listen XX.XX.X.XXX:80;
server_name mydomain.com;
root /home/mydomain/public_html/test2/app;
# serve directly - analogous for static/staticfiles
location /media/ {
# if asset versioning is used
if ($query_string) {
expires max;
}
}
location /admin/media/ {
# this changes depending on your python version
root /home/mydomain/public_html/test2/lib/python2.7/site-packages/django/contrib;
}
location /src/ {
autoindex on;
root /home/mydomain/public_html/test2;
}
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://localhost:8000/;
}
# what to serve if upstream is not available or crashes
error_page 500 502 503 504 /media/50x.html;
}
Static files are stored in /home/mydomain/public_html/test2/src.
I've tried chown mydomain.mydomain -R * and chmod 755 /home/mydomain -R * without any effect.
use this
btw. IfIsEvil
server {
listen 80;
server_name mydomain.com;
#access_log /var/log/nginx/x_access.log;
#error_log /var/log/nginx/x_error.log;
location /static {
alias /path/to/your/static;
}
location /media {
alias /path/to/your/media;
}
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://localhost:8000/;
}
}
Here is a working solution to my initial problem:
server {
listen XX.XX.X.XXX:80;
server_name mydomain.com;
root /home/mydomain/public_html/test2/app;
location /admin/media/ {
# this changes depending on your python version
root /home/mydomain/public_html/test2/lib/python2.7/site-packages/django/contrib;
}
location /src {
root /home/mydomain/public_html/test2;
}
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://localhost:8000/;
}
# what to serve if upstream is not available or crashes
error_page 500 502 503 504 /media/50x.html;
}
Another way to do this is to use try_files. The advantage of this is that Nginx will first look for a real file to serve, and if it fails to find one it passes execution to your django app. This is perfect for serving a dynamic sitemap.xml for example since you do not need to special-case the file in nginx.conf.
# Set default expires headers (used for static assets)
expires 30d;
server {
listen 80;
server_name mydomain.com;
root /some/path/assets/;
try_files $uri #django;
location #django {
expires -1d;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_pass http://unix:/some/path/server.sock;
}
location /static/admin/ {
alias /some/path/lib/python2.7/site-packages/django/contrib/admin/static/admin/;
}
}