I need these two types of rewrites:
subdomain.domain.com => domain.com/website/subdomain
otherdomain.com => domain.com/userdomain/otherdomain.com
My problem is that I want the user to see subdomain.domain.com, and otherdomain.com, not the redirected version. My current rewrite in nginx works, but the user's URL shows the rewrite, and I want this to be transparent to the user, any ideas?:
upstream domain_server { server localhost:8000 fail_timeout=0; }
server {
listen 80;
root /var/www/domain.com;
server_name domain.com ~^(?<subdomain>.*)\.domain\.com$ ~^(?<otherdomain>.*)$;
if ( $subdomain ) {
rewrite ^ http://domain.com/website/$subdomain break;
}
if ( $otherdomain ) {
rewrite ^ http://domain.com/userdomain/$otherdomain break;
}
location / {
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header X-forwarded-for $proxy_add_x_forwarded_for;
if (!-f $request_filename) {
proxy_pass http://domain_server;
break;
}
}
}
With nginx you don't need rewrites at all.
upstream domain_server { server localhost:8000 fail_timeout=0; }
proxy_set_header Host domain.com;
proxy_set_header X-forwarded-for $proxy_add_x_forwarded_for;
server {
listen 80 default_server;
location / {
proxy_pass http://domain_server/userdomain/$http_host;
}
}
server {
listen 80;
server_name domain.com;
root /var/www/domain.com;
location / {
try_files $uri #backend;
}
location #backend {
proxy_pass http://domain_server;
}
}
server {
listen 80;
server_name ~^(?<subdomain>.+)\.domain\.com$;
location / {
proxy_pass http://domain_server/website/$subdomain$request_uri;
}
}
http://nginx.org/r/proxy_pass
http://wiki.nginx.org/IfIsEvil
http://wiki.nginx.org/Pitfalls
http://nginx.org/en/docs/http/converting_rewrite_rules.html
Related
Now I config my location in Nginx:
server {
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
I want to change it into nested location:
http://exp.com/api instead of the current: http://exp.com/
I tried but it's not success:
server {
location / {
location /api {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
}
location does not need to be nested.
Have you tried the following?
server {
location /api {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
I have the following setup:
location #public {
auth_basic off;
}
location #webdav {
proxy_set_header Host $host;
proxy_pass http://localhost:8080;
}
location / {
# WebDAV server
if ($request_method != GET) {
error_page 418 = #webdav;
return 418;
}
gzip on;
fancyindex on;
location ~ /(public|\.well-known)/ {
if ($remote_user = "") {
error_page 418 = #public;
return 418;
}
}
location = /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /\n";
}
}
I want to redirect every non-GET request to my internal WebDAV handler written in Go. The /public folder should be accessible without basic auth, unlike the rest of the filesystem.
However, for nested location blocks, my parent if statement seems to be ignored. Attempting any non-GET request on /public results in 505, and on /robots.txt returns my configured text. However, this is not the case with gzip or fancyindex, as both /public and robots.txt are gzipped and fancy indexed.
Turns out the problem was the order in which nginx processes blocks. The two nested location blocks are executed first, and only then the parent location statements. Since my nested location blocks both return, the parent location statements are never reached. The solution was to add my WebDAV code to the beginning of each of these nested location blocks. Final code:
location #public {
auth_basic off;
}
location #webdav {
proxy_set_header Host $host;
proxy_pass http://localhost:8080;
}
location / {
# WebDAV server
if ($request_method != GET) {
error_page 418 = #webdav;
return 418;
}
gzip on;
fancyindex on;
location ~ /(public|\.well-known)/ {
# WebDAV server
if ($request_method != GET) {
error_page 418 = #webdav;
return 418;
}
if ($remote_user = "") {
error_page 418 = #public;
return 418;
}
}
location = /robots.txt {
# WebDAV server
if ($request_method != GET) {
error_page 418 = #webdav;
return 418;
}
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /\n";
}
}
I have an nginx with multiples server_name, and need redirect to https a specific server_name.
With my configuration (below), i got error ERR_TOO_MANY_REDIRECTS
My conf:
# /etc/nginx/sites-available/k2cloud_staging
upstream puma_k2cloud_staging {
server unix:/home/outracoisa/k2cloud/shared/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 8080;
client_max_body_size 4G;
keepalive_timeout 10;
error_page 500 502 504 /500.html;
error_page 503 #503;
server_name contoso.com www.contoso.com contoso.com.br www.contoso.com.br contoso.sapo.pt www.contoso.sapo.pt;
root /home/outracoisa/k2cloud/current/public;
try_files $uri/index.html $uri #puma_k2cloud_staging;
if ($host ~* www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*)$ http://$host_without_www$1 permanent;
}
rewrite ^/rio/?$ http://contoso.com/rio/pt-BR permanent;
rewrite ^/lisboa/?$ http://contoso.sapo.pt/lisboa/pt-PT permanent;
if ($host ~ contoso.com(\.br)) {
rewrite ^/?$ http://contoso.com/rio/pt-BR permanent;
}
if ($host = contoso.sapo.pt) {
rewrite ^/?$ http://contoso.sapo.pt/lisboa/pt-PT permanent;
}
location ~ ^/(rio|lisboa) {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma_k2cloud_staging;
# limit_req zone=one;
access_log /home/outracoisa/k2cloud/shared/log/nginx.access.log;
error_log /home/outracoisa/k2cloud/shared/log/nginx.error.log;
}
########## Ramos #####
if ($scheme != "https") {
set $a x;
}
if ($host = contoso.sapo.pt) {
set $a "${a}y";
}
if ($a = xy) {
rewrite ^(.*) https://$host$1 permanent;
break;
}
################
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location = /50x.html {
root html;
}
location = /404.html {
root html;
}
location #503 {
error_page 405 = /system/maintenance.html;
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html break;
}
rewrite ^(.*)$ /503.html break;
}
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
return 405;
}
if (-f $document_root/system/maintenance.html) {
return 503;
}
location ~ \.(php|html)$ {
return 405;
}
}
Anyone can help me to solve it please?
I think you do it very complicated. First: If is evil :)
As I see you want to do several things:
remove the www "prefix"
/rio and /lisboa: use a specific host
contoso.com and contoso.sapo.pt: use a specific directory
contoso.sapo.pt: force https
I would do it another way:
Use another server sections with server_name www.contoso.com, server_name www.contoso.com.br and return 301 $scheme://....
Try location /rio and location /lisboa! Or maybe better solution is to use alias (I think your nginx servers static contents and the /rio/pt-BR is a directory on your server).
Use server blocks!
Again in server block! return 301 https://$host$request_uri;
I think it would be easier maintain and debug if you create small blocks not only big one with many if and rewrite.
I have a configuration file (nginx default.conf) in which I have this kind of strings :
server {
location / {
proxy_set_header Host sudomain1.somewhere.com;
proxy_pass http://127.0.0.1:8999/;
}
}
server {
location / {
proxy_set_header Host sudomain2.somewhere.com;
proxy_pass http://127.0.0.1:8755/;
}
}
server {
location / {
proxy_set_header Host sudomain3.somewhere.com;
proxy_pass http://127.0.0.1:8525/;
}
}
How to subtract the configuration about subdomain2 ?
server {
location / {
proxy_set_header Host sudomain2.somewhere.com;
proxy_pass http://127.0.0.1:8755/;
}
}
If it is possible, using grep would be nice !
Thank you for your precious help !
You can use this gnu awk command to get a block matching subdomain2 using custom record separator (RS):
awk -v RS='}[[:space:]]*}[[:space:]]*' '/sudomain2/{printf $0 RT}' default.conf
server {
location / {
proxy_set_header Host sudomain2.somewhere.com;
proxy_pass http://127.0.0.1:8755/;
}
}
EDIT: To print other blocks except the subdomain2 use:
awk -v RS='}[[:space:]]*}[[:space:]]*' '!/sudomain2/{printf $0 RT}' file
server {
location / {
proxy_set_header Host sudomain1.somewhere.com;
proxy_pass http://127.0.0.1:8999/;
}
}
server {
location / {
proxy_set_header Host sudomain3.somewhere.com;
proxy_pass http://127.0.0.1:8525/;
}
}
I'm trying to server protected user-files from nginx and django.
nginx.conf:
server {
listen 80;
gzip off;
expires off;
location /static/ {
add_header X-Static hit;
autoindex on;
expires off;
root /Users/andrewshkovskii/workspace/ip_pbx/;
}
location / {
proxy_pass http://localhost:8000;
rewrite ^/audiofiles/get/(\d+)/ /audiofiles/serve/$1/ last;
}
location /media/audio {
internal;
root /var/ip_pbx/users;
}
}
Django view:
def get(self, request, *args, **kwargs):
audio_file = self.get_object()
ogg_file_version = audio_file.audiofileversion_set.filter(format="ogg")
if ogg_file_version.exists():
ogg_file_version = ogg_file_version[0]
res = HttpResponse()
res["Content-type"] = "audio/ogg"
res["X-Accel-Redirect"] = ogg_file_version.file.path
res["Content-length"] = ogg_file_version.file.size
return res
return Http404()
If I trying to GET , let's say, localhost/audiofiles/get/74/ , nginx will rewrite it to view (/audiofiles/serve/74/), and view will return response, but it respose, when returned, will trying to GET localhost:8000/%full_file_path% .. Why? (file exists..)
soled by config :
server {
listen 80;
gzip off;
expires off;
error_log /usr/local/Cellar/nginx/1.2.5/logs/error.log debug;
location /static/ {
add_header X-Static hit;
autoindex on;
expires off;
root /Users/andrewshkovskii/workspace/ip_pbx/;
}
location / {
proxy_pass http://localhost:8000;
rewrite ^/audiofiles/get/(\d+)/ /audiofiles/serve/$1/ last;
}
location ~ /var/ip_pbx/users_andrewshkovskii/(\d+)/(audio|calls)/(.*) {
internal;
root /;
}
}
Note the re for location of private files (in my case.. )