Slow SSH connections on Mac OS X

So, I have to spend quite a lot of time remotely logged into a unix server by SSH at the moment. Luckily Mac OS X comes with a nice SSH client already installed but I have been having problems with it taking forever (well, up to a minute) to connect which finally got annoying enough to fix this morning.

The first thing I did was to enable debug messages with the -v parameter.

dave$ ssh -v dave@192.168.0.200

When I ran that, the long pause came just before this error message:

debug1: An invalid name was supplied
Cannot determine realm for numeric host address

A few quick googles and I had the solution, add a DNS lookup for the IP address and the speed issue goes away leaving you with a fast and responsive SSH connection process!

To add the DNS lookup, simply edit the /etc/hosts file (you will need to sudo this or type your password when it is saved) and add a line something like this to the bottom:

192.168.0.200 myunixserver

Then you should be able to connect quickly using either the IP address or the new host name you assigned.

Advertisements

10 responses to “Slow SSH connections on Mac OS X

  1. Funny, I SSH to numeric hosts all the time, and have no delay at all. Thinking about it – I do remember having this delay a long, long time ago, and I changed something, somewhere that fixed it. Sorry, I can’t remember what it was, other than it was some setting or parameter for ssh.

  2. Once you have a host setting, you can switch back to using numeric hosts just fine so if you are in an environment with local DNS you wont have this issue.

  3. It’s not the forward-DNS it has issues with, for what it’s worth, it’s trying to reverse-map the domain in order to figure out a Kerberos realm name from the IP.

    I can’t for the life of me work out how to prevent SSH from trying to work with Kerberos, mind.

  4. I’ve been having this problem with our local house server, and twigged that it was dns related when i noticed that it just wouldn’t connect when the internet was being flakey.
    Try ‘ssh -o AddressFamily=inet’ The delay apparently sometimes comes from resolving addresses, the flag ‘inet’ sets it to IPv4 only, I’ve yet to thoroughly test this, but i seem to remember we have IPv6 internally, the lookups for which could, in theory, be causing problems.

  5. I’m not using IPs to connect to servers, coz I have several short domains at my servers – so it’s not that long. But thank you, I think I’ll edit my hosts file, coz it’s much more faster to “ssh serv” :D

  6. Nothing to do with this post, but I know you’re a fan of Cover Flow, well, they’ve sold the whole thing to Apple and you’ll now find it in iTunes 7 : ) Perfect.

  7. Thanks for posting this! I was having the same problem and your solution worked like a charm.

  8. I was noticing some delays. LONG ones.

    I started experimenting. There are some good solutions in here, if you read the story, understand it, and use my tips as they apply to you — not all will!

    First off, I noticed this HUGE delay connecting to a host using SSH. I went with it for a while, but really, with a nice fat connection on a good internal network I was getting annoyed.

    The first thing I suspected is that it was trying ipv6 first, then failing back to ipv4.

    So, as all of the suggestion pages said to try, I placed the following in my /etc/ssh_config (note, this is a symlink to /private/etc/ssh_config on OS X!). If I need to tell you that to edit this file you need to type:
    sudo vi /etc/ssh_config
    or
    sudo vi /private/etc/ssh_config

    then I suggest you get a geek friend to help you with this before you end up breaking something. :)

    Anyway, I located the line:
    # AddressFamily any
    which is commented out. Below it, I added:
    AddressFamily inet
    which forces ipv4 to be used.

    This did not even slightly improve my delay.

    adding verbose options to the ssh commandline didn’t help at all, as I normally use:
    ssh -2 -v user@host
    Even with more verbosity, all you see is a delay, no useful information as to what it’s trying to do, or what it’s waiting for.

    I was using Wireshark to watch the connection initiate when I noticed something odd. I was not seeing all of my DNS replies!

    I tried the following:
    host my.server.net
    and got an answer, lickety split.
    Then i tried:
    host 1.2.3.4
    and… slight delay… then instead of SERVFAIL (I don’t have reverse dns on my hostname for a reason) I got:
    “no name servers could be reached”
    !!!

    Funny, so I dug into things.

    It turns out that a release of the firmware for a m0n0wall firewall installed on a Soekris device that is firewalling a chunk of network I was on has a bug in it.

    It is defined to use three DNS servers, and had its DNS Forwarder turned on. Problem is, it was only forward NAME queries, not numeric queries. How retarded is that? I poked around for a while trying to figure out if it’s not internally setting some firewall rule, and then it hit me:

    Why am I now focusing on fixing a remote device for a delay that is still on my side?

    What I mean by this is: I am telling my computer to connect as user “user” to host “my.server.net” and it looks it up and gets the number. THEN it turns around to verify that the number looks up to the host name. DNS verification, and this is what is failing, hence the long delay.

    A couple points: my server is also a web server. with many virtual hostnames. ploop.net, crap.net, example.net, etc could all resolve to my 1.2.3.4 IP. So why in the hell would I want this to be verified?

    Another point– What if I’m on a “broken network” again? IE: I’ve visited coffeeshop hotspots, been in hotel rooms, etc… where DNS is just plain crappy. I’m going to see this issue again unless I figure out a way around it.

    A friend of mine, Jeff, said that the DNS lookup verification sounded like a kerberos issue, and suggested I look at these four options in /etc/ssh_config, and here is how they appear:

    # GSSAPIAuthentication yes
    # GSSAPIDelegateCredentials no
    # GSSAPIKeyExchange yes
    # GSSAPITrustDNS yes

    After much experimentation, there are two new lines in my /etc/ssh_config:

    GSSAPIKeyExchange no
    ADdressFamily inet

    Boom. Lickety-split!
    the ssh connection didn’t hesitate even for a second, it felt like.

    So…

    If you’ve tried this over and over and have still not triumphed over a delay, there are a few things to consider here. and a few questions to ask yourself.

    1) Do you want your computer to be more versatile on alien networks that are potentially “broken” whether purposefully, or otherwise? I did.

    2) Can you, if you have access, and if you can do you want to, because it’s a remote fix for a local delay, modify remote servers’ sshd_config files, or add DNS records for hosts on networks so that you don’t have to alter GSSAPI (blah) options? I didn’t want to, mostly for philosophical reasons. That and logic. and not being retarded.

    3) Note that this can cause issues if you actually make use of kerberos stuff that uses ssh-hooks, or has roots into the ssh configuration of your machine. Since I’m not in that situation, I didn’t care… you might.

    4) Do you care that you’re not comparing each side of a DNS lookup for verification that both sides of it are correct? I don’t, because I use ssh-keys, not passwords, so I have other verification methods. I also pay close attention to host fingerprints. Another also, more often than not, I’m dealing with multiple-hostname-serving single-IP-address servers, or ISPs (Charter Communications, Cox, and a few others have made my list) who are either in the habit of hiring retarded ass monkeys to administer their DNS servers. Or hiring nobody at all, since sometimes they just never work ever. So, one side might work, one side (reverse, usually) will be broken. Since I know this is something I’ll never fix (you can’t fix “stupid”) and I verify with more reliable means, I don’t care about this. But you might. And I hope that you move on down a path toward not caring because you are using SSH keys and paying attention to fingerprints of hosts some day. It’s the right thing to do.

    I could go on, lots more details on what is good/bad about this situation, fix, and the things it can potentially affect. But frankly, my hands are tired of typing into this post-it-yellow box. So I’ll close with this:

    NOTE changes like this on paper (a notebook somewhere. maybe next to your AOL password list) — what file you changed, what you added/changed/removed, and when you did it, and why. Because two weeks later, if you’re wondering why something is weird, you have that note or list of notes to go back to. :)

    HTH,
    -jre

  9. Add this line to /etc/ssh_config:

    GSSAPIKeyExchange no

    That’s it ! (It’s yes by default).
    I figured this out by comparing the ssh_config file to a Linux ssh_config file.

  10. Jerome, it worked for me too–by setting GSSApiKeyExchange to no. Now have to figure out exactly what this does.