问题
On my debian 10 system I do the follwing as user "joerg":
joerg@h2257088:~/temporary/play$ export NODE_PATH=myOwnNodePath
joerg@h2257088:~/temporary/play$ node
Welcome to Node.js v12.20.0.
Type ".help" for more information.
> module.paths
[
'/home/joerg/temporary/play/repl/node_modules',
'/home/joerg/temporary/play/node_modules',
'/home/joerg/temporary/node_modules',
'/home/joerg/node_modules',
'/home/node_modules',
'/node_modules',
'/usr/lib/node'
]
>
Doing the same as user "root" gives:
root@h2257088:/home/joerg/temporary/play# export NODE_PATH=myOwnNodePath
root@h2257088:/home/joerg/temporary/play# node
Welcome to Node.js v12.20.0.
Type ".help" for more information.
> module.paths
[
'/home/joerg/temporary/play/repl/node_modules',
'/home/joerg/temporary/play/node_modules',
'/home/joerg/temporary/node_modules',
'/home/joerg/node_modules',
'/home/node_modules',
'/node_modules',
'myOwnNodePath',
'/root/.node_modules',
'/root/.node_libraries',
'/usr/lib/node'
]
>
Here I have three additional entries (which, by the way I want to have (with the obvious change of "/root" to "/home/joerg")):
'myOwnNodePath',
'/root/.node_modules',
'/root/.node_libraries',
What is defining the content of module.paths in a nodejs environment? What can I do, to get the missing entries?
This question is related to (the not answered) question: NODE_PATH has no effect on module.paths or finding modules.
EDIT:
After an
apt-get purge -y nodejs
apt-get install -y nodejs
it works. That is: Identical for both users root and joerg, with the behaviour formerly appearing for root only and hence, as I want to have it. This solves my principal problem, but does not answer the question.
回答1:
This is actually not a configuration issue. Instead there is some dynamics in putting entries into the module.paths array. On Unix (not on Windows), if the node binary should be treated securely, certain entries stemming from unsecure environment variables are not included in the module.paths array.
More precisely, if the node binary has set-user-ID or set-group-ID or has capabilities, the entries stemming from the environment variables HOME and NODE_PATH will not be included in the module.paths array, which are exactly the three entries mentioned as missing by the question.
To solve my problem I will copy the node binary so that I have two: node for "normal" execution (running javascript scripts) and nodeServer, which will get the capabilities (to use low port numbers), for execution as an http-server.
Even more precisely, if the AT_SECURE entry of the auxiliary vector has a non-zero value (see man getauxval), the three entries
$NODE_MODULES
$HOME/.node_modules
$HOME/.node_libraries
are not included. To quote man getauxval:
Most commonly, a nonzero value of AT_SECURE indicates that the process is executing a set-user-ID or set-group-ID binary (so that its real and effective UIDs or GIDs differ from one another), or that it gained capabilities by executing a binary file that has capabilities. Alternatively, a nonzero value may be triggered by a Linux Security Module.
After reinstalling node the capabilities are not longer set, which explains the observation in the EDIT of the question. Re-doing the
setcap CAP_NET_BIND_SERVICE=+eip /usr/bin/node
will re-introduce the unwanted behaviour.
Evidence comes out of the source for node (version 12 because this is what I use):
In lib/internal/modules/cjs/loader.js:
Module._initPaths = function() {
const homeDir = isWindows ? process.env.USERPROFILE : safeGetenv('HOME');
const nodePath = isWindows ? process.env.NODE_PATH : safeGetenv('NODE_PATH');
...
In src/node_credentials.cc:
bool SafeGetenv(const char* key, std::string* text, Environment* env) {
#if !defined(__CloudABI__) && !defined(_WIN32)
if (per_process::linux_at_secure || getuid() != geteuid() ||
getgid() != getegid())
goto fail;
#endif
...
And in src/node_main.cc:
#if defined(__linux__)
char** envp = environ;
while (*envp++ != nullptr) {}
Elf_auxv_t* auxv = reinterpret_cast<Elf_auxv_t*>(envp);
for (; auxv->a_type != AT_NULL; auxv++) {
if (auxv->a_type == AT_SECURE) {
node::per_process::linux_at_secure = auxv->a_un.a_val;
break;
}
}
#endif
来源:https://stackoverflow.com/questions/65532425/how-to-configure-the-content-of-module-paths-in-a-nodejs-environment