

Bud – A TLS terminating proxy - indutny
https://github.com/indutny/bud

======
nailer
Love bud! Fedor does a massive amount of the work on node's TLS
implementation. I recently remarked to him that that bud's OCSP code would be
better as a separate module - merely as a suggestion - and the next thing I
knew [https://www.npmjs.com/package/ocsp](https://www.npmjs.com/package/ocsp)
was released.

bud is one of the few node based TLS terminators and easily the best
maintained. Modulus (the hosting company) use a Go based implementation. I
think Nodejitsu had a node TLS terminator too but I'm not sure what happened
to it post-GoDaddy.

------
Animats
If you're running a release build with asserts turned off, and the connection
uses SPDY, and the length of the domain name of the host is in the valid range
of 245-253 bytes, then it looks like you can overwrite the stack at line 158
of xforward.c, at

    
    
        memcpy(frame + 12, client->remote.host, client->remote.host_len);
    

It's 2015. One should not be hand-coding string manipulation at the pointer
level.

~~~
indutny
Wow, thank you very much for this! Doing a release right now.

~~~
indutny
Wait a second, this is not domain name. This is an IP address, it is 46 bytes
maximum. Thanks for posting this, but I don't see any issue with this.

~~~
vardump
Well, you should still range check it. If someone manages to [un]intentionally
corrupt bud_client_s.remote.(unsigned int)host_len, it's not secure, it will
become a stack overwrite.

Defensive programming like that is a very good idea especially for something
network facing.

If you're sure it's always at most 46 bytes, make it 48 bytes and specify
"#define BUD_MAX_HOST_IP_LEN (48)".

Very secure and compiler will probably replace those memcpys with a few SSE
[1] instructions, because 48 is a multiply of 16.

Copying 48 bytes is always _much faster_ than copying 1 byte with a dynamic
length argument for memcpy.

[1]: Like 6x MOVDQU instructions. Probably interleaved with the rest of the
code to hide latency.

~~~
indutny
Great feedback! I wonder if you might be interested in contributing this to
bud? This thing will be very valuable addition!

~~~
vardump
Writing networking code in C/C++ is very stressful, for safety and security
reasons. I write enough safety critical C/C++ at my day job.

If bud was my own pet project, I'd write it in Golang, which is great for
networking code. The software I've written so far in Golang has been rock
solid, with practically zero defects, in addition to being very understandable
and readable code _for other people_. I wish I could say same of C/C++...

Or maybe in Rust to get a better hang of it. I think Rust will eventually
capture a lot of C/C++'s "market share". It should be feasible to write
firmware, operating systems and device drivers in Rust.

------
jorangreef
The author of Bud is Fedor Indutny who won the CloudFlare Heartbleed Challenge
([https://blog.cloudflare.com/the-results-of-the-cloudflare-
ch...](https://blog.cloudflare.com/the-results-of-the-cloudflare-challenge/)).

------
eropple
Is there a feature-based reason to use this over HAProxy or nginx, or is this
a "it's written in Node" thing?

~~~
indutny
There are lots of features:

* Asynchronous SNI - you may load cert/key pairs on the fly and let bud know which backend do you want it to connect the incoming client to

* Asynchronous OCSP stapling

* TLS ticket rotation, with possibility to scale to the big cluster

* x-forward frame for SPDY, and soon for HTTP/2 too

* Lots of other features, but nothing bud-specific

~~~
eropple
On-the-fly key pairs is a really nice thing (HAProxy does require a short
period of downtime while restarting)--I'll have to check this out. Thanks.

------
sanxiyn
Name clash with [https://github.com/bloom-lang/bud](https://github.com/bloom-
lang/bud) is unfortunate.

