3

Yes, I'm aware that I wrote "SSH shell" in the title.

TL;DR: The first paragraph, the one with the link, and the one with the error message are most important.

I have my Raspberry Pi at home which I can access over the internet but only via IPv6. I'm currently in a location where I don't have IPv6.

I can execute commands on it by first logging in to a server which has both IPv4 and IPv6 and then logging into my pi from there. However, I use SSH on it for more than executing commands on it:

  • git
  • backups (Deja Dup)
  • accessing files (SFTP)
  • VNC (I tunnel through SSH and can then connect to localhost via VNC)

These are in decreasing order of importance. I want to access my git repos.

A few more details:

  • I can't simply make my Pi accessible via IPv4. The modem it's behind has an IPv4 address and an IPv6 subnet but I have to use hardware I didn't choose running software I can't change. That software is not only buggy and I can't even take a look at it, but furthermore, it doesn't allow IPv4 port forwarding it all.
  • I don't control the server with both IPv4 and IPv6 on it. I only have a normal user account on it and can't – for example – install new software if more than standard user rights are required for it.

Googling for a solution brought up this rather promising page, and it actually works for git. I set up new remotes for the repos I'm using, simply replacing the pi's domain name by localhost:3333.

But it looks much more promising than that. It looks like the solution for all of the above. And it kind of started to work out!

SFTP works and I can't really determine whether backups via Deja Dup work, yet, because my connection is too slow, but it hasn't failed yet, and something's causing network traffic, so that's good and promising.

But why can't I just do ssh localhost:3333 to connect to my laptop to get a shell on my pi? The command results in this error message:

ssh: Could not resolve hostname localhost:3333: Name or service not known

I'm mainly interested in why I can't get a shell the way I'd expect it to work.

  • 1
    shh localhost:3333: ssh does not support this semantics. It is ssh -p 3333 localhost if it is the question (didn't read it all). – Jakuje Dec 27 '16 at 16:47
5

You might want to look into ssh's ProxyCommand configuration, which allows for this to work more seamlessly, and will work for shells, SFTP, tunnels, and anything else you might want to proxy via ssh.

Let's say you have the following three hosts:

  • workstation.example.com - This is the machine you're physically working on
  • proxy.example.com - This is the machine you're routing your SSH traffic through
  • endpoint.example.com - This is where you want the traffic to ultimately end up

In ~/.ssh/config on workstation, add the following:

Host endpoint
    User EndpointUser # set this to the username on the destination host
    HostName endpoint.example.com
    ProxyCommand ssh username@proxy.example.com nc %h %p 2> /dev/null

On the proxy host, make sure nc (netcat) is installed.

Then, on workstation, you can ssh endpoint or sftp endpoint and you will be transparently proxied to the machine by way of your proxy host.

  • One thing for Ubuntu users (and I suppose other distros as well): You don't need the package netcat. nc is probably already installed. In Ubuntu 16.04, it's already installed via the package netcat-openbsd. – UTF-8 Dec 27 '16 at 16:45
  • Awesome, it works! I can even use a different SSH alias I already defined instead of username@proxy.example.com. :) Can you tell my why shh localhost:3333 doesn't work, though? – UTF-8 Dec 27 '16 at 16:45
  • 2
    Don't use netcat. Use ssh -W %h:%p username@proxy.example.com instead. It does not require anything else installed. – Jakuje Dec 27 '16 at 16:48
  • 1
    Sure! shh localhost:3333 is not valid syntax to ssh to a specified port. It will literally look for a host or alias called localhost:3333. You'd want to use ssh -p 3333 localhost, and that would have to be to an SSH server. – DopeGhoti Dec 27 '16 at 16:48
  • @Jakuje, thanks for that! Is -W new? I've not seen that before. Also, will that work if you have a different username on the other host? – DopeGhoti Dec 27 '16 at 16:51
0

There are a couple of pieces which can be cobbled together in different ways, depending on what works best for you. Each piece is optional, and has variants.

I will use the following terms:

  • "desktop" => the machine you are seated in front of (in your example, the one with ipv4).
  • "jump host" => the machine in the middle, the one you have to go through (in your example, with ipv4 & ipv6)
  • "target" => the final machine you actually want to be on (in your case, the Pi).

    1. consider using ssh keys, instead of passwords. This will save you a lot of time typing in passwords. See https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
    2. Make sure you can ssh directly to the jumphost with 'ssh jumphostname' or 'ssh jumpuser@jumphostname' - if there are any other options you need to connect (port number etc), add an entry to your ~/.ssh/config for this jumphost.
    3. Add an entry to ~/.ssh/config for the target, with a clause 'ProxyJump jumphostname' or 'ProxyJump jumpuser@jumphostname'.
    4. If you sometimes access the target directly, and sometimes via a jumphost (e.g. 'desktop' is a laptop which you sometimes use at home, and sometimes at work), you can give the target and/or jumphost a different name (e.g. 'Host jump-pi' or 'Host jump-proxy'), and specify the real hostname or ip of the target in the 'hostname' clause.
    5. You should now be able to ssh directly from your desktop to the pi. Behind the scenes, ssh will create a connection from your desktop to the jump host, and then start another connection directly from your desktop through that first connection, to the target.
    6. You can add port forwards to the ssh command (or add it to your ssh config). For example, if you want your pi to be able to access ssh on your desktop, pick a port to listen to on the pi (I will pick 2222), and run the commands as follows: "ssh -R2222:localhost:22 piusername@pi" - this says, after ssh connects, any incoming connections to port 2222 (on the pi), should be forwarded back through the tunnel to your desktop, which should then connect to "localhost port 22". Then, on the pi, you can "ssh -p 2222 desktopuser@localhost". You can do the same for any other single port (provided you can specify the hostname and port for the program you are using).
    7. If you want to have general networking, you can run Dynamic Socks. ssh has this built in, but it only works in the OTHER direction. To allow connections going BACK (from the Pi to your desktop), you will need a Dynamic Socks server on your desktop. Then set up a tcp connection from the Pi to the Dynamic Socks server (as per step 6), then run a Dynamic Socks client on the Pi (some applications have Dynamic Socks built in, e.g. wget, or you can use something like 'tsocks').
    8. If this is not generic enough, run PPP over ssh. This will give you another "network card" on both your desktop and the Pi, they can then talk to each other directly. You can set up routing via this interface (be careful, if you lose connectivity to the Pi, you won't be able to fix it remotely).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.