Nginx rewrite with proxy_pass - nginx

I recently have a requirement in Nginx to rewrite a URL and then forward this onto to another backend server to a dynamic proxy pass address. I've tried a few things but have not had much luck at the moment. For example, this is the kind of setup I have in my nginx.conf file:
server {
listen 443;
server_name scheduler.domain-name;
rewrite ^scheduler(.*)/(.*)/(.*) $2$1$3; # scheduler.domain.local/changepass/report?target=service
...
location / {
proxy_pass $to-rewrite-address:9443; # changepass.domain.local/report?target=service
...
}
Essentially, I just need to use a re-written URL variable to forward the request on a different port but can't seen to get this to work.
I've done quite a bit of searching but haven't found the solution to this as of yet, though I understand that the DNS resolver has to be set when using a proxy pass variable (Dynamic proxy_pass to $var with nginx 1.0).
Grateful if anyone could advise on how the above could be achieved, many thanks.

Assuming your endpoint would always be specified as the first part of your URI, here is an example of configuration that should work:
server {
listen 443;
server_name scheduler.domain-name;
resolver <your resolver for domain.local>;
...
location ~ ^/(?<endpoint>changepass|endpoint2|endpoint3|...)(?<route>/.*) {
proxy_pass http://$endpoint.domain.local:9443$route;
}
}
I'm using named capturing groups here for a better readibility, this location block is equal to
location ~ ^/(changepass|endpoint2|endpoint3|...)(/.*) {
proxy_pass http://$1.domain.local:9443$2;
}
I'm not sure if query arguments would be preserved with such a construction, if they won't, change
proxy_pass http://$endpoint.domain.local:9443$route;
to
proxy_pass http://$endpoint.domain.local:9443$route$is_args$args;

Related

Nginx pass_proxy with variables

I'm having trouble making nginx proxy an url with variable to a service within kubernetes.
Url looks like this:
http://localhost/user?username=Dave
I expect this url to take me to a subpage /user, which will read ?username=Dave and then fetch data from a database. However this takes me to the home page of the application(/ instead of /user) and does not read the variable even though url includes /user?username=Dave.
My current nginx config file looks like this:
server {
listen 0.0.0.0:80;
server_name localhost;
location / {
proxy_pass http://${FLASK_APP}:8080/;
}
location /user {
proxy_pass http://${GO_APP}:8000/;
}
}
I have read that location /user will match the url I'm passing. What is wrong with it? Or do I need to add something to proxy_pass http://${GO_APP}:8000/; or location /user?
As noted in the comments, the issue arises because you are using a variable in the proxy_pass target. As also noted in the comments, this question is related. As the answer referencing the docs states:
A special case is using variables in the proxy_pass statement: The
requested URL is not used and you are fully responsible to construct
the target URL yourself.
This means that you either need to use a static proxy_pass target, such as
// note that I added the forward slash
location /user/ {
proxy_pass http://destination:8000/;
}
Or as an alternative, I believe you can do it this way also
location /user/ {
proxy_pass http://${GO_APP}:8000/user$is_args$args;
}

Nginx reverse-proxy based on requested URL

I'd like to configure my nginx as reverse-proxy which will allow me such things:
requests like:
test.xxx.dev.example.com -> xxx.domain.dev.example.com
test.yyy.dev.example.com -> yyy.domain.dev.example.com
My current config:
server_name ~^test/.(?<app>\w+)\.dev\.example\.com
location / {
proxy_pass http://$app.domain.dev.example.com/;
}
I'm getting 502 error. Logs say: no resolver defined to resolve .domain.dev.example.com :( Any help?
Edit1: When added resolver 127.0.0.11 (this is docker-compose based env), error "no resolver defined to resolve..." disappears, but new one appear:
.domain.dev.example.com could not be resolved, host not found. It seems like for some reasons, variable $app is not passed to proxy_pass directive. Any idea ?
Well, It seems like the problem was with resolver and wrong regex. Below config works as expected for me:
resolver 127.0.0.11;
server {
listen 80;
server_name ~^test\.(?<app>.+)\.dev\.example\.com$;
location / {
proxy_pass http://$app.domain.dev.example.com$url;
}
}
#Richard in my regex, I'm declaring variable and value :) this is done by "?<'app>" where app is variable name.
Thanks for all the hints and help!

Deploying multiple Go applications using Nginx

The are two web applications (websites) written on Go. One is turalasgar.pro (here I am using Go built-in server). Another is engossip.com (for now it displays the same ip as former). I have a vps. I know I should use Nginx, but have no idea how? I have heard of Caddy. Please, I need only nginx server, not Caddy. What I need is run two (or more) applications by using my same vps. How should I configure Nginx configuration? Whether by listening to different ports or to the same port. Practical advices and examples highly appreciated.
It's called reverse proxy. Each application uses it's own port to listen. And then you just point to them in nginx config:
server {
listen 80;
server_name turalasgar.pro;
location / {
proxy_pass http://localhost:8080;
...
}
}
server {
listen 80;
server_name engossip.com;
location / {
proxy_pass http://localhost:8081;
...
}
}
Well is really easy.
follow this guide:
https://www.digitalocean.com/community/tutorials/how-to-use-martini-to-serve-go-applications-behind-an-nginx-server-on-ubuntu
After you achieved one application working with martini+nginx just add another server block for the other app.
In case you need more information about server blocks:
https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-14-04-lts
Above solutions I tried but didn't work for me
https://gist.github.com/soheilhy/8b94347ff8336d971ad0
server {
listen ...;
...
location / {
proxy_pass http://127.0.0.1:8080;
}
location /blog {
rewrite ^/blog(.*) /$1 break;
proxy_pass http://127.0.0.1:8181;
}
location /mail {
rewrite ^/mail(.*) /$1 break;
proxy_pass http://127.0.0.1:8282;
}
...
}

Nginx: how to add /something to a uri and still keep it working

I have a nginx instance running. My config is something like the following.
server {
listen 80;
listen 443;
location / {
...
proxy_pass http://127.0.0.1:8080;
...
proxy_redirect http://127.0.0.1:8080 example.com;
}
}
I have some software running in 8080 and I want that the user enters example.com/somepath and be able to be redirected to the root 127.0.0.1:8080 through my domain. The software should receive all urls without /somepath but the browser should still show /somepath in the name.
I am quite new so sorry for the basic question I could not find any relevant info on how to do this exactly: I tried rewrite rules and setting location /mysoftware { tests with no luck.
The client browser uses /somepath/... to access /...in the application. This means that nginx must rewrite the URI before passing it upstream.
The proxy_pass directive has a basic rewrite capability. See this document for details. For example:
location /somepath/ {
proxy_pass http://127.0.0.1:8080/;
...
}
Alternatively, you might use a rewrite ... break statement. See this document for details. For example:
location /somepath {
rewrite ^/somepath/?(.*)$ /$1 break;
proxy_pass http://127.0.0.1:8080;
...
}
The difficult part is preventing your application from breaking out of /somepath. The proxy_redirect directive can handle the 3xx responses from your application. But the location of resource files (.css and .js) and the target for hyperlinks, can cause problems for applications that are not aware that they need to stay inside a subdirectory.

nginx redirect twice from https to http

i have 2 servers, one has ssl and i config it like this,
in the server with SSL certification(which is https:// www.example.com):
location ~^/abc/.* {
proxy_pass http://www.example.com:8214/
}
in another server(which is http:// www.anotherExample.com):
server {
listen 8214;
server_name www.anotherExample.com;
rewrite ^/(.*)$ http://www.anotherExample.com:8080/$1 permanent;
}
and after access https:// www.example.com/abc/api/getGroup
it can't redirect to http:// www.anotherExample.com:8080/api/getGroup
Anything wrong???
There are a couple of things you could do to improve your configuration.
location ^~ /abc/ {
proxy_pass http://www.example.com:8214$uri;
#You should have other directives set here as well.
}
Also, consider setting up an upstream.
Then, for your server block:
server{
listen 8124;
server_name www.anotherExample.com;
rewrite ^/abc/(.*)$ http://www.anotherExample.com:8080/$1 permanent;
}
server{
listen 8080;
server_name www.anotherExample.com;
location ^~ /api/ {
#your_config_here
}
}
The explanation:
In your first location block, you shouldn't have .* in the expression. Nginx will match this for you. Then, when you're proxying, you can explicitly tell Nginx to send the URI as well.
Next, you're sending the URI www.anotherExample.com:8124, which includes /abc/, so you want to extract everything after that.
Lastly, because you've rewritten it to point to 8080 port, you'll need to define a separate server block for this.
I don't know what you're aiming to achieve, but so much proxying and redirects isn't necessary in most cases, and might lead to poor performance. Another consideration that you should take into account is you're sending unencrypted information to anotherExample.com, which, if not on the same local network, might be a security vulnerability.

Resources