My biggest headache with most tools (like the article) is that they don't easily support cross-account roles. This leaves me using a combination of the awscli and jq.
I don't make much use of cross-account roles so I haven't added this yet. If you're interested in making a pull request describing how this could be changed to fit in to your workflow, I can look at adding it.
Wow. I was trying to write this exact tool 2 days ago. Thing that stuck me was how to pick the user name. There's no easy way from the API to figure out what the OS image name is and map it to a default user.
I suppose you could store a mapping of AMI IDs to default user names in the script, but this would add a lot of overhead when it comes to creating and releasing new AMI versions.
How about using tags to store the default user name for each AMI? Then you could modify this script to look up the username before connecting.
All of the logic is in one script though - if you download this from the repo and rename it to ssh2ec2 it will work (as long as you have the Boto library installed).
Just like most similar tools, this lacks indices. For example, if you use ASGs (Auto Scaling Groups), all instances would have the same name tag, so, you need to be able to specify an index if there are multiple instances under the same name.
Edit 1: Created an issue [0] already.
Edit 2: Added a request [1] to integrate fwknop [2] for full automation and better security.
I sometimes find myself needing to connect to any instance in a particular ASG, and I don't really care which one. This tool is built to solve that particular problem. If I want to access a specific instance I will address it by its instance ID (ssh2ec2 --instance-id i-123456).
What would the index refer to? The list of instances in an ASG would need to be sorted (perhaps by instance ID) in order for an index to be useful. The behaviour would still be undefined to a certain extent, as the logic would be "return the instance at position n in the list", when the number of instances in the ASG might have changed due to a scaling event.
Edit: Thanks for the pull requests - we can discuss further there.
As you mentioned in the GH issue, Fabric would probably be a better tool - this isn't supposed to be a config management framework or anything in that direction.
Having said that, you can do something on all matching instances with:
If you don't want to implement it - it's fine, don't, I understand it. This tool should be used for ad-hoc commands and there are some other tools that already use an index, which means that I'm not the only one who thinks a little addition like is useful.
As previously covered multiple times, some innovative startups don't even enable SSH for their servers as SSH doesn't fit nicely in the immutable infrastructure paradigm.
> If you don't want to implement it - it's fine, don't, I understand it.
If you want to address a unique instance, do it by instance ID. If you want to address all of them, use the command example Mike put forth. To add an index is redundant. Use fabric if you're interested in that level of control.
Not SSHing to your instances works just fine, until you need to tweak a knob without launching a new instance, or get logs that you didn't know you needed to get. If you feel the need to get on the immutable infrastructure hype train though, go for it.
Or you could just use google cloud and have nice functionality like this by default. :)
We recently began migrating all our infrastructure from EC2 to Google Cloud, and my first impression is that google cloud is ORDERS OF MAGNTITUDE more usable than EC2, rapidly approaching major feature-set parity, cheaper, and seemingly more performant.
Google has the advantage over Amazon of releasing its cloud product half a decade after Amazon, so Google could learn from the mistakes of EC2. Not to mention Google has run its cloud internally for 10+ years, and likely has more capable engineers working on it than Amazon does. After all, Google is a tech company first and foremost... Amazon started as a retailer.
The preparedness of Google is clearly evident in the superiority of its cloud offerings. Google was able to avoid all the bad choices of EC2, and Google Cloud is not gimped by arcane dependencies and backwards compatibility requirements resulting from bad initial choices.
A few things I like much better on Google:
- Networks (equivalent of VPC) are first class citizens. If you launch two virtual machines in the same region, by default they are placed into the same network, and addressable by machine name. Routing is much easier and more intuitive to setup than in Amazon VPC.
- The GUI is way, way, way nicer than the EC2 GUI. Honestly, it does not even compare. The EC2 console is a complete and utter mess, finding what you need is nearly impossible. The google console is plain white, basic HTML, and intuitively structured such that it's obvious where to look for what you need.
- The CLI is also way better than the EC2 CLI. It's one comprehensive SDK with authentication and tab completion built into it from the beginning. There's no need to install multiple SDKs and libraries to interface with the "cloud" like there is with EC2 (aws-cli, boto, s3, are all inconsistently structured tools that you need to install and configure separately). Google is just one single SDK that works perfectly.
- The EC2 documentation is complete shit, often outdated and incorrect, not to mention difficult to browse through (multiple pages on the same topic, all linking to each other). If you have a problem, you usually have to google it and find an EC2 forum thread with 50 people complaining to a support rep about the problem. There is rarely any acknowledgement of bugs or changes in the original documentation. In contrast, the google documentation is clean, follows sane best-practices, and is easily navigable and searchable.
My one complaint about Google so far is that it's not immediately clear how to use native `ssh` and `scp` commands to talk to instances. Instead you need to go through the `gcloud` client. I'm sure there's a way around it, but for now the `gcloud` client has been sufficient.
> After all, Google is a tech company first and foremost... Amazon started as a retailer.
Yet, Amazon has proven to be extremely capable of being both technical and marketable. I almost wanted to stop reading your comment when you said that, but I kept going because I don't use Google Compute.
> The GUI is way, way, way nicer than the EC2 GUI
Absolutely agree, but I don't have Google Compute, can you share some screenshot or pull one off the internet so we can actually compare?
> There's no need to install multiple SDKs and libraries to interface with the "cloud" like there is with EC2
I think this goes back to legacy consolidation/ For example, we still have to rely on s3cmd for certain exclusive operations because aws cli does not offer that out of the box. AWS documentation itself is also not most readable. Furthermore, filtering is quite primitive and limited in most APIs (and also very inconsistent). Some products aren't even available entirely in CloudFormation, or partially available.
> Google has the advantage over Amazon of releasing its cloud product half a decade after Amazon, so Google could learn from the mistakes of EC2
Do people really have all the instances in their infrastructure serving ssh to the public internet?
We use a gateway box that's the only machine in the cluster serving ssh to the public and jump to our other machines from there. Why would you build it any other way?
It depends on the context. In some cases a bastion host makes sense. In others, a security group that limits SSH to a set of IPs is sufficient.
I agree with the point of your comment - allowing SSH from the public internet is not a good idea. However, there is nothing about this script that assumes SSH is publicly available - you could even run this script on your bastion host.
I'm also planning to add an option to use the private IP of the instance so it works seamlessly when you are on a VPN connection linking you to a VPC.
Fair enough. I had an employer many years ago (~12) who insisted in spite of my objections that all of our servers be accessible via ssh (as root! On port 22!) with a shared, 7 character password on the public internet. Worst of all it was an (very small, working with other small businesses) IT consulting company, and my boss insisted on the same thing for client servers.
Needless to say, a number of boxes, both our own and belonging to our clients) ended up as C&C machines for various botnets and I learned a very valuable lesson about how to treat a machine serving ssh to the public internet (namely: don't listen to a boss who doesn't know wtf they're talking about with regards to security, don't allow password ssh logins _ever_, for fuck's sake don't serve ssh to the public internet if you don't absolutely have to, and bloody hell denyhosts!).
The headaches of dealing with pwned machines that were critical to the business in question while I was being paid 30k/year very much colored my opinion of how to handle ssh.
Obviously I quit that job as soon as I had a credible alternative and was able to double my salary twice in two years (amazing what you can do once you know what you're actually worth on the market).
I'm primarily a developer now, but do share some infrastructure management responsibility at the small (9 person) startup where I work now. Aws and opsworks has enabled us to run without a dedicated ops team, and I'm the most security paranoid person on the engineering team.
Perhaps neither here nor there, but an often overlooked feature of boto (the official python AWS client) is that you can create an SSH client to an instance:
Thanks for the link - I wasn't aware of that feature in boto. I think I still would have chosen to shell out to ssh as it gives me more control over SSH options (key forwarding etc.), although I see that boto is using paramiko under the hood so perhaps it would still be possible to get key forwarding and other features.
Being able to go from an EC2 Instance object directly to an SSH session in pure Python will definitely come in handy in future.
> Edit: Wow, a lot of you have built or found ssh-to-ec2 clients.
Indeed, it seems to be a popular itch to scratch. At some point AWS will probably integrate something like this in awscli, thus rendering all of these 'ssh to ec2' scripts pointless :-)
I've done something very similar to this using the Perl SSH::Batch module. That module uses a file called .fornodesrc to list and aggregate servers.
I have a ruby script that uses the AWS SDK to create that file based on tag names, both individual and aggregate sets. SSH::Batch does the dirty work from there since it lets you to simple transformations like SETS - THESE, etc.
32 comments
[ 2.1 ms ] story [ 68.5 ms ] threadhttps://github.com/facebookarchive/ec2-ssh
My biggest headache with most tools (like the article) is that they don't easily support cross-account roles. This leaves me using a combination of the awscli and jq.
https://blogs.aws.amazon.com/security/post/Tx70F69I9G8TYG/Ho...
https://github.com/mikery/ssh2ec2
Bonus points if it opens all the sessions in tmux if there are multiple results.
https://github.com/davidhollenberger/ansible-iterm-profile
I recently published a related tool, keymaker:
https://github.com/kislyuk/keymaker
It lets you connect to EC2 instances using your IAM account (specifically, by uploading your public SSH key to your IAM user account).
How about using tags to store the default user name for each AMI? Then you could modify this script to look up the username before connecting.
All of the logic is in one script though - if you download this from the repo and rename it to ssh2ec2 it will work (as long as you have the Boto library installed).
Seems like maybe we all just scratched our own itches :)
Edit 1: Created an issue [0] already.
Edit 2: Added a request [1] to integrate fwknop [2] for full automation and better security.
[0]: https://github.com/mikery/ssh2ec2/issues/1
[1]: https://github.com/mikery/ssh2ec2/issues/2
[2]: http://www.cipherdyne.org/fwknop/
I sometimes find myself needing to connect to any instance in a particular ASG, and I don't really care which one. This tool is built to solve that particular problem. If I want to access a specific instance I will address it by its instance ID (ssh2ec2 --instance-id i-123456).
What would the index refer to? The list of instances in an ASG would need to be sorted (perhaps by instance ID) in order for an index to be useful. The behaviour would still be undefined to a certain extent, as the logic would be "return the instance at position n in the list", when the number of instances in the ASG might have changed due to a scaling event.
Edit: Thanks for the pull requests - we can discuss further there.
Having said that, you can do something on all matching instances with:
As previously covered multiple times, some innovative startups don't even enable SSH for their servers as SSH doesn't fit nicely in the immutable infrastructure paradigm.
But then there's the real world.
If you want to address a unique instance, do it by instance ID. If you want to address all of them, use the command example Mike put forth. To add an index is redundant. Use fabric if you're interested in that level of control.
Not SSHing to your instances works just fine, until you need to tweak a knob without launching a new instance, or get logs that you didn't know you needed to get. If you feel the need to get on the immutable infrastructure hype train though, go for it.
We recently began migrating all our infrastructure from EC2 to Google Cloud, and my first impression is that google cloud is ORDERS OF MAGNTITUDE more usable than EC2, rapidly approaching major feature-set parity, cheaper, and seemingly more performant.
Google has the advantage over Amazon of releasing its cloud product half a decade after Amazon, so Google could learn from the mistakes of EC2. Not to mention Google has run its cloud internally for 10+ years, and likely has more capable engineers working on it than Amazon does. After all, Google is a tech company first and foremost... Amazon started as a retailer.
The preparedness of Google is clearly evident in the superiority of its cloud offerings. Google was able to avoid all the bad choices of EC2, and Google Cloud is not gimped by arcane dependencies and backwards compatibility requirements resulting from bad initial choices.
A few things I like much better on Google:
- Networks (equivalent of VPC) are first class citizens. If you launch two virtual machines in the same region, by default they are placed into the same network, and addressable by machine name. Routing is much easier and more intuitive to setup than in Amazon VPC.
- The GUI is way, way, way nicer than the EC2 GUI. Honestly, it does not even compare. The EC2 console is a complete and utter mess, finding what you need is nearly impossible. The google console is plain white, basic HTML, and intuitively structured such that it's obvious where to look for what you need.
- The CLI is also way better than the EC2 CLI. It's one comprehensive SDK with authentication and tab completion built into it from the beginning. There's no need to install multiple SDKs and libraries to interface with the "cloud" like there is with EC2 (aws-cli, boto, s3, are all inconsistently structured tools that you need to install and configure separately). Google is just one single SDK that works perfectly.
- The EC2 documentation is complete shit, often outdated and incorrect, not to mention difficult to browse through (multiple pages on the same topic, all linking to each other). If you have a problem, you usually have to google it and find an EC2 forum thread with 50 people complaining to a support rep about the problem. There is rarely any acknowledgement of bugs or changes in the original documentation. In contrast, the google documentation is clean, follows sane best-practices, and is easily navigable and searchable.
My one complaint about Google so far is that it's not immediately clear how to use native `ssh` and `scp` commands to talk to instances. Instead you need to go through the `gcloud` client. I'm sure there's a way around it, but for now the `gcloud` client has been sufficient.
Yet, Amazon has proven to be extremely capable of being both technical and marketable. I almost wanted to stop reading your comment when you said that, but I kept going because I don't use Google Compute.
> The GUI is way, way, way nicer than the EC2 GUI
Absolutely agree, but I don't have Google Compute, can you share some screenshot or pull one off the internet so we can actually compare?
> There's no need to install multiple SDKs and libraries to interface with the "cloud" like there is with EC2
I think this goes back to legacy consolidation/ For example, we still have to rely on s3cmd for certain exclusive operations because aws cli does not offer that out of the box. AWS documentation itself is also not most readable. Furthermore, filtering is quite primitive and limited in most APIs (and also very inconsistent). Some products aren't even available entirely in CloudFormation, or partially available.
> Google has the advantage over Amazon of releasing its cloud product half a decade after Amazon, so Google could learn from the mistakes of EC2
Certainly.
We use a gateway box that's the only machine in the cluster serving ssh to the public and jump to our other machines from there. Why would you build it any other way?
I agree with the point of your comment - allowing SSH from the public internet is not a good idea. However, there is nothing about this script that assumes SSH is publicly available - you could even run this script on your bastion host.
I'm also planning to add an option to use the private IP of the instance so it works seamlessly when you are on a VPN connection linking you to a VPC.
Needless to say, a number of boxes, both our own and belonging to our clients) ended up as C&C machines for various botnets and I learned a very valuable lesson about how to treat a machine serving ssh to the public internet (namely: don't listen to a boss who doesn't know wtf they're talking about with regards to security, don't allow password ssh logins _ever_, for fuck's sake don't serve ssh to the public internet if you don't absolutely have to, and bloody hell denyhosts!).
The headaches of dealing with pwned machines that were critical to the business in question while I was being paid 30k/year very much colored my opinion of how to handle ssh.
Obviously I quit that job as soon as I had a credible alternative and was able to double my salary twice in two years (amazing what you can do once you know what you're actually worth on the market).
I'm primarily a developer now, but do share some infrastructure management responsibility at the small (9 person) startup where I work now. Aws and opsworks has enabled us to run without a dedicated ops team, and I'm the most security paranoid person on the engineering team.
http://boto.cloudhackers.com/en/latest/ref/manage.html#boto....
given that you have an EC2 `Instance` object, which can be hydrated in a variety of ways.
Edit: Wow, a lot of you have built or found ssh-to-ec2 clients.
Being able to go from an EC2 Instance object directly to an SSH session in pure Python will definitely come in handy in future.
> Edit: Wow, a lot of you have built or found ssh-to-ec2 clients.
Indeed, it seems to be a popular itch to scratch. At some point AWS will probably integrate something like this in awscli, thus rendering all of these 'ssh to ec2' scripts pointless :-)
I have a ruby script that uses the AWS SDK to create that file based on tag names, both individual and aggregate sets. SSH::Batch does the dirty work from there since it lets you to simple transformations like SETS - THESE, etc.