Hacker News new | past | comments | ask | show | jobs | submit login

It's 2024! Please avoid writing SSH commands like that.

Instead, configure your ~/.ssh/config with LocalForward, RemoteForward, and ProxyJump. This can save you a significant amount of time, especially when using ssh, scp, or rsync to transfer data from a remote server that requires multiple intermediate SSH connections.

e.g:

    Host jump-host-1
        HostName jump1.example.com
        User your_username
        IdentityFile ~/.ssh/id_rsa

        Host jump-host-2
            HostName jump2.example.com
            User your_username
            IdentityFile ~/.ssh/id_rsa
            ProxyJump jump-host-1

            Host jump-host-3
                HostName jump3.example.com
                User your_username
                IdentityFile ~/.ssh/id_rsa
                ProxyJump jump-host-2

                Host target-server
                    HostName target.example.com
                    User your_username
                    IdentityFile ~/.ssh/id_rsa
                    ProxyJump jump-host-3
                    LocalForward 0.0.0.0:8080 0.0.0.0:80  
                    RemoteForward 0.0.0.0:9022 0.0.0.0:22

    # after this:
    # - you can ssh/scp/rsync to your target-server via an alias
    # - forward traffic FROM port 80 on your target-server to port 8080 on your local machine
    # - forward ssh requests TO port 9022 on your target-server to port 22 on your local machine
    # - remember, for LocalForward & RemoteForward : 
    #   + left is target-server
    #   + right is your local
    #   + use 0.0.0.0 instead of localhost or 127.0.0.1



While we're sharing neat ssh_config tricks, here's my favorite trick I use:

My home network is set up so that if I'm home or on my self-hosted VPN, I can SSH directly to my various things. But if I'm away from home and not on the VPN, I can SSH into my home systems through a jump host.

In the ssh_config file, I have it configured to detect how/where I am and optionally use a jump host.

  Host jump jump.example.org
    HostName                        jump.example.org
    Port                            41444
    User                            mmh
    UserKnownHostsFile              /dev/null
    ChallengeResponseAuthentication no
    CheckHostIP                     no
    Compression                     yes
    ForwardX11                      no
    GSSAPIAuthentication            no
    LogLevel                        ERROR
    PreferredAuthentications        publickey,keyboard-interactive
    ProxyJump                       none
    PermitLocalCommand              yes

  # Order here matters. Detect VPN first, then home network.
  # If connecting to a *.example.org host and router.example.org = 10.0.0.1, must be home/vpn.
  Match host *.example.org exec "getent ahosts router.example.org | grep -q ^10.0.0.1"
    ProxyJump                 none
  # If connecting to a *.example.org host and the macaddr of 10.0.0.1 is NOT 2a:70:ff:ff:ff:ff, then use jump.example.org:
  Match host *.example.org exec "! arp -ne 10.0.0.1 | grep -Fq 2a:70:ff:ff:ff:ff"
    ProxyJump                 jump.example.org


  ## Define the things
  Host tv tv.example.org
    HostName                  tv.example.org
    User                      mmh


This is really cool, I didnt know you could use "exec".


You should probably replace that "arp -ne" command with "ip neigh show" instead (assuming this is Linux).


Wow. Nice trick! I didn't know SSH Config can do that exec control flow.


> It's 2024! Please avoid writing SSH commands like that.

Sometimes you just want to do it once and you don't want to write a config file for it.

For example, I am often building up a short lived vps in order to use ssh as a socks proxy and bypass georestrictions.

Also it happens that sometimes you are asked to help a different team and need to access a server you aren't accessing usually and have very few reasons to ever access again.


I think that using 0.0.0.0 it's a bad idea. That is supposedly opening the port in all network interfaces, including the external ones. So, if you don't have a firewall (especially on the remote server) you are exposing something to the world.

OTOH if I'm going to use some tunnelling/port forwarding quite often, I would use the config file option, but for an one time or sporadic use, the command line option is better IMHO.


Nice catch. You're right. At my company all servers operate inside a complex & heavily-guarded intranet, so I usually use 0.0.0.0 instead of localhost / 127.0.0.1. Sometimes, only using the former worked (e.g: using Code-Server or Jupyter Notebook), and I'm not so good at networking to dive into iptables and firewall things.


Speaking of things like this. How are folks managing setup for their local machines to standardize config like this across them? I’ve been in search of a git-ops like solution that is single user/multiple machine compatible doesn’t require having an existing server online somewhere from which configs would be fetched (e.g. I’m fine using GitHub).


But I don’t always want the shell to happen? I whipped up some basic bash/fish functions that let me do it much easier and with minimal arguments to remember, and I can always refer to the well documented functions if I forget something.


This is interesting. I always made a bash function to proxyjump. This seems cleaner. I'll try it.


Oh wow, I was still using `ProxyCommand ssh -W %h:%p jump-host`




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

Search: