haproxy limit access to root path for specific ip range, but allow from anywhere for specific subdirectory - haproxy

I'm using HA-Proxy version 1.8.19
I want to restrict access from external or allow access only for specific IP Range to my website https://testxy.com/, but want to allow access from anywhere to subfolder https://testxy.com/tempDownload/.
I tried it already with following:
http-request deny if { path -i -m beg / } !{ src 10.10.20.0/24 }
How can I do that?

http-request allow if { path_dir -i /tempDownload } { src 0.0.0.0/0 }
http-request allow if { path_dir -i /xy1 } { src 10.10.20.0/24 }
http-request allow if { path_dir -i /xy2 } { src 10.10.20.0/24 }
http-request deny if { path_dir -i -m beg / } !{ src 10.10.20.0/24 }
This solved my problem (if anyone else has the same question)

I would use the exact match instead of beg path
The -i is here also useless as there is no lower- or upper-case version of / ACL Flags
http-request deny if { path / } !{ src 10.10.20.0/24 }

Related

Cache Static Contents in HAProxy

Is there any suitable way for caching in HAProxy. I want to cache only the static files (css, js, images). So, my initial plan was to do something like below
backend app_backend
mode http
balance source
option httpchk GET /heartbeat
http-check expect status 200
http-request cache-use mycache if { path -i -m beg /html/ } || { path -i -m beg /css/ } || { path -i -m beg /favicon.ico } || { path -i -m beg /assets/ } || { path -i -m beg /images/ } || { path -i -m beg /js/ }
http-response cache-store mycache
option httpclose
But I don't see anything is getting cached in my Proxy server.
What am I doing wrong?

why nginx proxy_pass to sub directory is not working?

I am trying to do a proxy_pass to a subdirectory http://ms.server.com:8085/ms. So whenever anyone hit on http://ms.example.com' it should be redirected tohttp://ms.example.com/ms`. I am trying to do that through below configuration
upstream example {
server ms.server.com:8085;
}
server {
server_name ms.example.com;
location / {
proxy_pass http://example/ms;
}
}
Now I am redirecting to "Nginx Test page".
proxy_pass is used to inform Nginx where to send proxied requests at a host level, and does not account for the URI.
What you want to use instead is a return statement, like so:
upstream example {
server ms.server.com:8085;
}
server {
server_name ms.example.com;
location = / {
return 301 http://ms.example.com/ms;
}
location / {
proxy_pass http://example;
}
}
This will redirect requests to the root URL of the server_name http://ms.example.com using a 301 redirect, and all other traffic will be passed through to the defined upstream.

nginx redirection depending on host

I have two domains website1.com and website2.com linked to my server.
I'm trying to do the following rewrite rules:
http://website1.com/ --> /website1/ (static)
http://website2.com/ --> /website2/ (static)
http://website1.com/app/ --> http://localhost:8080/web-app/web1/
http://website2.com/app/ --> http://localhost:8080/web-app/web2/
The user will be redirected to a static website served by nginx or an application server depending on the url.
Here's what I tried so far:
location / {
root html;
index index.html index.htm;
if ($http_host = website1.com) {
rewrite / /website1/index.html break;
rewrite (.*) /website1/$1;
}
if ($http_host = website2.com) {
#same logic
}
}
location /app/ {
proxy_pass http://localhost:8080/web-app/;
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 ($http_host = website1.com) {
rewrite /app/(.*) /$1 break;
rewrite /app /index.html;
}
if ($http_host = website2.com) {
#same logic
}
}
The static part seems to work fine, but the redirection web app part seems to serve index.html no matter what the requested file is.
This is not much of a definitive answer, but rather just my explanation of how I get nginx proxies to work.
root html;
index index.html index.htm;
server {
listen 80;
server_name website1.com;
location / {
alias html/website1;
}
location /app/ {
proxy_pass http://localhost:8080/web-app/web1/
}
}
server {
listen 80;
server_name website2.com;
location / {
alias html/website2;
}
location /app/ {
proxy_pass http://localhost:8080/web-app/web2/
}
}
The issue looks like it's being caused by these rewrites:
rewrite /app/(.*) /$1 break;
rewrite /app /index.html;
Using server blocks with server_names and the alias directive, we can do away with needing to use that much logic. Let me know if there's anything that is still not clear.
I think you're doing it wrong. If there is so much difference between the hosts, it would be cleaner and more efficient to have two distinct configurations, one for each host.
On the other hand, if your intention is to have multiple almost-identical configurations, then the correct way to go about it might be map, and not if.
Back to your configuration — I've tried running it just to see how it works, and one thing that you may notice is that the path you specify within the proxy_pass effectively becomes a noop once the $host-specific rewrite within the same context gets involved to change the $uri — this is by design, and is very clearly documented within http://nginx.org/r/proxy_pass ("When the URI is changed inside a proxied location using the rewrite directive").
So, in fact, using the following configuration does appear to adhere to your spec:
%curl -H "Host: host1.example.com" "localhost:4935/app/"
host1.example.com/web-app/web1/
%curl -H "Host: host2.example.com" "localhost:4935/app/"
host2.example.com/web-app/web2/
%curl -H "Host: example.com" "localhost:4935/app/"
example.com/web-app/
Here's the config I've used:
server {
listen [::]:4935;
default_type text/plain;
location / {
return 200 howdy;
}
location /app/ {
proxy_set_header Host $host;
proxy_pass http://localhost:4936/web-app/;#path is NOOP if $uri get changed
if ($host = host1.example.com) {
rewrite /app/(.*) /web-app/web1/$1 break;
rewrite /app /web-app/index.html;
}
if ($host = host2.example.com) {
rewrite /app/(.*) /web-app/web2/$1 break;
rewrite /app /web-app/index.html;
}
}
}
server {
listen [::]:4936;
return 200 $host$request_uri\n;
}

nginx conditional redirects rules

I have such a task:
http://www.realtyadvisorselite.com/homes-for-sale/skokie
to redirect permanently to
http://www.realtyadvisorselite.com/residential/homes-for-sale/skokie
another words add "residential" subfolder if it is missing from url
I have such server blocks in nginx.conf
server {
listen 80;
server_name realtyadvisorselite.com;
return 301 http://www.realtyadvisorselite.com$request_uri;
}
server {
listen 80;
server_name www.realtyadvisorselite.com;
location / {
proxy_pass http://repar;
}
}
Sorry, seems like a simple task but I cannot understand nginx regexp approach... Thank you!
You question implies that it is a single URL that requires redirection. So a simple option is to use an exact match location and a return statement:
location = /homes-for-sale/skokie {
return 301 /residential/homes-for-sale/skokie;
}
If you wanted all URIs that begin with /homes-for-sale to be prefixed with /residential, you could use a prefix location and a return statement:
location ^~ /homes-for-sale/ {
return 301 /residential$request_uri;
}
See this document for more.

How to redirect a specific path to the same path without www in nginx

I've encountered an issue during server configuration: I require a 301 redirect from http://www.example.com to http://example.com just for one specific url alias - like /partners.
the expected output- http:// www.example.com/partners/stuff -> http:// example.com/partners/stuff.
I've tried adding the following code to the vhosts already:
server {
server_name http://www.example.com/partners;
return 301 $scheme://example.com/partners;
}
but vhosts gives me an error telling me this code isn't valid.
What's the correct way of implementing such rewrite?
server_name is for domain only. I can suggest you 2 solutions.
Copy configs between servers. This is the best solution recommended by nginx's author.
server {
server_name example.com;
include example.com.conf;
}
server {
server_name www.example.com;
include example.com.conf;
location /partners/ {
return 301 $scheme://example.com$request_uri;
}
}
Or using if. Bad solution due performance
server {
server_name .example.com;
...
location /partners/ {
if ($host = "www.example.com") {
return 301 $scheme://example.com$request_uri;
}
}
}
http://wiki.nginx.org/IfIsEvil
http://wiki.nginx.org/Pitfalls#Server_Name