Do not trust the firewall on the bastion host, if an attack can get into the bastion host, they can disable the firewall, so it cannot be used to limit egress. It's better than nothing, but consider using a firewall that's managed on a via a separate management network. I do agree that you should only allow SSH from a few known IPs.
Limiting the number of users is weird, and not recommended. Create all the accounts you need to provide individual accounts for the staff that need to access the bastion host, you will need that as things like HIPAA require named accounts for auditing. None of the accounts need any privileges other than the most basic. Users do not need sudo/root privileges on a jump host.
Other than those two complains, it's good recommendations.
A final recommendation: If you use AWS though, consider using Session Manager instead of SSH and drop the bastion host. You can still connect using the SSH command, using proxy command in OpenSSH, but no public IP or bastion host is required.
> A final recommendation: If you use AWS though, consider using Session Manager instead of SSH and drop the bastion host. You can still connect using the SSH command, using proxy command in OpenSSH, but no public IP or bastion host is required.
I wrote something similar after I moved our fleet to SSM because I didn't want yet another CLI app to memorize flags on. It's ruby based and runs in an interactive mode by default. It doesn't cover the whole set of `aws ssm` featureset but focuses just on things that are needed for debugging sort of tasks. Leaving it here incase it's useful to anyone else: https://github.com/ajbdev/ruby-ssm-ops
Nitpick: the aws-connect quickstart suggests to install it through bpkg. But it turns out that bpkg does not have any "uninstall" or anything similar. I ended up doing just:
> if an attack can get into the bastion host, they can disable the firewall, so it cannot be used to limit egress.
This assumes that the attacker can get unconstrained root access to the system. It's fine to assume that attackers will but it's not as if you can't make that difficult.
At least in the DoD and IC environments I've worked in that had bastion hosts, the bastion host was severely locked down:
- Shell compiled without built-ins
- No coreutils
- No sudo
- Root account disabled
- Read-only root filesystem
- No user home directories
- Destroyed and rebuilt from template every X hours on some maintenance schedule
Effectively, all you can do is ssh in, ssh out, and forward ports. It might be theoretically possible, but as far as I know, no one has ever compromised one, especially since you can already only get to the bastion from a government VPN anyway, and authentication to that requires a smart card, so there are an awful lot of things you need to compromise to get to that point.
This also answers the suggestion down the page of "why don't you just apply the same controls to every host and not have a bastion." Because the bastion is unusable and you want to actually use your other hosts.
From a defense standpoint, one should consider "shell on a box" to usually mean attackers can get root on a box. If they can get persistence, they can wait for a kernel CVE to abuse.
Now, if you're just using a bastion as a jump host, you don't need to offer shells on it. Just allow people to proxy a port to behind the bastion and be done with it.
PermitTTY no
ForceCommand /usr/sbin/nologin
AllowTcpForwarding yes
AllowAgentForwarding no
I think it's probably reasonable when performing your incident response or even threat modeling to assume the attacker has or could escalate privileges. The linked article doesn't discuss anything that would make that harder, although perhaps practices like staying patched and minimizing attack surface are somewhat assumed (they do bring up choosing your OS based on minimizing attack surface for example).
There's also a lot you can do to harden that boundary. You can harden your kernel, you can execute user's shells in constrained environments like docker containers or restricted shells, leverage sandboxing technologies like apparmor or selinux, etc.
The user/root boundary can be a lot thinner than people expect, so I get why you'd want to point out that reliance on the attacker not escalating should be met with an evaluation of that boundary, but I think it may be understating the boundary to unconditionally not trust a host based firewall, or to say that getting onto the bastion itself is enough to disable the firewall when it does indeed require escalation.
I haven't actually tried it, but you can use SSM in your ssh config as a ProxyCommand. As I understand it, that will allow you to just use the ssh command as normal, with all the normal ssh abilities to do tunneling and port forwarding.
Do not trust the firewall on the bastion host, if an attack can get into the bastion host, they can disable the firewall, so it cannot be used to limit egress. It's better than nothing, but consider using a firewall that's managed on a via a separate management network. I do agree that you should only allow SSH from a few known IPs.
Limiting the number of users is weird, and not recommended. Create all the accounts you need to provide individual accounts for the staff that need to access the bastion host, you will need that as things like HIPAA require named accounts for auditing. None of the accounts need any privileges other than the most basic. Users do not need sudo/root privileges on a jump host.
Other than those two complains, it's good recommendations.
A final recommendation: If you use AWS though, consider using Session Manager instead of SSH and drop the bastion host. You can still connect using the SSH command, using proxy command in OpenSSH, but no public IP or bastion host is required.