My nginx instance is behind a SSL terminated load balancer, and I want all urls to hit https endpoints, which means http to be redirected to https.   All is well when urls have a trailing slash. They all get redirected nicely:  #!/bin/sh  do_curl() {    echo "\n$ do_curl $1"    curl -L -s -D - "$1" -o /dev/null | grep -iE 'Location|HTTP/|server' }  $ do_curl https://example.com/ HTTP/2 200  $ do_curl http://example.com/foo/ HTTP/1.1 301 Moved Permanently Location: https://example.com/foo/ HTTP/2 200  $ do_curl https://example.com/foo/ HTTP/2 200   But when the same urls have no trailing slash, nginx's try_files seems to be issuing a http redirect always:   Here's my nginx vhost.conf:  server {     listen 80;     root /app/;     index index.html index.htm;      # This 'if' block is only needed because my SSL-terminated Load balancer proxies both http and https to nginx.     # If my Load balancer only proxied https to nginx, and dropped http, this 'if' block can be omitted.     if ($http_x_forwarded_proto = "http") {         return 301 https://$host$request_uri;     }      location / {         try_files $uri $uri/ =404;     } }   How do I get nginx's try_files to redirect directly with the https $scheme when it hits the $uri/ parameter (2nd parameter in my try_files above) and successfully finds a file matching $uri/&lt;index&gt; (where index is defined by the index directive in the nginx config above)?  I searched similar questions such as , , or  but still could not find anything remotely relevant.
120687
I have a website served by nginx behind an AWS ELB Load Balancer. Only HTTPS is enabled on the load balancer.  Requesting individual files, or directories with a trailing slash, work fine. However, requesting directories without a trailing slash don't work.  The reason is, when I request the directory without the trailing slash, nginx does a redirect to the path with the trailing slash (that's OK), but it also changes from HTTPS to HTTP. The load balancer is configured to only allow HTTPS, so that doesn't work (timeout).  On the nginx logfile, I can see that the request reaches nginx, and that it's nginx that responds with the 301 Permanent Redirect (so it's not e.g. a problem with the load balancer setup).  10.100.10.15 - - [24/Nov/2017:15:41:08 +0000] "GET /admin HTTP/1.1" 301 178 "-" "Wget/1.18 (darwin16.0.0)"   When I request the URL via curl I see the redirect:  $ curl -v https://example.com/admin *   Trying 1.2.3.4... * TCP_NODELAY set * Connected to example.com (1.2.3.4) port 443 (#0) * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 * Server certificate: example.com * Server certificate: Amazon * Server certificate: Amazon Root CA 1 * Server certificate: Starfield Services Root Certificate Authority - G2 &gt; GET /admin HTTP/1.1 &gt; Host: example.com &gt; User-Agent: curl/7.54.0 &gt; Accept: */* &gt;  &lt; HTTP/1.1 301 Moved Permanently &lt; Date: Mon, 27 Nov 2017 09:19:05 GMT &lt; Content-Type: text/html &lt; Content-Length: 178 &lt; Connection: keep-alive &lt; Server: nginx &lt; Location: http://example.com/admin/ &lt; X-UA-Compatible: IE=Edge &lt;  &lt;html&gt; &lt;head&gt;&lt;title&gt;301 Moved Permanently&lt;/title&gt;&lt;/head&gt; &lt;body bgcolor="white"&gt; &lt;center&gt;&lt;h1&gt;301 Moved Permanently&lt;/h1&gt;&lt;/center&gt; &lt;hr&gt;&lt;center&gt;nginx&lt;/center&gt; &lt;/body&gt; &lt;/html&gt; * Connection #0 to host example.com left intact   My nginx config file is just   server {     root /var/www; }   The /etc/nginx/nginx.conf is .  I have tried server_name_in_redirect off but it did not make any difference.  I would like to avoid putting the hostname in the config file, because this is packed into a Docker image which is then deployed on different hosts (QA, Prod, etc.).  I would like nginx to do this redirect, but stay on HTTPS. What can I do?
121029
I'm using nginx with SSL, and I want to always redirect to www, regardless of whether the request is http or https. I just want to redirect to the respective protocol www version.  I have the port 80 server block working fine. Beneath my first server block I have...  server {     listen      80;     server_name example.com;     return 301  $scheme://www.example.com$request_uri; }   and this works fine. But for my port 443 server block for https, I have all kinds of information inside regarding ssl on and different ciphers to use.  I really don't want to mess up anything up related to security by doing something stupid.. so my question is on this block for port 443...  server {     listen      443;     server_name example.com;     return 301  $scheme://www.example.com$request_uri; }   do I need anything else? do I need ssl on or any other security related things? If they visit non-www does that mean it transfers the request insecurely or something (even for a split second while its redirecting?)  Just want to make sure what I have is solid and secure. It seems to work but I want to double check.  Thanks!
17146
Goals:   If the user support SNI and hit myurl1.server.com (https) or myurl2.server.com (https) it will match the right vhost. (the last 2 vhosts) If the user does not support SNI and hit myurl1.server.com (https) or myurl2.server.com (https) it will be catch by the fallback vhost (the first on port 443). It contains the SAN certificate and it  will hit the server again to do the match. This time it will hit the last 2 vhost.  If the user enter an unknown url with either http or https it will be catch in the first vhost that show a error page.   I have tested all 3 goals and it's working fine.  Questions:   When the user is hitting the SAN vhost (https) which make a new request to it self. How does Apache know it will match the last 2 vhost (443) when the proxypass in SAN vhost is using http(80) When the user is hitting the SAN vhost I can't see any requests in the SAN access log. The requests only appears in the  last 2 vhost even if it goes through the SAN vhost. However I can see some bot requests in the SAN access log.   The code only contains the important parts.  NameVirtualHost *:80 NameVirtualHost *:443  &lt;VirtualHost *:80&gt;   show error page &lt;/VirtualHost&gt;  &lt;VirtualHost *:443&gt;   SSLCertificateFile san.crt   CustomLog san-access.log    ProxyPass / http://my-local-url-server/   ProxyPassReverse / http://my-local-url-server/ &lt;/VirtualHost&gt;  &lt;VirtualHost *:443&gt;   ServerName myurl1.server.com   SSLCertificateFile myurl1.crt   CustomLog myurl1-access.log    ProxyPass / http://mybackend1/   ProxyPassReverse / http://mybackend1/ &lt;/VirtualHost&gt;  &lt;VirtualHost *:443&gt;   ServerName myurl2.server.com   SSLCertificateFile myurl2.crt   CustomLog myurl2-access.log    ProxyPass / http://mybackend2/   ProxyPassReverse / http://mybackend2/ &lt;/VirtualHost&gt;
35759
I have a running web-application at http://example.com/, and want to "mount" another application, on a separate server on http://example.com/en. Upstream servers and proxy_pass seem to work, but for one issue:  upstream luscious {  server lixxxx.members.linode.com:9001; }  server {   root /var/www/example.com/current/public/;   server_name example.com;    location /en {     proxy_pass http://luscious;   } }   When opening example.com/en, my upstream application returns 404 not found /en. This makes sense, as the upstream does not have the path /en.   Is proxy_path the right solution? Should I rewrite "upstream" so it listens to /en instead, as it root path? Or is there a directive that allows me to rewrite the path passed along to upstream?
15059
I am investigating the vulnerability to  and I think I understand how and why this sort of attack works.  What I don't understand is why Lighttpd and NginX are not affected (according to the same article as linked above). What do they make so different?
25732
I have one nginx server setup(two config files) with two gunicorn web servers setup and running. One gunicorn is production and the other is staging.   I want nginx to serve http requests to xyz.com as well as https requests to xyz.com to the production gunicorn server @ 127.0.0.1:8000.    I have accomplished this with:  server {    listen 80;    server_name xyz.com;    return 301 https://$http_host$request_uri; }  server {    listen 443 ssl;    server xyz.com;    ..... &lt;&lt;&lt; ssl stuff   location /{       .... proxy_stuff       proxy_pass http://127.0.0.1:8000;   } }   I also want http traffic to xyz.com:8080 and https traffic to xyz.com:8080 to hit the staging server @ 127.0.0.1:8081. I have been been able to get https traffic to xyz.com:8080 working as follows:  server {    listen 8080 ssl;    server_name xyz.com;    ...... &lt;&lt; ssl stuff    location / {       ...... &lt;&lt; proxy stuff       proxy_pass http://127.0.0.1:8081;    } }   But I can't seem to find a way to redirect http traffic at xyz.com:8080 to https traffic at xyz.com:8080. I have tried the same redirection that I did with port 80 but have not been successful.   Could use some direction.
112718
The Problem  Accessing my site over https (the only protocol allowed) I get the content, but none of the CSS, images etc.  Drupal is creating pages in response to https requests that include http links to these resources, but it should be using https.  What I've done  I have copied a site to a dev server. The site loads and basically works fine - I can log in etc. It's just that all the links drupal generates are http. The site I've copied it from also runs over https. The site does not exist on http (it would just get a Forbidden error). I've drush cc all.  So Apache's working - I can access the site. .htaccess is working (clean urls work, for example).  I'm using SNI to access the site because the server has other vhosts too, but I'm only accessing the site using the latest Firefox (and as it's a dev site and I'm the only dev, nobody else will use it).  I've done this dozens of times and am quite stumped! Why does Drupal not notice that the request came over https?  The fix  Turns out that .htaccess has this to say:   /* Base URL (optional).                                                          If Drupal is generating incorrect URLs on your site, which could             be in HTML headers (links to CSS and JS files) or visible links on pages     (such as in menus), uncomment the Base URL statement below (remove the       leading hash sign) and fill in the absolute URL to your Drupal installation.    Sure enough, putting $base_url = 'https://example.com'; fixed it.  But why is this necessary?
201
We're using setup with an nginx on one machine and (currently) one application server on apache in the back.  For multiple domains we got ssl certs, but only for the domain itself. So without subdomain www. Everything works as expected, we do not use the  anywhere. But we have customers who are typing this in by hand, resulting in a warning in the browser on the clientside. ..and a new seo guy insisting on working www subdomain WITH ssl.  What am i looking for: A creative solution which does not require new certificates for 20+ domains.  I already thought about getting certificates from let's encrypt for our www subdomain, then 301 to domain.tld.. but it's still in beta.  Any ideas ?
69201
Here's something I noticed while testing a client-side fix for .  If you follow a permalink / shortcut URL with an https: protocol, like:      you'll get redirected to:      even though, in fact, the https: version of the target URL would work just fine.  This rather frustrates any attempts to fix such links in post text to use HTTPS.  The same happens with other similar shortcuts too.  For example:      redirects to:      However, other non-permalink redirects do retain the correct protocol.  For example:      correctly redirects to:      It seems this is because those redirects are actually using relative URLs in the Location: header, which, while , does seem to work in most modern browsers.  Presumably, the permalink redirects could be changed to work the same way.
76790
I've looked at dozens of other questions and references on the web - and by all my calculations, my setup should work, but it doesn't.  I have nginx installation with php-fpm.  If I try to access a .php file, it runs correctly and I get the correct results.  I got this in my config file:  location ~ \.php$ {     try_files $uri =404;     fastcgi_pass unix:/var/run/php5-fpm.sock;     include fastcgi_params;     fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name; }   Now, I want to setup my web app so that /somedir/file automatically executes /somdir/file.php while still displaying /somdir/file in the browser's address bar.  So I modified my config to contain the following:  location / {     try_files $uri $uri/ $uri.php?query_string }   This kind of works, that is, the server does access the .php file.  Yet, instead of executing it using the existing location ~ \.php$ block above, it simply spits the php source code as the download into the browser.  If I append the .php manually to the requested URL, then the php is executed.  It feels as if once the server matches try_files to $uri.php, it then does not do another pass at locations to see that what it needs to do with the php files.  I tried putting the php block above and below the location /, but it makes no difference.  How can I get the php to be executed?
69843
I have two domains: staging.abc.com and www.example.com pointing to the same server IP in my DNS. I don't have a site enabled/available for staging.abc.com, but I have one for www.example.com. However, whenever I access staging.abc.com, it points to www.example.com.  Here are my confs. My /etc/nginx/nginx.conf is default. I didn't change anything.  I don't have a sites-available/default. It's been removed.  # sites-available/example server {   listen 80;   server_name example.com;   return 301 http://www.example.com$request_uri; }  server {   listen 80;   listen [::]:80;    root /home/deployer/example;   index index.php index.html index.htm;    server_name www.example.com;    location ~* .(jpg|jpeg|png|gif|ico|css|js|woff)$ {   expires 30d;   }    location / {     try_files $uri $uri/ /index.php?q=$uri&amp;$args;   }    error_page 404 /404.html;    error_page 500 502 503 504 /50x.html;   location = /50x.html {     root /usr/share/nginx/html;   }    location ~ \.php$ {     try_files $uri =404;     fastcgi_split_path_info ^(.+\.php)(/.+)$;     fastcgi_pass unix:/var/run/php5-fpm.sock;     fastcgi_index index.php;     include fastcgi_params;     fastcgi_read_timeout 300;   }    include /home/deployer/example/nginx.conf; }   # nginx.conf user www-data; worker_processes 4; pid /run/nginx.pid;  events {         worker_connections 768;         # multi_accept on; }  http {          ##         # Basic Settings         ##         charset utf-8;         sendfile on;         tcp_nopush on;         tcp_nodelay on;         keepalive_timeout 65;         types_hash_max_size 2048;         # server_tokens off;         proxy_read_timeout 300;          # server_names_hash_bucket_size 64;         # server_name_in_redirect off;          include /etc/nginx/mime.types;         default_type application/octet-stream; ...   I tried inserting this to the http block but to no avail:  server {     listen      80;     server_name "";     return      444; }   Here's what I want to achieve:   Changes are preferably done on sites-available. The server should not resolve any connection (returns 444) for all domain names that have not been assigned to any app.
104449
How can I use varnish cache with nginx SSL termination for my SSL-Only (Https only) website? I use ubuntu 18.04 and I am currently running a wordpress site on my server.
75499
I have the following nginx config, e.g.  server {         listen   80;         server_name example.com         allow 127.0.0.0/8;   When I restart, it warn me:  Restarting nginx: nginx: [warn] server name "127.0.0.0/8" has suspicious  symbols in /etc/nginx/sites-enabled/xxx   Any idea?
100409
I am asking this because whenever I hover over a link to a home page (e.g. http://www.example.com), I notice that a trailing slash is always added (as observed on the status bar of the browser) whether the home page link contains a href attribute that ends with a slash or not. But whenever I am on the home page, the URL on display will not have a trailing slash.  I tried entering a slash to the URL in the URL bar. And with Firebug enabled, I notice that the site always return a 200 OK status. An article  discussing this states that having a slash at the end will avoid a 301 redirection. But I am not seeing any redirection, even on  page.  Could this be a browser feature that is appending the slash?
82636
I want to rewrite all http requests on my web server to be https requests, I started with the following:   server {     listen      80;      location / {       rewrite     ^(.*)   https://mysite.com$1 permanent;     } ...    One Problem is that this strips away any subdomain information (e.g., node1.mysite.com/folder), how could I rewrite the above to reroute everything to https and maintain the sub-domain?
39391
What is the difference between the three Nginx variables $host, $http_host, and $server_name?  I have a rewrite rule where I'm not sure which one I should be using:  location = /vb/showthread.php {     # /vb/showthread.php?50271-What-s-happening&amp;p=846039     if ($arg_p) {         return 301 $scheme://$host/forum/index.php?posts/$arg_p/;         }   I'm looking for an answer that doesn't just say 'use ___ variable in your rewrite rule' but also explains the theoretical differences between them.
62628
I have an nginx configuration with a whole bunch of server {} blocks. I want to share error pages between them all, but many of them have different document roots. I can use a configuration like  error_page   404              /404.html; error_page   500 502 503 504  /50x.html;   outside of the server blocks and it gets shared, but then I have to put those same documents in all the roots, or have rules like  location = /404.html {     root /srv/http/errors; } location = /50x.html {     root /srv/http/errors; }   in all my server blocks.  Is there a way to share these documents without repeating myself over and over or having many copies in the filesystem?