Ask HN: How can I secure my AWS instance's SSH access if I have no static IP?
When I try to create a new instance on AWS, I get a warning:
`Rules with source of 0.0.0.0/0 allow all IP addresses to access your instance. We recommend setting security group rules to allow access from known IP addresses only.`
What are alternative security measures that I can apply to protect my servers?
47 comments
[ 0.23 ms ] story [ 106 ms ] threadOr if don’t want to do business with Oracle, you can find VPS/VM providers who offer tiny instances for $10-12/yr or less. You don’t need much ram for a bastion. 128M ram would do the trick, and even 64M (you’d have to use a stripped down image/distro though).
There are even providers who offer instances for even less $ and only give you an ipv6 range + NAT IPv4 address with a small port range. This would also work perfectly fine as a bastion.
- have minimal services running, preferably only ssh
- if you have other services running then use iptables or a firewall frontend to block all incoming ports except for the ones you specifically need/want open
- disable root ssh login
- disable password login (eg use ssh keys and preferably with a passphrase too)
- you can also use something like fail2ban or denyhosts but it’s not really necessary if you’ve also done all the above
- yum or apt update it frequently
- For your ssh connection from the bastion to your AWS instance or any other important ssh destinations from the bastion, use a key with a passphrase for increased security (on the off chance your bastion gets compromised)
- Don’t do anything else too important on your ssh bastion.. eg don’t have any important stuff or work laying around on it or other services/applications running. Just use it as a jumphost only.
that way i would not need to keep the keys in the bastion server at all.
https://www.redhat.com/sysadmin/ssh-proxy-bastion-proxyjump
If you want to reply with your contact details I can see if I can get that going and you can take over the vps if you want..
Other options for providers:
- netcup.eu (I use them.. they don’t have small instances but they are super great prices for the sizes they offer)
- Hetzner Cloud (never used but heard great things and their prices are very low)
- OVHCloud (I have dedi servers from Kimsufi and SoYouStart which have been great— OVH is the parent company)
- prgmr.com - these guys have been around since the very beginning of vps hosting. They wrote the book (quite literally) on Xen ( https://www.amazon.com/Book-Xen-Practical-System-Administrat... )
- low $ NAT VPS options:
https://clients.inceptionhosting.com/cart.php?gid=13
https://hosting.gullo.me/pricing
- free ipv6-only vps (or $1/mo to add an ipv4):
https://www.euserv.com/en/virtual-private-server/root-vserve...
- An informative resource: https://lowendbox.com/blog/free-vps-providers/
A compromise of oracle VPS and attacking AWS VPS is same as attacking AWS VPS from internet. If oracle VPS is not compromised, neither will be AWS.
Don’t see the point in this case.
Bastion makes sense if it’s locked down more than destination. This doesn’t apply if there is only one destination and one public service (SSH).
I suggest using AWS AMS or putting it behind vpn.
So back to the bastion. You have the bastion open to all IPs for port 22 because you want to be able to connect to it from anywhere. Yes you also of course lock it down and use best practice sshd config measures. But you only have ssh running and you use keys with passphrase for your outbound ssh connections for increased security. You keep it updated.
Your bastion will not be as locked down as your AWS instance though because it won’t have that AWS security in front of it, but you’re not concerned that much about your bastion, because it only has ssh listening, and you’ve disabled root ssh and password login, you keep it regularly updated, and the only thing you ever do with it is ssh to it and then ssh again to your important endpoints using a key WITH a passphrase.
Your AWS instance is your primary concern and is the important thing that you care about the most here. So you put the most protection in front of that in front of key services. Like OP said, ssh to the AWS instance sort of becomes “internal” so to speak, as you can only come in from the bastion with a key and passphrase.
Even better, no open port anywhere is actually needed.
Additionally, you can ensure password access is disabled and use ssh keys along with 2FA.
Add ipv6 into the mix and it's straight up infeasible to scan for even ONE port on every host!
Port knocking + key auth + non-default port is pretty damn good security, even against zero days in SSH.
If anyone knows about actual working attacks on ssh servers that don't allow password authentication I'd like to know about it. I don't mean state-level attackers who would probably hack into your laptop or strong-arm the hosting provider.
Firewall rules in front of ssh are a good idea but I don’t think that adds security to ssh itself. It does block apps opening ports, as you point out.
I don’t think state level actors can compromise it, if properly configured.
It’s far easier to hack the end point and steal the keys.
Other alternatives include ZeroTier and Nebula afaik, but I've never tried either.
(Still use SSH keys regardless though.)
Sure " simple port scan would reveal it" - but for those other script kiddes that do not do have it prevents it. And BTW, every bit helps of security helps. zerotier at an alternative port is slightly better than port 22.
Assuming you're using Amazon Linux 2 as your AMI, it's just as simple as assigning a instance profile with the right permissions (you can use the managed AmazonSSMManagedInstanceCore policy [2]). And you'll then be able to connect through the AWS Console or CLI.
[1]: https://docs.aws.amazon.com/systems-manager/latest/userguide...
[2]: https://console.aws.amazon.com/iam/home#/policies/arn:aws:ia...
tag_name="tmpip"
tag_time=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
aws ec2 authorize-security-group-ingress --group-id sg-86169665d2453e4 --protocol tcp --port 22 --cidr "$ip/32" --tag-specifications "ResourceType=security-group-rule,Tags=[{Key=Name,Value=${tag_name}},{Key=added,Value=${tag_time}}]"
The tag enables replacing the existing rule via tag Name, the further you go the easier it is to use the API SDKs
We use this for all our bastion hosts.