Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

A trick I learned recently: create .ssh/config

File format: as many of the following blocks as you like

  Host $ALIAS <-- whatever you want here
  Hostname www.example.com
  User someuser
  Port 1234
You can now ssh to that server as that user by doing "ssh $ALIAS" on the command line, without needing to specify the port or user with the usual command line arguments, or necessarily spell out the entire host name.


What is more, you can specify an abstraction for the tedious double-ssh where you first connect to some internet-facing host in order to gain access to an internal machine:

    Host $ALIAS
        User $USER
        HostName $INTERNAL
        ProxyCommand ssh $USER2@$PUBLIC -W %h:%p
Now

    laptop> ssh jim@public.example.com
    public> ssh dev@myworkstation
becomes

    laptop> ssh work
(I just realized that this slightly confused article seems to accomplish the same by using a convoluted setup of port-forwardings and netcat.)


The ssh -W option -- which replaces netcat -- is relatively new. E.g. Redhat 5.x did not have it, nor did Ubuntu 10.04 LTS. Until OpenSSH 5.4 netcat was the way to do this sort of proxying.


I ran into an issue[1] with the combination of -W and control persist -- using openssh versions < 6.0.

netcat worked fine.

  [1]: https://news.ycombinator.com/item?id=4678117


And if your router keeps dropping idle connections, add something like:

    ServerAliveInterval 240
    ServerAliveCountMax 5


Can help on mobile (3G/4G) connections too.


> (I just realized that this slightly confused article seems to accomplish the same by using a convoluted setup of port-forwardings and netcat.)

Yeah, the article sets separately first

    Host bar
      ...
and then

    Host behind.bar
      ...
But it can also be done by just one step:

    host behindbar
      User         <user-behindbar>
      Hostname     behindbar.domain
      ProxyCommand ssh <user-bar>@bar.domain nc %h %p 2> /dev/null


I use autossh[1] to keep a tunnel open in the background to $PUBLIC which lets me connect faster to $INTERNAL.

[1] http://www.harding.motd.ca/autossh/


A favorite .ssh/config feature of mine is pattern matching on hostnames with "?" and "*". So you can say something like:

    Host bos-??
    HostName %h.mydomain.com
    IdentityFile ~/.ssh/my-boston-key

    Host nyc-??
    HostName %h.mydomain2.com
    IdentityFile ~/.ssh/my-nyc-key
and log in with e.g. "ssh bos-14".


Yeah, I use a similar thing for ec2:

    Host *.amazonaws.com
      User ec2-user
      IdentityFile ...
And then it is just

    ssh ec2-X-X-X-X.compute-1.amazonaws.com


This seems to be relatively new. It doesn't work on a couple of boxes I tried.

Thanks though, I didn't know about the ?? syntax.


I found references to it going back to 2008, and the git repo that has my dotfiles says I've been using it (in Linux) for 3 or so years. Maybe it depends on the OS/distro.

The patterns are similar to shell globs: * matches zero or more characters, ? matches exactly one.


This is excellent advice. The best part is that you can use the same $ALIAS for tools built on SSH, including scp and rsync, like this:

    scp $ALIAS:/var/log/mylogs/logfile ~/backups/logs/


The aliases also work when mounting filesystems over the network in the File Browser.

Nautilus / Connect to Server / Server Address: work/home/user

(here 'work' is the alias for the work computer)


And.... Ansible uses those aliases too, making it trivial to maintain *NIX server that are behind firewalls and/or vpns.


Well, that sure beats my .bashrc that's full of alias "servername"="ssh user@servername -p portnum"...


What's more, you can specify as many Host aliases (on one line) as you want (with wildcards):

    Host 192.168.* *.foo.*.com *.bar.net


I've been doing this for a while now, but my file is now huge and it's cumbersome to edit. Is there no utility to mange that file?


I've worked around this by creating a ~/.ssh/config.d directory and splitting my configuration out into multiple files (normally by project). I then use dotdee[1] to watch that directory and automatically rebuild ~/.ssh/config anytime there is a change.

[1] https://launchpad.net/dotdee


I don't know of any, but one thing you can do is split up your config into multiple files and then use `cat` to combine them after making a change. There's also https://github.com/markhellewell/sshconfigfs


Here's what I put in my .bashrc:

  alias compile-ssh-config='echo -n > ~/.ssh/config && cat ~/.ssh/*.config > ~/.ssh/config'
  alias ssh='compile-ssh-config && ssh'
Compiles all your ~/.ssh/*.config files into a single ssh config file. It's simple and stupid and seems to do the trick.


I think storm[0] is what you are looking for.

[0] https://github.com/emre/storm


Aside from the ones already mentioned, there's a library called dot-ssh-config[1] that is useful for generating SSH configs.

[1] https://github.com/aelse/dot-ssh-config


Sadly, this doesn't work always. Some apps which implement their own ssh don't support ~/.ssh/config. For example, the OSX Subversion GUI client Cornerstone doesn't support this.


I'm confused how this is better than just using an alias/profile?

Maybe it is just me, but I prefer to dump all my custom commands and aliases into .zshrc so they are easy to backup/track/find.


You have been down voted, but the question is reasonable.

One reason is so that invocations of ssh outside of the context of user invocation of ssh at the command line will also have these customizations included. This is especially important for ssh, which has emerged as a main security interoperability tool for Unix systems.

For example, if you use rsync, the tunneling and host alias conventions you set up in .ssh/ will carry over transparently to the ssh tunnel used by rsync.

Another example would be invocations of ssh in scripts (sh/bash scripts, even) that will not or might not read your .zshrc.


Ya, I think the underlying issue is I do things very differently than people on HN.

The idea of creating dependencies on a configuration profile inside a bash script is the exact opposite of what I would do.

I also could not rsync things to my local machine [bandwidth constraints] and would be rsyncing between remote machines, which being a shared environment, I would rely on explicit invocations instead of creating configurations/aliases.

Thank you for telling me how/why other people make different choices. I always do seem to have the blinders of my process is the only process I consider when commenting on HN. :)


To add to what @mturmon said; you'll want to keep in mind that even GUI tools (i.e. consider your favorite database tool that supports SSH connection) that support SSH connection will pick up this configuration so you don't have to manually plug in all of the pieces for each session.

Just specify the alias host name as configured in ~/.ssh/config and the user, identify file, and anything else you put there will be used as set.


This never occurred to me...I don't use GUI tools for database management outside of a local development environment or diagram generation.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: