Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Compiling node with FIPS #2666

Closed
D4V3M0NK opened this issue May 1, 2020 · 22 comments
Closed

Compiling node with FIPS #2666

D4V3M0NK opened this issue May 1, 2020 · 22 comments

Comments

@D4V3M0NK
Copy link

D4V3M0NK commented May 1, 2020

  • Node.js Version: 12.x
  • OS: Ubuntu 18.04.04-FIPS
  • Scope (install, code, runtime, meta, other?): compile
  • Module (and version) (if relevant):OpenSSL 1.1.1

I'm attempting to compile node (12.x) on Ubuntu 18 with the recently certified OpenSSL module and when running ./configure --openssl-fips=/usr/include/openssl, I get the immediate error message

ERROR: FIPS is not supported in this version of Node.js

From #753 I was under the impression that compilation is possible if I had the FIPS libraries installed on a FIPS enabled kernel (which Bionic now is, as of 4/29/20). Am I sadly mistaken? Maybe moving to a later version of node would help? I used git clone -b v12.x..., which I presume is 12.16.3

Can someone give me some guidance please?

@addaleax
Copy link
Member

addaleax commented May 1, 2020

@nodejs/crypto

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 1, 2020 via email

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 1, 2020

I've read the OpenSSL strategy document and noted that only node v6 and v8 are currently FIPS compatible (with openssl 1.0.2) so I tried Ubuntu 16 (with OpenSSL FIPS enabled) and attempted to build v8 but that fails too (fipsld not found) ...

Any thoughts or pointers would be appreciated.

@richardlau
Copy link
Member

By default Node.js will statically compile and use the version of OpenSSL in deps/openssl. You probably want to be using --shared-openssl to link to your system OpenSSL and possibly also --openssl-is-fips based on nodejs/build#2176.

If it helps, I also cloned 13.14.0 and didn't get the same error, but did get the following:

Traceback (most recent call last): File "./configure", line 19, in from distutils.spawn import find_executable ModuleNotFoundError: No module named 'distutils.spawn'

You're running into nodejs/node#30189.

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 1, 2020

@richardlau thank you sir, that's great information right there.

So, I've gone ahead and just used ./configure --shared-openssl --openssl-is-fips which didn't throw any errors. Unfortunately, when I then used make -j4 I get:

g++ -o /home/vroot/node/out/Release/obj.target/v8_initializers/gen/torque-output-root/torque-generated/../../deps/v8/src/builtins/boolean-tq-csa.o /home/vroot/node/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/builtins/boolean-tq-csa.cc '-DV8_GYP_BUILD' '-DV8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64' '-D__STDC_FORMAT_MACROS' '-DV8_TARGET_ARCH_X64' '-DV8_EMBEDDER_STRING="-node.35"' '-DENABLE_DISASSEMBLER' '-DV8_PROMISE_INTERNAL_FIELD_COUNT=1' '-DENABLE_MINOR_MC' '-DV8_INTL_SUPPORT' '-DV8_USE_SNAPSHOT' '-DV8_CONCURRENT_MARKING' '-DV8_ENABLE_LAZY_SOURCE_POSITIONS' '-DV8_EMBEDDED_BUILTINS' '-DV8_USE_SIPHASH' '-DDISABLE_UNTRUSTED_CODE_MITIGATIONS' '-DV8_WIN64_UNWINDING_INFO' '-DV8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH' '-DUCONFIG_NO_SERVICE=1' '-DU_ENABLE_DYLOAD=0' '-DU_STATIC_IMPLEMENTATION=1' '-DU_HAVE_STD_STRING=1' '-DUCONFIG_NO_BREAK_ITERATION=0' -I../deps/v8 -I../deps/v8/include -I/home/vroot/node/out/Release/obj/gen/torque-output-root -I/home/vroot/node/out/Release/obj/gen/generate-bytecode-output-root -I../deps/icu-small/source/i18n -I../deps/icu-small/source/common -pthread -Wno-unused-parameter -m64 -Wno-return-type -fno-strict-aliasing -m64 -O3 -fno-omit-frame-pointer -fdata-sections -ffunction-sections -O3 -fno-rtti -fno-exceptions -std=gnu++1y -MMD -MF /home/vroot/node/out/Release/.deps//home/vroot/node/out/Release/obj.target/v8_initializers/gen/torque-output-root/torque-generated/../../deps/v8/src/builtins/boolean-tq-csa.o.d.raw -c
g++: internal compiler error: Segmentation fault (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See file:///usr/share/doc/gcc-7/README.Bugs for instructions.
tools/v8_gypfiles/v8_initializers.target.mk:277: recipe for target '/home/vroot/node/out/Release/obj.target/v8_initializers/gen/torque-output-root/torque-generated/../../deps/v8/src/builtins/array-join-tq-csa.o' failed
make[1]: *** [/home/vroot/node/out/Release/obj.target/v8_initializers/gen/torque-output-root/torque-generated/../../deps/v8/src/builtins/array-join-tq-csa.o] Error 4
make[1]: *** Waiting for unfinished jobs....
rm f90ccfe7a7f845b6f884909c43e9e3b9ac6d7143.intermediate 5ca5cf426f079a4f9aefe0df7ceef13a311b13d1.intermediate
Makefile:101: recipe for target 'node' failed
make: *** [node] Error 2

Forgive me, I'm not a programmer and not sure where I should go from here...

  • node 12.x
  • Ubuntu 18.04.04
  • OpenSSL 1.1.1
  • gcc/g++ version 7.5.0
  • clang v6.0.0
  • python 2.7.17
  • python3 3.6.9

@richardlau
Copy link
Member

g++: internal compiler error: Segmentation fault (program cc1plus)

Sorry, I don't know why the compiler appears to have crashed. We use g++ 6.3 in our CI, so your version of g++ should be compatible.

@sam-github
Copy link

I usually see compilers crashing due to lack of memory, I'd give that a check.

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 1, 2020

@sam-github Thanks Sam, I bumped up my VM to 4GB and the crashing has been resolved!
I also read #30189 (thank you @richardlau) and have installed python3-distutils ... but now running into this issue ...

g++ -o /home/vroot/node/out/Release/obj.target/libnode/gen/src/node/inspector/protocol/NodeRuntime.o /home/vroot/node/out/Release/obj/gen/src/node/inspector/protocol/NodeRuntime.cpp '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D__STDC_FORMAT_MACROS' '-DNODE_ARCH="x64"' '-DNODE_PLATFORM="linux"' '-DNODE_WANT_INTERNALS=1' '-DV8_DEPRECATION_WARNINGS=1' '-DNODE_OPENSSL_SYSTEM_CERT_PATH=""' '-DHAVE_INSPECTOR=1' '-DNODE_REPORT' '-D__POSIX__' '-DNODE_USE_V8_PLATFORM=1' '-DNODE_HAVE_I18N_SUPPORT=1' '-DNODE_HAVE_SMALL_ICU=1' '-DHAVE_OPENSSL=1' '-DNODE_FIPS_MODE' '-DUCONFIG_NO_SERVICE=1' '-DU_ENABLE_DYLOAD=0' '-DU_STATIC_IMPLEMENTATION=1' '-DU_HAVE_STD_STRING=1' '-DUCONFIG_NO_BREAK_ITERATION=0' '-DHTTP_PARSER_STRICT=0' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D_POSIX_C_SOURCE=200112' '-DNGHTTP2_STATICLIB' -I../src -I/home/vroot/node/out/Release/obj/gen -I/home/vroot/node/out/Release/obj/gen/include -I/home/vroot/node/out/Release/obj/gen/src -I../deps/histogram/src -I../deps/uvwasi/include -I../deps/v8/include -I../deps/icu-small/source/i18n -I../deps/icu-small/source/common -I../deps/zlib -I../deps/http_parser -I../deps/llhttp/include -I../deps/cares/include -I../deps/uv/include -I../deps/nghttp2/lib/includes -I../deps/brotli/c/include -Wall -Wextra -Wno-unused-parameter -pthread -Wall -Wextra -Wno-unused-parameter -m64 -O3 -fno-omit-frame-pointer -fno-rtti -fno-exceptions -std=gnu++1y -MMD -MF /home/vroot/node/out/Release/.deps//home/vroot/node/out/Release/obj.target/libnode/gen/src/node/inspector/protocol/NodeRuntime.o.d.raw -c
In file included from /usr/include/openssl/x509.h:25:0,
from /usr/include/openssl/ssl.h:20,
from ../src/node_crypto.h:37,
from ../src/node_crypto.cc:22:
../src/node_crypto.cc: In member function ‘virtual bool node::crypto::RSAPSSKeyPairGenerationConfig::Configure(const EVPKeyCtxPointer&)’:
../src/node_crypto.cc:5980:11: error: ‘EVP_PKEY_OP_TYPE_KEYGEN’ was not declared in this scope
if (EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx.get(), md_) <= 0)
^
../src/node_crypto.cc:5980:11: note: suggested alternative: ‘EVP_PKEY_OP_TYPE_NOGEN’
../src/node_crypto.cc: In function ‘void node::crypto::InitCryptoOnce()’:
../src/node_crypto.cc:6602:5: error: ‘OPENSSL_INIT_set_config_filename’ was not declared in this scope
OPENSSL_INIT_set_config_filename(settings, conf);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/node_crypto.cc:6602:5: note: suggested alternative: ‘OPENSSL_INIT_set_config_appname’
OPENSSL_INIT_set_config_filename(settings, conf);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OPENSSL_INIT_set_config_appname
libnode.target.mk:343: recipe for target '/home/vroot/node/out/Release/obj.target/libnode/src/node_crypto.o' failed
make[1]: *** [/home/vroot/node/out/Release/obj.target/libnode/src/node_crypto.o] Error 1
rm 1a4e6e23cad64e56f9d834ea3a7580ebfed0e450.intermediate f90ccfe7a7f845b6f884909c43e9e3b9ac6d7143.intermediate 5ca5cf426f079a4f9aefe0df7ceef13a311b13d1.intermediate 9239e8d3a43a11988c6aac88f3eb3ed499c5e40f.intermediate
Makefile:101: recipe for target 'node' failed
make: *** [node] Error 2

I'm trying to work out if this is a V8 issue or an OpenSSL configuration issue?

@sam-github
Copy link

https://github.com/nodejs/TSC/blob/master/OpenSSL-Strategy.md

fips isn't supported for node 10 and later.

see https://wiki.openssl.org/index.php/FIPS_module_2.0

Maybe if you build that, then build node 12 against it, it might work but I don't expect so. I've never done it, and its not supported, but YMMV.

Your compile above failed because whatever you are building against doesn't have an openssl 1.1.1 compatible API, I'm not sure why.

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 1, 2020

From what I can see, I'm wondering if shared-openssl-includes should be set, referring to the folder that contains the openssl conf.h file? Would that make sense?

Um ... 30mins later ... nope, it wasn't that...

@sam-github : thanks for your continued responses - perhaps I'll try node 8 and see how well that works ...

@sam-github
Copy link

It at least was supported on Node.js 8. Not that Node.js or openssl of that vintage is supported, but the feature at least existed.

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 1, 2020

Ok, so cloning v8.x compiled with --shared-openssl --shared-openssl-includes= successfully compiles!! After following up with make install and node -v I get 8.17.1-pre. This is a significant move forward.

The last thing I need to understand is why "make -j4 binary" (as was mentioned in #753) bails out on me... stating that

#NODE_VERSION_IS_RELEASE is set to 0.
Did you remember to update src/node_version.h?
Makefile:766: recipe for target 'release-only' failed
make: *** [release-only] Error 1

Am I going to screw anything up if I change node_version.h and set #define NODE_VERSION_IS_RELEASE from 0 to 1 in order to get a binary, so that I can use that binary on another (like) system?

@bnoordhuis
Copy link
Member

Should be fine. The only thing it controls is whether process.version includes -pre (for prerelease) in the string.

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 4, 2020

I'm going to close this issue as of right now - thank you for all your help @richardlau and @sam-github for pointers in the right direction. I'm going to post the commands I used to get this going (binary works too):

  1. Use with Ubuntu 16.04.6, with the certified 1.0.2g OpenSSL Crypto Module configured and operating in FIPS mode
    1. $ uname -r shows "fips" as does $ openssl version
  2. git clone -b v8.x https://github.com/nodejs/node.git
    1. this pulls the "latest" version of Node that is FIPS supported, currently 8.
  3. cd node
  4. ./configure --shared-openssl --shared-openssl-includes=/usr/include/openssl
  5. If a binary build is required ...
    1. Edit src/node_header.h and alter NODE_VERSION_IS_RELEASE from 0 to 1
    2. Save the file
    3. Commit the file
    4. make -j4 binary
  6. ... otherwise, simply
    1. make -j4
    2. make -j4 install

@D4V3M0NK D4V3M0NK closed this as completed May 4, 2020
@D4V3M0NK D4V3M0NK reopened this May 4, 2020
@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 4, 2020

Ah ... jumped a little too early I think. So I've compiled to a binary and then moved this onto another identical system. Expanded the binaries out (as per the wiki) and whilst everything looks just fine, when I run npm version I get a rather interesting response when it comes to openssl:

{ npm: '6.13.4',
ares: '1.10.1-DEV',
cldr: '32.0',
http_parser: '2.8.0',
icu: '60.1',
modules: '57',
napi: '4',
nghttp2: '1.39.2',
node: '8.17.1',
openssl: '1.0.2s',
tz: '2017c',
unicode: '10.0',
uv: '1.23.2',
v8: '6.2.414.78',
zlib: '1.2.11' }

That OpenSSL version should read, IMHO, 1.0.2g should it not - the same version that my system has, the same version of the certified FIPS Crypto Module?!

@richardlau
Copy link
Member

@D4V3M0NK If you run make binary the Makefile reruns configure: https://github.com/nodejs/node/blob/39ff64756bd5bc7147236b36ee9444ceddb3e6d2/Makefile#L1167-L1172

You can pass in extra flags via the CONFIG_FLAGS Makefile variable.

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 4, 2020

@richardlau ... oh that's mighty good to know! Will let you know how I get on...

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 5, 2020

@richardlau : you sir, are a gentleman and a scholar - that was the last piece of the puzzle! OpenSSL 1.0.2g-fips listed in npm version! I can't put down in words just how efficient everyone has been in assisting me in this process. I can't thank you all enough...
For historical purposes, I shall place the final build solution as below:

  1. Use with Ubuntu 16.04.6, with the certified 1.0.2g OpenSSL Crypto Module configured and operating in FIPS mode
    1. $ uname -r shows "fips" as does $ openssl version
  2. git clone -b v8.x https://github.com/nodejs/node.git
    1. this pulls the "latest" version of Node that is FIPS supported, currently 8.
  3. cd node
  4. ./configure --shared-openssl --shared-openssl-includes=/usr/include/openssl
  5. If a binary build is required ...
    1. Edit src/node_header.h and alter NODE_VERSION_IS_RELEASE from 0 to 1
    2. Save the file
    3. Commit the file
    4. CONFIG_FLAGS=--shared-openssl --shared-openssl-includes=/usr/include/openssl make -j4 binary
    5. Once created, place the binary on a (like) system and then install according to the wiki
  6. ... otherwise, simply
    1. make -j4
    2. make -j4 install

@D4V3M0NK D4V3M0NK closed this as completed May 5, 2020
@f33losopher
Copy link

@D4V3M0NK when you do uname -r, where do you see FIPS? Is it kernel-name, nodename, etc...

@D4V3M0NK
Copy link
Author

D4V3M0NK commented May 18, 2021

kernel-name and openssl version

@hoanghua
Copy link

hoanghua commented Dec 19, 2021

@D4V3M0NK thank you for the summary of the steps. I've followed the same step and can make it built successfully with Node 8. However, as Node 8 is already end of support in 2020. I'm trying to build with Node 16; however, I faced with a similar error you've posted above

../src/crypto/crypto_util.cc: In function ‘void node::crypto::InitCryptoOnce()’: ../src/crypto/crypto_util.cc:135:5: error: ‘OPENSSL_INIT_set_config_filename’ was not declared in this scope OPENSSL_INIT_set_config_filename(settings, conf); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../src/crypto/crypto_util.cc:135:5: note: suggested alternative: ‘OPENSSL_INIT_set_config_appname’ OPENSSL_INIT_set_config_filename(settings, conf); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OPENSSL_INIT_set_config_appname In file included from ../src/crypto/crypto_util.h:19:0, from ../src/crypto/crypto_keys.h:6, from ../src/crypto/crypto_cipher.h:6, from ../src/crypto/crypto_rsa.h:6, from ../src/crypto/crypto_rsa.cc:1: ../src/crypto/crypto_rsa.cc: In static member function ‘static node::crypto::EVPKeyCtxPointer node::crypto::RsaKeyGenTraits::Setup(node::crypto::RsaKeyPairGenConfig*)’: ../src/crypto/crypto_rsa.cc:62:9: error: ‘EVP_PKEY_OP_TYPE_KEYGEN’ was not declared in this scope EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx.get(), params->params.md) <= 0) { ^ ../src/crypto/crypto_rsa.cc:62:9: note: suggested alternative: ‘EVP_PKEY_OP_TYPE_NOGEN’ ../src/crypto/crypto_rsa.cc: In function ‘v8::Maybe<bool> node::crypto::GetRsaKeyDetail(node::Environment*, std::shared_ptr<node::crypto::KeyObjectData>, v8::Local<v8::Object>)’: ../src/crypto/crypto_rsa.cc:583:36: error: ‘RSA_get0_pss_params’ was not declared in this scope const RSA_PSS_PARAMS* params = RSA_get0_pss_params(rsa); ^~~~~~~~~~~~~~~~~~~ ../src/crypto/crypto_rsa.cc:583:36: note: suggested alternative: ‘RSA_get0_crt_params’ const RSA_PSS_PARAMS* params = RSA_get0_pss_params(rsa); ^~~~~~~~~~~~~~~~~~~ RSA_get0_crt_params libnode.target.mk:372: recipe for target '/home/ubuntu/hoang/node-v16.13.0/out/Release/obj.target/libnode/src/crypto/crypto_util.o' failed make[1]: *** [/home/ubuntu/hoang/node-v16.13.0/out/Release/obj.target/libnode/src/crypto/crypto_util.o] Error 1 make[1]: *** Waiting for unfinished jobs.... libnode.target.mk:372: recipe for target '/home/ubuntu/hoang/node-v16.13.0/out/Release/obj.target/libnode/src/crypto/crypto_rsa.o' failed make[1]: *** [/home/ubuntu/hoang/node-v16.13.0/out/Release/obj.target/libnode/src/crypto/crypto_rsa.o] Error 1 rm 58f0bb9d673dc8524358464081636a66d0200c83.intermediate 45cfe825109e2d0b854e6101f9e73c16f3f88057.intermediate Makefile:110: recipe for target 'node' failed make: *** [node] Error 2

May I ask if you've been able to pass this error in the past? Or you have to switch to Node 8 to overcome that?

@D4V3M0NK
Copy link
Author

Until the newer version of OpenSSL (FIPS) is released, I had to resort to sticking with Node8 as that was the last version that worked with OpenSSL.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants