Comment by lamnguyenx

Comment by lamnguyenx 2 months ago

11 replies

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
mmh0000 2 months ago

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
  • dbacar 2 months ago

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

  • teddyh 2 months ago

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

  • lamnguyenx 2 months ago

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

prmoustache 2 months ago

> 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.

cfinnberg 2 months ago

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.

  • lamnguyenx 2 months ago

    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.

appplication 2 months ago

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).

EasyMark 2 months ago

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.

fracus 2 months ago

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

glandium 2 months ago

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