21

I have a Node.JS HTTPS webserver instantiated as follows:

var privateKey = fs.readFileSync('./../ssl/localhost.key').toString();
var certificate = fs.readFileSync('./../ssl/localhost.crt').toString();

https.createServer({
    key: privateKey,
    cert: certificate
}, server).listen(80, 'localhost');

My private key is on my server which Node.JS reads to create the HTTPS webserver. If a hacker has read access to server files he can access the private key and impersonate the webserver.

Should the private key be stored on the server? Should it be destroyed once the HTTPS server has been instantiated?

Randomblue
  • 1,685
  • 3
  • 15
  • 17

2 Answers2

23

You do not want to destroy your private key: you will need it again if you server restarts. Reboots happen sometimes...

That's a generic observation: you want your server to be able to restart in an unattended fashion. Therefore it must contain the private key, and that private key must be available to the server software.

If an attacker hijacks your complete machine, then he gets a copy of your key. That's a fact of life. Live with it. There are mitigations, though:

  • You can use the "DHE" cipher suites for SSL. With these cipher suites, the server key is used for signatures, not for encryption. This means that the attacker who steals your key can thereafter impersonate your server (i.e. run a fake server) but not decrypt SSL sessions which he previously recorded. This is a good property known as Perfect Forward Secrecy.

  • If you store the key in a Hardware Security Module then the key will not be stolen. The attacker may play with the key as long as he has effective control of the server, but not extract it. This decreases his power of nuisance (but HSM are expensive).

In practice, you will just make sure that the file containing the private key is readable only to the system account which runs the server (chown and chmod on Unix-like systems, NTFS access rights on Windows).

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • 1
    Can't a new private/public key be generated at each reboot? – Randomblue Jan 11 '13 at 19:48
  • 8
    @Justin: you can generate a new key pair, but what of the certificate ? SSL clients (Web browser) prefer certificates issued by known CA; self-signed certificates trigger scary warnings; and self-signed certificates _which change after each reboot_ trigger _many more_ scary warnings. – Thomas Pornin Jan 11 '13 at 19:54
  • If you are investing in SSL, then an HSM should be considered part of the total cost of SSL, even if you are using Microsoft's free Certificate Authority for internal certs. – Bill Frank Jan 11 '13 at 20:24
  • hm, it is possible to have HSM module to be simulated for XEN servers ? – zb' Jan 11 '13 at 22:04
  • 1
    @EICTO: If your CPU/north bridge combo supports IOMMU then you can present the PCI device to the guest, I don't think there are virtual HSMs available, though a networked solution would be quite easy to create (also, "HSM Module" is the same as "PIN Number" and "ATM Machine", please don't say it) – Hubert Kario Jan 11 '13 at 23:15
  • @HubertKario I mean HSM for virtual machines, no hardware part at all, just some soft that support same api and provide it to virtual machines. – zb' Jan 11 '13 at 23:18
  • @eicto: like I said, I don't know of any virtual HSMs, creating a custom, networked solution that would support your use case (private keys stored in host machine) is quite easy to create. So, while there may not be ready-to-use solutions, creating one that has the same effect should be easy. Creating one that does implement a PKCS#11 API would be a bit harder, but then it would be a real drop-in-replacement for a real HSM. – Hubert Kario Jan 11 '13 at 23:31
  • It seems safer to have the private key readable only by root, rather than by the "system account which runs the server". Node.js can start as root, read the key file, and then set its user ID and group ID to that system account. That way if some hacks the webapp, they only have the permissions of that system account and can't read the key file. – Paul Lynch Mar 20 '15 at 20:26
2

Probably you are looking for a reverse proxy like nginx. It is considered best practice™.

Applications running in production usually need to run on port 80 (HTTP), port 443 (HTTPS), or both. This can be a challenge if several components of your application interact with the user or you are using a web server on port 80 to deliver other assets. This makes it necessary to proxy to the Socket.IO server, and NGINX is the best way to do that. - Using NGINX and NGINX Plus with Node.js and Socket.IO, the WebSocket API - nginx blog

or HARDENING NODE.JS FOR PRODUCTION PART 3: ZERO DOWNTIME DEPLOYMENTS WITH NGINX

Basically, you are most probably looking for a stable solution also for load balancing, request limiting, etc. while you are trying to store the private key securely.

bessbd
  • 121
  • 2
  • I am not sure how your answer addresses the question. It is discussing private key storage in a Node.JS SSL server. Your answer and the two links don't seem to address private key storage at all. – Neil Smithline Sep 11 '15 at 03:36
  • This way no "paid" private key has to be stored on the hosting server. (Presuming that is a concern.) – bessbd Sep 11 '15 at 07:37
  • 2
    Ahh. I get it. Good answer. Perhaps changing the first sentence to something like `By using a reverse proxy like nginx to terminate SSL you can avoid storing your private key on Node.JS altogether.` will make it less likely that people will be confused the way I was. – Neil Smithline Sep 11 '15 at 13:49
  • @NeilSmithline: Now that you have pointed it out, I am pretty sure I missed a sentence there or two... – bessbd Sep 11 '15 at 15:29
  • Can I delete the private key once the ngnix is started? – Amit Kumar Gupta Dec 18 '18 at 14:47
  • What would be the use case there, @AmitKumarGupta? – bessbd Dec 19 '18 at 17:22
  • Suppose I create 2 users on my server: security guard and worker. Security guard deals with ngnix, SSH keys and other creds. He also runs security services for encryption/decryption. On the other side, worker consumes security services without being aware with any confidential information. For an extra layer of security, I'm thinking to delete the SSH keys as soon as the nginx is started, as, I feel, they're not needed. However, I'm not sure if it'll cause the issue in autoscaling. – Amit Kumar Gupta Dec 20 '18 at 02:31
  • 1
    @AmitKumarGupta: mind that SSH and SSL are not the same ( https://stackoverflow.com/questions/723152/difference-between-ssh-and-ssl-especially-in-terms-of-sftp-vs-ftp-over-ssl ). Also, I believe Thomas Pornin's answer on this question ( https://security.stackexchange.com/a/27890/86513 ) should clarify the private key deletion related issue. – bessbd Dec 20 '18 at 05:29