Skip to content

Commit d3b3b22

Browse files
author
Patrick M
committed
add posts
1 parent cf904b1 commit d3b3b22

File tree

2 files changed

+232
-0
lines changed

2 files changed

+232
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
layout: post
3+
title: "Using curl with SNI"
4+
date: 2024-05-01 00:00:00 -0400
5+
category: "General"
6+
tags: ["linux", "bash"]
7+
---
8+
9+
This is a short little reminder for myself, when using curl to make requests to local things and spoofing SNI, use the following command.
10+
11+
```bash
12+
curl -vik --resolve google.com:443:127.0.0.1 https://google.com
13+
```
14+
15+
Happy Curling
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
---
2+
layout: post
3+
title: "Configuring Traefik to work over Tailscale"
4+
date: 2024-05-27 00:00:00 -0400
5+
category: "General"
6+
tags: ["linux", "docker"]
7+
---
8+
9+
This is a bit of an extention to [this tailscale blog post](https://tailscale.com/blog/docker-tailscale-guide). I would start there to get an idea of setting up tags and auth, as well as just information about exactly what this does in more detail.
10+
11+
My setup differs slightly in that I wanted to still be able to access things locally over Traefik when I was on my local network. This takes a bit of split DNS'ing and making sure to expose Traefik ports (via the Tailscale container) to the host. First to get Traefik set up, I start by creating my data directory.
12+
13+
For the purpose of this blog post I am configuring [Immich](https://github.com/immich-app/immich) for use over tailscale.
14+
15+
## Traefik Config
16+
17+
```bash
18+
mkdir data
19+
cd data
20+
touch traefik.yml
21+
touch acme.json
22+
chmod 600 acme.json
23+
```
24+
25+
Then I configure the traefik.yml file
26+
27+
```bash
28+
nano traefik.yml
29+
```
30+
31+
```yaml
32+
api:
33+
dashboard: false
34+
debug: true
35+
entryPoints:
36+
http:
37+
address: ":80"
38+
http:
39+
redirections:
40+
entryPoint:
41+
to: https
42+
scheme: https
43+
https:
44+
address: ":443"
45+
ping:
46+
address: ":8080"
47+
ping:
48+
entryPoint: "ping"
49+
serversTransport:
50+
insecureSkipVerify: true
51+
providers:
52+
docker:
53+
endpoint: "unix:///var/run/docker.sock"
54+
exposedByDefault: false
55+
file:
56+
filename: /config.yml
57+
certificatesResolvers:
58+
cloudflare:
59+
acme:
60+
storage: acme.json
61+
dnsChallenge:
62+
provider: cloudflare
63+
# disablePropagationCheck: true # uncomment this if you have issues pulling certificates through cloudflare, By setting this flag to true disables the need to wait for the propagation of the TXT record to all authoritative name servers.
64+
resolvers:
65+
- "1.1.1.1:53"
66+
- "1.0.0.1:53"
67+
```
68+
69+
I think this is a pretty standard config that will allow Traefik to configure Cloudflare to create LetsEncrypt certificates automatically. Once that's created I create a `.env` with the following values. You'll need to create a [cloudflare API token](https://dash.cloudflare.com/profile/api-tokens). You'll also need to create [some kind of Tailscale auth](https://login.tailscale.com/admin/settings/keys)
70+
71+
```env
72+
# Enviornmental Variables file .env
73+
CF_API_EMAIL={{ Replace with cloudflare api email address }}
74+
CF_DNS_API_TOKEN={{ Replace with cloudflare api token }}
75+
WAN_HOSTNAME={{ This is to add a response header with the proxy hostname for debugging }}
76+
77+
TS_AUTHKEY={{ Tailscale auth token }}
78+
```
79+
80+
Now I can add my config.yml file.
81+
82+
```bash
83+
nano config.yml
84+
```
85+
86+
```yaml
87+
http:
88+
routers:
89+
immich:
90+
entryPoints:
91+
- "https"
92+
rule: "Host(`immich.mydomain.com`)"
93+
middlewares:
94+
- default-headers
95+
- https-redirectscheme
96+
tls: {}
97+
service: immich
98+
99+
services:
100+
immich:
101+
loadBalancer:
102+
servers:
103+
- url: "http://immich-app:3001"
104+
passHostHeader: true
105+
106+
middlewares:
107+
https-redirectscheme:
108+
redirectScheme:
109+
scheme: https
110+
permanent: true
111+
112+
default-headers:
113+
headers:
114+
frameDeny: true
115+
browserXssFilter: true
116+
contentTypeNosniff: true
117+
forceSTSHeader: true
118+
stsIncludeSubdomains: true
119+
stsPreload: true
120+
stsSeconds: 15552000
121+
customFrameOptionsValue: SAMEORIGIN
122+
customResponseHeaders:
123+
X-Proxy-By: {{env "WAN_HOSTNAME"}}
124+
customRequestHeaders:
125+
X-Forwarded-Proto: https
126+
```
127+
128+
> Notice that I have used the immich container hostname for my URL.
129+
130+
Using the containername and internal port is important because Traefik will be running in the bridged network and will see the Immich container's name and port, not the host. `localhost` will reference the traefil/tailscale container in this context and will not resolve.
131+
132+
## Docker Compose
133+
134+
Once that's set up you can add the docker compose file.
135+
136+
```bash
137+
nano docker-compose.yaml
138+
```
139+
140+
```yaml
141+
services:
142+
tailscale:
143+
image: tailscale/tailscale:latest
144+
container_name: tailscale
145+
hostname: immich
146+
environment:
147+
- TS_AUTHKEY=${TS_AUTHKEY}?ephemeral=false
148+
- TS_EXTRA_ARGS=--advertise-tags=tag:immich
149+
- TS_STATE_DIR=/var/lib/tailscale
150+
volumes:
151+
- ./tailscale/state:/var/lib/tailscale
152+
- /dev/net/tun:/dev/net/tun
153+
cap_add:
154+
- net_admin
155+
restart: unless-stopped
156+
ports:
157+
- 443:443
158+
- 80:80
159+
networks:
160+
- immich_immich
161+
162+
traefik:
163+
image: traefik:latest
164+
container_name: traefik
165+
restart: unless-stopped
166+
environment:
167+
- TRAEFIK_CERTIFICATESRESOLVERS_CLOUDFLARE_ACME_EMAIL=${CF_API_EMAIL}
168+
- CF_API_EMAIL
169+
- CF_DNS_API_TOKEN
170+
- TRAEFIK_AUTH
171+
- WAN_HOSTNAME
172+
volumes:
173+
- /etc/localtime:/etc/localtime:ro
174+
- /var/run/docker.sock:/var/run/docker.sock:ro
175+
- ./data/traefik.yml:/traefik.yml:ro
176+
- ./config.yml:/config.yml:ro
177+
- ./data/acme.json:/acme.json
178+
labels:
179+
- "traefik.enable=true"
180+
- "traefik.http.services.traefik.loadbalancer.server.port=1337"
181+
- "traefik.http.routers.traefik-secure.tls=true"
182+
- "traefik.http.routers.traefik-secure.tls.certresolver=cloudflare"
183+
- "traefik.http.routers.traefik-secure.tls.domains[0].main=immich.mydomain.com"
184+
- "traefik.http.routers.traefik-secure.service=api@internal"
185+
network_mode: service:tailscale
186+
187+
watchtower:
188+
image: containrrr/watchtower:latest
189+
container_name: watchtower
190+
volumes:
191+
- /var/run/docker.sock:/var/run/docker.sock
192+
193+
networks:
194+
immich_immich:
195+
external: true
196+
```
197+
198+
## Networking Bits
199+
200+
You'll notice that I've included the network from my other docker compose file. This network is created specifically so that I can bridge these two separate docker networks. In the other docker compose I configure this using:
201+
202+
```yaml
203+
networks:
204+
immich:
205+
driver: bridge
206+
```
207+
208+
Then each container declared in that compose file specifies the network in the service definition.
209+
210+
```yaml
211+
networks:
212+
- immich
213+
```
214+
215+
In my tailscale container I do something similar and specify `immich_immich`. In this case the namespace is immich and then the network is immich, because the network originates from the other compose file. You'll also see my traefik container definition does not speficy any ports, but does specify it's network is the tailscale container. Then the tailscale container specifies all the ports I want to expose for both (traefik and tailscale) containers.
216+
217+
Once you run this with `docker compose up -d` you'll need to check your tailscale admin panel and ensure you see immich. Then in cloudflare you can set your dns record to either an A record with the tailscale IP, or a CNAME with the _something.something.ts.net_ hostname.

0 commit comments

Comments
 (0)