Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
In #1173644: Use winrs when using "drush ssh" command on Windows, we discuss adding a drush ssh command and --bastion argument to that command to allow people to execute the following flow:
- SSH to a predefined site
- Forward the key through a bastion or intermediary server
- End up on the target command line
After speaking with both bjaspan and msonnabaum, we believe it would be useful to do a similar dance for drush aliases. I am willing to write this functionality. I just need a couple of pointers as to where I should begin.
The end result would be that users could run drush @site [command] --bastion=foo.bar.com
(or define it in their aliases file) and have it successfully return the result of the command.
Comments
Comment #1
greg.1.anderson CreditAttribution: greg.1.anderson commentedSounds pretty cool, but is it necessary to support as a drush feature? See http://backdrift.org/transparent-proxy-with-ssh for an example. It seems that if @site has 'remote-host' => 'myhost.com', then you could just make an entry in your .ssh/config as shown in the above link where
Host myhost.com
has a ProxyCommand to foo.bar.com.It is not clear to me how to do this via commandline options to ssh (instead of a ProxyCommand in .ssh/config); however, if you provide an example of how to do this, it would be pretty easy to add the option to drush's backend invoke mechanism.
Comment #2
moshe weitzman CreditAttribution: moshe weitzman commentedThe bastion stuff is in the category of "I'll take it if it just costs a dozen lines of reasonably simple code". If it is more than that, then it isn’t worth it IMO. Quite a specialized need.
Comment #3
greg.1.anderson CreditAttribution: greg.1.anderson commentedIt's probably about half a dozen lines in backend invoke if it is supported via ssh commandline args. If we have to connect to the bastion host and run netcat "by hand", then it's not worth it -- use .ssh/config.
Recipes welcome.
Comment #4
greg.1.anderson CreditAttribution: greg.1.anderson commentedFrom
man ssh
, it looks like you could drop-o "ProxyCommand ssh user@foo.bar.com nc %h %p"
on the ssh commandline, and in theory that will use foo.bar.com to connect to whatever hostname you are trying to ultimately reach (e.g. myhost.com).How do you do that? Well, you could add 'ssh-options' => '...' to your site alias, and it should work the way you expect it to.
If someone wants to try this out, then 'bastion' => '...' could be shorthand for "append a -o ProxyCommand to my ssh-options", and could be implemented in just a few lines of code.
Comment #5
webkenny CreditAttribution: webkenny commentedI'll give it a run. It's just been my experience with larger enterprises that bastions are all the rage. I agree it's kind of edge case. I have to agree with you both even though I proposed it. If it's more than a few lines of code and a test or two, it's not worth it. :)
I'll report back shortly.
Comment #6
webkenny CreditAttribution: webkenny commentedDid some testing of the above scenario passing -o to the ssh-options - Got the following output which makes me believe drush is attempting to directly access the 2nd hop.
I thought originally that perhaps the lack of -A was causing the key not to forward but the error made me think different.
Anyway, still working on this and I think it will probably end up as a recipe in the documentation as these initial passes are making me think this could be trickier than it's worth.
Comment #7
webkenny CreditAttribution: webkenny commentedWell look at that. The reason I thought it was trying to connect to the backend host first was that it was. :) The ProxyCommand should be the bastion (the proxy, duh) and the drush definition in the alias should be the backend server's hostname and user. This gets even slicker when using SSH config files.
I'll write up some cohesive documentation to this end. Where do we prefer recipes go? Does it make sense to write this as an example in the drush package's doxygen docs?
Comment #8
greg.1.anderson CreditAttribution: greg.1.anderson commentedI think that the recipe could go in examples/example.aliases.drushrc.php file.
Comment #9
moshe weitzman CreditAttribution: moshe weitzman commentedPerhaps docs should go in example.aliases.drushrc.php.
Comment #10
greg.1.anderson CreditAttribution: greg.1.anderson commentedI was just using this today. I can easily do something like this in my .ssh/config file:
Works great!
I can also put something like this in my drush alias file:
However, I need one more feature. I'd like to put in the 'ssh-options' conditionally, so that my laptop will use the bastion server when I'm away from work, but will go straight to the server when I'm in a specified network (e.g. inside the corporate intranet).
In
man ssh_config
, there is this intriguing reference to a 'from' attribute in the 'pattern lists' section:I can't get this 'from' thing to work. With
From="!172.?.?.?"
, I get the following error message:If this isn't an ssh feature after all, then I could either (a) make a wrapper script for ssh that specifies a separate config file based on my network settings, or (b) use drush features to conditionally include options in my alias records. The ssh config
from
option would be the best and simplest way to get this functionality, though, if it works. Can anyone confirm or deny this ssh feature?Comment #11
greg.1.anderson CreditAttribution: greg.1.anderson commentedI stopped short at looking at the source of ssh, but it seems there isn't a way to make .ssh/config react conditionally to the network environment you are operating in. So, this is what I did instead:
In my drushrc.php:
In my alias file, servers.aliases.drushrc.php:
Then, any server that needs to go through the Bastion just has an entry
'parent' => '@intranet-proxy'
. This will add the Bastion proxy command to any site that needs it, but only if you are outside the intranet that it lives in.If this technique looks reasonable to everyone, I'll write up some documentation. I'll probably add a bastion server topic to
drush topic
, and reference it from example.aliases.drushrc.php.Comment #12
moshe weitzman CreditAttribution: moshe weitzman commentedlooks reasonable to me.
Comment #13
greg.1.anderson CreditAttribution: greg.1.anderson commentedCommitted http://drupalcode.org/project/drush.git/commit/4da1d73 to master.
I think these instructions should all work in drush-4.x, so this could be backported if desired. Just needs testing on 4.x.
Comment #14
webkenny CreditAttribution: webkenny commentedGreg, this is a killer addition to the documentation! I love the network-aware piece you added. I'll test this out on a drush 4 install a little later today and we'll see if we can get this back ported (I think we can, since I started off on this road with drush 4, but I'll let you know) - If it works, I'll roll a patch for 4.x
This is why I love this community. Good ideas become great ideas in the hands of the contributors.
Comment #15
greg.1.anderson CreditAttribution: greg.1.anderson commentedNow I am using drush to manage my non-Drupal ssh connections, punching through my firewall (conditionally) with ease. Be sure to try the ssh alias in examples/example.bashrc in master. If you add your own alias
alias ssh='sshd'
then you can usessh @mydrushalias
to skip over to your internal machine. Must say it's quite nifty -- thanks for turning me on to ssh's bastion features.Comment #16
greg.1.anderson CreditAttribution: greg.1.anderson commentedThanks for your great blog post on this feature.
Comment #17
moshe weitzman CreditAttribution: moshe weitzman commentedTell folks about new docs
Comment #18
moshe weitzman CreditAttribution: moshe weitzman commentedAdded change notice: http://drupal.org/node/1407114
Comment #19
msonnabaum CreditAttribution: msonnabaum commentedDocs backported.