Find me on GitHub
https://github.com/josehu07
CV | LinkedIn | Google Scholar
guanzhou.hu (at) wisc.edu | |
josehu (at) cs.wisc.edu |
To all my loved ones and my friends ♥
GitHub Pages — Theme by orderedlist
22 Dec 2021 - Guanzhou Hu
Wisc campus VPN and our CS departmental VPN both use GlobalProtect. On the user side, GlobalProtect clients cannot configure VPN split tunneling, meaning that once connected, all outbound traffic from my host machine goes through the VPN. I have a daily need to access my lab machine sitting behind the departmental VPN, yet I would like all other traffic (e.g., searching Google) to bypass the VPN. I came up with a solution of using one or two Raspberry Pi chips as an always-on SSH proxy server.
Originally, I was using the GlobalProtect client directly on my host PC or on my laptop. My lab machine labmachine.cs.wisc.edu
sits behind the departmental VPN. The VPN connection scheme looked like:
Since GlobalProtect clients force all outbound traffic to go through the VPN once connected, I could not let only one terminal SSH session to use VPN while leaving all other connections native. One workaround would be to install a virtual machine on the host, start GlobalProtect client in the virtual machine, and do SSH from there, but that requires careful configuration of guest networking and also seems to be an unnecessarily heavy-weight solution.
If you get lucky and have one or two spare Raspberry Pi chips at home, you can follow the steps listed below to setup them up properly as an SSH proxy server. SSH connections are very light-weight, so even RPi Zero chips can do the work nicely.
Let’s first assume that the RPi chip is within the same local network with the host machine (where I want split tunneling). In this case, one RPi chip should be sufficient. The next section will talk about adding an extra RPi chip and setting up Dynamic DNS (DDNS) to allow accessing the proxy server from anywhere on the Internet.
With one RPi chip, the network connection scheme looks like:
Setup steps:
192.168.0.1
for my TP-Link Archer). Identify the RPi’s hardware MAC address.192.168.0.131
).ssh piuser@192.168.0.131
. Setup password-less SSH if desired.Start GlobalProtect client on RPi:
(on-rpi) globalprotect connect --portal compsci.vpn.wisc.edu
After the above steps, I can connect to my lab machine from my host PC using the nice Proxy Jump feature of SSH:
ssh -J piuser@192.168.0.131 labuser@labmachine.cs.wisc.edu
It is strongly recommended to setup alias targets in .ssh/config
to save future typing, e.g.:
Host josepi4
Hostname 192.168.0.131
User piuser
Port 22
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 30
Host labmachine
Hostname labmachine.cs.wisc.edu
User labuser
Port 22
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 30
Host labmachine-jl
Hostname labmachine.cs.wisc.edu
User labuser
Port 22
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 30
ProxyJump josepi4
Then, to SSH to the RPi from local network at home:
ssh josepi4
To SSH to the lab machine behind VPN, either will work:
ssh -J josepi4 labmachine
# or simpler:
ssh labmachine-jl
Notice that the GlobalProtect client on RPi might timeout and disconnect after a few minutes of inactivity. It might be possible to write a simple keep-alive script that runs indefinitely on the RPi to keep GlobalProtect connected.
So far, the RPi proxy server is available to any machine connected to my home router’s local network. However, I still want access to the proxy server from anywhere on the Internet when I’m not at home.
It is time to introduce two more techniques into the workflow:
Due to strict traffic hijacking of GlobalProtect, the virtual server feature does not work when the previous RPi is on GlobalProtect VPN. Hence, unfortunately, an additional RPi chip needs to be involved. (RPi chips are cheap enough, anyway.)
The final network connection scheme looks like:
Setup steps:
192.168.0.130
), similarly.ssh piuser@192.168.0.130
. Setup password-less SSH if desired.22122
) to internal port 192.168.0.130:22
. It is recommended to choose a non-default external port to avoid exposing port 22
on public Internet.josedns.ddns.net
), and activate it.After the above steps, I can connect to the second RPi from anywhere on the public Internet through:
ssh piuser@josedns.ddns.net:22122
To access the first RPi:
ssh -J piuser@josedns.ddns.net:22122 piuser@192.168.0.131
Notice that SSH proxy jumps can be chained, so to access the lab machine behind VPN:
ssh -J piuser@josedns.ddns.net:22122,piuser@192.168.0.131 labuser@labmachine.cs.wisc.edu
Add a few more SSH config entries to save typing, e.g.:
Host josepi0
Hostname 192.168.0.130
User piuser
Port 22
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 30
Host josepi0-jp
Hostname josedns.ddns.net
User piuser
Port 22122
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 30
Host josepi4-jp
Hostname 192.168.0.131
User piuser
Port 22
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 30
ProxyJump josepi0-jp
Host labmachine-jp
Hostname labmachine.cs.wisc.edu
User labuser
Port 22
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 30
ProxyJump josepi4-jp
Then, to connect to the second RPi when away from home:
ssh josepi0-jp
To access the first RPi:
ssh josepi4-jp
To access the lab machine:
ssh labmachine-jp
Hooray!
Please comment below anything you wanna say! 😉