I have a Flask application served using gunicorn, and with NGINX on top of it. I want to use Basic Authentication (user/password) to protect all URL's starting with /admin, which is the back office, but still continue serving all other URLs with gunicorn without password.
Here is my current NGINX config:
server {
listen 80;
server_name example.com;
charset utf-8;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /admin {
auth_basic "Administrator Login";
auth_basic_user_file /home/app/.htpasswd;
# the following four directives are duplicated :(
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If I don't duplicate the proxy_* directives in the second location block, then the URLs starting with /admin doesn't get forwarded to gunicorn and I get a 404.
Is there any way to avoid the configuration duplication? I tried location nesting but apparently in the end NGINX only "executes" a single location block.
The proxy_pass must be within the location block. However, there's no need to duplicate the proxy_set_header directives, they can be moved into the server block. So your mistake was simply the assumption that proxy_pass could live in the server block :-)
Related
I'm in the unfortunate situation that I need to extend my react application with an iframe containing an external application.
My application is hosted by a nginx reverse proxy that handles /api and signalr communication.
Unfortunately it also handles the outbout iframe src url.
in this example my site is on the url https://example.com
The iframe src url is in this case "https://external-site.com/someapp/session?token=1234"
When i see the requests in the browser the url has changed to https://example.com/esternal-site.com/someapp/session?token=1234, which needless to say is not working out of the box.
I've been toying with the nginx configuration but has been unable to just pass the request through without modification.
The iframe/destination works as expected when running locally.
I've attempted with a few different configuations inspired by stackoverflow and medium etc. but they've all returned various error codes.
the server runs on port 80, but https is handled by ingress on azure.
This is what i have currently:
upstream bff_service {
server ${BFF_HOST}:${BFF_PORT};
keepalive 32;
keepalive_requests 1000;
keepalive_timeout 75s;
}
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
add_header Set-Cookie "msal_client_id=${BFF_MSAL_CLIENT_ID};Path=/;Secure";
}
location /api {
proxy_read_timeout 300s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host ${BFF_HOST};
proxy_set_header X-NginX-Proxy true;
proxy_pass ${BFF_PROTOCOL}://bff_service;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_redirect off;
}
location ^~ /external-site.com {
add_header Content-Security-Policy "frame-src 'self' https://external-site.com";
proxy_pass https://external-site.com/$request_uri;
}
}
I've also tried adding the lines below to the location:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-NginX-Proxy true;
I'm looking for a configuration that allows me to embed an iframe with an external location. Perhaps even avoid nginx proxying it at all?
I've installed several web applications on different ports on the same server. From that server when I send an http request using wget or curl the request goes through and I get the response. I've set up nginx server to not have to specify the port each time. Here's the related nginx config:
server {
listen 10.0.223.34:80;
server_name app1.domain.com;
access_log /var/log/nginx/app1.domain.com.access.log;
error_log /var/log/nginx/app1.domain.com.error.log;
location / {
proxy_pass http://10.0.223.34:8080;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If I try app1.domain.com from outside I get 502 Bad gateway error. But if I change the proxy_pass to http:\\www.example.com, then nginx takes me to the example.com website.
Inside the nginx.conf file I've specified user nginx;. I've tried changing it to root but it didn't help either. Do you have any idea what else I need to check?
Try this:
upstream app1 {
server localhost:8080;
}
server {
listen 10.0.223.34:
server_name app1.domain.com;
access_log /var/log/nginx/app1.domain.com.access.log;
error_log /var/log/nginx/app1.domain.com.error.log;
location / {
proxy_pass http://app1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I have a nginx reverse proxy setup for apache wordpress which works fine. However based on location need to redirect to an external url which fails. Please check the below config. Is this a valid setup ?
https://platform.com/ - this works - also any subsequent wp pages also works
https://platform.com/pen - this needs to redirect to https://abcdef.com - this doesn't work - 404 page load error Any help ?
server {
listen 443 ssl default_server;
listen [::]:443 default_server;
server_name platform.com;
server_tokens off;
root /var/www/html/def/public/;
index index.php;
ssl on;
ssl_certificate /tmp/fgh.crt;
ssl_certificate_key /tmp/fgh.pem;
access_log /var/log/nginx/access2.log;
error_log /var/log/nginx/error2.log;
location / {
proxy_set_header X-Forwarded-Proto $scheme;
try_files $uri #apache;
}
location #apache {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
location ~[^?]*/$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
location /pen {
proxy_pass https://abcdef.com;
}
}
After changing the server name (wordpress site) from http prefix to www prefix, proxy pass re directions worked. Had to redirect all http https server blocks to www server block in nginx config
What you are doing is a proxy_pass to https://abcdef.com , not a redirect. if you meant a redirect the code is :
location /pen {
return 301 https://abcdef.com;
}
If it's not a definitive redirect, use 302 instead of 301, so is not cached (for tests is much better).
The reason the 404 is given is because you are accessing the https://abcdef.com with a request with the host/url https://platform.com/pen
If the destiny server is not prepared to recive this whole url, it returns 404, as /pen is not found.
I have configured nginx as reverse proxy tool. I have come across a problem which I have not been able to deal with. Following are the rules I have set in my .conf file.
server {
listen 80;
server_name rp.mydomain.com;
return 301 https://$host/myapp1/;
location / {
proxy_pass <local ip address>;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect http://$host https://$host;
proxy_set_header Host $host;
}
}
server {
listen 443 ssl;
server_name rp.mydomain.com;
location / {
proxy_pass <local ip address>;
proxy_redirect http:// https://;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host;
proxy_ssl_session_reuse on;
}
}
My application resides on /myapp1/ . The reason why I am not writing /myapp1/ in the proxy_pass [I tried] is because the redirection is not working properly WHEN I try to login on the page. I get the error page not found.
But after this rule in listen 80 block, return 301 https://$host/myapp1/; its working like charm, but only if I go open the http page.
When I open the link, rp.mydomain.com. The redirection is working perfectly and the application works fine too. The http request is redirected to https and I can log in through my app.
But, when I go through https://rp.mydomain.com, I end up at the blank page of <local ip address>, because of the proxy_pass rule in listen 443.
My requirement is whenever the specific request of the page is generated, which is, https://rp.mydomain.com, its redirected to https://rp.mydomain.com/myapp1/ (like when it does when the user accesses the page through http://rp.mydomain.com) but the other requests, like https://rp.mydomain.com/myapp1/ or https://rp.mydomain.com/myapp1/profile [etc etc] are not affected.
Just one specific page https://rp.mydomain.com gets redirected automatically.
Is it possible to do so? Please help me in this issue.
Thank you.
Try:
server {
listen 80;
server_name rp.mydomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name rp.mydomain.com;
location = / {
rewrite ^ /myapp1/ last;
}
location / {
proxy_pass <local ip address>;
proxy_redirect http:// https://;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host;
proxy_ssl_session_reuse on;
}
}
The location = / block has been added to create the mapping from / to /myapp1/. To change the URL in the browser, use permanent instead of last. See this document for details.
You will need to add additional proxy_redirect statements to prevent your local ip address leaking out when the application performs a redirect. See this document for details.
It is assumed that your SSL certificates are defined in an outer block and inherited.
I have a VPS whose primary interface is accessible via two internet names which I'll give here as personal.me and company.com. I am running a Mattermost server and can access it via personal.me using the following nginx rule:
server {
server_name personal.me;
location / {
client_max_body_size 50M;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://localhost:8065;
}
}
This is working perfectly well but I would also like to access the instance via http://company.com/fora/ -- the point being that this time there is a /fora/ path to remove. I know that I should be using https:// but that is a separate matter, for later. I tried:
server {
listen 80;
server_name company.com;
location / {
root [...];
index index.html;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /fora/ {
client_max_body_size 50M;
rewrite /fora/ / break;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://localhost:8065;
}
}
but when I navigate to http://company.com/fora/ although the title-bar changes to Mattermost, there is no content --- the page is blank. Since I can access Mattermost via the personal.me URL, I believe that Mattermost is running correctly.
What is wrong with the company.com rule? Is it something to do with not passing the path into Mattermost?
According to Nginx reverse proxy (proxy_pass) does not pass subfolder and http://forum.mattermost.org/t/blank-page-when-installing-mattermost-with-nginx-proxy-pass-as-subdirectory/1604 this isn't possible but I don't get that ... surely removing a bit of the URL is one of nginx's core capabilities?
This seems to be impossible with Mattermost currently as the app assumes it is at the server root.
See this issue on their github and this ticket for further details and to track when/if this becomes a supported feature.
What we do is create a subdomain for each mattermost service we want to access on a domain. I suggest creating a subdomain fora.company.com then use that subdomain in your nginx settings.