Rudder security & hardening

Rudder provides secure defaults whenever possible, but depending on your use case you can add additional configurations to make your Rudder installation more secure.

Server

HTTPS

  • By default, all HTTPS traffic is handled by the same virtual host in Apache httpd. To allow hardening the connection security, a first step is to split public Web/API from internal node-server communication. You can do so by commenting the default virtual host in /etc/apache2/sites-enabled/rudder.conf or /etc/httpd/conf.d/rudder.conf (depending on the distribution), and uncommenting the two separate configurations. You need to define a method to distinguish both configurations, in general with a different port (which allows applying different firewall rules too) or a specific domain for Web/API.

  • Once your virtual hosts are split, set up a valid certificate for the Web/API. This allows validating the server identity from Web browsers and API clients. You can use an internal PKI or a publicly trusted certificate, like with Let’s Encrypt. The certificate configuration is done in /etc/apache2/sites-enabled/rudder.conf or /etc/httpd/conf.d/rudder.conf depending on your distribution, in the Web/API virtual host. To configure the TLS settings of the Web/API virtual hosts depending on your requirements and platform, we recommend using Mozilla SSL configurator generator.

  • HTTP Strict Transport Security (HSTS) ensures the user’s browser will always use HTTPS to connect to your server. It is not enabled by default as it may conflict with other services served from the same domain (e.g. package repositories). If you only use HTTPS with your Rudder’s server domain, you can enable the HSTS header in /opt/rudder/etc/rudder-web.properties by modifying or adding the following properties (and restarting the rudder-jetty service to apply it):

rudder.server.hsts=true
rudder.server.hstsIncludeSubDomains=true
  • You may want to hide the Apache httpd version from the headers. It cannot be done inside Rudder’s configuration as it is a global httpd setting. To do so, you need to set the ServerTokens parameter to the Prod value (in /etc/httpd or /etc/apache depending on your distribution).

Authentication and user management

  • It is recommended to use an external authentication backend exposing an OpenID connect or OAUTH2 interface with a second authentication factor (TOTP, WebAuthn, etc.), configured through the auth-backends plugins.

  • In case you use local Rudder users, your passwords should be hashed with bcrypt. It may not be the case of you upgraded your server from pre-6.0 versions. You can check this either in the user management page or /opt/rudder/etc/rudder-users.xml.

  • Session expiration is configured by default to 30 minutes of user inactivity. You may want to shorten this value in /opt/rudder/etc/rudder-web.properties by modifying or adding the following property (and restarting the rudder-jetty service to apply it):

rudder.auth.idle-timeout=15 minutes
  • Give minimal privileges to Rudder users using roles (through the user-management plugin).

  • Give minimal privileges to your HTTP API tokens (though the api-authorizations plugin) and use a different token for each application.

Agent

  • If you don’t use the remote-run feature (using the Trigger agent button in node details or the nodes/apply HTTP API), you can totally disable the service listening on the network. This way, your Rudder agents will not expose anything on the network. To do so, you need to disable the rudder-cf-serverd sub-service, with a Rudder technique or the systemctl disable --now rudder-cf-serverd command.

    • Note: On Rudder servers and relays this service is necessary as it handles policy distribution, and hence cannot be disabled.

Network

Generalities

  • Even if all communications are encrypted with TLS 1.2+, we recommend avoiding Rudder communications across public networks, and using a VPN in case you need access outside your private network.

  • Add firewall rules to limit access to Rudder ports to relevant systems.

Pre-establish trust

By default, Rudder agent and server/relay mutually authenticate based on a Trust On First Use (TOFU) principle. The first inventory will provide a key that will be stored by the server on node acceptation, and the agent will pin the server certificate present in the first policies downloaded. The following steps allows configuring Rudder to perform certificate validation from the start by establishing mutual trust with pre-shared information during agent provisioning.

Provisioning an agent with pre-established server trust

Pre-configuring the server information requires providing local changes to the agent just after installation, and should be scripted as part of the node provisioning process. Here the policy server refers to you node’s server, either a relay or a server.

On the policy server, get the key hashes with:

# rudder agent info

[...]
Key/Certificate
           Key hash: MD5=595221aa16c00dcec78ba1259d7708de
           Key hash: sha256//2cMrJbjcdh25hJkzFVlyKs62DXsaFmumbcFpQ6/ZguU=
[...]

Now you need to pin the certificate for both protocols.

  • For HTTPS, put the value of the hash starting with sha256// into /var/rudder/lib/ssl/policy_server_hash on the node.

  • For the policy update protocol:

    • First copy the content of /var/rudder/cfengine-community/ppkeys/localhost.pub from the policy server on the node into /var/rudder/cfengine-community/ppkeys/root-${HASH}.pub, where HASH is the hash starting with MD5= from the info command. It should look like:

# cat /var/rudder/cfengine-community/ppkeys/root-MD5=595221aa16c00dcec78ba1259d7708de.pub
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEA78g1gmG98Sh4hso8mYGagj98M+SZU7mklbC5Ylv90mecsLD9QlcZ
[...]
C9o5xHCOTDecATXMg0gGQHbjm0x0a1nt+X1gyyjNfHLX13n5as9JXf0CAwEAAQ==
-----END RSA PUBLIC KEY-----
  • Then put the MD5= hash into /var/rudder/cfengine-community/ppkeys/policy_server_hash so that it looks like:

# cat /var/rudder/cfengine-community/ppkeys/policy_server_hash
MD5=595221aa16c00dcec78ba1259d7708de
  • To check if the key pinning is correctly configured on the node, you can check the output of rudder agent info (it should indicate full):

[root@rudder ~]# rudder agent info

[...]
        Key pinning: full
[...]

Now you can set your policy server with rudder agent policy-server mypolicyserver and the agent will only accept the connection if it matches the provided key hash, on both communication protocols.

Pre-provision a node on the server

To automate node acceptation on the server while checking the node’s identity, you can use the node creation API. You can make a call to this API in your node provisioning process, and provide the agentKey parameter (which should contain the content of /opt/rudder/etc/ssl/agent.cert on the node), and the accepted status.

This way, once the node sends its first inventory, if the node id and certificate match the pre-provisioned entry, the node inventory will be updated. Please note that you can also pre-defined node properties using this API, to ensure that the pre-provisionned node is already in the correct groups


← Uninstall Webapp administration →