Camel rest - Allow specific ip to access send request - apache-camel

I have below camel rest route. Currently all the host is able to access this route using the URL exposed.
Is there anyway I can restrict remote host to access based on the IP configured.
I want to allow certain IP address to access this URL. Is there any configuration in camel available to handle this ?
rest("/api/")
.id("reset-api-route")
.get("/reset")
.to("direct:resetRoute");

With camel-netty4-http component you can have remote IP address in the headers.
However it might make more sense to make network level isolation on firewall before your application.
With camel-netty4-http you can inspect and do logic with remote IP like this:
#Override
public void configure() throws Exception {
restConfiguration()
.component("netty4-http")
.host("localhost")
.port(8000)
.bindingMode(RestBindingMode.auto);
rest("/api/")
.id("reset-api-route")
.get("/reset")
.to("direct:resetRoute");
from("direct:resetRoute")
.log("${in.headers.CamelNettyRemoteAddress}")
.choice()
.when(header("CamelNettyRemoteAddress").startsWith("/127.0.0.1:")) // localhost
.transform().constant("allowed").endChoice()
.otherwise()
.transform().constant("denied");
}
If your Camel application is running inside Spring-Boot then you can use Spring Security IP filtering. Also keep in mind that if your application is behind load balancer then depending on the load balancer you might always see the load balancer's address instead of the original caller.

Related

Requests NOT passing through Cloudflare's network?

From my understanding of Cloudflare - the service is supposed to act as a reverse proxy for your server/website. I have added my site to Cloudflare, assigned my nameservers to Cloudflare's nameservers, and have enabled my DNS records to be proxied. The issue I'm having is that requests sent to my site are NOT coming from Cloudflare? The requests are just coming from regular IP addresses. I can see the requests on Cloudflare's WAF event logger, but when the request gets to my actual site - it's just the persons IP address. How can I set it up to where all requests come directly from Cloudflare? I tried adding rules in my .htaccess to allow Cloudflare IPs, and block all other requests, but that just returns an HTTP 403 Forbidden error. Any ideas on what I may have messed up in my Cloudflare configuration, or how to fix this?
I tried adjusting firewall settings on the server, and various changes in .htaccess to force requests only from Cloudflare's network
I think you're mixing two things:
If you add your site to Cloudflare DNS, it will just reply to dns queries, but the traffic from each client will go directly to your site.
If you want Cloudflare to proxy all the traffic to your site, you should use something like Cloudflare tunnels.

Unable to access mule-worker external URL from clients network

I have a mule application deployed on cloudhub. My client is trying to trigger the mule-worker URL (http://mule-worker-appname.us-e2.cloudhub.io:8081) from his network (connecting to their VPN), but it is giving Timed Out error. However, when he tries to hit with SLB URL (http://appname.us-e2.cloudhub.io) he is getting the response.
When client disconnects his VPN then worker URL is also working.
Can someone explain why the worker url is not working where as SLB url is working? I thought worker external url is a public url and can be accessed, then why there is a restriction from their network? Is there some firewalls that client must be having?
When accessing the worker directly (ie using http(s)://mule-worker-myappname.region.cloudhub.io:port) you have to add explicitly the default HTTP (8081) or HTTPS (8082) ports to the request. Example: `http://mule-worker-testapp.us-e2.cloudhub.io:8081)
Also if in the VPC firewall those ports are blocked of access from anywhere (ie public Internet access) you may not be able to access.

How to secure connection between different GAEs?

For some reason I need to create two GAEs with project A and B:
A(flex env) is a proxy server bounded with Endpoint and restrict access with API key.
B(standard env) is real server which does real jobs.(B cannot apply Endpoint framework)
Client only awares proxy server address and send all requests to A
Now I would like to secure connection between A and B. In other words, B is only accessible from A. Is there any way to achieve it? (Firewall not work here because GAE has not static IP range.)
If you want to determine the identity of the App Engine app that is
making a request to your App Engine app, you can use the request
header X-Appengine-Inbound-Appid. This header is added to the request
by the URLFetch service and is not user modifiable, so it safely
indicates the requesting application's ID, if present.
In your application handler, you can check the incoming ID by reading
the X-Appengine-Inbound-Appid header and comparing it to a list of IDs
allowed to make requests.
Note: The X-Appengine-Inbound-Appid header is only set if the call is
made to the appspot.com domain. If the app has a custom domain, this
header will not be set.
https://cloud.google.com/appengine/docs/standard/go/appidentity/#asserting_identity_to_other_app_engine_apps
This should work the same for all App Engine standard environments.

Kubernetes and AAD authentication

On configured AKS there is docker container with application that is using AAD authentication.
Based on this article there is also configured ingress. API is working well.
When I add to Azure Active Directory application registration reply URL with https prefix I receive error "The reply url specified in the request does not match the reply urls configured for the application". And I see that in browser address line redirect_uri is starting with http.
When I add reply URL that is starting with http, then I receive "Exception: Correlation failed".
What I have tried: Add to ingress.yaml setting ingress.kubernetes.io/force-ssl-redirect: "true"
May be there is some way to force ingress run https instead of http, or there might be some AAD redirect configuration? Any ideas?
UPDATE 2: Probably http redirect is because of ADAL.
PS: Was able to find similar topic without an answer
UPDATE3:
I have decided not to use nginx as ingress. Instead I am using now Load balancer. Soon it would be possible to use Azure Application Gateway Ingress Controller
Have you tried this?
By default the controller redirects HTTP clients to the HTTPS port 443 using a 308 Permanent Redirect response if TLS is enabled for that Ingress.
This can be disabled globally using ssl-redirect: "false" in the NGINX config map, or per-Ingress with the nginx.ingress.kubernetes.io/ssl-redirect: "false" annotation in the particular resource.
More information on this on the Ingress documentation link.
You have to make a decision whether to use HTTPS or not. If this is just the start of a development cycle, start without it and get auth to work - but implement HTTPS as soon as possible.
AAD supports both http and https, but of course, the reply urls must be added to the application registration respectively.
As #mihail-stancescu says, ssl-redirect must be set to false, if you choose not to use HTTPS. In addition to this, you also have to ensure that your app does not make the redirect from HTTP to HTTPS.
Using curl with -L -k and -v options will give you a lot of information on what is actually happening with your requests.
When the http/https thing is solved, you have to remove any rewrite annotations you have in your ingress. (e.g. ingress.kubernetes.io/rewrite-target: / should be removed).
Now, if your ingress path to the service in question is e.g. /myservice, then the reply-url should also have that part of the path added ([host]/myservice/signin-oidc) - both in the AAD application registration and in the configuration of your app. (The path in the config should not contain the host)
If you are using https, then you must also have a proper certificate. You can use the free LetsEncrypt (https://letsencrypt.org/) in conjunction with KubeLego (https://github.com/jetstack/kube-lego), where you can find some nice examples on how to implement it.

Opensso with SSL Configuration issue in F5 Load Balancers

We are having a web application architecture where our application EAR is deployed in appServer configured with non-ssl Http Port Listener. Every request is routing via F5 Load Balancer-> Web Server-> App Server.
In Load Balancer, we have set an iRule where every Http Request is forwarded to Https set on port 443 and our application is working fine. Now we are trying to implement a SSO using OpenSSO federation solution and SAML Technology. we have deployed the opensso with the non-ssl http listener configuration in our app server.
now when we try to access the opensso using the url xhttp://domain_name/opensso(dummy protocol), it is redirected as per iRule set on the Load Balancer as xhttps://domain_name/opensso. But in the appearing configuration page of opensso, the server URL is populated as xhttp://domain_name only instead of xhttps://domain_name. Likewise, the same approach is followed to populate all the URL properties throughout the opensso configuration. So when I tried to generate the metadata using ssoadm GUI, In the form action attribute the url is formed as 'http' and the request method is passed as 'POST' only as per Opensso convention. But when it is redirected to 'https' as per the Load Balancer Rule the Request method is passed as 'GET' instead of post and the opensso validation fails and throwing the error as 'HTTP Post Protocol is required.
So the issue here is, By default the opensso URL properties should be populated with "https" instead of "http". I would like to know what is the wrong configuration done here. how we could resolve this issue? Thanks.
I think that you will find that the answer actually lies within your application server, not the application itself. You need to indicate to the servlet that it is being proxied, and that it is responsible for creating URLs with the HTTPS scheme, not HTTP.
If you're using Tomcat or a derivative, you can modify the server.xml to include the following:
proxyPort="443"
proxyName="www.domain_name.com"
scheme="https"
secure="true"
You can configure the load balancer to redirect to https with a 307 http status code which informs the client to use the original request method. If POST was the original request method then following the redirect the client will continue to use POST instead of a GET.
HTTP::respond 307 Location "https://[HTTP::host][HTTP::uri]"

Resources