Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Bud – A TLS terminating proxy (github.com/indutny)
42 points by indutny on June 9, 2015 | hide | past | favorite | 16 comments


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 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.


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.


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


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.


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.


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


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.


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

True, although that was building a binary message, not exactly a string.

"frame" should have probably been a (packed) struct instead of "unsigned char frame[256];".


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


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


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


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.


> is this a "it's written in Node" thing?

Bud is written in C, not Node. It uses NPM for cross-platform packaging, but that is optional.

> Is there a feature-based reason to use this over HAProxy or nginx,

It can be useful to have SSL termination be in its own process to isolate OpenSSL from other parts of your internal system like HTTP routing/request handling. For instance, in cases where you have explicit security requirements like FIPS 140-2.


> Bud is written in C, not Node. It uses NPM for cross-platform packaging, but that is optional.

Got it, thanks.

> It can be useful to have SSL termination be in its own process to isolate OpenSSL from other parts of your internal system like HTTP routing/request handling. For instance, in cases where you have explicit security requirements like FIPS 140-2.

Sure. I run two HAProxy instances for that, though.


I think it would almost certainly be the latter. I can't imagine it's more performant or more secure than the likes of HAProxy or Pound


Name clash with https://github.com/bloom-lang/bud is unfortunate.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: