GithubHelp home page GithubHelp logo

programingjd / bit.node.servers.multidomain Goto Github PK

View Code? Open in Web Editor NEW
0.0 3.0 0.0 98 KB

nodejs http2 server that supports handling requests for several domains with different certificates

License: MIT License

JavaScript 99.25% HTML 0.75%

bit.node.servers.multidomain's Introduction

Node.js version Bit.dev package GitHub package.json version GitHub Travis (.org) Coveralls github

Node.js module.

HTTPS server with support for multiple domains with different certificates.

HTTP requests redirect to HTTPS with the HSTS header.

Requests are upgraded to HTTP2 requests if the client supports it.

There's a special endpoint to trigger a renewall of the certificates from let's encrypt.

Usage

const Server = require('@bit/programingjd.node.servers.multidomain');
const server = Server();
const handler = (request, response, hostname, remoteAddress, serverInstance)=>{
  response.writeHead(200, { 'Content-Type': 'text/plain' });
  response.write(`Request from ${remoteAddress} to ${hostname}\n`);
  response.end(`Hostnames served: ${serverInstance.hostnames()}`);
};
(async()=>{
  await server.addServer(
    {
      hostnames: [ 'mydomain.com', 'www.mydomain.com' ],
      key: {
        path: 'path/to/domain/certificate/key'
      },
      cert: {
        path: 'path/to/domain/certificate'
      },
      handler: handler
    }
  );
})();

The addServer async function takes a server object, representing a list of domains served with the same certificate.

The server object has these properties:

  • hostnames (required)

    the list of domain names that the certificate covers

  • key.path (required)

    the path to the certificate key

  • cert.path (required)

    the path to the certificate

  • acme.email (optional)

    the email of a Let's Encrypt account

  • handler (optional)

    the function called to handle the requests

  • handlers (optional)

    an array of handler objects

The default handler loops through the array of handlers (accessible through server.handlers). The first one that accepts the request is used to handle that request. If no handler accepts the request, then a 404 NOT FOUND response is sent.

You can override this behaviour by providing your own handler function. It takes these parameters:

  • request

    the request object (Http2ServerRequest)

  • response

    the response object (Http2ServerResponse)

  • hostname

    the hostname from the request url

  • remoteAddress

    the ip address the request originates from ('127.0.0.1' for a request made from the same host)

  • handlers

    the array of handlers supplied through the server object handlers property

Handler objects have two required properties:

  • accept

    a function that returns null when this handler cannot handle the request, but returns an object with all the information needed to handle the request if it can

    its parameters are the same as the server's main handle function except that the list of handlers is missing:

    • request

      the request object (Http2ServerRequest)

    • response

      the response object (Http2ServerResponse)

    • hostname

      the hostname from the request url

    • remoteAddress

      the ip address the request originates from ('127.0.0.1' for a request made from the same host)

  • handle

    the function responsible for handling the request, which takes the result of the accept call as parameter

Certificate updates

If the certificate is issued by Let's Encrypt, you can make use of the special endpoint to trigger a certificate update. The new certificates are replaced on the fly and the server doesn't need to be restarted.

Note that the optional acme.email property on the server object is used as the email for the account when requesting certificate updates. Therefore, the request will fail if this was not specified.

The endpoint is /update_certificate. It needs to be called via http (not https) and it only works on the same host. It also needs to be called for each server object.

E.g. http://domain1.com/update_certificate

This endpoint returns a 200 OK response when the update succeeds and a 500 Internal Server Error when it doesn't.


You can also trigger a certificate update from code by using the updateCertificate async function on the server instance.

It takes one parameter: hostname.

It returns true when the update succeeds and false when it doesn't.

Running the server with Systemd

The server supports running via Systemd with socket activation.

This is very useful for binding to port 80 and 443.

You should not specify the http and https ports in the Server constructor when you intend to bind to systemd activated sockets. The http server will bind to the first activated socket and the https server will bing to the second.

Example configuration:

MyServer.service

[Unit]
Description=nodejs multiserver
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/home/admin/myserver
ExecStart=/usr/bin/node myserver.js
NonBlocking=true
Restart=on-failure
RestartSec=15s

[Install]
WantedBy=multi-user.target

MyServer.socket

[Socket]
ListenStream=80
ListenStream=443
NoDelay=true

[Install]
WantedBy=sockets.target

You can also have the certificates renewed by Systemd timers. Remember that you need to call the update_certificate endpoint for each group of domains handled by the same certificate.

Domain1CertificateRenewal.service

[Unit]
Description=domain1.com certificate renewal
Wants=Domain1CertificateRenewal.timer

[Service]
ExecStart=/usr/bin/curl "http://domain1.com/update_certificate"
WorkingDirectory=/home/admin

[Install]
WantedBy=multi-user.target

Domain1CertificateRenewal.timer

[Unit]
Description=Runs domain1.com certificate renewal every week
Requires=Domain1CertificateRenewal.service

[Timer]
Unit=Domain1CertificateRenewal.service
OnBootSec=5min
OnUnitInactiveSec=1w
RandomizedDelaySec=12h
AccuracySec=1h

[Install]
WantedBy=timers.target

bit.node.servers.multidomain's People

Contributors

programingjd avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.