RFC: Node.js® 4.x support
This issue is intended to describe the current challenges around supporting Node.js 4.x in the nodejs-buildpack
, and introduces several potential tracks of work, along with the Buildpack PM's preferred solution.
The Challenge
Node.js 4.x depends on openssl 1.0.2
OpenSSL is not infrequently updated in response to security vulnerabilities (CVEs), and as such the Buildpacks team has been dynamically linking the Node binaries against the rootfs openssl library. This allows applications to be patched with a rootfs update (i.e., applications don't need to be restaged).
The cflinuxfs2
rootfs packages Debian's openssl
v1.0.1, which is the version depended upon by Node 0.12.x and earlier.
As of Node 4.x, though, the dependency is on openssl 1.0.2. We've opened a Github Issue reporting this as a bug, but have not made much progress in convincing the Node core team to support openssl 1.0.1.
The Proposal
Full explanation and context are below, but in short the proposal is:
nodejs-buildpack
would ship binaries for node 4.x that statically link the vendored openssl 1.0.2; with the downside that openssl patches will require app restaging.
- Based on usage and feedback, we may decide later to maintain openssl 1.0.2 on the cflinuxfs2 rootfs; but would defer this decision for now.
What We've Tried So Far
Compile against openssl 1.0.2 and dynamically link against 1.0.1
We attempted to take advantage of the ABI backwards-compatibility between 1.0.2 and 1.0.1 by compiling against the former, then dynamically loading the latter.
Unsurprisingly, this didn't work, as Node 4.x is actually using new methods corresponding to new features in openssl 1.0.2.
Install openssl 1.0.2 into cflinuxfs2
We attempted to install 1.0.2 from upstream (backported) Ubuntu Wily on the same system as 1.0.1, but unfortunately the .deb packages clobber each other, as they have the same package name: openssl
.
Remaining Possible Solutions
Introduce a wily-based stack
wily
ships with openssl 1.0.2, and so we could introduce a new stack based on this Ubuntu distribution.
This is an extraordinarily heavyweight solution, which I'm extremely hesitant to even suggest, given an absence of compelling reasons to introduce this level of complexity to the product.
Let's pretend I didn't even bring this up.
Maintain our own openssl 1.0.2 for dynamic linking
We could build our own CF-specific openssl 1.0.2 package to install alongside the rootfs's openssl 1.0.1.
Pros:
- This isn't totally crazy,
- and would allow us to continue to patch applications via rootfs updates (not restaging)
Cons:
- This is a little bit crazy.
- It would add complexity to our build system,
- and would take a significant upfront investment to make sure it was done right and automated properly,
- to add support for an interpreter that we're not yet sure anyone actually wants to use.
Statically link the Node-vendored openssl 1.0.2
The final option is to follow the Node team's advice, and just take the Node-vendored openssl 1.0.2 as it is, and statically link it into the interpreter binary.
This solution requires the Node team make prompt releases after openssl vulnerabilities. The 0.12.x (and previous) release cycles were not great, but the io.js team running the release cycle for 3.x and 4.x appear to really have their act together, making nearly-weekly feature and bugfix releases.
Pros:
- Very little work for the Buildpacks team,
- allowing us to ship something and validate the need for Node 4.x support.
Cons:
- Restaging would be required to patch apps for future openssl CVEs.
- Requires relying on the Node team for prompt updates.
Related Issues
Worth noting that this bug filed against node 0.12.x is related, in that the stock openssl 1.0.1.f shipped with Ubuntu Trusty doesn't contain an upstream patch that is applied in the vendored openssl (1.0.1.k, it looks like) in the 0.12.x official build.
In Summary, or, How You Can Help
Given the fact that I've seen very little demand for Node 4.x support, I hereby propose to choose the most expedient solution, "Statically Link v1.0.2", in order to be able to quickly validate whether CF users actually even care about Node 4.
If we see real demand for production Node 4.x support, either in this ticket or after we implement static linking of v1.0.2, then I'm open to moving to the "Maintain Our Own Dynamically Linked Openssl v1.0.2" solution.
How You Can Help
Comment on this issue.
If you want to see Node 4.x support, let us know!
If you prefer one solution or the other, let us know!
If you have any other ideas on how to accomplish our goal of Node 4.x support, let us know!