Skip to content

Commit ef958d6

Browse files
committed
all grammar checked
1 parent df9308f commit ef958d6

File tree

1 file changed

+19
-17
lines changed
  • src/content/post/2025/05-29-traefik-load-balancer

1 file changed

+19
-17
lines changed

src/content/post/2025/05-29-traefik-load-balancer/index.mdx

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,19 @@ I already wrote about the advantage of resolving SSL certificates locally on the
7878
2. The home server is tunnel-agnostic and reusable
7979
3. No coupling between the tunnel server and client, no need to maintain state or version
8080
4. Decoupled debugging
81-
5. Improved securityan additional encryption layer further down the tunnel
81+
5. Improved security, an additional encryption layer further down the tunnel
8282
8383
## Traefik load balancer and Rathole server
8484
85-
Since we passthrough encrypted HTTPS traffic, Traefik can't read subdomain from a HTTP request as usual. Instead, we will run Traefik router in TCP mode, using the [HostSNIRegexp](https://doc.traefik.io/traefik/routing/routers/#hostsni-and-hostsniregexp) matcher. This will run the router on layer 4 (TCP) instead of usual layer 7 (HTTP).
85+
Since we passthrough encrypted HTTPS traffic, Traefik can't read the subdomain from an HTTP request as usual. Instead, we will run the Traefik router in TCP mode, using the [HostSNIRegexp](https://doc.traefik.io/traefik/routing/routers/#hostsni-and-hostsniregexp) matcher. This will run the router on layer 4 (TCP) instead of the usual layer 7 (HTTP).
8686
87-
For more in depth info how this works you can read here: [Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication).
87+
For more in-depth info on how this works, you can read here: [Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication).
8888
89-
Now that we understand the principle we can get to the practical implementation.
89+
Now that we understand the principle, we can get to the practical implementation.
9090
9191
### Traefik HTTP and TCP routers
9292
93-
Bellow is the complete `docker-compose.yml` that defines Traefik TCP router and the Rathole server with 2 HTTP, HTTPS tunnel pairs for 2 home servers, `pi` - OrangePi and `local` - MiniPC in my case.
93+
Below is the complete `docker-compose.yml` that defines the Traefik TCP router and the Rathole server with 2 HTTP/HTTPS tunnel pairs for 2 home servers: `pi` (OrangePi) and `local` (MiniPC), in my case.
9494

9595
```yml title="docker-compose.yml"
9696
version: '3.8'
@@ -177,19 +177,21 @@ networks:
177177
external: true
178178
```
179179
180-
Let's start with the most important part, `labels` on the `rathole` container that define load balancing on the two tunnels. First we define two HTTP routers using `HostRegexp()` matcher. It takes HTTP traffic from entrypoint on port `80` and load balances it between two tunnels on ports `5080` and `5081`.
180+
Let's start with the most important part: the `labels` on the `rathole` container that define load balancing on the two tunnels.
181181

182-
Second pair of labels define TCP router that takes traffic from HTTPS entrypoint on port `443` and passes it through without decrypting and load balances it between tunnels on ports `5443` and `5444`. Note that with `HostSNIRegexp()` matcher you can't include escaped dot '`.`' in the regex but you must repeat the entire domain sequence to handle `www` variant of the domain.
182+
First, we define two HTTP routers using the `HostRegexp()` matcher. It takes HTTP traffic from the entrypoint on port `80` and load balances it between two tunnels on ports `5080` and `5081`.
183183

184-
Also note that we use a separate regex variants to match the root subdomain explicitly, e.g. `pi.nemanjamitic.com` and `www.pi.nemanjamitic.com` for both HTTP and TCP routers.
184+
The second pair of labels defines a TCP router that takes traffic from the HTTPS entrypoint on port `443`, passes it through without decrypting, and load balances it between tunnels on ports `5443` and `5444`. Note that with the `HostSNIRegexp()` matcher, you can't include escaped dots (`.`) in the regex, you must repeat the entire domain sequence to handle the `www` variant of the domain.
185+
186+
Also note that we use separate regex variants to match the root subdomain explicitly, e.g. `pi.nemanjamitic.com` and `www.pi.nemanjamitic.com` for both HTTP and TCP routers.
185187

186188
That's it, this is the main load balancing logic definition.
187189

188-
**Note:** Because we use `HostRegexp()` and `HostSNIRegexp()` on the server you will need to use `Host()` and `HostSNI()` matchers **for the Traefik running on the client side of the tunnel**, or you will get `404` errors without additional configuration. Regex matchers on both server and client seems to be too loose.
190+
**Note:** Because we use `HostRegexp()` and `HostSNIRegexp()` on the server, you will need to use `Host()` and `HostSNI()` matchers **for the Traefik running on the client side of the tunnel**, or you will get `404` errors without additional configuration. Regex matchers on both the server and client sides seem to be too loose.
189191

190192
### Rathole server config
191193

192-
Now it's just left to write config for Rathole server that defines 2x2 tunnels. Just make sure to use **a different token and port** for each tunnel.
194+
Now it's just left to write the config for the Rathole server that defines 2×2 tunnels. Just make sure to use **a different token and port** for each tunnel.
193195

194196
```toml title="rathole.server.toml"
195197
[server]
@@ -222,13 +224,13 @@ token = "secret_token_2"
222224
bind_addr = "0.0.0.0:5444"
223225
```
224226

225-
**Reminder:** You just need to open port `2333` in the VPS firewall for the Rathole control channel and not for the ports `5080, 5081, 5443, 5444` because they are used by Rathole internally.
227+
**Reminder:** You just need to open port `2333` in the VPS firewall for the Rathole control channel and not for the ports `5080`, `5081`, `5443`, or `5444`, because they are used by Rathole internally.
226228

227229
### Traefik dashboard
228230

229-
Additionally, for the sake of debugging we expose Traefik dashboard using `labels` on `traefik` container. To simplify the configuration and avoid handling `acme.json` file we expose it using HTTP.
231+
Additionally, for the sake of debugging, we expose the Traefik dashboard using `labels` on the `traefik` container. To simplify the configuration and avoid handling the `acme.json` file, we expose it using HTTP.
230232

231-
**Warning:** When setting dashboard hashed password via the `TRAEFIK_AUTH` environment variable make sure to escape the `$` characters properly or auth will break. For that you will need to use both double quotes `"..."` and escape slash '`\`', see the example bellow:
233+
**Warning:** When setting the dashboard hashed password via the `TRAEFIK_AUTH` environment variable, make sure to escape the `$` characters properly or authentication will break. To do that, you need to use both double quotes `"..."` and the escape slash '`\`', as shown in the example below:
232234

233235
```bash
234236
# install apache2-utils
@@ -253,9 +255,9 @@ TRAEFIK_AUTH=admin:\$asd1\$E3lsdAo\$3Mertp57JJ4LVU.HRR0
253255

254256
## Rathole client
255257

256-
The client part of the tunnel is almost same like for a single home server. The only thing to keep in mind is to to bind the specific client just to tunnels that are meant for him, and not to all tunnels. Kind of obvious and self-explanatory, but just in case let's be very clear and explicit.
258+
The client part of the tunnel is almost the same as for a single home server. The only thing to keep in mind is to bind the specific client only to the tunnels that are meant for it, and not to all tunnels. Kind of obvious and self-explanatory, but just in case, let's be very clear and explicit.
257259

258-
Here we define the `rathole.client.toml` Rathole client config to bind the `pi` home server to it's HTTP `pi-traefik-http` and HTTPS `pi-traefik-https` tunnels.
260+
Here, we define the `rathole.client.toml` Rathole client config to bind the `pi` home server to its HTTP (`pi-traefik-http`) and HTTPS (`pi-traefik-https`) tunnels.
259261

260262
```toml title="rathole.client.toml"
261263
[client]
@@ -304,7 +306,7 @@ token = "secret_token_2"
304306
local_addr = "traefik:443"
305307
```
306308

307-
`docker-compose.yml` for the Rathole client and Traefik are exactly the same as they were for a single home server, I am repeating it here just for the sake of completeness.
309+
`docker-compose.yml` for the Rathole client and Traefik is exactly the same as it was for a single home server. I am repeating it here just for the sake of completeness.
308310

309311
```yml title="docker-compose.yml"
310312
version: '3.8'
@@ -364,7 +366,7 @@ networks:
364366
365367
## Conclusion
366368
367-
You can use this setup to expose as many home servers you want, in a cost effective and practical way, as long as your VPS has enough network bandwidth to support their traffic. It can bring your homelab on another level.
369+
You can use this setup to expose as many home servers as you want, in a cost-effective and practical way, as long as your VPS has enough network bandwidth to support their traffic. It can bring your homelab to another level.
368370
369371
What tool and method did you use to expose your home servers to the internet? Do you like this approach, are you willing to give it a try? Let me know in the comments.
370372

0 commit comments

Comments
 (0)