Manage multiple secure Node servers with one tool.
This project is in beta. There are lots of debug logs that have been left in.
The project has not been fully vetted for security vulnerabilities, and should not be used in production.
- Run and maintain multiple Node servers with one tool, each with its own process (and optionally its own user, group, working directory, and environment variables)
- TLS SNI (think vhost, but for TLS)
- Different certificates for each host
- Distinct Mutual TLS (mTLS) settings for each host
- Optional plaintext HTTP fallback
This project started out of a need to host multiple Node HTTPS servers on the same machine with some requiring mTLS and some not. My options were to either require mTLS on all endpoints and only enforce validation on some, which would create issues with UX, or use renegotiation and forgo the security benefits from the latest TLS version. So, I decided to build my own tool. Because I also needed to manage these servers, I decided to turn this tool into one that would automatically spawn these Node servers as well. It's still a work-in-progress, but most things should work.
- Recent version of Node
- Recent version of TypeScript (one that supports project references)
- Install and configure the server.
- Create a server using Node.
- Pass the server (with options, if necessary) to the handler.
- Run InterTLS!
Tested on Ubuntu Server:
# clone the repo
git clone https://github.com/hieyou1/intertls.git
# cd into the repo
cd intertls-main
# use your text editor of choice; see "Configuration" for details
nano config.json
# install packages
npm i
# build
npm run build
# run intertls
./dist/run.js
# install intertls as a service (for systems that use systemctl)
# fix path to intertls and create intertls.service
sed "s|/PATH/TO/intertls|$(pwd)|g" SAMPLE_intertls.service > intertls.service
# copy service to systemctl
sudo cp intertls.service /etc/systemd/system
# start service
sudo systemctl start intertls.service
# (optional) enable service on boot
sudo systemctl enable intertls.service
$schema
: For a full JSON schema, see config.schema.json.log
: Centralized logging. Either a list ofLogType
s (newsock
(high-level information about creation [and potential forced destruction] of new sockets),sni
,ipc
,child_procs
(console logs from your servers),handler
(logs from the InterTLS handler itself),init
) or aboolean
to enable/disable logging as a whole.port
: Main port InterTLS should listen on. Usually 443.encoding
:BufferEncoding
InterTLS should use when transferring data in string format to and from its child processes (servers). utf8 is good for logging purposes, otherwise, base64 is probably a good bet.tcpFallback
: Set to true to enable the plaintext TCP & HTTP fallback; be sure to also settcpPort
.tcpPort
: Port InterTLS should listen on fortcpFallback
. InterTLS expects plaintext HTTP traffic on this port. Usually 80. Ignored whentcpFallback
is set to false.servers
: Array of servers for InterTLS to run, manage, and forward traffic to.host
: String or string array specifying hostname(s) of this server. Should match the server name that clients pass in for SNI and the HTTPHost
header if using TCP fallback.tls
: TLS options for this server. Set to{"dynamic": true}
to dynamically handle TLS, otherwisecert
,key
, andrequestCert
are required.ca
andrejectUnauthorized
are the two other options that have been tested and are explicitly defined in the schema, and YMMV with other SecureContextOptions, but feel free to try them and PR!process
: Node options for this server.main
: Node entrypoint of the server.cwd
: Working directory of the server.env
(optional): Object with environment variables to pass to the server. Defaults to {}.uid
(optional): User ID for the process. Defaults to the user of the process running InterTLS (which is probably not what you want!)gid
(optional): Group ID for the process. Defaults to the group of the process running InterTLS (which is probably not what you want!)
ipFallback
: TLS configuration (seeservers.tls
above) for those accessing the server that bypass SNI by connecting directly to its IP.
dynamicTLS
: If using Dynamic TLS, this should be a function that takes in ahost
as a string and returns aPromise
with the SecureContextOptions to use for it.autoListen
: Set tofalse
to prevent the InterTLS handler from automatically listening for IPC messages from the parent. Useful if there is additional logic to be done after invoking the handler.override
: If needed, declaratively override thelocalAddress
andlocalPort
attributes of theMockTcp
streams that are emitted to the server.
This project is licensed under GPLv3.