pnxtech / hydra-router

A service aware router for Hydra Services. Implements an API Gateway and can route web socket messages.
MIT License
60 stars 26 forks source link

Support for private routes #111

Open cjus opened 7 years ago

cjus commented 7 years ago

There is a need to block internal service APIs from external access via Hydra-Router. I created this issue ticket to openly discuss options.

In Hydra-Express a set of routes is registered this way:

  hydraExpress.registerRoutes({
    '/v1/hello': require('./routes/hello-v1-routes')
  });

Given two routes /v1/hello/public and /v1/hello/private the goal would be to specify the latter as private and not allow access through the hydra-router. Services behind the router should still be able to access each others private routes.

Sebastiansch commented 7 years ago

Here's my solution, which we use for our "proxy/router" to serve microservices to external users. We have a config file which looks basically like

"demo" : { "type": "jwt", "password": "tryme", "routes": { "ac5-api": [ "[(.*)]/profile/application/setapplicanthash/(.*)" } }, "178.210.103.179": { "type": "ip", "routes": { } }, "public": { "type": "public", "routes": { "ac5-api": [ "[get]/profile/application/getapplicanthash/(.*)" ]

This allows us to define public routes, which can be used by everyone, or restricted routes, either restricted by ip address or by login authentification.

Since all "internal" services run in a port range, which is not accessible from outside, the only way to access any services is through the proxy itself and its checks

cjus commented 7 years ago

@Sebastiansch which proxy/router do you use?

Sebastiansch commented 7 years ago

We built a custom service since we had some issues getting the router running, and also needed some extra features like SSL and the auth stuff.

We're using hydra.getServiceNodes()/hydra.getAllServiceRoutes() to evaluate all running services and routes, and then apply our route matching and auth stuff, before passing the request to the service in question

khoinguyen commented 7 years ago

As we are working with microservice, one of the primary intention is to able to deploy only the service/services in concern.

Configure the proxy/router as per @Sebastiansch suggest also a solution, however, I think with that approach, we will need to re-configure proxy/router and of course re-test for that re-configure to see if it is affect any other services (strictly procedure if any)

I suggest that we should allow the service to re-configure himself, and the proxy/router should pickup from that. No manually re-configure at the proxy level.

Sebastiansch commented 7 years ago

Sounds also good, was also one of out thoughts. The reason why we included it in the router is that several customers (users in "auth") share different services. So its easier for us to define it at one place, instead of changing config for several microservices behind, when we setup or change a API user

jedsmithobd commented 7 years ago

Personally, I prefer keeping as much configuration out of the router/proxy as possible. If you put your logic determining what can and can't be shown there then you can't update a new microservice or change the routes on a microservice without updating it in the router as well.

I think something simple would be the way to go unless we need more granularity.

hydraExpress.registerRoutes({
  '/v1/hello': require('./routes/hello-v1-routes', 'private')
});
emadum commented 7 years ago

I think it'd be best to use middleware in the route handlers for this. The router could add a HTTP header like via to all the requests it proxies. The middleware could check for the presence of this header and return a 401 or 404 or whatever is appropriate.