summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhyang <hyang@hyang.xyz>2024-03-26 17:27:30 -0700
committerhyang <hyang@hyang.xyz>2024-03-26 17:27:30 -0700
commit0e8d36757874d673920ac85dcf443ec8c998b90f (patch)
treeb194ca83a955029b1f82554e7eccbdb2bb75f91e
parent4535ecd8944df8af03c67d07249695de051dc505 (diff)
actually finish article sadlfkjasflksadf
-rw-r--r--content/posts/routing-select-containers.md62
1 files changed, 46 insertions, 16 deletions
diff --git a/content/posts/routing-select-containers.md b/content/posts/routing-select-containers.md
index 08bbfc9..88414ee 100644
--- a/content/posts/routing-select-containers.md
+++ b/content/posts/routing-select-containers.md
@@ -6,8 +6,6 @@ draft: false
ShowToc: true
---
-**TODO: Finish this article**
-
# Preface
This site, *hyang.xyz* is hosted using a small, cheap VPS which reverse proxies back to my home computer. WireGuard is used to securely communicate with each other. The VPS runs the WireGuard "server", which allows me to connect to the VPS without ever having to port forward. For various reasons, I also need certain container's outbound traffic routed to WireGuard. Originally, I just routed all traffic to the VPS. This mostly worked fine. However, for whatever reason this prevented me from SSH'ing into my computer using my network connection.
@@ -16,7 +14,7 @@ My method will essentially create a WireGuard interface on the host, and do the
# Create user defined Docker Bridge
First, we'll make a user defined bridge for Docker. You can learn more about it [here](https://docs.docker.com/network/network-tutorial-standalone/#use-user-defined-bridge-networks).
```
-# docker network create --subnet 172.22.0.0/24 wg
+docker network create --subnet 172.22.0.0/24 wg
```
This bridge will be what the container will use to connect to the Internet, and we will use to forward container traffic to WG.
@@ -27,19 +25,19 @@ Wg-quick automatically sets routes in the main routing table depending on the *A
1. Create the interface
```
- # ip link add dev docker_wg0 type wireguard
+ ip link add dev docker_wg0 type wireguard
```
-2. Assign address
+2. Assign address (the network 10.0.0.0/24 will be used for this article)
```
- # ip address add dev docker_wg0 10.0.0.2/24
+ ip address add dev docker_wg0 10.0.0.2/24
```
3. Set WireGuard configuration (Assuming your WG configuration is at /etc/wireguard/wg0.conf)
```
- # wg setconf docker_wg0 /etc/wireguard/wg0.conf
+ wg setconf docker_wg0 /etc/wireguard/wg0.conf
```
4. Finally, activate the interface
```
- # ip link set up dev docker_wg0
+ ip link set up dev docker_wg0
```
# Routing the traffic
@@ -47,8 +45,10 @@ This is where we will actually route the traffic to WireGuard!
Before we start, you'll also want to do this:
```
-# ip route add 10.0.0.0/24 dev docker_wg0
+ip route add 10.0.0.0/24 dev docker_wg0
```
+*Note: This may be optional as it could have already been added when creating the interface*
+
This tells Linux to route everything in our VPN subnet 10.0.0.0/24 to the WireGuard interface. This is sort of what `wg-quick` does, assuming that the AllowedIP field is 10.0.0.0/24.
First, we need to find the name of the docker bridge we made [here](#create-user-defined-docker-bridge)
@@ -56,7 +56,7 @@ First, we need to find the name of the docker bridge we made [here](#create-user
## Get our Docker bridge's name
To get the name of the bridge:
```
-$ ip route show
+ip route show
```
This will list a bunch of routes configured on your computer, like this:
```
@@ -68,10 +68,10 @@ default via 192.168.1.254 dev eno1 proto dhcp src 192.168.1.90 metric 100
The bridge we defined [here](#create-user-defined-docker-bridge) will have the same subnet as shown in this routing table. In this case, the name is **br-b5a8e9e3afe4**.
## Messing with Iptables
```
-# iptables -A FORWARD -i docker_wg0 -j ACCEPT
-# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
-# iptables -t nat -A POSTROUTING -o docker_wg0 -j MASQUERADE
-# iptables -t mangle -A PREROUTING -i br-b5a8e9e3afe4 -j MARK --set-mark 5102
+iptables -A FORWARD -i docker_wg0 -j ACCEPT
+iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
+iptables -t nat -A POSTROUTING -o docker_wg0 -j MASQUERADE
+iptables -t mangle -A PREROUTING -i br-b5a8e9e3afe4 -j MARK --set-mark 5102
```
1. We first let Iptables know to allow packets that are forwarded to docker_wg0.
2. Next, we'll masquerade packets that are going to your router (interface name may be different). We'll also masquerade packets that are going to the docker_wg0 interface. This is so that packets can properly communicate to the WG interface, which then communicates to your router interface.
@@ -89,11 +89,41 @@ The name of the table can be anything you want, but we'll name it *docker_wg*. T
# Assuming that the arbitrary mark defined in the last step was 5102!
ip rule add fwmark 5102 table docker_wg
```
-Then, we'll add a policy rule which tells Linux to route packets marked with integer 5102 using the docker_wg routing table.
+We'll add a policy rule which tells Linux to route packets marked with integer 5102 using the docker_wg routing table.
+
+Finally, we'll add a default gateway for the table
```
-ip rule add fwmark 5102 table docker_wg
+ip route add default via 10.0.0.1 dev docker_wg0 table docker_wg0
+```
+
+# Routing a Docker container
+Finally, to make a container route through the VPN, simply attach the wg network to the container.
+
+Here's an example in docker-compose.yml:
+```yml
+version: '3.8'
+
+services:
+ hyangxyz:
+ image: nginx
+ networks:
+ - wg
+
+# [...]
+
+networks:
+ wg:
+ external: true
```
+You can find the public-facing IP inside the container using
+```
+curl -4 ifconfig.me
+```
+
+# Afterword
+Note that any configurations made with `ip` are not persistent! You'll need to figure out how to persist these changes on your own, as it varies by distribution. An example would be using a service script.
+
# Further Reading
- https://www.linuxserver.io/blog/routing-docker-host-and-container-traffic-through-wireguard