leafac / kill-the-newsletter

Convert email newsletters into Atom feeds
https://kill-the-newsletter.com
MIT License
2.31k stars 113 forks source link

Should never run as root #42

Closed Daniel15 closed 2 years ago

Daniel15 commented 2 years ago

The example systemd configuration is very insecure as it runs kill-the-newsletter as root: https://github.com/leafac/kill-the-newsletter/blob/main/deployment-example/kill-the-newsletter.service. This is generally a bad idea, but especially in the case of interpreted languages like JavaScript.

I'd recommend changing it to a dedicated user, or at least the "www-data" or "nobody" user depending on which Linux distro is in use - Debian uses "www-data" for web services whereas RHEL/CentOS uses "nobody".

I'd change it and submit a PR but I'm not not sure if any other documentation pages would need updating too.

Daniel15 commented 2 years ago

Just saw you have a section in the readme about this - It was collapsed so I missed it.

Daniel15 commented 2 years ago

For what it's worth, this config is sufficient to allow it to run as a non-root user yet still listen to port 25:

[Unit]
Description=Kill the Newsletter!
After=network.target

[Service]
ExecStart=/opt/kill-the-newsletter/kill-the-newsletter /etc/kill-the-newsletter/configuration.js
Environment=NODE_ENV=production
User=www-data
Group=www-data
Restart=always
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

and this is the config I'm using - I have an Nginx reverse proxy so I'm just serving plain HTML from Kill the Newsletter and then Nginx encrypts the connection:

module.exports = async (require) => {
  const path = require("path");
  const express = require("express");
  const killTheNewsletter = require(".").default;

  const { webApplication, emailApplication } = killTheNewsletter(
    path.join(__dirname, "data")
  );

  webApplication.set("url", "https://example.com/");
  webApplication.set("email", "smtp://example.com");
  webApplication.set("administrator", "mailto:example@d.sb");

  webApplication.listen(8392, 'localhost', () => {
    console.log('Web server started');
  });
  emailApplication.listen(25, () => {
    console.log("Email server started");
  });
};

Both of these might be worth documenting?

leafac commented 2 years ago

Thanks for all the information. I trust that other people like yourself who are running reverse proxies and who care about not running services as root will know how to manage this. At this point there are so many things that become specific to one’s setup that I don’t consider it necessary to document. Thanks again for your contribution!