
Using HAProxy as an API Gateway, Part 1 - phil21
https://www.haproxy.com/blog/using-haproxy-as-an-api-gateway-part-1/
======
tnolet
This is a great article and I love HAproxy. Even so much that I wrote a REST-
like wrapper for it a couple of years ago to turn HAproxy into an API gateway.
It touched many of the points in the article. Maybe useful for people in the
field [https://github.com/magneticio/vamp-
router](https://github.com/magneticio/vamp-router)

~~~
Natsu
Am I wrong, or is there still nothing that handles security in the API
Gateway?

For example, suppose you want to do OAuth in the gateway instead of building
it into every API. I couldn't see anything to handle a use case like that. The
best I see is that it can probably handle one-way SSL, but I'm not clear on
how it would handle mutual authentication or verification of client certs
(pinning, CRLs, or OCSP).

It's a lot of work to build that into APIs separately and a lot of people who
use API Gateways prefer to have the gateway itself handle security.

~~~
rzzzt
Kong does handle security in that layer:
[https://docs.konghq.com/0.14.x/auth/](https://docs.konghq.com/0.14.x/auth/)

~~~
dannyfriar82
im not sure Kong supports mtls or cert pinning.
[https://github.com/Kong/kong/issues/2048](https://github.com/Kong/kong/issues/2048)

i dont think it's able to hash your secret tokens either - rather stores them
in plaintext.
[https://github.com/Kong/kong/issues/1237](https://github.com/Kong/kong/issues/1237)

this kind of rules Kong out for any serious applications AFAIK - especially
considering that an API Gateway is supposed to be a security product.

istio, tyk, traefik support that out of box.

~~~
fosk
Marco, CTO of Kong here. Static mTLS has been supported since 3 years almost,
while dynamic mTLS is being supported with Kong 1.0 (required for Service
Mesh). Kong itself has been used in highly regulated industries, including
financial, healthcare and governmental (including military branches)
institutions.

When it comes to enforcing strong security OpenID Connect or JWT
authentications are almost always better options. Since Kong is built on top
of NGINX, anything NGINX supports by extension Kong also supports + Kong
Plugins.

~~~
geezerjay
> Kong itself has been used in highly regulated industries,

Was it used in any application that actually was covered by any regulation
enforcing authentication and authorization to the point that kong could
directly determine if an implementation does or does not comply with the
regulation?

Or was it simply used in highly regulated industries like car stickers are
used in the highly regulated auto industry?

~~~
fosk
> Was it used in any application that actually was covered by any regulation
> enforcing authentication and authorization to the point that kong could
> directly determine if an implementation does or does not comply with the
> regulation?

Yes. Kong Enterprise running on the execution path of in-flight information
across distributed and open systems must be audited in the context of enforced
regulations, especially banking and healthcare. We do work regularly with our
customers to make sure Kong is compliant within their specific use-case and
make those audits successful.

------
Erwin
Just how pluggable is HAProxy, or is there anything else out there which
allows higher async control over the routing?

My need is some rather customized request routing, currently done by Python
(fast enough to do thousands of RPS in just Python with PyPy) but it'd nice to
use a standard product.

For every incoming request, I want to decide where it gets routed on a per-
request basis to but not necessarily immediately (so some callback / event
based / out of process interface is needed) and I want to be notified when the
request finishes or fails.

Basically the request for /foo/bar may need to spawn a new foo-bar management
process which can take a while to warm up, and appear at some unknown future
destination.

I had a look at e.g. Traefik, Kong, Envoy but they didn't seem like quite the
right fit.

Using e.g. Proxygen seems like overkill.

~~~
caleblloyd
You can use the `auth_request` module in NGINX to create a subrequest to an
HTTP service that does authentication and/or dynamic routing.

The subrequest can return response headers that are available in
`$upstream_http_*` variables, which can br used to dynamically route the
original request.

[http://nginx.org/en/docs/http/ngx_http_auth_request_module.h...](http://nginx.org/en/docs/http/ngx_http_auth_request_module.html)

~~~
Erwin
Thanks, nginx looks promising, either through this lighter weight integration,
or by writing something similar with LUA and OpenResty/Kong.

------
bedis9
Hi,

I did write this blog post. Feel free to ask if you have any questions.

~~~
krn
An honest question: why HAProxy should be prefered over EnvoyProxy[1] for
building API Gateways?

[1] [https://www.envoyproxy.io/](https://www.envoyproxy.io/)

~~~
tonyarkles
Not the OP, but a young greybeard with opinions :)

I've set up a couple of API Gateways. One was a hand-rolled Go server; this
could have probably been done using an existing off-the-shelf server, but
there were some odd-ball requirements and it was pretty straightforward to
just build the functionality. It did service discovery through Consul, applied
some routing rules and the "special" logic, and that was about it.

Every other time I've just use nginx. Why? Most of the API Gateway projects
out in the wild are bloody complicated! I just looked at the docs for
EnvoyProxy and the "Architecture Overview" pane is taller than my 1080p
monitor! Yes, at massive scale with thousands of services, something like this
is probably the right solution. When you've got a handful of services, an
automated rolling deploy across a small cluster of nginx servers is A-OK.

I've looked at a bunch of different packages, and every time my conclusion is
that they introduce a massive amount of complexity that could be beneficial in
the large, but will likely require a dedicated team to understand all of the
intricacies of the whole system. KISS.

~~~
rdli
Envoy Proxy is pretty complex. It is really designed for machine
configuration. This is one reason projects like Ambassador API Gateway
([https://www.getambassador.io](https://www.getambassador.io)) exist -- it
translates decentralized declarative Kube config into Envoy configuration
(non-trivial exercise).

That said, Envoy has some great features such as distributed tracing, a robust
runtime API for dynamic configuration, gRPC load balancing, etc.

Disclosure: I work on Ambassador.

~~~
bedis9
All of this is on it's way. depending on what you mean by distributed tracing,
it may already be doable

------
unixhero
Can the open source version of HAProxy also be used to achieve what is
described in this tutorial?

~~~
gerdesj
Yes, I use all of those features and more. The built in stats are not as
pretty as those shown and you don't get graphs but you can obviously do your
own (and I do - the logs are very good)

~~~
bedis9
I could not have answered in a better way.

Just adding we love and do open source.

------
sf_barbary
I found it easier to create a centralized graphql server that stitches
together all of my rest services with resolvers. I define all of the types,
resolvers, and mutations for each of the services in the central graphql
gateway and it clients don't need to know where they get data from. Why
wouldn't you just use this approach?

~~~
yellow
The biggest problem with GraphQL in this regard is that it is a single
endpoint. API gateways often define authorization rules, throttling rates, and
caching times differently for each route. Consequently, you may need to write
authorization, throttling, and caching logic in a separate layer or perhaps
even in your microservices themselves.

------
fulafel
Piggybacking on this thread, what would currently be the most secure frontend
proxy? Preferably something that is implemented in a memory-safe language, and
has some credibile story about focus on security and being battle tested.

~~~
jively
[Caveat emptor: I’m the CEO of Tyk] Tyk is an open source API gateway written
in Go, it’s been battle tested in production PCI compliant environments and
offers a large selection of security features.

It’s also customisable in other languages other than Lua (Python, JS, and
anything gRPC) ;-)

~~~
rhymenoceros
How does Tyk compare with Kong and other "API gateway" implementations?

~~~
jively
Tyk and Kong are similar in terms of what they do, though with a Tyk we bake a
lot of key functionality into the core instead of asking the community to
build them for us.

We also don’t have the concept of proprietary plugins, so where Kong is “Open
Core” (for example if you want to use openID connect you need to buy
enterprise, with us it’s just par for the course), we bake everything gateway-
related into the open source version and don’t hide the ball. Our “value add”
is in our dashboard GUI (proprietary) and multi-cloud/multi-DC server (also
proprietary).

Also, in Tyk you can model your api routing as a file, with Kong you need to
specify all routes as API calls to the gateway, so backing up/version
controlling your APIs is difficult without using a community-provided
solution. (Though don’t get me wrong, both Tyk Gateway and Dashboard are
entirely API driven, so you can do everything programmatically or
declaratively).

Lastly - we have a compatability promise of “no breaking changes within major
versions”. It’s harder to do, but makes our users happy :-)

Ah, and in terms of extensibility, we provide middleware and event hooks that
can be hooked into with any gRPC compatible language and offer native binary
(FFI) Support in Python and Lua, we also have a baked in ECMAScript
interpreter which is fast (it’s written in Go), but being an interpreter
doesn’t have the expressiveness of some of the other extension options)

In terms of other implementations, in open source there’s not many thst have
quite the breadth of functionality we offer.

To be fair though, the other solutions out there (especially coming out of the
Go/K8s/CNCF communities are very impressive.

------
rubyn00bie
Anyone have any idea how using HAProxy compares to say Kong?

~~~
graphememes
I had to muck around a lot more to get HAProxy (2-3 days) do what I could do
with Kong out of the box (1-2 hours) and Kong was easier to scale for me
(simple terraform scripts).

------
rhymenoceros
Has HAProxy cleaned up their dynamic reload issues? I am a pretty big fan
having used HAProxy in production, but compared to the relative simplicity of
"nginx -s reload" the restart complexity of HAProxy always gives me pause.

~~~
rogerdonut
Hello, HAProxy 1.8 brought hitless reloads and has solved all of these issues.
You can find information on this here [1][2]

[1] [https://www.haproxy.com/blog/truly-seamless-reloads-with-
hap...](https://www.haproxy.com/blog/truly-seamless-reloads-with-haproxy-no-
more-hacks/)

[2] [https://www.haproxy.com/blog/hitless-reloads-with-haproxy-
ho...](https://www.haproxy.com/blog/hitless-reloads-with-haproxy-howto/)

~~~
rhymenoceros
This is an improvement but it still seems like HAProxy is offloading a small
(but annoying) amount of responsibility to users when handling restart
requests. You still have to track the existing process' PID and give it to the
new process, give the new process the same "-x [socket_file]" argument, and
make sure the new process comes up before making any subsequent changes to the
HAProxy config file.

Does HAProxy have any plans to wrap this process juggling to make things as
stupidly easy as nginx's reload behavior?

~~~
rogerdonut
The current method integrates with both init scripts and systemd. You
shouldn't need to manually pass any of that information. Also, the -x option
is not required if you are running HAProxy in master/worker mode in which case
sending a SIGUSR2 to the master process would be sufficient. With that said,
we do have further improvements planned for an upcoming release. Stay tuned :)

------
abledon
Why not just use Kong

