Restrict SOAP calls using Nginx Reverse Proxy - soap

We have a Nginx server configured for reverse proxying to protect an aging SOAP server that can't be patched.
I've been asked to restrict what calls clients can make from specific IP ranges.
I've no idea how to allow some SOAP calls but filter out others.
The Nginux config is
server {
listen 443;
listen [::]:443;
server_name shiny.nginx.server;
ssl on;
ssl_certificate "/public/directory/proxy.pem";
ssl_certificate_key "/secret/directory/proxy.key";
location / {
proxy_pass http://very.old.server:80/;
proxy_buffering off;
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;
auth_basic "Username and Password Required";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
Any ideas how I achieve this?
Thanks

I'v found a solution to this.
server {
listen 443;
listen [::]:443;
server_name shiny.nginx.server;
ssl on;
ssl_certificate "/public/directory/proxy.pem";
ssl_certificate_key "/secret/directory/proxy.key";
location / {
proxy_pass http://very.old.server:80/;
proxy_buffering off;
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;
auth_basic "Username and Password Required";
auth_basic_user_file /etc/nginx/.htpasswd;
if ($remote_addr ~ 192.168.1.1) {
set $is_user Y;
}
if ($http_soapaction ~ SOAP/Request/Goes/Here) {
set $user_allowed Y;
}
set $user_test "${is_user}${user_allowed}";
if ($user_test = YY) {
set $good yes;
}
if ($good != yes) {
return 403;
}
}
Not being able to do nested or complex tests made it a bit tricky...

Related

Artifactory docker registry docker image

I am playing around with the 4.13 version of artifactory using the pro-registry docker image
I created a virtual docker repo and a local docker repo as suggested in the doc and changed the nginx conf as follows
log into the running container
sudo docker exec -i -t containerID# /bin/bash
vi /etc/nginx/conf.d/default.conf
ssl_certificate /etc/nginx/ssl/demo.pem;
ssl_certificate_key /etc/nginx/ssl/demo.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;
server {
listen 80;
listen 443 ssl;
client_max_body_size 2048M;
location / {
proxy_set_header Host $host;
proxy_pass http://localhost:8081/artifactory/;
proxy_read_timeout 90;
}
access_log /var/log/nginx/access.log upstreamlog;
location /basic_status {
stub_status on;
allow all;
}
}
## Sub domain config for docker repository
server {
listen 443 ssl;
listen 80 ;
server_name my-docker-virtual.art.local art.local;
if ($http_x_forwarded_proto = '') {
set $http_x_forwarded_proto $scheme;
}
## Application specific logs
access_log /var/log/nginx/docker-access.log;
error_log /var/log/nginx/docker-error.log;
rewrite ^/(v1|v2)/(.*) /artifactory/api/docker/my-docker-virtual/$1/$2;
client_max_body_size 0;
chunked_transfer_encoding on;
location /artifactory/ {
proxy_read_timeout 900;
proxy_pass_header Server;
proxy_cookie_path ~*^/.* /;
proxy_pass http://artifactory_lb/artifactory/
proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port/artifactory;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
This works great I can do the following
docker login my-docker-virtual.art.local
user
pass
email
docker push my-docker-virtual.art.local/busybox
docker pull busybox
However when I change the nginx o the following
ssl_certificate /etc/nginx/ssl/demo.pem;
ssl_certificate_key /etc/nginx/ssl/demo.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;
server {
listen 80;
listen 443 ssl;
client_max_body_size 2048M;
location / {
proxy_set_header Host $host;
proxy_pass http://localhost:8081/artifactory/;
proxy_read_timeout 90;
}
access_log /var/log/nginx/access.log upstreamlog;
location /basic_status {
stub_status on;
allow all;
}
}
## Sub domain config for docker repository
server {
listen 443 ssl;
listen 80 ;
server_name my-docker-virtual.art.local art.local;
if ($http_x_forwarded_proto = '') {
set $http_x_forwarded_proto $scheme;
}
## Application specific logs
access_log /var/log/nginx/docker-access.log;
error_log /var/log/nginx/docker-error.log;
rewrite ^/(v1|v2)/(.*) /artifactory/api/docker/wrong-docker-virtual/$1/$2;
client_max_body_size 0;
chunked_transfer_encoding on;
location /artifactory/ {
proxy_read_timeout 900;
proxy_pass_header Server;
proxy_cookie_path ~*^/.* /;
proxy_pass http://localhost:8081/artifactory/
proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port/artifactory;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
after this I reload the config
Everything still works which it should not, the redirect should fail. Shouldnt it?
Note that I am using the self signed cert that comes with the docker image
So I had to do a service nginx restart in order to see these changes reflected

How to change request_uri in nginx proxy_pass?

I am running a django application through gunicorn via unix socket and I have my nginx configuration which looks like this :
Current NGINX config File :
upstream django_app_server {
server unix:/django/run/gunicorn.sock fail_timeout=0;
}
server{
listen 80;
server_name demo.mysite.com;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://django_app_server;
break;
}
}
}
so my django is running on a unix socket here , lets say if it was running on localhost then it has a url which looks like :
http://127.0.0.1:8000/demo/app1
http://127.0.0.1:8000/demo/notifications
Main goal
so what i want to do is , when someone visit http://demo.mysite.com/app1 they can access via proxy pass the url : http://127.0.0.1:8000/demo/app1
It would have been really easy if i would be running django on localhost tcp port and i could have easy done this and it would have worked for me :
server{
listen 80;
server_name demo.mysite.com;
location / {
proxy_pass http://127.0.0.1:8000/demo/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
How do i achieve this with my current nginx configurtion ?
One approach is to use rewrite ... break, for example:
location / {
try_files $uri #proxy;
}
location #proxy {
rewrite ^ /demo$uri break;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://django_app_server;
}
See this document for details.

Nginx HTTP to HTTPS redirect loop

I have the folloiwng Nginx configuration:
server {
listen 80;
server_name .example.net .example.com;
return 301 https://example.com$request_uri;
}
server {
listen 80;
server_name beta.example.com;
error_page 403 /403;
error_page 404 /404;
error_page 500 /500;
client_max_body_size 5M;
# Handle all locations
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/cert_chain.crt;
ssl_certificate_key /etc/ssl/csr.pem;
server_name example.com;
error_page 403 /403;
error_page 404 /404;
error_page 500 /500;
client_max_body_size 5M;
location / {
proxy_pass http://127.0.0.1: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;
}
}
I'm wanting to redirect HTTP requests to HTTPS however I get a redirect loop. I've read other answers on different questions including this one and this one however none of their solutions solved mine. Any ideas? Thanks.
It seems like your backend (running on 127.0.0.1:8000) issues Location: http://example.com/ header.
Please look into the access logs, nginx's and backend's too.
Or use httpliveheaders or tcpdump to investigate the traffic.

Nginx Reverse Proxy Redirect Issues

I have been struggling with this for some time now. My reverse proxy install essentially looks like this:
global_nginx: http://192.168.115.200/client1/ => docker_nginx: http://localhost:8877/ => docker_app: http://app:8080/
Reverse proxy is working fine, but I have trouble when my app is sending redirects. Essentially the app itself is just a Spring MVC application that redirects as following:
#Controller
public class Ctrl {
#RequestMapping(value = { "/" })
public String redir() {
return "redirect:home";
}
}
The result is that when I browse http://192.168.115.200/client1/ I am redirected to: http://192.168.115.200/home/ but should be redirected to http://192.168.115.200/client1/home/
This is the global_nginx conf:
location /client1 {
proxy_pass http://localhost:8877/.;
proxy_redirect http://localhost:8877/ /;
port_in_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
And this is my docker_nginx conf:
location / {
proxy_pass http://app:8080/;
proxy_redirect http://app:8080/ /;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
You need to add the /client1 prefix in your proxy_redirect directive.
Maybe:
proxy_redirect http://$host:8877/ /client1/;
You can have more than one proxy_redirect directive, if you need to match multiple conditions. See this document for details.

Nginx: dynamic proxy from url to subdomain

I'm trying to write a nginx conf to dynamically redirect a url to a webapp, based on the uri. I use proxypass directive.
For example, I want redirect http://www.example.com/clientname/ to http://clientname.internaldomain.local/webapp
So far, I only succeded replacing new host, but the uri is broken because I can't split it. (Now I can't even replace the host, dunno why ...)
Here is my actual non working conf:
server {
resolver 192.168.137.71;
listen 80;
server_name tomservpa1;
location ~ (^\/(.*)\/) {
set $ccehost $2;
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-Real-IP $remote_addr;
proxy_pass http://$ccehost.internaldomain.local:9780/webapp/$new_request_uri;
proxy_redirect off;
proxy_set_header Host $host;
}
}
Did someone already do something like that ?
Thanks.
You can use named captures in the location directive is avoid scope and ambiguity issues. For example:
location ~ ^/(?<ccehost>[^/]+)/(?<new_request_uri>.*)$ {
rewrite ^ /webapp/$new_request_uri break;
...
proxy_pass http://$ccehost.internaldomain.local:9780;
...
}
this is the way to do it: (set in production)
location ~* ^/(?<ccehost>.*)/(.*) {
proxy_intercept_errors on;
proxy_cookie_path ~*^/.* /;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_pass http://$ccehost.app.ptf:8080/app/$2;
}