Examine individual changes

From Gentoo Wiki
Abuse Filter navigation (Home | Recent filter changes | Examine past edits | Abuse log)
Jump to:navigation Jump to:search

This page allows you to examine the variables generated by the Abuse Filter for an individual change, and test it against filters.

Variables generated for this change

VariableValue
Edit count of the user (user_editcount)
338
Name of the user account (user_name)
'Vitaly-zdanevich'
Age of the user account (user_age)
215201670
Page ID (page_id)
134804
Page namespace (page_namespace)
0
Page title (without namespace) (page_title)
'Node.js'
Full page title (page_prefixedtitle)
'Node.js'
Action (action)
'edit'
Edit summary/reason (summary)
'/* npm */ add about what to do for installing of packages to ~/.local'
Old content model (old_content_model)
'wikitext'
New content model (new_content_model)
'wikitext'
Old page wikitext, before the edit (old_wikitext)
'{{Stub}} {{InfoBox stack |{{InfoBox homepage|https://nodejs.org/en|header=true}} |{{InfoBox odoc|https://nodejs.org/en/docs}} |{{InfoBox wikipedia|Node.js}} |{{InfoBox github|nodejs/node}} |{{InfoBox irc|#node.js}} |{{InfoBox blog|https://nodejs.org/en/blog}} }} '''Node.js''' is a [[Article description::cross platform, open source, JavaScript server environment]]. == Installation == === USE flags === {{USEflag|package=net-libs/nodejs}} === npm === Node.js has a [[USE_flag|USE flag]] to include npm, the Node.js package manager. {{c|npm}} is necessary to install a Node.js application's dependencies, which are defined in a file named <tt>package.json</tt>. The USE can be disabled if {{c|npm}} is not necessary locally, or prefer to only install an alternative, for example, {{Package|sys-apps/yarn}}. You will receive error if try to install a package from NPM globaly - [https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677 see this about how to install NPM packages to your home directory] - for safe coliving for Portage. == Standalone Node.js server == {{Warning| Node.js and Express.js suggest to run Node.js behind a '''reverse proxy''' to mitigate '''DoS attacks''' and improve '''performance'''. <ref>https://nodejs.org/en/learn/getting-started/security-best-practices</ref><ref>https://expressjs.com/en/advanced/best-practice-security.html</ref><ref>https://expressjs.com/en/advanced/best-practice-performance.html</ref> This section goes against these recommendations and even includes an example of using Node.js itself as a reverse proxy. Not following these recommendations is allowed if the server will not be public. With caution, the methods provided here can be used for small homelab projects. It is also important to understand that reverse proxies are not a panacea. They may contain vulnerabilities that could lead to the execution of arbitrary code (e.g. {{Bug|CVE-2021-23017}}) or root privilege escalation (e.g. {{Bug|CVE-2016-1247}}). Not using reverse proxies limits the attack vector to Node.js only. }} Node.js can be run as a standalone HTTP server. It does not require root privileges and can be accessed from the Internet, for example on port 3000. To launch the [https://nodejs.org/en/learn/getting-started/introduction-to-nodejs official example], the <code>hostname</code> (a variable in the example) must be set to a public IPv6 or IPv4 address (<code>localhost</code> will not work). The modified example can be executed from the user space as following: {{Cmd|node modified-downloaded-example.js}} The only problem is the inability to connect to [[Wikipedia:List_of_TCP_and_UDP_port_numbers#Well-known_ports|well-known ports]] (e.g. 80) from unprivileged user space. But this problem can be solved with {{Link|#Port redirection|port redirection}}. === SELinux policy === {{Warning| The policy provided in this section is created using <code>audit2allow</code>. Review the policy before using it. }} As of March 26, 2024, the Node.js package does not come with a {{Link|SELinux}} policy, so creating a custom policy is required. The following custom policy assumes that Node.js will be executed from unprivileged user space. The policy was tested with Nodejs v. 20.6.1 on the <code>default/linux/arm64/17.0/musl/hardened/selinux</code> profile. {{FileBox|filename=nodejs-workaround.te|1= module nodejs-workaround 1.0; require { type unreserved_port_t; type ntop_port_t; type node_t; type user_t; class process execmem; class tcp_socket { name_bind node_bind }; } #============= user_t ============== #!!!! This avc can be allowed using the boolean 'user_tcp_server' allow user_t node_t:tcp_socket node_bind; allow user_t ntop_port_t:tcp_socket name_bind; #!!!! This avc can be allowed using the boolean 'allow_execmem' allow user_t self:process execmem; allow user_t unreserved_port_t:tcp_socket name_bind; }} {{Important| Delete the following lines if there are no plans to use Node.js on ports other than <code>3000</code>: <code>type unreserved_port_t;</code> and <code>allow user_t unreserved_port_t:tcp_socket name_bind;</code> }} To compile and install the policy module, run the commands: {{RootCmd|make -f /usr/share/selinux/strict/include/Makefile nodejs-workaround.pp|semodule --install nodejs-workaround.pp}} Node.js should immediately become functional. To remove the policy, run the command: {{RootCmd|semodule --remove nodejs-workaround}} The policy is created based on the following AVC: {{RootCmd|collapse-output=true|cat /var/log/audit/audit.log|output=<pre> audit: type=1400 audit(1710592438.060:241): avc: denied { execmem } for pid=1795 comm="node" scontext=user_u:user_r:user_t tcontext=user_u:user_r:user_t tclass=process permissive=0 audit: type=1400 audit(1710592130.148:234): avc: denied { name_bind } for pid=1705 comm="node" src=3005 scontext=user_u:user_r:user_t tcontext=system_u:object_r:unreserved_port_t tclass=tcp_socket permissive=0 audit: type=1400 audit(1710592738.512:259): avc: denied { node_bind } for pid=1877 comm="node" saddr=7777:777:7777:7777::1 src=3004 scontext=user_u:user_r:user_t tcontext=system_u:object_r:node_t tclass=tcp_socket permissive=0 audit: type=1400 audit(1710592851.496:274): avc: denied { name_bind } for pid=1920 comm="node" src=3000 scontext=user_u:user_r:user_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 </pre> }} Other AVC messages caused by Node.js are also present (and will be present after policy definition) in the log. But they do not affect the use of Node.js. The above messages are the only ones that cause Node.js to fail. === Port redirection === This section describes a way to redirect ports using the legacy {{Link|iptables}} approach or the modern {{Link|nftables}} approach. Choose one. ==== iptables ==== The redirection requires the following option to be enabled in the kernel: {{KernelBox|title=Enable redirections|1= [*] Networking support ---> --- Networking support Networking options ---> [*] Network packet filtering framework (Netfilter) ---> --- Network packet filtering framework (Netfilter) Core Netfilter Configuration ---> [*] REDIRECT target support }} {{Important|The examples below assume that the server is running on a public IPv6 address. For an IPv4 address use <code>iptables</code> instead of <code>ip6tables</code>, the syntax is the same. IPv4 and IPv6 have separate NAT tables.}} Assuming the Node.js server is running on port 3000, run the following command to redirect port 80 to 3000: {{RootCmd|ip6tables --table nat --append PREROUTING --protocol tcp --dport 80 --jump REDIRECT --to-port 3000}} The server should be immediately accessible via port 80. {{Note| The created rule will disappear after a reboot. }} To see the modified NAT table, run the command: {{RootCmd|collapse-output=true|ip6tables --table nat --list|output=<pre> Chain PREROUTING (policy ACCEPT) target prot opt source destination REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 3000 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination </pre>}} To remove the added rule (to change the port or because of a mistake), run the command: {{Important|Make sure the rule is the first (<code>1</code>) in the <code>PREROUTING</code> chain, otherwise specify the correct number.}} {{RootCmd|ip6tables --table nat --delete PREROUTING 1}} ==== nftables ==== The redirection requires the following options to be enabled in the kernel: {{KernelBox|title=Enable redirections|1= [*] Networking support ---> --- Networking support Networking options ---> [*] Network packet filtering framework (Netfilter) ---> --- Network packet filtering framework (Netfilter) Core Netfilter Configuration ---> [*] Netfilter nf_tables support [*] Netfilter nf_tables redirect support [*] Netfilter nf_tables nat module }} {{KernelBox|title=IPv6|1= [*] Networking support ---> --- Networking support Networking options ---> [*] Network packet filtering framework (Netfilter) ---> --- Network packet filtering framework (Netfilter) IPv6: Netfilter Configuration ---> [*] IPv6 nf_tables support }} {{KernelBox|title=IPv4|1= [*] Networking support ---> --- Networking support Networking options ---> [*] Network packet filtering framework (Netfilter) ---> --- Network packet filtering framework (Netfilter) IP: Netfilter Configuration ---> [*] IPv4 nf_tables support }} {{Important|The examples below assume that the server is running on a public IPv6 address. For an IPv4 address use <code>inet</code> or <code>ip</code> instead of <code>ip6</code>}} Create the NAT table and chain: {{RootCmd|nft add table ip6 nat|nft add chain ip6 nat prerouting '{ type nat hook prerouting priority 0; }'}} Redirect port <code>80</code> to port <code>3000</code>: {{RootCmd|nft add rule ip6 nat prerouting tcp dport 80 counter redirect to 3000}} The server should be immediately accessible via port 80. {{Note| The created rule will disappear after a reboot. }} To see the prerouting chain, run the command: {{RootCmd|collapse-output=true|nft --handle list chain ip6 nat prerouting|output=<pre> table ip6 nat { chain prerouting { # handle 1 type nat hook prerouting priority filter; policy accept; tcp dport 80 counter packets 0 bytes 0 redirect to :3000 # handle 2 } } </pre>}} To remove the added rule (to change the port or because of a mistake), run the command: {{Important|Make sure the rule is matched as <code># handle 2</code> in the above output, otherwise specify the correct number.}} {{RootCmd|nft delete rule ip6 nat prerouting handle 2}} === HTTPS === This section relies on [https://expressjs.com/en/starter/installing.html Express.js] because it provides a simple way to host static files that appear dynamically. All paths match the {{Link|Let's_Encrypt#acme-tiny|acme-tiny configuration guide}}, but there are no strict requirements, the files can be anywhere. ==== Certificate issuance (Let's Encrypt) ==== First, it is necessary to create and run a server script that will host the Let's Encrypt token for the [https://letsencrypt.org/docs/challenge-types/#http-01-challenge HTTP-01 challenge]: {{FileBox|filename=http-server.js|lang=javascript|1= const express = require('express'); const PORT = 3000; const ACME_CHALLENGE_PATH = '/var/www/localhost/acme-challenge'; const app = express(); app.use('/.well-known/acme-challenge', express.static(ACME_CHALLENGE_PATH)); app.listen(PORT); }} Then redirect port <code>80</code> to port <code>3000</code> as described {{Link|#Port redirection|above}}. Install acme-tiny as described {{Link|Let's_Encrypt#acme-tiny_.28optional.29|here}} and issue the certificate as described {{Link|Let's_Encrypt#acme-tiny|here}}. ==== Certificate usage ==== Once the certificate has been issued, the server script needs to be replaced with this one: {{FileBox|filename=https-server.js|lang=javascript|1= const fs = require('node:fs'); const https = require('node:https'); const express = require('express'); const PORT = 3000; const CERTIFICATE_PATH = '/var/lib/letsencrypt/chained.pem'; const PRIVATE_KEY_PATH = '/var/lib/letsencrypt/domain.key'; const app = express(); const options = { cert: fs.readFileSync(CERTIFICATE_PATH), key: fs.readFileSync(PRIVATE_KEY_PATH) }; https.createServer(options, app).listen(PORT); }} Redirect port <code>443</code> to <code>3000</code> as described {{Link|#Port redirection|above}}. The connection should now be encrypted. The above script doesn't actually require Express.js anymore, but it's left as an example, an example of pure Node.js can be found [https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener here]. The ACME challenge is not required either, even for renewals. === Node.js as a reverse proxy for Forgejo\Gitea (or anything else) === The simplest way to set up a reverse proxy is to use [https://expressjs.com/en/starter/installing.html Express.js] with [https://github.com/villadora/express-http-proxy express-http-proxy]. The following example shows a way to redirect all requests coming to <code>http://<DOMAIN>/projects</code> to [https://forgejo.org/ Forgejo] (or {{Link|Gitea}}). The example assumes that port <code>80</code> is redirected to port <code>3000</code> as described {{Link|#Port redirection|above}}. The minimal Forgejo [https://forgejo.org/docs/latest/admin/config-cheat-sheet/ configuration]: {{FileBox|filename=<Forgejo\Gitea root directory>/custom/conf/app.ini|lang=ini|1= [server] ROOT_URL = http://<DOMAIN GOES HERE>/projects/ HTTP_PORT = 3001 }} {{Note| Replace <code>http://</code> with <code>https://</code> if HTTPS is used. }} The minimal HTTP server: {{FileBox|filename=server.js|lang=javascript|1= const express = require('express'); const proxy = require('express-http-proxy'); const PORT = 3000; const app = express(); app.use('/projects', proxy('localhost:3001')); app.listen(PORT); }} To use HTTPS, just inject the following lines in the script provided {{Link|#Certificate usage|here}}: {{CodeBox|lang=javascript|1= const proxy = require('express-http-proxy'); app.use('/projects', proxy('localhost:3001')); }} == Web application daemons with nginx and monit == This section will walk through installing Node.js behind nginx and using Monit to keep Node instances alive. Since Node.js is a single-process application, the goal is to launch multiple instances of the application and load balance using nginx. === Packages === Use {{Package|app-admin/monit}} for spawning Node.js servers. {{Emerge|monit nginx nodejs}} === Configure Monit === {{FileBox|filename=/etc/monit.d/my-app|title=Auto restart NodeJS App|1= check process mysql with pidfile /var/run/my-app/mysqld.pid start program = "/bin/bash -c 'rc-service mysql start'" stop program = "/bin/bash -c 'rc-service mysql stop'" }} === Configure Nginx === {{FileBox|filename=/etc/nginx/nginx.conf|title=Nginx Config|1= http { upstream myapp1 { least_conn; server srv1.example.com; server srv2.example.com; server srv3.example.com; } server { listen 80; location / { proxy_pass http://myapp1; } } } }} == Web application with openrc runscript == {{FileBox|filename=/etc/init.d/nodejs-server|title=Sample init.d file for a Node.js daemon|lang=bash|1= #!/sbin/openrc-run user{{=}}"nobody" group{{=}}"nobody" command{{=}}"/usr/bin/node" directory{{=}}"/opt/${RC_SVCNAME}" command_args{{=}}"httpd.js" command_user{{=}}"${user}:${group}" command_background{{=}}"yes" pidfile{{=}}"/run/${RC_SVCNAME}.pid" output_log{{=}}"/var/log/${RC_SVCNAME}.log" error_log{{=}}"${output_log}" depend() { use net } }} == References == {{reflist}} [[Category:Development]]'
New page wikitext, after the edit (new_wikitext)
'{{Stub}} {{InfoBox stack |{{InfoBox homepage|https://nodejs.org/en|header=true}} |{{InfoBox odoc|https://nodejs.org/en/docs}} |{{InfoBox wikipedia|Node.js}} |{{InfoBox github|nodejs/node}} |{{InfoBox irc|#node.js}} |{{InfoBox blog|https://nodejs.org/en/blog}} }} '''Node.js''' is a [[Article description::cross platform, open source, JavaScript server environment]]. == Installation == === USE flags === {{USEflag|package=net-libs/nodejs}} === npm === Node.js has a [[USE_flag|USE flag]] to include npm, the Node.js package manager. {{c|npm}} is necessary to install a Node.js application's dependencies, which are defined in a file named <tt>package.json</tt>. The USE can be disabled if {{c|npm}} is not necessary locally, or prefer to only install an alternative, for example, {{Package|sys-apps/yarn}}. You will receive error if try to install a package from NPM globaly - [https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677 see this about how to install NPM packages to your home directory] - for safe coliving for Portage: {{Cmd|npm config set prefix '${NPM_PACKAGES}'}} {{FileBox|filename=~/.config/bash/bashrc|lang=bash|1= export NPM_PACKAGES=$HOME/.local/ NODE_PATH="$NPM_PACKAGES/lib/node_modules" export PATH="/home/$USER/go/bin:/home/$USER/.local/bin:$NPM_PACKAGES/bin:$PATH" MANPATH="$NPM_PACKAGES/share/man:$MANPATH" # We have this against messing with Portage files. # Bonus: now you can `npm install -g` without root. # According to # https://wiki.gentoo.org/wiki/Node.js#npm # https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677 # https://www.reddit.com/r/Gentoo/comments/ydzkml/nodejs_is_it_ok_to_install_global_packages/ }} == Standalone Node.js server == {{Warning| Node.js and Express.js suggest to run Node.js behind a '''reverse proxy''' to mitigate '''DoS attacks''' and improve '''performance'''. <ref>https://nodejs.org/en/learn/getting-started/security-best-practices</ref><ref>https://expressjs.com/en/advanced/best-practice-security.html</ref><ref>https://expressjs.com/en/advanced/best-practice-performance.html</ref> This section goes against these recommendations and even includes an example of using Node.js itself as a reverse proxy. Not following these recommendations is allowed if the server will not be public. With caution, the methods provided here can be used for small homelab projects. It is also important to understand that reverse proxies are not a panacea. They may contain vulnerabilities that could lead to the execution of arbitrary code (e.g. {{Bug|CVE-2021-23017}}) or root privilege escalation (e.g. {{Bug|CVE-2016-1247}}). Not using reverse proxies limits the attack vector to Node.js only. }} Node.js can be run as a standalone HTTP server. It does not require root privileges and can be accessed from the Internet, for example on port 3000. To launch the [https://nodejs.org/en/learn/getting-started/introduction-to-nodejs official example], the <code>hostname</code> (a variable in the example) must be set to a public IPv6 or IPv4 address (<code>localhost</code> will not work). The modified example can be executed from the user space as following: {{Cmd|node modified-downloaded-example.js}} The only problem is the inability to connect to [[Wikipedia:List_of_TCP_and_UDP_port_numbers#Well-known_ports|well-known ports]] (e.g. 80) from unprivileged user space. But this problem can be solved with {{Link|#Port redirection|port redirection}}. === SELinux policy === {{Warning| The policy provided in this section is created using <code>audit2allow</code>. Review the policy before using it. }} As of March 26, 2024, the Node.js package does not come with a {{Link|SELinux}} policy, so creating a custom policy is required. The following custom policy assumes that Node.js will be executed from unprivileged user space. The policy was tested with Nodejs v. 20.6.1 on the <code>default/linux/arm64/17.0/musl/hardened/selinux</code> profile. {{FileBox|filename=nodejs-workaround.te|1= module nodejs-workaround 1.0; require { type unreserved_port_t; type ntop_port_t; type node_t; type user_t; class process execmem; class tcp_socket { name_bind node_bind }; } #============= user_t ============== #!!!! This avc can be allowed using the boolean 'user_tcp_server' allow user_t node_t:tcp_socket node_bind; allow user_t ntop_port_t:tcp_socket name_bind; #!!!! This avc can be allowed using the boolean 'allow_execmem' allow user_t self:process execmem; allow user_t unreserved_port_t:tcp_socket name_bind; }} {{Important| Delete the following lines if there are no plans to use Node.js on ports other than <code>3000</code>: <code>type unreserved_port_t;</code> and <code>allow user_t unreserved_port_t:tcp_socket name_bind;</code> }} To compile and install the policy module, run the commands: {{RootCmd|make -f /usr/share/selinux/strict/include/Makefile nodejs-workaround.pp|semodule --install nodejs-workaround.pp}} Node.js should immediately become functional. To remove the policy, run the command: {{RootCmd|semodule --remove nodejs-workaround}} The policy is created based on the following AVC: {{RootCmd|collapse-output=true|cat /var/log/audit/audit.log|output=<pre> audit: type=1400 audit(1710592438.060:241): avc: denied { execmem } for pid=1795 comm="node" scontext=user_u:user_r:user_t tcontext=user_u:user_r:user_t tclass=process permissive=0 audit: type=1400 audit(1710592130.148:234): avc: denied { name_bind } for pid=1705 comm="node" src=3005 scontext=user_u:user_r:user_t tcontext=system_u:object_r:unreserved_port_t tclass=tcp_socket permissive=0 audit: type=1400 audit(1710592738.512:259): avc: denied { node_bind } for pid=1877 comm="node" saddr=7777:777:7777:7777::1 src=3004 scontext=user_u:user_r:user_t tcontext=system_u:object_r:node_t tclass=tcp_socket permissive=0 audit: type=1400 audit(1710592851.496:274): avc: denied { name_bind } for pid=1920 comm="node" src=3000 scontext=user_u:user_r:user_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 </pre> }} Other AVC messages caused by Node.js are also present (and will be present after policy definition) in the log. But they do not affect the use of Node.js. The above messages are the only ones that cause Node.js to fail. === Port redirection === This section describes a way to redirect ports using the legacy {{Link|iptables}} approach or the modern {{Link|nftables}} approach. Choose one. ==== iptables ==== The redirection requires the following option to be enabled in the kernel: {{KernelBox|title=Enable redirections|1= [*] Networking support ---> --- Networking support Networking options ---> [*] Network packet filtering framework (Netfilter) ---> --- Network packet filtering framework (Netfilter) Core Netfilter Configuration ---> [*] REDIRECT target support }} {{Important|The examples below assume that the server is running on a public IPv6 address. For an IPv4 address use <code>iptables</code> instead of <code>ip6tables</code>, the syntax is the same. IPv4 and IPv6 have separate NAT tables.}} Assuming the Node.js server is running on port 3000, run the following command to redirect port 80 to 3000: {{RootCmd|ip6tables --table nat --append PREROUTING --protocol tcp --dport 80 --jump REDIRECT --to-port 3000}} The server should be immediately accessible via port 80. {{Note| The created rule will disappear after a reboot. }} To see the modified NAT table, run the command: {{RootCmd|collapse-output=true|ip6tables --table nat --list|output=<pre> Chain PREROUTING (policy ACCEPT) target prot opt source destination REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 3000 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination </pre>}} To remove the added rule (to change the port or because of a mistake), run the command: {{Important|Make sure the rule is the first (<code>1</code>) in the <code>PREROUTING</code> chain, otherwise specify the correct number.}} {{RootCmd|ip6tables --table nat --delete PREROUTING 1}} ==== nftables ==== The redirection requires the following options to be enabled in the kernel: {{KernelBox|title=Enable redirections|1= [*] Networking support ---> --- Networking support Networking options ---> [*] Network packet filtering framework (Netfilter) ---> --- Network packet filtering framework (Netfilter) Core Netfilter Configuration ---> [*] Netfilter nf_tables support [*] Netfilter nf_tables redirect support [*] Netfilter nf_tables nat module }} {{KernelBox|title=IPv6|1= [*] Networking support ---> --- Networking support Networking options ---> [*] Network packet filtering framework (Netfilter) ---> --- Network packet filtering framework (Netfilter) IPv6: Netfilter Configuration ---> [*] IPv6 nf_tables support }} {{KernelBox|title=IPv4|1= [*] Networking support ---> --- Networking support Networking options ---> [*] Network packet filtering framework (Netfilter) ---> --- Network packet filtering framework (Netfilter) IP: Netfilter Configuration ---> [*] IPv4 nf_tables support }} {{Important|The examples below assume that the server is running on a public IPv6 address. For an IPv4 address use <code>inet</code> or <code>ip</code> instead of <code>ip6</code>}} Create the NAT table and chain: {{RootCmd|nft add table ip6 nat|nft add chain ip6 nat prerouting '{ type nat hook prerouting priority 0; }'}} Redirect port <code>80</code> to port <code>3000</code>: {{RootCmd|nft add rule ip6 nat prerouting tcp dport 80 counter redirect to 3000}} The server should be immediately accessible via port 80. {{Note| The created rule will disappear after a reboot. }} To see the prerouting chain, run the command: {{RootCmd|collapse-output=true|nft --handle list chain ip6 nat prerouting|output=<pre> table ip6 nat { chain prerouting { # handle 1 type nat hook prerouting priority filter; policy accept; tcp dport 80 counter packets 0 bytes 0 redirect to :3000 # handle 2 } } </pre>}} To remove the added rule (to change the port or because of a mistake), run the command: {{Important|Make sure the rule is matched as <code># handle 2</code> in the above output, otherwise specify the correct number.}} {{RootCmd|nft delete rule ip6 nat prerouting handle 2}} === HTTPS === This section relies on [https://expressjs.com/en/starter/installing.html Express.js] because it provides a simple way to host static files that appear dynamically. All paths match the {{Link|Let's_Encrypt#acme-tiny|acme-tiny configuration guide}}, but there are no strict requirements, the files can be anywhere. ==== Certificate issuance (Let's Encrypt) ==== First, it is necessary to create and run a server script that will host the Let's Encrypt token for the [https://letsencrypt.org/docs/challenge-types/#http-01-challenge HTTP-01 challenge]: {{FileBox|filename=http-server.js|lang=javascript|1= const express = require('express'); const PORT = 3000; const ACME_CHALLENGE_PATH = '/var/www/localhost/acme-challenge'; const app = express(); app.use('/.well-known/acme-challenge', express.static(ACME_CHALLENGE_PATH)); app.listen(PORT); }} Then redirect port <code>80</code> to port <code>3000</code> as described {{Link|#Port redirection|above}}. Install acme-tiny as described {{Link|Let's_Encrypt#acme-tiny_.28optional.29|here}} and issue the certificate as described {{Link|Let's_Encrypt#acme-tiny|here}}. ==== Certificate usage ==== Once the certificate has been issued, the server script needs to be replaced with this one: {{FileBox|filename=https-server.js|lang=javascript|1= const fs = require('node:fs'); const https = require('node:https'); const express = require('express'); const PORT = 3000; const CERTIFICATE_PATH = '/var/lib/letsencrypt/chained.pem'; const PRIVATE_KEY_PATH = '/var/lib/letsencrypt/domain.key'; const app = express(); const options = { cert: fs.readFileSync(CERTIFICATE_PATH), key: fs.readFileSync(PRIVATE_KEY_PATH) }; https.createServer(options, app).listen(PORT); }} Redirect port <code>443</code> to <code>3000</code> as described {{Link|#Port redirection|above}}. The connection should now be encrypted. The above script doesn't actually require Express.js anymore, but it's left as an example, an example of pure Node.js can be found [https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener here]. The ACME challenge is not required either, even for renewals. === Node.js as a reverse proxy for Forgejo\Gitea (or anything else) === The simplest way to set up a reverse proxy is to use [https://expressjs.com/en/starter/installing.html Express.js] with [https://github.com/villadora/express-http-proxy express-http-proxy]. The following example shows a way to redirect all requests coming to <code>http://<DOMAIN>/projects</code> to [https://forgejo.org/ Forgejo] (or {{Link|Gitea}}). The example assumes that port <code>80</code> is redirected to port <code>3000</code> as described {{Link|#Port redirection|above}}. The minimal Forgejo [https://forgejo.org/docs/latest/admin/config-cheat-sheet/ configuration]: {{FileBox|filename=<Forgejo\Gitea root directory>/custom/conf/app.ini|lang=ini|1= [server] ROOT_URL = http://<DOMAIN GOES HERE>/projects/ HTTP_PORT = 3001 }} {{Note| Replace <code>http://</code> with <code>https://</code> if HTTPS is used. }} The minimal HTTP server: {{FileBox|filename=server.js|lang=javascript|1= const express = require('express'); const proxy = require('express-http-proxy'); const PORT = 3000; const app = express(); app.use('/projects', proxy('localhost:3001')); app.listen(PORT); }} To use HTTPS, just inject the following lines in the script provided {{Link|#Certificate usage|here}}: {{CodeBox|lang=javascript|1= const proxy = require('express-http-proxy'); app.use('/projects', proxy('localhost:3001')); }} == Web application daemons with nginx and monit == This section will walk through installing Node.js behind nginx and using Monit to keep Node instances alive. Since Node.js is a single-process application, the goal is to launch multiple instances of the application and load balance using nginx. === Packages === Use {{Package|app-admin/monit}} for spawning Node.js servers. {{Emerge|monit nginx nodejs}} === Configure Monit === {{FileBox|filename=/etc/monit.d/my-app|title=Auto restart NodeJS App|1= check process mysql with pidfile /var/run/my-app/mysqld.pid start program = "/bin/bash -c 'rc-service mysql start'" stop program = "/bin/bash -c 'rc-service mysql stop'" }} === Configure Nginx === {{FileBox|filename=/etc/nginx/nginx.conf|title=Nginx Config|1= http { upstream myapp1 { least_conn; server srv1.example.com; server srv2.example.com; server srv3.example.com; } server { listen 80; location / { proxy_pass http://myapp1; } } } }} == Web application with openrc runscript == {{FileBox|filename=/etc/init.d/nodejs-server|title=Sample init.d file for a Node.js daemon|lang=bash|1= #!/sbin/openrc-run user{{=}}"nobody" group{{=}}"nobody" command{{=}}"/usr/bin/node" directory{{=}}"/opt/${RC_SVCNAME}" command_args{{=}}"httpd.js" command_user{{=}}"${user}:${group}" command_background{{=}}"yes" pidfile{{=}}"/run/${RC_SVCNAME}.pid" output_log{{=}}"/var/log/${RC_SVCNAME}.log" error_log{{=}}"${output_log}" depend() { use net } }} == References == {{reflist}} [[Category:Development]]'
Unified diff of changes made by edit (edit_diff)
'@@ -22,5 +22,20 @@ Node.js has a [[USE_flag|USE flag]] to include npm, the Node.js package manager. {{c|npm}} is necessary to install a Node.js application's dependencies, which are defined in a file named <tt>package.json</tt>. The USE can be disabled if {{c|npm}} is not necessary locally, or prefer to only install an alternative, for example, {{Package|sys-apps/yarn}}. -You will receive error if try to install a package from NPM globaly - [https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677 see this about how to install NPM packages to your home directory] - for safe coliving for Portage. +You will receive error if try to install a package from NPM globaly - [https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677 see this about how to install NPM packages to your home directory] - for safe coliving for Portage: + +{{Cmd|npm config set prefix '${NPM_PACKAGES}'}} + +{{FileBox|filename=~/.config/bash/bashrc|lang=bash|1= +export NPM_PACKAGES=$HOME/.local/ +NODE_PATH="$NPM_PACKAGES/lib/node_modules" +export PATH="/home/$USER/go/bin:/home/$USER/.local/bin:$NPM_PACKAGES/bin:$PATH" +MANPATH="$NPM_PACKAGES/share/man:$MANPATH" +# We have this against messing with Portage files. +# Bonus: now you can `npm install -g` without root. +# According to +# https://wiki.gentoo.org/wiki/Node.js#npm +# https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677 +# https://www.reddit.com/r/Gentoo/comments/ydzkml/nodejs_is_it_ok_to_install_global_packages/ +}} == Standalone Node.js server == '
Old page size (old_size)
15258
Lines added in edit (added_lines)
[ 0 => 'You will receive error if try to install a package from NPM globaly - [https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677 see this about how to install NPM packages to your home directory] - for safe coliving for Portage:', 1 => '', 2 => '{{Cmd|npm config set prefix '${NPM_PACKAGES}'}}', 3 => '', 4 => '{{FileBox|filename=~/.config/bash/bashrc|lang=bash|1=', 5 => 'export NPM_PACKAGES=$HOME/.local/', 6 => 'NODE_PATH="$NPM_PACKAGES/lib/node_modules"', 7 => 'export PATH="/home/$USER/go/bin:/home/$USER/.local/bin:$NPM_PACKAGES/bin:$PATH"', 8 => 'MANPATH="$NPM_PACKAGES/share/man:$MANPATH"', 9 => '# We have this against messing with Portage files.', 10 => '# Bonus: now you can `npm install -g` without root.', 11 => '# According to', 12 => '# https://wiki.gentoo.org/wiki/Node.js#npm', 13 => '# https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677', 14 => '# https://www.reddit.com/r/Gentoo/comments/ydzkml/nodejs_is_it_ok_to_install_global_packages/', 15 => '}}' ]
Lines removed in edit (removed_lines)
[ 0 => 'You will receive error if try to install a package from NPM globaly - [https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677 see this about how to install NPM packages to your home directory] - for safe coliving for Portage.' ]
New page text, stripped of any markup (new_text)
' This article is a stub. Please help out by expanding it - how to get started. Resources Home Official documentation Wikipedia GitHub #node.js (webchat) Blog Node.js is a cross platform, open source, JavaScript server environment. Contents 1 Installation 1.1 USE flags 1.2 npm 2 Standalone Node.js server 2.1 SELinux policy 2.2 Port redirection 2.2.1 iptables 2.2.2 nftables 2.3 HTTPS 2.3.1 Certificate issuance (Let's Encrypt) 2.3.2 Certificate usage 2.4 Node.js as a reverse proxy for Forgejo\Gitea (or anything else) 3 Web application daemons with nginx and monit 3.1 Packages 3.2 Configure Monit 3.3 Configure Nginx 4 Web application with openrc runscript 5 References Installation[edit | edit source] USE flags[edit | edit source] USE flags for net-libs/nodejs A JavaScript runtime built on Chrome&#39;s V8 JavaScript engine corepack Enable the experimental corepack package management tool debug Enable extra debug codepaths, like asserts and extra output. If you want to get meaningful backtraces see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces doc Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally icu Enable ICU (Internationalization Components for Unicode) support, using dev-libs/icu inspector Enable V8 inspector lto Enable Link-Time Optimization (LTO) to optimize the build npm Enable NPM package manager pax-kernel Enable building under a PaX enabled kernel snapshot Enable snapshot creation for faster startup ssl Add support for SSL/TLS connections (Secure Socket Layer / Transport Layer Security) system-icu Use system dev-libs/icu instead of the bundled version system-ssl Use system OpenSSL instead of the bundled one systemtap Enable SystemTAP/DTrace tracing test Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently) Data provided by the Gentoo Package Database &#183; Last update: 2024-05-07 17:46 More information about USE flags npm[edit | edit source] Node.js has a USE flag to include npm, the Node.js package manager. npm is necessary to install a Node.js application's dependencies, which are defined in a file named package.json. The USE can be disabled if npm is not necessary locally, or prefer to only install an alternative, for example, sys-apps/yarn. You will receive error if try to install a package from NPM globaly - see this about how to install NPM packages to your home directory - for safe coliving for Portage: user $npm config set prefix '${NPM_PACKAGES}' FILE ~/.config/bash/bashrc export NPM_PACKAGES=$HOME/.local/ NODE_PATH=&quot;$NPM_PACKAGES/lib/node_modules&quot; export PATH=&quot;/home/$USER/go/bin:/home/$USER/.local/bin:$NPM_PACKAGES/bin:$PATH&quot; MANPATH=&quot;$NPM_PACKAGES/share/man:$MANPATH&quot; # We have this against messing with Portage files. # Bonus: now you can `npm install -g` without root. # According to # https://wiki.gentoo.org/wiki/Node.js#npm # https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677 # https://www.reddit.com/r/Gentoo/comments/ydzkml/nodejs_is_it_ok_to_install_global_packages/ Standalone Node.js server[edit | edit source] WarningNode.js and Express.js suggest to run Node.js behind a reverse proxy to mitigate DoS attacks and improve performance. &#91;1&#93;&#91;2&#93;&#91;3&#93; This section goes against these recommendations and even includes an example of using Node.js itself as a reverse proxy. Not following these recommendations is allowed if the server will not be public. With caution, the methods provided here can be used for small homelab projects. It is also important to understand that reverse proxies are not a panacea. They may contain vulnerabilities that could lead to the execution of arbitrary code (e.g. bug #CVE-2021-23017) or root privilege escalation (e.g. bug #CVE-2016-1247). Not using reverse proxies limits the attack vector to Node.js only. Node.js can be run as a standalone HTTP server. It does not require root privileges and can be accessed from the Internet, for example on port 3000. To launch the official example, the hostname (a variable in the example) must be set to a public IPv6 or IPv4 address (localhost will not work). The modified example can be executed from the user space as following: user $node modified-downloaded-example.js The only problem is the inability to connect to well-known ports (e.g. 80) from unprivileged user space. But this problem can be solved with port redirection. SELinux policy[edit | edit source] WarningThe policy provided in this section is created using audit2allow. Review the policy before using it. As of March 26, 2024, the Node.js package does not come with a SELinux policy, so creating a custom policy is required. The following custom policy assumes that Node.js will be executed from unprivileged user space. The policy was tested with Nodejs v. 20.6.1 on the default/linux/arm64/17.0/musl/hardened/selinux profile. FILE nodejs-workaround.te module nodejs-workaround 1.0; require { type unreserved_port_t; type ntop_port_t; type node_t; type user_t; class process execmem; class tcp_socket { name_bind node_bind }; } #============= user_t ============== #!!!! This avc can be allowed using the boolean &#39;user_tcp_server&#39; allow user_t node_t:tcp_socket node_bind; allow user_t ntop_port_t:tcp_socket name_bind; #!!!! This avc can be allowed using the boolean &#39;allow_execmem&#39; allow user_t self:process execmem; allow user_t unreserved_port_t:tcp_socket name_bind; ImportantDelete the following lines if there are no plans to use Node.js on ports other than 3000: type unreserved_port_t; and allow user_t unreserved_port_t:tcp_socket name_bind; To compile and install the policy module, run the commands: root #make -f /usr/share/selinux/strict/include/Makefile nodejs-workaround.pproot #semodule --install nodejs-workaround.pp Node.js should immediately become functional. To remove the policy, run the command: root #semodule --remove nodejs-workaround The policy is created based on the following AVC: root #cat /var/log/audit/audit.logaudit: type=1400 audit(1710592438.060:241): avc: denied { execmem } for pid=1795 comm="node" scontext=user_u:user_r:user_t tcontext=user_u:user_r:user_t tclass=process permissive=0 audit: type=1400 audit(1710592130.148:234): avc: denied { name_bind } for pid=1705 comm="node" src=3005 scontext=user_u:user_r:user_t tcontext=system_u:object_r:unreserved_port_t tclass=tcp_socket permissive=0 audit: type=1400 audit(1710592738.512:259): avc: denied { node_bind } for pid=1877 comm="node" saddr=7777:777:7777:7777::1 src=3004 scontext=user_u:user_r:user_t tcontext=system_u:object_r:node_t tclass=tcp_socket permissive=0 audit: type=1400 audit(1710592851.496:274): avc: denied { name_bind } for pid=1920 comm="node" src=3000 scontext=user_u:user_r:user_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 Other AVC messages caused by Node.js are also present (and will be present after policy definition) in the log. But they do not affect the use of Node.js. The above messages are the only ones that cause Node.js to fail. Port redirection[edit | edit source] This section describes a way to redirect ports using the legacy iptables approach or the modern nftables approach. Choose one. iptables[edit | edit source] The redirection requires the following option to be enabled in the kernel: KERNEL Enable redirections [*] Networking support ---&gt; --- Networking support Networking options ---&gt; [*] Network packet filtering framework (Netfilter) ---&gt; --- Network packet filtering framework (Netfilter) Core Netfilter Configuration ---&gt; [*] REDIRECT target support ImportantThe examples below assume that the server is running on a public IPv6 address. For an IPv4 address use iptables instead of ip6tables, the syntax is the same. IPv4 and IPv6 have separate NAT tables. Assuming the Node.js server is running on port 3000, run the following command to redirect port 80 to 3000: root #ip6tables --table nat --append PREROUTING --protocol tcp --dport 80 --jump REDIRECT --to-port 3000 The server should be immediately accessible via port 80. NoteThe created rule will disappear after a reboot. To see the modified NAT table, run the command: root #ip6tables --table nat --listChain PREROUTING (policy ACCEPT) target prot opt source destination REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 3000 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination To remove the added rule (to change the port or because of a mistake), run the command: ImportantMake sure the rule is the first (1) in the PREROUTING chain, otherwise specify the correct number. root #ip6tables --table nat --delete PREROUTING 1 nftables[edit | edit source] The redirection requires the following options to be enabled in the kernel: KERNEL Enable redirections [*] Networking support ---&gt; --- Networking support Networking options ---&gt; [*] Network packet filtering framework (Netfilter) ---&gt; --- Network packet filtering framework (Netfilter) Core Netfilter Configuration ---&gt; [*] Netfilter nf_tables support [*] Netfilter nf_tables redirect support [*] Netfilter nf_tables nat module KERNEL IPv6 [*] Networking support ---&gt; --- Networking support Networking options ---&gt; [*] Network packet filtering framework (Netfilter) ---&gt; --- Network packet filtering framework (Netfilter) IPv6: Netfilter Configuration ---&gt; [*] IPv6 nf_tables support KERNEL IPv4 [*] Networking support ---&gt; --- Networking support Networking options ---&gt; [*] Network packet filtering framework (Netfilter) ---&gt; --- Network packet filtering framework (Netfilter) IP: Netfilter Configuration ---&gt; [*] IPv4 nf_tables support ImportantThe examples below assume that the server is running on a public IPv6 address. For an IPv4 address use inet or ip instead of ip6 Create the NAT table and chain: root #nft add table ip6 natroot #nft add chain ip6 nat prerouting '{ type nat hook prerouting priority 0; }' Redirect port 80 to port 3000: root #nft add rule ip6 nat prerouting tcp dport 80 counter redirect to 3000 The server should be immediately accessible via port 80. NoteThe created rule will disappear after a reboot. To see the prerouting chain, run the command: root #nft --handle list chain ip6 nat preroutingtable ip6 nat { chain prerouting { # handle 1 type nat hook prerouting priority filter; policy accept; tcp dport 80 counter packets 0 bytes 0 redirect to :3000 # handle 2 } } To remove the added rule (to change the port or because of a mistake), run the command: ImportantMake sure the rule is matched as # handle 2 in the above output, otherwise specify the correct number. root #nft delete rule ip6 nat prerouting handle 2 HTTPS[edit | edit source] This section relies on Express.js because it provides a simple way to host static files that appear dynamically. All paths match the acme-tiny configuration guide, but there are no strict requirements, the files can be anywhere. Certificate issuance (Let's Encrypt)[edit | edit source] First, it is necessary to create and run a server script that will host the Let's Encrypt token for the HTTP-01 challenge: FILE http-server.js const express = require(&#39;express&#39;); const PORT = 3000; const ACME_CHALLENGE_PATH = &#39;/var/www/localhost/acme-challenge&#39;; const app = express(); app.use(&#39;/.well-known/acme-challenge&#39;, express.static(ACME_CHALLENGE_PATH)); app.listen(PORT); Then redirect port 80 to port 3000 as described above. Install acme-tiny as described here and issue the certificate as described here. Certificate usage[edit | edit source] Once the certificate has been issued, the server script needs to be replaced with this one: FILE https-server.js const fs = require(&#39;node:fs&#39;); const https = require(&#39;node:https&#39;); const express = require(&#39;express&#39;); const PORT = 3000; const CERTIFICATE_PATH = &#39;/var/lib/letsencrypt/chained.pem&#39;; const PRIVATE_KEY_PATH = &#39;/var/lib/letsencrypt/domain.key&#39;; const app = express(); const options = { cert: fs.readFileSync(CERTIFICATE_PATH), key: fs.readFileSync(PRIVATE_KEY_PATH) }; https.createServer(options, app).listen(PORT); Redirect port 443 to 3000 as described above. The connection should now be encrypted. The above script doesn't actually require Express.js anymore, but it's left as an example, an example of pure Node.js can be found here. The ACME challenge is not required either, even for renewals. Node.js as a reverse proxy for Forgejo\Gitea (or anything else)[edit | edit source] The simplest way to set up a reverse proxy is to use Express.js with express-http-proxy. The following example shows a way to redirect all requests coming to http://&lt;DOMAIN&gt;/projects to Forgejo (or Gitea). The example assumes that port 80 is redirected to port 3000 as described above. The minimal Forgejo configuration: FILE &lt;Forgejo\Gitea root directory&gt;/custom/conf/app.ini [server] ROOT_URL = http://&lt;DOMAIN GOES HERE&gt;/projects/ HTTP_PORT = 3001 NoteReplace http:// with https:// if HTTPS is used. The minimal HTTP server: FILE server.js const express = require(&#39;express&#39;); const proxy = require(&#39;express-http-proxy&#39;); const PORT = 3000; const app = express(); app.use(&#39;/projects&#39;, proxy(&#39;localhost:3001&#39;)); app.listen(PORT); To use HTTPS, just inject the following lines in the script provided here: CODE const proxy = require(&#39;express-http-proxy&#39;); app.use(&#39;/projects&#39;, proxy(&#39;localhost:3001&#39;)); Web application daemons with nginx and monit[edit | edit source] This section will walk through installing Node.js behind nginx and using Monit to keep Node instances alive. Since Node.js is a single-process application, the goal is to launch multiple instances of the application and load balance using nginx. Packages[edit | edit source] Use app-admin/monit for spawning Node.js servers. root #emerge --ask monit nginx nodejs Configure Monit[edit | edit source] FILE /etc/monit.d/my-appAuto restart NodeJS App check process mysql with pidfile /var/run/my-app/mysqld.pid start program = &quot;/bin/bash -c &#39;rc-service mysql start&#39;&quot; stop program = &quot;/bin/bash -c &#39;rc-service mysql stop&#39;&quot; Configure Nginx[edit | edit source] FILE /etc/nginx/nginx.confNginx Config http { upstream myapp1 { least_conn; server srv1.example.com; server srv2.example.com; server srv3.example.com; } server { listen 80; location / { proxy_pass http://myapp1; } } } Web application with openrc runscript[edit | edit source] FILE /etc/init.d/nodejs-serverSample init.d file for a Node.js daemon #!/sbin/openrc-run user=&quot;nobody&quot; group=&quot;nobody&quot; command=&quot;/usr/bin/node&quot; directory=&quot;/opt/${RC_SVCNAME}&quot; command_args=&quot;httpd.js&quot; command_user=&quot;${user}:${group}&quot; command_background=&quot;yes&quot; pidfile=&quot;/run/${RC_SVCNAME}.pid&quot; output_log=&quot;/var/log/${RC_SVCNAME}.log&quot; error_log=&quot;${output_log}&quot; depend() { use net } References[edit | edit source] ↑ https://nodejs.org/en/learn/getting-started/security-best-practices ↑ https://expressjs.com/en/advanced/best-practice-security.html ↑ https://expressjs.com/en/advanced/best-practice-performance.html'
Parsed HTML source of the new revision (new_html)
'<div class="mw-parser-output"><div class="alert alert-info"><span class="fa fa-fw fa-pencil"></span> This article is a <a href="/wiki/Category:Stub" title="Category:Stub">stub</a>. Please help out by <a rel="nofollow" class="external text" href="//wiki.gentoo.org/index.php?title=Node.js&amp;action=edit">expanding it</a> - <a href="/wiki/Gentoo_Wiki:Contributor%27s_guide" title="Gentoo Wiki:Contributor&#39;s guide">how to get started</a>. </div> <div id="infobox-stack" class="list-group" style="width: 25em; float: right; clear: right; font-size: 90%; margin-left: 1em;"> <div class="list-group-item text-center" style="padding-top: 3px; padding-bottom: 3px; background-color: #463C65; color: white;"><b>Resources</b></div> <div id="infobox" class="list-group-item" style="display: flex; align-items: center; padding: 5px; min-height: 3em;"><span style="display: inline-block; width: 3em; overflow: hidden; text-align: center;"><span class="fa fa-home fa-fw fa-2x"></span></span><span><a rel="nofollow" class="external text" href="https://nodejs.org/en">Home</a></span></div> <div id="infobox" class="list-group-item" style="display: flex; align-items: center; padding: 5px; min-height: 3em;"><span style="display: inline-block; width: 3em; overflow: hidden; text-align: center;"><span class="fa fa-file-text fa-fw fa-2x"></span></span><span><a rel="nofollow" class="external text" href="https://nodejs.org/en/docs">Official documentation</a></span></div> <div id="infobox" class="list-group-item" style="display: flex; align-items: center; padding: 5px; min-height: 3em;"><span style="display: inline-block; width: 3em; overflow: hidden; text-align: center;"><span class="fa fa-wikipedia-w fa-fw fa-2x"></span></span><span><a href="https://en.wikipedia.org/wiki/Node.js" class="extiw" title="wikipedia:Node.js">Wikipedia</a></span></div> <div id="infobox" class="list-group-item" style="display: flex; align-items: center; padding: 5px; min-height: 3em;"><span style="display: inline-block; width: 3em; overflow: hidden; text-align: center;"><span class="fa fa-github fa-fw fa-2x"></span></span><span><a rel="nofollow" class="external text" href="https://github.com/nodejs/node">GitHub</a></span></div> <div id="infobox" class="list-group-item" style="display: flex; align-items: center; padding: 5px; min-height: 3em;"><span style="display: inline-block; width: 3em; overflow: hidden; text-align: center;"><span class="fa fa-comments-o fa-fw fa-2x"></span></span><span><span style="font-family: monospace; font-size: 95%;"><a rel="nofollow" class="external text" href="ircs://irc.libera.chat/#node.js">#node.js</a></span> (<span style="font-family: monospace; font-size: 95%;"><a rel="nofollow" class="external text" href="https://web.libera.chat/#node.js">webchat</a></span>)</span></div> <div id="infobox" class="list-group-item" style="display: flex; align-items: center; padding: 5px; min-height: 3em;"><span style="display: inline-block; width: 3em; overflow: hidden; text-align: center;"><span class="fa fa-rss fa-fw fa-2x"></span></span><span><a rel="nofollow" class="external text" href="https://nodejs.org/en/blog">Blog</a></span></div> </div> <p><b>Node.js</b> is a cross platform, open source, JavaScript server environment. </p> <div id="toc" class="toc" role="navigation" aria-labelledby="mw-toc-heading"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2 id="mw-toc-heading">Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Installation"><span class="tocnumber">1</span> <span class="toctext">Installation</span></a> <ul> <li class="toclevel-2 tocsection-2"><a href="#USE_flags"><span class="tocnumber">1.1</span> <span class="toctext">USE flags</span></a></li> <li class="toclevel-2 tocsection-3"><a href="#npm"><span class="tocnumber">1.2</span> <span class="toctext">npm</span></a></li> </ul> </li> <li class="toclevel-1 tocsection-4"><a href="#Standalone_Node.js_server"><span class="tocnumber">2</span> <span class="toctext">Standalone Node.js server</span></a> <ul> <li class="toclevel-2 tocsection-5"><a href="#SELinux_policy"><span class="tocnumber">2.1</span> <span class="toctext">SELinux policy</span></a></li> <li class="toclevel-2 tocsection-6"><a href="#Port_redirection"><span class="tocnumber">2.2</span> <span class="toctext">Port redirection</span></a> <ul> <li class="toclevel-3 tocsection-7"><a href="#iptables"><span class="tocnumber">2.2.1</span> <span class="toctext">iptables</span></a></li> <li class="toclevel-3 tocsection-8"><a href="#nftables"><span class="tocnumber">2.2.2</span> <span class="toctext">nftables</span></a></li> </ul> </li> <li class="toclevel-2 tocsection-9"><a href="#HTTPS"><span class="tocnumber">2.3</span> <span class="toctext">HTTPS</span></a> <ul> <li class="toclevel-3 tocsection-10"><a href="#Certificate_issuance_.28Let.27s_Encrypt.29"><span class="tocnumber">2.3.1</span> <span class="toctext">Certificate issuance (Let's Encrypt)</span></a></li> <li class="toclevel-3 tocsection-11"><a href="#Certificate_usage"><span class="tocnumber">2.3.2</span> <span class="toctext">Certificate usage</span></a></li> </ul> </li> <li class="toclevel-2 tocsection-12"><a href="#Node.js_as_a_reverse_proxy_for_Forgejo.5CGitea_.28or_anything_else.29"><span class="tocnumber">2.4</span> <span class="toctext">Node.js as a reverse proxy for Forgejo\Gitea (or anything else)</span></a></li> </ul> </li> <li class="toclevel-1 tocsection-13"><a href="#Web_application_daemons_with_nginx_and_monit"><span class="tocnumber">3</span> <span class="toctext">Web application daemons with nginx and monit</span></a> <ul> <li class="toclevel-2 tocsection-14"><a href="#Packages"><span class="tocnumber">3.1</span> <span class="toctext">Packages</span></a></li> <li class="toclevel-2 tocsection-15"><a href="#Configure_Monit"><span class="tocnumber">3.2</span> <span class="toctext">Configure Monit</span></a></li> <li class="toclevel-2 tocsection-16"><a href="#Configure_Nginx"><span class="tocnumber">3.3</span> <span class="toctext">Configure Nginx</span></a></li> </ul> </li> <li class="toclevel-1 tocsection-17"><a href="#Web_application_with_openrc_runscript"><span class="tocnumber">4</span> <span class="toctext">Web application with openrc runscript</span></a></li> <li class="toclevel-1 tocsection-18"><a href="#References"><span class="tocnumber">5</span> <span class="toctext">References</span></a></li> </ul> </div> <h2><span class="mw-headline" id="Installation">Installation</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=1" class="mw-editsection-visualeditor" title="Edit section: Installation">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=1" title="Edit section: Installation">edit source</a><span class="mw-editsection-bracket">]</span></span></h2> <h3><span class="mw-headline" id="USE_flags">USE flags</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=2" class="mw-editsection-visualeditor" title="Edit section: USE flags">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=2" title="Edit section: USE flags">edit source</a><span class="mw-editsection-bracket">]</span></span></h3> <p class="mw-empty-elt"> </p><div class="panel panel-default gp-panel"> <div class="panel-heading gp-panel-heading"> <h3 class="panel-title"> <span class="text-muted">USE flags for</span> <a href="https://packages.gentoo.org/packages/net-libs/nodejs">net-libs/nodejs</a> <small><span class="fa fa-external-link-square"></span></small> <small class="gp-pkg-desc">A JavaScript runtime built on Chrome&#39;s V8 JavaScript engine</small> </h3> </div> <div class="table-responsive gp-useflag-table-container"> <table class="table gp-useflag-table"> <tbody><tr> <td> <code><a href="https://packages.gentoo.org/useflags/corepack">corepack</a></code> </td> <td> Enable the experimental corepack package management tool </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/debug">debug</a></code> </td> <td> Enable extra debug codepaths, like asserts and extra output. If you want to get meaningful backtraces see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/doc">doc</a></code> </td> <td> Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/icu">icu</a></code> </td> <td> Enable ICU (Internationalization Components for Unicode) support, using dev-libs/icu </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/inspector">inspector</a></code> </td> <td> Enable V8 inspector </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/lto">lto</a></code> </td> <td> Enable Link-Time Optimization (LTO) to optimize the build </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/npm">npm</a></code> </td> <td> Enable NPM package manager </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/pax-kernel">pax-kernel</a></code> </td> <td> Enable building under a PaX enabled kernel </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/snapshot">snapshot</a></code> </td> <td> Enable snapshot creation for faster startup </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/ssl">ssl</a></code> </td> <td> Add support for SSL/TLS connections (Secure Socket Layer / Transport Layer Security) </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/system-icu">system-icu</a></code> </td> <td> Use system dev-libs/icu instead of the bundled version </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/system-ssl">system-ssl</a></code> </td> <td> Use system OpenSSL instead of the bundled one </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/systemtap">systemtap</a></code> </td> <td> Enable SystemTAP/DTrace tracing </td> </tr> <tr> <td> <code><a href="https://packages.gentoo.org/useflags/test">test</a></code> </td> <td> Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently) </td> </tr> </tbody></table> </div> <div class="panel-footer gp-panel-footer"> <small class="pull-right"> Data provided by the <a href="https://packages.gentoo.org">Gentoo Package Database</a> &#183; Last update: 2024-05-07 17:46 </small> <small> <a href="/wiki/Handbook:AMD64/Working/USE">More information about USE flags</a> </small> </div> </div> <p class="mw-empty-elt"></p> <h3><span class="mw-headline" id="npm">npm</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=3" class="mw-editsection-visualeditor" title="Edit section: npm">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=3" title="Edit section: npm">edit source</a><span class="mw-editsection-bracket">]</span></span></h3> <p>Node.js has a <a href="/wiki/USE_flag" title="USE flag">USE flag</a> to include npm, the Node.js package manager. <span style="font-family: monospace; font-size: 95%; font-weight: bold;" class="tripleclick-separator">npm</span> is necessary to install a Node.js application's dependencies, which are defined in a file named <tt>package.json</tt>. The USE can be disabled if <span style="font-family: monospace; font-size: 95%; font-weight: bold;" class="tripleclick-separator">npm</span> is not necessary locally, or prefer to only install an alternative, for example, <span style="white-space: nowrap;" class="plainlinks" title="External link to https&#58;//packages.gentoo.org for the sys-apps/yarn package."><a rel="nofollow" class="external text" href="https://packages.gentoo.org/packages/sys-apps/yarn"><span style="font-family: monospace; font-size: 95%; color: MidnightBlue;">sys-apps/yarn</span></a><span style="color: grey; margin-left: 0.1em; font-size: 70%;" class="fa fa-hdd-o fa-fw"></span></span>. </p><p>You will receive error if try to install a package from NPM globaly - <a rel="nofollow" class="external text" href="https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677">see this about how to install NPM packages to your home directory</a> - for safe coliving for Portage: </p> <div class="cmd-box"><div><code style="color: #4E9A06; font-weight: bold;">user <span style="color:royalblue;">$</span></code><span class="tripleclick-separator"></span><code>npm config set prefix '${NPM_PACKAGES}'</code></div></div> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #54487A">FILE</span> <strong><code style="border: none; background: none; color: #54487A; margin-right: .5em;">~/.config/bash/bashrc</code></strong><strong></strong></div> <div class="mw-highlight mw-highlight-lang-bash mw-content-ltr" dir="ltr"><pre><span></span><span class="nb">export</span><span class="w"> </span><span class="nv">NPM_PACKAGES</span><span class="o">=</span><span class="nv">$HOME</span>/.local/ <span class="nv">NODE_PATH</span><span class="o">=</span><span class="s2">&quot;</span><span class="nv">$NPM_PACKAGES</span><span class="s2">/lib/node_modules&quot;</span> <span class="nb">export</span><span class="w"> </span><span class="nv">PATH</span><span class="o">=</span><span class="s2">&quot;/home/</span><span class="nv">$USER</span><span class="s2">/go/bin:/home/</span><span class="nv">$USER</span><span class="s2">/.local/bin:</span><span class="nv">$NPM_PACKAGES</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">&quot;</span> <span class="nv">MANPATH</span><span class="o">=</span><span class="s2">&quot;</span><span class="nv">$NPM_PACKAGES</span><span class="s2">/share/man:</span><span class="nv">$MANPATH</span><span class="s2">&quot;</span> <span class="c1"># We have this against messing with Portage files.</span> <span class="c1"># Bonus: now you can `npm install -g` without root.</span> <span class="c1"># According to</span> <span class="c1"># https://wiki.gentoo.org/wiki/Node.js#npm</span> <span class="c1"># https://stackoverflow.com/questions/10081293/install-npm-into-home-directory-with-distribution-nodejs-package-ubuntu/13021677#13021677</span> <span class="c1"># https://www.reddit.com/r/Gentoo/comments/ydzkml/nodejs_is_it_ok_to_install_global_packages/</span> </pre></div> <h2><span class="mw-headline" id="Standalone_Node.js_server">Standalone Node.js server</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=4" class="mw-editsection-visualeditor" title="Edit section: Standalone Node.js server">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=4" title="Edit section: Standalone Node.js server">edit source</a><span class="mw-editsection-bracket">]</span></span></h2> <div class="alert alert-danger gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-exclamation-triangle"></i> Warning</strong><br />Node.js and Express.js suggest to run Node.js behind a <b>reverse proxy</b> to mitigate <b>DoS attacks</b> and improve <b>performance</b>. <sup id="cite_ref-1" class="reference"><a href="#cite_note-1">&#91;1&#93;</a></sup><sup id="cite_ref-2" class="reference"><a href="#cite_note-2">&#91;2&#93;</a></sup><sup id="cite_ref-3" class="reference"><a href="#cite_note-3">&#91;3&#93;</a></sup> This section goes against these recommendations and even includes an example of using Node.js itself as a reverse proxy. Not following these recommendations is allowed if the server will not be public. With caution, the methods provided here can be used for small homelab projects. It is also important to understand that reverse proxies are not a panacea. They may contain vulnerabilities that could lead to the execution of arbitrary code (e.g. <span class="plainlinks" style="color: MidnightBlue; font-family: monospace; font-size: 95%;" title="External link to https&#58;//bugs.gentoo.org."><a rel="nofollow" class="external text" href="https://bugs.gentoo.org/show_bug.cgi?id=CVE-2021-23017"><span style="color: MidnightBlue;">bug #CVE-2021-23017</span></a><span style="color: grey; margin-left: 0.1em; font-size: 70%;" class="fa fa-bug fa-fw"></span></span>) or root privilege escalation (e.g. <span class="plainlinks" style="color: MidnightBlue; font-family: monospace; font-size: 95%;" title="External link to https&#58;//bugs.gentoo.org."><a rel="nofollow" class="external text" href="https://bugs.gentoo.org/show_bug.cgi?id=CVE-2016-1247"><span style="color: MidnightBlue;">bug #CVE-2016-1247</span></a><span style="color: grey; margin-left: 0.1em; font-size: 70%;" class="fa fa-bug fa-fw"></span></span>). Not using reverse proxies limits the attack vector to Node.js only.</div> <p>Node.js can be run as a standalone HTTP server. It does not require root privileges and can be accessed from the Internet, for example on port 3000. </p><p>To launch the <a rel="nofollow" class="external text" href="https://nodejs.org/en/learn/getting-started/introduction-to-nodejs">official example</a>, the <code>hostname</code> (a variable in the example) must be set to a public IPv6 or IPv4 address (<code>localhost</code> will not work). The modified example can be executed from the user space as following: </p> <div class="cmd-box"><div><code style="color: #4E9A06; font-weight: bold;">user <span style="color:royalblue;">$</span></code><span class="tripleclick-separator"></span><code>node modified-downloaded-example.js</code></div></div> <p>The only problem is the inability to connect to <a href="https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports" class="extiw" title="wikipedia:List of TCP and UDP port numbers">well-known ports</a> (e.g. 80) from unprivileged user space. But this problem can be solved with <a href="#Port_redirection">port redirection</a>. </p> <h3><span class="mw-headline" id="SELinux_policy">SELinux policy</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=5" class="mw-editsection-visualeditor" title="Edit section: SELinux policy">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=5" title="Edit section: SELinux policy">edit source</a><span class="mw-editsection-bracket">]</span></span></h3> <div class="alert alert-danger gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-exclamation-triangle"></i> Warning</strong><br />The policy provided in this section is created using <code>audit2allow</code>. Review the policy before using it.</div> <p>As of March 26, 2024, the Node.js package does not come with a <a href="/wiki/SELinux" title="SELinux">SELinux</a> policy, so creating a custom policy is required. The following custom policy assumes that Node.js will be executed from unprivileged user space. The policy was tested with Nodejs v. 20.6.1 on the <code>default/linux/arm64/17.0/musl/hardened/selinux</code> profile. </p> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #54487A">FILE</span> <strong><code style="border: none; background: none; color: #54487A; margin-right: .5em;">nodejs-workaround.te</code></strong><strong></strong></div> <div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre><span></span>module nodejs-workaround 1.0; require { type unreserved_port_t; type ntop_port_t; type node_t; type user_t; class process execmem; class tcp_socket { name_bind node_bind }; } #============= user_t ============== #!!!! This avc can be allowed using the boolean &#39;user_tcp_server&#39; allow user_t node_t:tcp_socket node_bind; allow user_t ntop_port_t:tcp_socket name_bind; #!!!! This avc can be allowed using the boolean &#39;allow_execmem&#39; allow user_t self:process execmem; allow user_t unreserved_port_t:tcp_socket name_bind; </pre></div> <div class="alert alert-warning gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-exclamation-circle"></i> Important</strong><br />Delete the following lines if there are no plans to use Node.js on ports other than <code>3000</code>: <p><code>type unreserved_port_t;</code> and </p> <code>allow user_t unreserved_port_t:tcp_socket name_bind;</code></div> <p>To compile and install the policy module, run the commands: </p> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>make -f /usr/share/selinux/strict/include/Makefile nodejs-workaround.pp</code></div><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>semodule --install nodejs-workaround.pp</code></div></div> <p>Node.js should immediately become functional. </p><p>To remove the policy, run the command: </p> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>semodule --remove nodejs-workaround</code></div></div> <p>The policy is created based on the following AVC: </p> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>cat /var/log/audit/audit.log</code></div><span class="mw-collapsible mw-collapsed"><pre>audit: type=1400 audit(1710592438.060:241): avc: denied { execmem } for pid=1795 comm="node" scontext=user_u:user_r:user_t tcontext=user_u:user_r:user_t tclass=process permissive=0 audit: type=1400 audit(1710592130.148:234): avc: denied { name_bind } for pid=1705 comm="node" src=3005 scontext=user_u:user_r:user_t tcontext=system_u:object_r:unreserved_port_t tclass=tcp_socket permissive=0 audit: type=1400 audit(1710592738.512:259): avc: denied { node_bind } for pid=1877 comm="node" saddr=7777:777:7777:7777::1 src=3004 scontext=user_u:user_r:user_t tcontext=system_u:object_r:node_t tclass=tcp_socket permissive=0 audit: type=1400 audit(1710592851.496:274): avc: denied { name_bind } for pid=1920 comm="node" src=3000 scontext=user_u:user_r:user_t tcontext=system_u:object_r:ntop_port_t tclass=tcp_socket permissive=0 </pre></span></div> <p>Other AVC messages caused by Node.js are also present (and will be present after policy definition) in the log. But they do not affect the use of Node.js. The above messages are the only ones that cause Node.js to fail. </p> <h3><span class="mw-headline" id="Port_redirection">Port redirection</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=6" class="mw-editsection-visualeditor" title="Edit section: Port redirection">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=6" title="Edit section: Port redirection">edit source</a><span class="mw-editsection-bracket">]</span></span></h3> <p>This section describes a way to redirect ports using the legacy <a href="/wiki/Iptables" title="Iptables">iptables</a> approach or the modern <a href="/wiki/Nftables" title="Nftables">nftables</a> approach. Choose one. </p> <h4><span class="mw-headline" id="iptables">iptables</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=7" class="mw-editsection-visualeditor" title="Edit section: iptables">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=7" title="Edit section: iptables">edit source</a><span class="mw-editsection-bracket">]</span></span></h4> <p>The redirection requires the following option to be enabled in the kernel: </p> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #4E9A06">KERNEL</span> <strong>Enable redirections</strong></div> <div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre><span></span>[*] Networking support ---&gt; --- Networking support Networking options ---&gt; [*] Network packet filtering framework (Netfilter) ---&gt; --- Network packet filtering framework (Netfilter) Core Netfilter Configuration ---&gt; [*] REDIRECT target support </pre></div> <div class="alert alert-warning gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-exclamation-circle"></i> Important</strong><br />The examples below assume that the server is running on a public IPv6 address. For an IPv4 address use <code>iptables</code> instead of <code>ip6tables</code>, the syntax is the same. IPv4 and IPv6 have separate NAT tables.</div> <p>Assuming the Node.js server is running on port 3000, run the following command to redirect port 80 to 3000: </p> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>ip6tables --table nat --append PREROUTING --protocol tcp --dport 80 --jump REDIRECT --to-port 3000</code></div></div> <p>The server should be immediately accessible via port 80. </p> <div class="alert alert-info gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-sticky-note-o fa-rotate-180"></i> Note</strong><br />The created rule will disappear after a reboot.</div> <p>To see the modified NAT table, run the command: </p> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>ip6tables --table nat --list</code></div><span class="mw-collapsible mw-collapsed"><pre>Chain PREROUTING (policy ACCEPT) target prot opt source destination REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 3000 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination </pre></span></div> <p>To remove the added rule (to change the port or because of a mistake), run the command: </p> <div class="alert alert-warning gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-exclamation-circle"></i> Important</strong><br />Make sure the rule is the first (<code>1</code>) in the <code>PREROUTING</code> chain, otherwise specify the correct number.</div> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>ip6tables --table nat --delete PREROUTING 1</code></div></div> <h4><span class="mw-headline" id="nftables">nftables</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=8" class="mw-editsection-visualeditor" title="Edit section: nftables">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=8" title="Edit section: nftables">edit source</a><span class="mw-editsection-bracket">]</span></span></h4> <p>The redirection requires the following options to be enabled in the kernel: </p> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #4E9A06">KERNEL</span> <strong>Enable redirections</strong></div> <div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre><span></span>[*] Networking support ---&gt; --- Networking support Networking options ---&gt; [*] Network packet filtering framework (Netfilter) ---&gt; --- Network packet filtering framework (Netfilter) Core Netfilter Configuration ---&gt; [*] Netfilter nf_tables support [*] Netfilter nf_tables redirect support [*] Netfilter nf_tables nat module </pre></div> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #4E9A06">KERNEL</span> <strong>IPv6</strong></div> <div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre><span></span>[*] Networking support ---&gt; --- Networking support Networking options ---&gt; [*] Network packet filtering framework (Netfilter) ---&gt; --- Network packet filtering framework (Netfilter) IPv6: Netfilter Configuration ---&gt; [*] IPv6 nf_tables support </pre></div> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #4E9A06">KERNEL</span> <strong>IPv4</strong></div> <div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre><span></span>[*] Networking support ---&gt; --- Networking support Networking options ---&gt; [*] Network packet filtering framework (Netfilter) ---&gt; --- Network packet filtering framework (Netfilter) IP: Netfilter Configuration ---&gt; [*] IPv4 nf_tables support </pre></div> <div class="alert alert-warning gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-exclamation-circle"></i> Important</strong><br />The examples below assume that the server is running on a public IPv6 address. For an IPv4 address use <code>inet</code> or <code>ip</code> instead of <code>ip6</code></div> <p>Create the NAT table and chain: </p> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>nft add table ip6 nat</code></div><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>nft add chain ip6 nat prerouting '{ type nat hook prerouting priority 0; }'</code></div></div> <p>Redirect port <code>80</code> to port <code>3000</code>: </p> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>nft add rule ip6 nat prerouting tcp dport 80 counter redirect to 3000</code></div></div> <p>The server should be immediately accessible via port 80. </p> <div class="alert alert-info gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-sticky-note-o fa-rotate-180"></i> Note</strong><br />The created rule will disappear after a reboot.</div> <p>To see the prerouting chain, run the command: </p> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>nft --handle list chain ip6 nat prerouting</code></div><span class="mw-collapsible mw-collapsed"><pre>table ip6 nat { chain prerouting { # handle 1 type nat hook prerouting priority filter; policy accept; tcp dport 80 counter packets 0 bytes 0 redirect to :3000 # handle 2 } } </pre></span></div> <p>To remove the added rule (to change the port or because of a mistake), run the command: </p> <div class="alert alert-warning gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-exclamation-circle"></i> Important</strong><br />Make sure the rule is matched as <code># handle 2</code> in the above output, otherwise specify the correct number.</div> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>nft delete rule ip6 nat prerouting handle 2</code></div></div> <h3><span class="mw-headline" id="HTTPS">HTTPS</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=9" class="mw-editsection-visualeditor" title="Edit section: HTTPS">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=9" title="Edit section: HTTPS">edit source</a><span class="mw-editsection-bracket">]</span></span></h3> <p>This section relies on <a rel="nofollow" class="external text" href="https://expressjs.com/en/starter/installing.html">Express.js</a> because it provides a simple way to host static files that appear dynamically. All paths match the <a href="/wiki/Let%27s_Encrypt#acme-tiny" title="Let&#39;s Encrypt">acme-tiny configuration guide</a>, but there are no strict requirements, the files can be anywhere. </p> <h4><span id="Certificate_issuance_(Let&#39;s_Encrypt)"></span><span class="mw-headline" id="Certificate_issuance_.28Let.27s_Encrypt.29">Certificate issuance (Let's Encrypt)</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=10" class="mw-editsection-visualeditor" title="Edit section: Certificate issuance (Let&#039;s Encrypt)">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=10" title="Edit section: Certificate issuance (Let&#039;s Encrypt)">edit source</a><span class="mw-editsection-bracket">]</span></span></h4> <p>First, it is necessary to create and run a server script that will host the Let's Encrypt token for the <a rel="nofollow" class="external text" href="https://letsencrypt.org/docs/challenge-types/#http-01-challenge">HTTP-01 challenge</a>: </p> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #54487A">FILE</span> <strong><code style="border: none; background: none; color: #54487A; margin-right: .5em;">http-server.js</code></strong><strong></strong></div> <div class="mw-highlight mw-highlight-lang-javascript mw-content-ltr" dir="ltr"><pre><span></span><span class="kd">const</span><span class="w"> </span><span class="nx">express</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> <span class="kd">const</span><span class="w"> </span><span class="nx">PORT</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3000</span><span class="p">;</span> <span class="kd">const</span><span class="w"> </span><span class="nx">ACME_CHALLENGE_PATH</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;/var/www/localhost/acme-challenge&#39;</span><span class="p">;</span> <span class="kd">const</span><span class="w"> </span><span class="nx">app</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">express</span><span class="p">();</span> <span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="s1">&#39;/.well-known/acme-challenge&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">express</span><span class="p">.</span><span class="k">static</span><span class="p">(</span><span class="nx">ACME_CHALLENGE_PATH</span><span class="p">));</span> <span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">PORT</span><span class="p">);</span> </pre></div> <p>Then redirect port <code>80</code> to port <code>3000</code> as described <a href="#Port_redirection">above</a>. Install acme-tiny as described <a href="/wiki/Let%27s_Encrypt#acme-tiny_.28optional.29" title="Let&#39;s Encrypt">here</a> and issue the certificate as described <a href="/wiki/Let%27s_Encrypt#acme-tiny" title="Let&#39;s Encrypt">here</a>. </p> <h4><span class="mw-headline" id="Certificate_usage">Certificate usage</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=11" class="mw-editsection-visualeditor" title="Edit section: Certificate usage">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=11" title="Edit section: Certificate usage">edit source</a><span class="mw-editsection-bracket">]</span></span></h4> <p>Once the certificate has been issued, the server script needs to be replaced with this one: </p> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #54487A">FILE</span> <strong><code style="border: none; background: none; color: #54487A; margin-right: .5em;">https-server.js</code></strong><strong></strong></div> <div class="mw-highlight mw-highlight-lang-javascript mw-content-ltr" dir="ltr"><pre><span></span><span class="kd">const</span><span class="w"> </span><span class="nx">fs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;node:fs&#39;</span><span class="p">);</span> <span class="kd">const</span><span class="w"> </span><span class="nx">https</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;node:https&#39;</span><span class="p">);</span> <span class="kd">const</span><span class="w"> </span><span class="nx">express</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> <span class="kd">const</span><span class="w"> </span><span class="nx">PORT</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3000</span><span class="p">;</span> <span class="kd">const</span><span class="w"> </span><span class="nx">CERTIFICATE_PATH</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;/var/lib/letsencrypt/chained.pem&#39;</span><span class="p">;</span> <span class="kd">const</span><span class="w"> </span><span class="nx">PRIVATE_KEY_PATH</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;/var/lib/letsencrypt/domain.key&#39;</span><span class="p">;</span> <span class="kd">const</span><span class="w"> </span><span class="nx">app</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">express</span><span class="p">();</span> <span class="kd">const</span><span class="w"> </span><span class="nx">options</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="nx">cert</span><span class="o">:</span><span class="w"> </span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">CERTIFICATE_PATH</span><span class="p">),</span> <span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">PRIVATE_KEY_PATH</span><span class="p">)</span> <span class="p">};</span> <span class="nx">https</span><span class="p">.</span><span class="nx">createServer</span><span class="p">(</span><span class="nx">options</span><span class="p">,</span><span class="w"> </span><span class="nx">app</span><span class="p">).</span><span class="nx">listen</span><span class="p">(</span><span class="nx">PORT</span><span class="p">);</span> </pre></div> <p>Redirect port <code>443</code> to <code>3000</code> as described <a href="#Port_redirection">above</a>. The connection should now be encrypted. The above script doesn't actually require Express.js anymore, but it's left as an example, an example of pure Node.js can be found <a rel="nofollow" class="external text" href="https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener">here</a>. The ACME challenge is not required either, even for renewals. </p> <h3><span id="Node.js_as_a_reverse_proxy_for_Forgejo\Gitea_(or_anything_else)"></span><span class="mw-headline" id="Node.js_as_a_reverse_proxy_for_Forgejo.5CGitea_.28or_anything_else.29">Node.js as a reverse proxy for Forgejo\Gitea (or anything else)</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=12" class="mw-editsection-visualeditor" title="Edit section: Node.js as a reverse proxy for Forgejo\Gitea (or anything else)">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=12" title="Edit section: Node.js as a reverse proxy for Forgejo\Gitea (or anything else)">edit source</a><span class="mw-editsection-bracket">]</span></span></h3> <p>The simplest way to set up a reverse proxy is to use <a rel="nofollow" class="external text" href="https://expressjs.com/en/starter/installing.html">Express.js</a> with <a rel="nofollow" class="external text" href="https://github.com/villadora/express-http-proxy">express-http-proxy</a>. </p><p>The following example shows a way to redirect all requests coming to <code>http://&lt;DOMAIN&gt;/projects</code> to <a rel="nofollow" class="external text" href="https://forgejo.org/">Forgejo</a> (or <a href="/wiki/Gitea" title="Gitea">Gitea</a>). The example assumes that port <code>80</code> is redirected to port <code>3000</code> as described <a href="#Port_redirection">above</a>. </p><p>The minimal Forgejo <a rel="nofollow" class="external text" href="https://forgejo.org/docs/latest/admin/config-cheat-sheet/">configuration</a>: </p> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #54487A">FILE</span> <strong><code style="border: none; background: none; color: #54487A; margin-right: .5em;">&lt;Forgejo\Gitea root directory&gt;/custom/conf/app.ini</code></strong><strong></strong></div> <div class="mw-highlight mw-highlight-lang-ini mw-content-ltr" dir="ltr"><pre><span></span><span class="k">[server]</span> <span class="na">ROOT_URL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">http://&lt;DOMAIN GOES HERE&gt;/projects/</span> <span class="na">HTTP_PORT</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">3001</span> </pre></div> <div class="alert alert-info gw-box" style="padding-top: 8px; padding-bottom: 8px;"><strong><i class="fa fa-sticky-note-o fa-rotate-180"></i> Note</strong><br />Replace <code>http://</code> with <code>https://</code> if HTTPS is used.</div> <p>The minimal HTTP server: </p> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #54487A">FILE</span> <strong><code style="border: none; background: none; color: #54487A; margin-right: .5em;">server.js</code></strong><strong></strong></div> <div class="mw-highlight mw-highlight-lang-javascript mw-content-ltr" dir="ltr"><pre><span></span><span class="kd">const</span><span class="w"> </span><span class="nx">express</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express&#39;</span><span class="p">);</span> <span class="kd">const</span><span class="w"> </span><span class="nx">proxy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express-http-proxy&#39;</span><span class="p">);</span> <span class="kd">const</span><span class="w"> </span><span class="nx">PORT</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">3000</span><span class="p">;</span> <span class="kd">const</span><span class="w"> </span><span class="nx">app</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">express</span><span class="p">();</span> <span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="s1">&#39;/projects&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">proxy</span><span class="p">(</span><span class="s1">&#39;localhost:3001&#39;</span><span class="p">));</span> <span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">PORT</span><span class="p">);</span> </pre></div> <p>To use HTTPS, just inject the following lines in the script provided <a href="#Certificate_usage">here</a>: </p> <div class="gw-box"><div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #204A87">CODE</span> <strong></strong></div> <div class="mw-highlight mw-highlight-lang-javascript mw-content-ltr" dir="ltr"><pre><span></span><span class="kd">const</span><span class="w"> </span><span class="nx">proxy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;express-http-proxy&#39;</span><span class="p">);</span> <span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="s1">&#39;/projects&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">proxy</span><span class="p">(</span><span class="s1">&#39;localhost:3001&#39;</span><span class="p">));</span> </pre></div></div> <h2><span class="mw-headline" id="Web_application_daemons_with_nginx_and_monit">Web application daemons with nginx and monit</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=13" class="mw-editsection-visualeditor" title="Edit section: Web application daemons with nginx and monit">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=13" title="Edit section: Web application daemons with nginx and monit">edit source</a><span class="mw-editsection-bracket">]</span></span></h2> <p>This section will walk through installing Node.js behind nginx and using Monit to keep Node instances alive. Since Node.js is a single-process application, the goal is to launch multiple instances of the application and load balance using nginx. </p> <h3><span class="mw-headline" id="Packages">Packages</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=14" class="mw-editsection-visualeditor" title="Edit section: Packages">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=14" title="Edit section: Packages">edit source</a><span class="mw-editsection-bracket">]</span></span></h3> <p>Use <span style="white-space: nowrap;" class="plainlinks" title="External link to https&#58;//packages.gentoo.org for the app-admin/monit package."><a rel="nofollow" class="external text" href="https://packages.gentoo.org/packages/app-admin/monit"><span style="font-family: monospace; font-size: 95%; color: MidnightBlue;">app-admin/monit</span></a><span style="color: grey; margin-left: 0.1em; font-size: 70%;" class="fa fa-hdd-o fa-fw"></span></span> for spawning Node.js servers. </p> <div class="cmd-box"><div><code style="color: #ef2929; font-weight: bold;">root <span style="color:royalblue;">#</span></code><span class="tripleclick-separator"></span><code>emerge --ask monit nginx nodejs</code></div></div> <h3><span class="mw-headline" id="Configure_Monit">Configure Monit</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=15" class="mw-editsection-visualeditor" title="Edit section: Configure Monit">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=15" title="Edit section: Configure Monit">edit source</a><span class="mw-editsection-bracket">]</span></span></h3> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #54487A">FILE</span> <strong><code style="border: none; background: none; color: #54487A; margin-right: .5em;">/etc/monit.d/my-app</code></strong><strong>Auto restart NodeJS App</strong></div> <div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre><span></span>check process mysql with pidfile /var/run/my-app/mysqld.pid start program = &quot;/bin/bash -c &#39;rc-service mysql start&#39;&quot; stop program = &quot;/bin/bash -c &#39;rc-service mysql stop&#39;&quot; </pre></div> <h3><span class="mw-headline" id="Configure_Nginx">Configure Nginx</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=16" class="mw-editsection-visualeditor" title="Edit section: Configure Nginx">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=16" title="Edit section: Configure Nginx">edit source</a><span class="mw-editsection-bracket">]</span></span></h3> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #54487A">FILE</span> <strong><code style="border: none; background: none; color: #54487A; margin-right: .5em;">/etc/nginx/nginx.conf</code></strong><strong>Nginx Config</strong></div> <div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre><span></span>http { upstream myapp1 { least_conn; server srv1.example.com; server srv2.example.com; server srv3.example.com; } server { listen 80; location / { proxy_pass http://myapp1; } } } </pre></div> <h2><span class="mw-headline" id="Web_application_with_openrc_runscript">Web application with openrc runscript</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=17" class="mw-editsection-visualeditor" title="Edit section: Web application with openrc runscript">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=17" title="Edit section: Web application with openrc runscript">edit source</a><span class="mw-editsection-bracket">]</span></span></h2> <div class="box-caption"><span class="label" style="margin-right: .5em; background-color: #54487A">FILE</span> <strong><code style="border: none; background: none; color: #54487A; margin-right: .5em;">/etc/init.d/nodejs-server</code></strong><strong>Sample init.d file for a Node.js daemon</strong></div> <div class="mw-highlight mw-highlight-lang-bash mw-content-ltr" dir="ltr"><pre><span></span><span class="ch">#!/sbin/openrc-run</span> <span class="w"> </span> <span class="nv">user</span><span class="o">=</span><span class="s2">&quot;nobody&quot;</span> <span class="nv">group</span><span class="o">=</span><span class="s2">&quot;nobody&quot;</span> <span class="nv">command</span><span class="o">=</span><span class="s2">&quot;/usr/bin/node&quot;</span> <span class="nv">directory</span><span class="o">=</span><span class="s2">&quot;/opt/</span><span class="si">${</span><span class="nv">RC_SVCNAME</span><span class="si">}</span><span class="s2">&quot;</span> <span class="nv">command_args</span><span class="o">=</span><span class="s2">&quot;httpd.js&quot;</span> <span class="nv">command_user</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">${</span><span class="nv">user</span><span class="si">}</span><span class="s2">:</span><span class="si">${</span><span class="nv">group</span><span class="si">}</span><span class="s2">&quot;</span> <span class="nv">command_background</span><span class="o">=</span><span class="s2">&quot;yes&quot;</span> <span class="nv">pidfile</span><span class="o">=</span><span class="s2">&quot;/run/</span><span class="si">${</span><span class="nv">RC_SVCNAME</span><span class="si">}</span><span class="s2">.pid&quot;</span> <span class="nv">output_log</span><span class="o">=</span><span class="s2">&quot;/var/log/</span><span class="si">${</span><span class="nv">RC_SVCNAME</span><span class="si">}</span><span class="s2">.log&quot;</span> <span class="nv">error_log</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">${</span><span class="nv">output_log</span><span class="si">}</span><span class="s2">&quot;</span> <span class="w"> </span> depend<span class="o">()</span><span class="w"> </span><span class="o">{</span> <span class="w"> </span>use<span class="w"> </span>net <span class="o">}</span> </pre></div> <h2><span class="mw-headline" id="References">References</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Node.js&amp;veaction=edit&amp;section=18" class="mw-editsection-visualeditor" title="Edit section: References">edit</a><span class="mw-editsection-divider"> | </span><a href="/index.php?title=Node.js&amp;action=edit&amp;section=18" title="Edit section: References">edit source</a><span class="mw-editsection-bracket">]</span></span></h2> <div class="reflist" style="list-style-type: decimal;"> <div class="mw-references-wrap"><ol class="references"> <li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text"><a rel="nofollow" class="external free" href="https://nodejs.org/en/learn/getting-started/security-best-practices">https://nodejs.org/en/learn/getting-started/security-best-practices</a></span> </li> <li id="cite_note-2"><span class="mw-cite-backlink"><a href="#cite_ref-2">↑</a></span> <span class="reference-text"><a rel="nofollow" class="external free" href="https://expressjs.com/en/advanced/best-practice-security.html">https://expressjs.com/en/advanced/best-practice-security.html</a></span> </li> <li id="cite_note-3"><span class="mw-cite-backlink"><a href="#cite_ref-3">↑</a></span> <span class="reference-text"><a rel="nofollow" class="external free" href="https://expressjs.com/en/advanced/best-practice-performance.html">https://expressjs.com/en/advanced/best-practice-performance.html</a></span> </li> </ol></div></div> '
Unix timestamp of change (timestamp)
1715915404