Unix: add reverse proxy blog
This commit is contained in:
parent
9373a15b90
commit
7ec3d37186
1 changed files with 170 additions and 0 deletions
170
src/content/unix/reverse-proxy.md
Normal file
170
src/content/unix/reverse-proxy.md
Normal file
|
@ -0,0 +1,170 @@
|
|||
---
|
||||
title: 'Bypass Network Lockdowns'
|
||||
description: 'Reverse Proxies and SDWAN'
|
||||
updateDate: 'Apr 21 2024'
|
||||
---
|
||||
|
||||
# Bypassing Network Lockdowns
|
||||
|
||||
I manage the network infrastructure for a [robotics club](https://arvp.org) on
|
||||
campus. Unfortunately, the campus network has been heavily locked down for
|
||||
security. It takes years to get Information Services and Technology (IST) to
|
||||
agree to forward a port, and it's even harder for student clubs.
|
||||
|
||||
Our club members need access to the robot through the open internet. This is
|
||||
especially important for new members who aren't able to access the club's room
|
||||
after hours.
|
||||
|
||||
Due to this, I've put considerable effort into bypassing the restrictions placed
|
||||
by the university. As it turns out, once you know what you're doing, it's pretty
|
||||
easy! All you need is *outward* access to the internet, from there you can
|
||||
easily get *inward* access to any port.
|
||||
|
||||
## ZeroTier One
|
||||
|
||||
The easiest method, and probably recommended for most users, is using Software
|
||||
Driven WAN (SDWAN). This is similar to a VPN, but unlike Wireguard, ZeroTier One
|
||||
doesn't [[1]] require a centralized server.
|
||||
|
||||
Advantages:
|
||||
- Free version is good enough for most small groups
|
||||
- Very simple setup
|
||||
- Very fast through UDP hole-punching
|
||||
|
||||
Drawbacks:
|
||||
- Limit of 25 clients (on the [free
|
||||
version](https://www.zerotier.com/pricing/))
|
||||
- Requires installing separate software on all clients
|
||||
- Sometimes fails to connect for up to an hour... very hard to debug when it
|
||||
happens
|
||||
- Can only be used by clients on the VPN. For example, a public webserver won't
|
||||
be able to use this
|
||||
|
||||
To use ZeroTier:
|
||||
1. Sign up for an account at [zerotier.com](https://www.zerotier.com/)
|
||||
2. Under "Networks" create a network and give it a name. Ensure access control
|
||||
is private.
|
||||
3. Install ZeroTier One on all clients you'd like to connect. You can add more
|
||||
later.
|
||||
4. On Linux, start and enable the ZeroTier one daemon with `systemctl enable
|
||||
--now zerotier-one.service`.
|
||||
5. Find your network ID in the online console, then join with `sudo
|
||||
zerotier-cli join <network-id>`.
|
||||
6. Back in the web console, click the checkmark next to the new client that
|
||||
joined, and give it a name.
|
||||
7. Now `sudo zerotier-cli listnetworks` should say `OK PRIVATE` for your
|
||||
network.
|
||||
8. Repeat steps 3-7 for every new client you add.
|
||||
|
||||
Now you should be able to use the IP listed in the web console for your device.
|
||||
This will be in the right column under "Managed IPs". For example, if your
|
||||
server has a zerotier IP of `172.27.100.10` another client would be able to
|
||||
`ping 172.27.100.10` or with an ssh daemon running `ssh <user>@172.27.100.10`.
|
||||
|
||||
[[1]]: ZeroTier One still requires a centralized server, but they have "root
|
||||
servers" which are available to the public for free, so no setup required on our
|
||||
part.
|
||||
|
||||
## Reverse Proxy
|
||||
|
||||
Reverse proxies are a slightly more involved but generally better approach. They
|
||||
use a second computer to forward information to the internal network.
|
||||
|
||||
Advantages:
|
||||
- Can be accessed by the public
|
||||
- No additional software limits
|
||||
- No client limits
|
||||
|
||||
Drawbacks:
|
||||
- No UDP hole punching: might have a bit more latency
|
||||
- Requires a centralized server with a public IP (not necessarily static tho)
|
||||
|
||||
To setup a reverse proxy, you'll need a computer with a public IP, that's
|
||||
accessible behind the router. You could use your home computer, but it'll need
|
||||
to always stay on. A more popular approach is grabbing a cheap cloud computer. I
|
||||
personally use the most basic droplets on [Digital
|
||||
Ocean](https://www.digitalocean.com/pricing/droplets) for $4/month. Be sure to
|
||||
choose the closest datacenter possible and ideally in the same country, to
|
||||
minimize latency.
|
||||
|
||||
I'll be referring to the computer powering the reverse proxy as the "droplet",
|
||||
but the steps can easily be applied on your own Linux machine.
|
||||
|
||||
Setting up a reverse proxy
|
||||
1. Build the [rathole](https://github.com/rapiz1/rathole) binary that's
|
||||
compatible with your system. The droplet may require a different llvm
|
||||
target.
|
||||
2. Create a client-side rathole configuration on the server. The token can be
|
||||
any random string. Assuming the IP of the droplet is `172.27.10.10` and
|
||||
we're using port `9001`, the configuration might look like this:
|
||||
```toml
|
||||
[client]
|
||||
remote_addr = "172.27.10.10:9001"
|
||||
|
||||
[client.services.ssh]
|
||||
token = "yNx6KUuG4P-VRIkzr-NWysZSI6-;04IWQs4sG0;a"
|
||||
local_addr = "127.0.0.1:22"
|
||||
|
||||
[client.services.webserver]
|
||||
token = "C;KPmX-fYxAb;iGMwXEAl48woaYE;ey-CLapQJHs"
|
||||
local_addr = "127.0.0.1:80"
|
||||
|
||||
[client.services.forgejo]
|
||||
token = "-zUbD;Wy6v35KmO;GZLHs;51sws-;7o5bJ-TjSJs"
|
||||
local_addr = "127.0.0.1:8080"
|
||||
```
|
||||
3. Create a systemd service on the server called `rathole_client.service`.
|
||||
Edit the path of your `rathole` executable, and the argument to the config
|
||||
file above:
|
||||
```systemd
|
||||
# /etc/systemd/system/rathole_client.service
|
||||
[Unit]
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
Group=root
|
||||
Type=forking
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
KillMode=control-group
|
||||
KillSignal=SIGTERM
|
||||
ExecStart=/usr/local/bin/rathole /etc/rathole/client.toml
|
||||
# You MUST edit the line above to point to your rathole binary
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
4. On the droplet, create a `server.toml`. It might look something like this,
|
||||
matching the `client.toml` provided in step 2.
|
||||
```toml
|
||||
[server]
|
||||
bind_addr = "0.0.0.0:9001" # Must match port client is trying to contact
|
||||
|
||||
[server.services.ssh]
|
||||
token = "yNx6KUuG4P-VRIkzr-NWysZSI6-;04IWQs4sG0;a"
|
||||
bind_addr = "0.0.0.0:8022" # Doesn't have to match client
|
||||
|
||||
[server.services.webserver]
|
||||
token = "C;KPmX-fYxAb;iGMwXEAl48woaYE;ey-CLapQJHs"
|
||||
bind_addr = "127.0.0.1:80"
|
||||
|
||||
[server.services.forgejo]
|
||||
token = "-zUbD;Wy6v35KmO;GZLHs;51sws-;7o5bJ-TjSJs"
|
||||
bind_addr = "127.0.0.1:443"
|
||||
```
|
||||
5. On the droplet, you can simply start rathole manually in a tmux session with
|
||||
`./rathole server.toml`.
|
||||
6. On the client run `systemctl enable --now rathole_client.service`
|
||||
|
||||
Check the output of both commands (`systemctl status rathole_client.service`) to
|
||||
make sure there aren't any errors. Assuming it's all good, you should be able to
|
||||
contract the server through the droplet. For example, if we wanted to ssh into
|
||||
the `emiliko` user on the server, the above config should allow that through:
|
||||
|
||||
```bash
|
||||
ssh -p 8022 emiliko@172.27.10.10
|
||||
```
|
||||
|
||||
This will be forwarded to port 22 on the server!
|
Loading…
Reference in a new issue