Restricting SSH Sessions for CI/CD with GNU Rush - Thu, Aug 18, 2022
When you are automating the testing and deployment of code, you eventually need to develop a way to securely move the output of you CI/CD pipeline or "artefacts" to a remote system.
Typically this remote system will be either a test or production system where the tested & built artefacts will replace the previous version, become the new "live" version users will access.
There are a few key goals when setting up a deployment mechanism securely to consider -
- Encryption: depending on the sensitivity of the artefacts, it can be essential to encrypt data in transit. Generally speaking, it's a nice to have for all content.
- Authentication: so you don't get any unexpected artefacts deployed by strangers, you want to make sure you can authenticate deployments.
- The principle of least privilege: essentially making sure that by opening up the remote system for deployment, you are not opening it up for potentially unexpected and undesirable access too.
One method for deployment that addresses these requirements when deploying to remote *nix systems is SSH coupled with rsync. The only gap is that typically, even if you use SSH as a transport (encryption, authentication) you by default provide the deployment service account with a full shell. In order to meet the principle of least privilege, you need to allow only the access required to deploy your CI/CD artefacts.
This is where GNU Rush comes in. GNU Rush is a replacement shell you can configure on a *nix user's account, and coupled with some rules you can restrict the deployment user to only be able to use file transfer tools like SCP and RSYNC.
First, install rush. The `rush` binary is part of the Debian `rush` package if that is your distro of choice. Second, Set the `deploy` user (as an example) to use `/usr/sbin/rush` with `usermod –shell /usr/sbin/rush deploy`. Third, add a `rush.rc` file in `/etc/rush.rc` to set your policies. An example which restricts to `scp` and `rsync` in `/var/www/html` (used by this blog!) is below.
rule default
limits t10r20
umask 007
env - USER LOGNAME HOME
fall-through
rule scp-to
command ^scp (-v )?-r -d -t /var/www/html/
set[0] /usr/bin/scp
chdir /var/www/html
newgroup www-data
rule rsync-to
command ^rsync (--server )?
set[0] /usr/bin/rsync
chdir /var/www/html
newgroup www-data