Don't allow direct calls to Microservices. Only allow through API Gateway
Asked Answered
B

5

28

Maybe this is a strange question (I'm new with Microservices). But I'm looking for some info on how proceed with this. Does not need to be Spring specific, but that's the framework I'm using at the moment.

Example: Lets say we have two Microservices

a) http://myurlfortesting.com:8085/api/rest/serviceone

b) http://myurlfortesting.com:8090/api/rest/servicetwo

and we have setup Spring Zuul (acting as the API Gateway) with the following rules that forward the incoming calls:

/rest/one -> http://myurlfortesting.com:8085/api/rest/serviceone

/rest/two -> http://myurlfortesting.com:8090/api/rest/servicetwo

The question... Is there a way to stop users from directly accessing the services mentioned in A and B (only allow the ones that come through the API Gateway)?

Can this be done with Springs Zuul (Acting as a API Gateway) by setting up some extra filters or do we set it up in Microservices endpoints?

Would even like to know if there is a way to not even processing the direct calls on the Microservices endpoints that don't come via the API Gateway.

Maybe this is solved with server specific rules and has nothing to do with Spring?

Many thanks,

/D

Bubonocele answered 21/12, 2016 at 12:20 Comment(5)
I would look into the firewall setup.Maternal
Are your Zuul endpoints running on another port on the server? Assuming that you have a firewall in place, you could restrict inbound traffic to server to the ports that your Zuul endpoints are exposed on and disallow anyone from accessing the microservices' ports directly.Lehmann
@RiaanNel Endpoints are running on another port on the server. Can this be done with some other way (without firewall) Programatically etc?Bubonocele
You could force the endpoints to check for a specific HTTP header or something that is set by Zuul prior to forwarding a request, but that would be hacky and easy to circumvent. Based on my past experiences, the "right" way would be to do this via a firewall. Your app should be responsible for dealing with requests. Your firewall should be responsible for deciding who can hit specific endpoints.Lehmann
@RiaanNel Could please add your comment as an "answer" so that I can pin this on you. Think you covered/verified my question. Thanks!Bubonocele
L
18

Assuming that you have a firewall in place, you could restrict inbound traffic to server to the ports that your Zuul endpoints are exposed on and disallow anyone from accessing the microservices' ports directly.

If you want to avoid going the firewall route, you could force the endpoints to check for a specific HTTP header or something that is set by Zuul prior to forwarding a request, but that would be hacky and easy to circumvent. Based on my past experiences, the "right" way would be to do this via a firewall. Your app should be responsible for dealing with requests. Your firewall should be responsible for deciding who can hit specific endpoints.

Lehmann answered 21/12, 2016 at 14:54 Comment(0)
C
11

Generally, such kind of situation are handled by implementing proper OAuth server wherein only your API gateway will handle the token validation. Any direct call to microservice will not have proper token exchange and hence requests will be aborted.

In case, you have deployed your micro-services on any cloud then you can acheive this by exposing routes to only API gateway. And yes, firewall blocking, IP whitelisting are some of the other ways in restricting the access to your microservices.

Clad answered 27/12, 2016 at 11:54 Comment(0)
N
6

Use a reverse proxy. We use Nginx for the same purpose. Api gateways should always be deployed behind a load balancer in production scenarios to avoid the gateway being a single point of failure(If it is not a managed service like AWS API gateway). Also, the gateway and services are deployed within a VPC and not visible to the public. enter image description here

November answered 10/4, 2019 at 10:51 Comment(2)
@MuizzMahdy "Also, the gateway and services are deployed in a VPC."November
Sorry, I have missed that.Bumble
S
2

Hey I finally find a solution to accept request just from the API Gateway by using microservices architecture, for that you can create a filter, and like Zuul act as a proxy, checking the header 'X-Forwarded-Host', if it doesn't match with the gateway service then return an Unauthorised exception.

public class CustomGatewayFilter extends GenericFilterBean {

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
        throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;

    String proxyForwardedHostHeader = request.getHeader("X-Forwarded-Host");

    if (proxyForwardedHostHeader == null || !proxyForwardedHostHeader.equals(GatewayConstant.getGatewayURL())) {
        UnauthorisedException unauthorisedException = new UnauthorisedException("Unauthorized Access",
                "Unauthorized Access, you should pass through the API gateway");
        byte[] responseToSend = restResponseBytes(unauthorisedException.getErrorResponse());
        ((HttpServletResponse) response).setHeader("Content-Type", "application/json");
        ((HttpServletResponse) response).setStatus(401);
        response.getOutputStream().write(responseToSend);
        return;
    }
    chain.doFilter(request, response);
}

private byte[] restResponseBytes(ErrorResponse errorResponse) throws IOException {
    String serialized = new ObjectMapper().writeValueAsString(errorResponse);
    return serialized.getBytes();
}

}

do not forget to add your custom filter in SpringSecurity Configuration

.and().addFilterBefore(new CustomGatewayFilter(), ConcurrentSessionFilter.class);
Sever answered 5/12, 2019 at 16:28 Comment(1)
Spoofing may break that. Its worth looking into: portswigger.net/web-security/host-header portswigger.net/web-security/host-header/exploitingPsalter
F
0

The right way to do this with AWS API Gateway would be with the recently launched 'VPC Link' integration, which secures the connection between API Gateway and your backend inside your VPC.

https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-api-gateway-supports-endpoint-integrations-with-private-vpcs/

Figurant answered 21/12, 2017 at 23:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.