Work from Home Through P2P Network
by 0xc0000156
After years of being a Windows programmer using VS and some other IDEs, I started to appreciate Vim.
For me, it's still hard to use, but it hasn't changed in decades which now seems to be a good thing. I became more and more lazy after turning 35. Plus, combine Vim with Latex - I feel special.
One good thing about Vim is that it's lightweight. It allows me to work remotely through an SSH terminal. I can just set up a server at work. The server doesn't even need a GUI and it keeps on for months.
I have a laptop at work. For some reason, some laptops don't have Ethernet sockets anymore. So my laptop can only connect to a Wi-Fi network. But the IP address is dynamically assigned. Each time it connects to the Wi-Fi, it may got a new one. If I want to connect to it from home, there might be a problem. I thought I could write a script and let it send an email with the new IP address. Turns out that was too difficult for me. I also don't want to use remote control software such as TeamViewer because the rendering of GUI is slow. All I need is an SSH terminal and Vim.
I also have a desktop at work which has a static IP address. So my goal is to let the laptop connect to my desktop whenever it boots up or whenever it gets a new IP address. I could simply create a reverse tunnel.
Let's say my laptop's IP address is L.L.L.L and my desktop's IP address is D.D.D.D. On my laptop, I execute the following command:
laptop$ ssh user@D.D.D.D -R 8888:localhost:22Where user is my username. This command says: SSH to D.D.D.D (desktop) as user user. Once connected, open a TCP port (8888 at the desktop). All the connections to port 8888 will be forwarded to the laptop's port 22 (which is the SSH port).
Notice that the localhost in this command is quite confusing - it means the laptop. I can use the laptop's IP address instead, but it kind of defeats the purpose. (You also can specify any IP address here - connections will be forwarded to it.)
Following this command, I need to type in the password and a shell will be spawned. Meanwhile, port 8888 is opened, so on my desktop, if I type:
desktop$ ssh localhost -p 8888It will connect to my laptop.
Now I need this to be done in an automatic way. First, no typing password.
Step 1
Create authentication SSH-keygen keys on my laptop:
laptop$ ssh-keygen -t rsaLeave empty for passphrase. It creates files:
~/.ssh/id_rsa ~/.ssh/id_rsa.pubStep 2
Create .ssh directory on desktop D.D.D.D:
laptop$ ssh user@D.D.D.D mkdir -p .sshStep 3
Upload generated public-keys to desktop D.D.D.D:
laptop$ cat .ssh/id_rsa.pub | ssh user@D.D.D.D 'cat >> .ssh/authorized_keys'Step 4
Set permissions:
laptop$ ssh user@D.D.D.D 'chmod 700 .ssh; chmod 640 .ssh/authorized_keys'O.K., try to login without a password!:
laptop$ ssh user@D.D.D.DNow, I need this reverse tunnel to be established after the system boots up or to be reestablished whenever the network recovers from a breakdown. It seems that system daemon is a good choice (I use Ubuntu).
I create the following script on my laptop:
laptop$ sudo vi /etc/systemd/system/sshreversetunnel.serviceAnd add:
[Unit] Description=SSH Reverse Tunnel After=network.target [Service] Restart=always RestartSec=20 User=user ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=60 -o "ExitOnForwardFailure yes" -R 8888:localhost:22 user@D.D.D.D [Install] WantedBy=multi-user.targetTo enable and start it:
$ sudo systemctl enable sshreversetunnel $ sudo systemctl start sshreversetunnelTo update once the config file is changed:
$ sudo systemctl daemon-reloadAt this point, you probably already know that I copy and paste from Stack Overflow. And you probably would ask: why don't you just do your work at your desktop?
What if I don't have a static IP desktop? Or what if my home and my work don't even share the same network? There may be several layers of NAT.
To solve this, I need some relay on the Internet that can deliver my connections. The first thing that comes to my mind is instant messaging or IRC. Years ago, I tried Google's Gtalk, which used an extended XMPP protocol. It provided open-sourced library libjingle, gnat. But, as we all know, Google shut down the Gtalk service.
I needed to find another project or I would have to write an ugly one myself. After trying several open-source projects that claimed they could do it, I finally found one that worked for me. It's called Tuntox. You can learn more about it at their GitHub page: github.com/gjedeer/tuntox.
You can compile it yourself - I didn't. I downloaded the binary from the Releases tab. On my laptop:
laptop$ wget https://github.com/gjedeer/tuntox/releases/download/0.0.9/tuntox-x64 laptop$ chmod +x tuntox-x64 laptop$ TUNTOX_SHARED_SECRET=password ./tuntox-x64 -C ./ 2018-11-23 03:32:58: [INFO] Tuntox built from git commit 896775c6089baa24edee06e04f5b83c3bb3bef5d 2018-11-23 03:32:58: [INFO] Using 56214 for TCP relay port and 23893-23903 for UDP 2018-11-23 03:32:58: [INFO] Using Tox ID: xxxxxxxxxxxxxxxxxxxxxxxxxx 2018-11-23 03:33:06: [INFO] Connection status changed: An UDP connection has been establishedNote: Replace password with your real password and remember your Tox ID. Parameter -C ./ indicates that Tuntox will create a file called tox_save under the current directory. With this file, it will have a fixed Tox ID all the time.
Now from any computer, with this Tox ID, run the following command:
$ TUNTOX_SHARED_SECRET=password ./tuntox-x64 -i xxxxxxxxxxxxxxxxxxxxxxxxxx -L 2222:127.0.0.1:22 2018-11-22 22:46:08: [DEBUG] Server whitelist mode enabled 2018-11-22 22:46:08: [INFO] Tuntox built from git commit 896775c6089baa24edee06e04f5b83c3bb3bef5d 2018-11-22 22:46:08: [INFO] Using 26501 for TCP relay port and 14364-14374 for UDP 2018-11-22 22:46:08: [INFO] Connecting to Tox... 2018-11-22 22:46:16: [INFO] Connection status changed: An UDP connection has been established 2018-11-22 22:46:16: [INFO] Connected. Sending friend request. 2018-11-22 22:46:16: [INFO] Waiting for friend to accept us... 2018-11-22 22:46:30: [INFO] Friend request accepted (A TCP connection has been established (via TCP relay))!Quite like the previous SSH command, it opens local port 2222. Open another terminal:
$ ssh localhost -p 2222Try it out - it works!
Combine it with the system daemon script that we introduced earlier:
[Unit] Description=SSH P2P Tunnel After=network.target [Service] Restart=always RestartSec=20 User=user Environment=TUNTOX_SHARED_SECRET=123123 ExecStart=/home/u/tuntox/tuntox-x64 -D -C /home/u/tuntox/ [Install] WantedBy=multi-user.targetNow I can connect to my laptop from anywhere, so I can work from home. Or I get a pretty good backdoor!