Jenkins With Nginx Reverse Proxy And Resolver - nginx

I am running Jenkins inside Docker behind an Nginx reverse proxy. Now I got a problem with the resolver.
When I activate the resolver with:
set $backend "http://jenkins:8080/";
proxy_pass $backend;
I will get the following error for all javascript files:
Refused to execute script from 'http://localhost/static/....js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
When I simply proxy pass without resolver:
proxy_pass http://jenkins:8080/;
It works but without resolver. The resolver is mandatory otherwise the setup won't work when the host jenkins changes it's Ip (Docker DNS Server).
My configuration:
resolver 127.0.0.11 ipv6=off valid=30s;
client_max_body_size 100m;
keepalive_timeout 65;
types_hash_max_size 2048;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
set $backend "http://jenkins:8080/";
proxy_pass $backend;
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;
}
}

Based on the error message you receive, it sounds like you're getting HTML pages in place of JavaScript.
Using a proxy_pass paradigm with a variable, you're telling nginx that it shouldn't mess with the value any further, e.g., regardless of the location and the URI, all requests to your backend will always be just as the variable says (e.g., with the same URI in your case).
The best option would probably be to use $uri, $is_args and $args, as per NGINX proxy_pass remove path prefix & resolve DNS:
- set $backend "http://jenkins:8080/";
- proxy_pass $backend;
+ proxy_pass http://jenkins:8080$uri$is_args$args;
Another option, which potentially could be less secure, is to use $uri_request, which has a slightly different meaning than the plain $uri in certain limited cases, as per Nginx pass_proxy subdirectory without url decoding:
proxy_pass http://jenkins:8080$request_uri;

Related

Nginx not appending path when using proxy_path

I am trying to use Nginx as a reverse proxy for a few backends. It's probably not relevant, but the backends are all hosted within a single Docker network, and the network is being created using docker-compose.
The backends all have the same endpoints that need to be exposed, so to reduce duplicate configuration lines I am trying to use map.
map $http_host $backend {
host-a.example.com host-a;
host-b.example.com host-b;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name _;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
location / {
# there is no DNS resolution if we set proxy_pass targets dynamically,
# use the docker internal DNS server
resolver 127.0.0.11;
proxy_pass "http://$backend:8080/";
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
The resolver line has been added as Nginx will otherwise give the error: no resolver defined to resolve *hostname*
However with this configuration I am finding that requests are being sent to the wrong path, for example if I send a request to https://host-a.example.com/books or https://host-a.example.com/books/123/front-cover.jpg the page that is returned is always the root of the site (i.e. https://host-a.example.com/), it seems that for some reason proxy_pass is not including the path with the request to the backend server.
Is there a way that I can make this work with map or do I need to create a separate server block for each of the backends that I want to proxy requests to.
From the proxy_pass documentation:
When variables are used in proxy_pass
. . .
In this case, if URI is specified in the directive, it is passed to the server as is, replacing the original request URI.
You should either remove the trailing / (the documentation calls this the optional URI) :
proxy_pass http://$backend:8080;
Or provide the full URL of the request (conveniently available as a built-in variable) :
proxy_pass http://$backend:8080$request_uri;

prestashop under docker with reverse proxy URL subfolder problem

i need some help with my configuration.
I followed the example already listed here => Deploy existing Prestashop to server using Docker
In order to build a prestashop using docker. The problem is that i have in my server a revers proxy configured like this :
server {
listen 80;
listen 443 ssl http2;
server_name example1.test;
# Path for SSL config/key/certificate
ssl_certificate /etc/ssl/certs/nginx/example1.test/example1.crt;
ssl_certificate_key /etc/ssl/certs/nginx/example1.test/example1.key;
include /etc/nginx/includes/ssl.conf;
location /shop {
include /etc/nginx/includes/proxy.conf;
proxy_pass http://x.x.x.x:9001;
}
access_log off;
error_log /var/log/nginx/error.log error;
}
Options "proxy.conf" that i'm including are :
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_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_intercept_errors on;
to be simple when i access "example1.test/shop" prestashop is redirecting me to the root as it doesn't know the /shop path so im getting 404 error because reverse proxy dont know / too.
example1.test/shop in the browser => redirect to example1.test/ which is not defined in the reverse proxy
i tried all things on internet to configure prestashop in order to recognize the /shop and redirection follow /shop/... but nothing works/
I think configuring prestashop is illogic as it is installed on the / of the docker container. I must change somthing in my reverse proxy to fix it like rewreting response from prestashop container to /shop or something like that.
Any ideas please ?

WSO2 APIM: Subdomains for different contexts

We have the WSO2 API Manager 1.10.0 deployed and working. Although we are trying to figure out if it is possible to have multiple subdomains for it.
For example:
store.domain.com
publisher.domain.com
carbon.domain.com
Is this at all possible? We've seen this https://docs.wso2.com/display/Carbon442/Adding+a+Custom+Proxy+Path, but this is for different applications, we want to do this only with the API Manager.
In front of the API Manager, we are using nginx with reverse proxy. Below, you can find a snippet from nginx to help while understanding the problem.
server {
listen 80;
server_name store.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
ssl on;
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH";#:AES128+EDH";
ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=63072000";
server_name store.domain.com;
ssl_certificate /etc/nginx/ssl/domain.com/self-ssl.crt;
ssl_certificate_key /etc/nginx/ssl/domain.com/self-ssl.key;
access_log /var/log/nginx/store.log;
underscores_in_headers on;
location / {
proxy_pass http://wso2server:9443/store/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
When attempting to access with HTTP (for the store context) all works fine, but as soon as we switch this over to HTTPS this fails with the following error in nginx upstream prematurely closed connection while reading response header from upstream however, we see nothing in API Manager logs.
Thanks in advance!
Best Regards
You can solve your issue by one of following methods.
Adding proxy_redirect configs to Nginx. So nginx will rewrite all the URLs to proper URL. Please refer the following config segment.
proxy_redirect http://wso2server/ http://store.domain.com/;
Also you can achieve the same by adding reverse proxy configurations in API Manager store. To do this Open "repository/deployment/server/jaggeryapps/store/site/conf/site.json" and see the following config section
"reverseProxy" : {
"enabled" : false, // values true , false , "auto" - will look for X-Forwarded-* headers
"host" : "sample.proxydomain.com", // If reverse proxy do not have a domain name use IP
"context":"",
//"regContext":"" // Use only if different path is used for registry
},

How to configure nginx rules so that if one failed it serve the request using another

Note, this question is moved to stackoverflow from superuser
I got the following nginx conf:
server {
listen 80;
listen 443 ssl;
...
# specific rule to serve versioned js resources
location ~ ^/js/([0-9\.]+)/(.*)$ {
alias /opt/x/public/deploy/js/$1/$2;
}
location / {
add_header P3P 'CP="CAO PSA OUR"';
proxy_pass http://127.0.0.1:8088;
set $ssl off;
if ($scheme = https) {
set $ssl on;
}
proxy_set_header X-Forwarded-Ssl $ssl;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
It works as expected. However if a certain versioned js resource does not exists in the deployed dir, say /opt/x/public/deployed/js/1.1/, it will return 404. What I want is in that case nginx shall pass the request to the backend service running at 8088 port instead of returning 404. Is this even doable?
Thanks!
Green
http://wiki.nginx.org/HttpCoreModule#try_files
try_files is your friend, here you can do the order you want to try files and finaly have the proxypass upstream.

nginx subdomain to directory , too many redirect , why?

this is my config:
server {
listen 80;
server_name ~^(?<sb>.+)\.a\.b\.c\.com$;
access_log /data/logs/nginx/tas.access.log main;
location / {
proxy_intercept_errors on;
proxy_pass http://b.c/a/$sb/;
proxy_set_header Host $host;
proxy_redirect off;
}
}
and browser report to many redirects.
If, as you say, you want to proxy to localhost:8082, you need to say so in the proxy_pass line:
server {
listen 80;
server_name ~^(?<sb>.+)\.a\.b\.c\.com$;
access_log /data/logs/nginx/tas.access.log main;
location / {
proxy_intercept_errors on;
proxy_pass http://localhost:8082/a/$sb/;
proxy_set_header Host $host;
proxy_redirect off;
}
}
Without all of the information, it's hard to guess what's going on. Based on the comments, my guess is that you are using virtual hosting so that the upstream site is also served by the same nginx. So this line is the problem:
proxy_set_header Host $host;
The nginx variable $host is pointing to the current Host header (which matches the server_name). So if you set the same host header for the upstream again, then nginx will find the same location block above because nginx relies on the Host header to find the proper server. Thus the redirect loop.
Set
proxy_set_header Host your_upstream_server_name
will fix it then.

Resources