Vorwort
In diesem Beitrag findest du eine Step-by-Step Anleitung zur Installation eines Traefik Reverse Proxys mit dem Bezug eines Let´s Encrypt Wildcard Zertifikates.
Voraussetzungen
- Docker Host
- DNS-Nameserver der eigenen Domain via Cloudflare
Erstellung Cloudflare API Token
Hier kann ein Cloudflare API Token erstellt werden, welcher zum Bezug des Wildcard Zertifikates via Let´s Encrypt benötigt wird.
Erstellung Docker Compose Projekt
In den folgenden Schritten ist das Docker Compose Projekt zu erstellen.
1
2
3
4
5
6
7
8
| mkdir traefik
cd traefik
mkdir logs
touch acme.json
chmod 600 acme.json
touch traefik.yml
touch config.yml
touch docker-compose.yml
|
1
2
3
| sudo apt update
sudo apt install apache2-utils
echo $(htpasswd -nb <USER> <PASSWORD>) | sed -e s/\\$/\\$\\$/g
|
1
| sudo nano docker-compose.yml
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| Version: '3'
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
environment:
- CF_API_EMAIL=max.muser@DOMAIN.de #Mit E-Mail-Adresse zu ersetzten
- CF_DNS_API_TOKEN=APITOKENCLOUDFLARE #Mit eigenem API Token zu ersetzten
- TZ=Europe/Berlin
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /docker/traefik/traefik.yml:/traefik.yml:ro
- /docker/traefik/acme.json:/acme.json
- /docker/traefik/config.yml:/config.yml:ro
- /docker/traefik/logs:/treafik_logs
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`traefik.DOMAIN.de`)" #DOMAIN ist durch die eigene zu ersetzen.
- "traefik.http.middlewares.traefik-auth.basicauth.users=USERNAME:PASSWORD" #Siehe Anleitung zur Generierung der Basicauth Daten
- "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
- "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.DOMAIN.de`)" #DOMAIN ist durch die eigene zu ersetzen.
- "traefik.http.routers.traefik-secure.middlewares= default-headers@file, default-whitelist@file, rate-limit@file"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.options=tls-options@file"
- "traefik.http.routers.traefik-secure.tls.certresolver=cloudflare"
- "traefik.http.routers.traefik-secure.tls.domains[0].main=DOMAIN.de"
- "traefik.http.routers.traefik-secure.tls.domains[0].sans=*.DOMAIN.de"
- "traefik.http.routers.traefik-secure.service=api@internal"
|
Beispiel Konfiguration
Folgend eine Beispiel Konfiguration mit welcher nach Anpassung begonnen werden kann.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| api:
dashboard: true
debug: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
serversTransport:
insecureSkipVerify: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /config.yml
watch: true
certificatesResolvers:
cloudflare:
acme:
email: max.muser@DOMAIN.de #Mit eigener E-Mail-Adresse zu ersetzen.
storage: acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"
pilot:
token: "APITOKEN_PILOT" #Mit Traefik Pilot Token zu ersetzen
dashboard: false #Nach ersetzen auf true setzen.
log:
filePath: "/treafik_logs/traefik.log"
level: ERROR
accessLog:
filePath: "/treafik_logs/access.log"
bufferingSize: 100
fields:
names:
StartUTC: drop
filters:
minDuration: "10ms"
retryAttempts: true
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
| #DOMAIN ist durch die eigene zu ersetzen.
#APP ist durch die gewünschte Subdomain zu ersetzten und im Service abzubilden.
#IP-Adresse ist durch das gewünschte Ziel zu ersetzen.
http:
#region routers
routers:
base_ip_http:
entryPoints:
- "http"
rule: "HostRegexp(`{host:^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$}`)"
middlewares:
- redirect-website
- default-headers
- rate-limit
service: www
base_ip_https:
entryPoints:
- "https"
rule: "HostRegexp(`{host:^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$}`)"
middlewares:
- redirect-website
- default-headers
- rate-limit
tls:
options: tls-options
service: www
www:
entryPoints:
- "https"
rule: "Host(`www.DOMAIN.de`)"
middlewares:
- default-headers
- https-redirect
- rate-limit
tls:
options: tls-options
service: www
www-root:
entryPoints:
- "https"
rule: "Host(`DOMAIN.de`)"
middlewares:
- default-headers
- https-redirect
- redirect-website
- rate-limit
tls:
options: tls-options
service: www
APP:
entryPoints:
- "https"
rule: "Host(`APP.DOMAIN.de`)"
middlewares:
- default-headers
- https-redirect
- rate-limit
tls:
options: tls-options
service: APP
APP_api:
entryPoints:
- "https"
rule: "Host(`APP.DOMAIN.de`)&& PathPrefix(`/api`, `/oauth`)"
middlewares:
- default-headers
- https-redirect
- rate-limit
- default-whitelist # #IP Whitelist
tls:
options: tls-options
service: APP
pihole:
entryPoints:
- "https"
rule: "Host(`pihole.DOMAIN.de`)"
middlewares:
- default-headers
- default-whitelist
- addprefix-pihole
- https-redirect
- rate-limit
tls:
options: tls-options
service: pihole
#endregion
#region services
services:
www:
loadBalancer:
servers:
- url: "https://IP-WEBSERVER"
passHostHeader: true
APP:
loadBalancer:
servers:
- url: "https://IP-WEBSERVER:PORT"
passHostHeader: true
pihole:
loadBalancer:
servers:
- url: "http://IP-PiHole"
#endregion
middlewares:
addprefix-pihole:
addPrefix:
prefix: "/admin"
redirect-website:
redirectRegex:
regex: ".*"
replacement: "https://www.DOMAIN.de"
permanent: true
https-redirect:
redirectScheme:
scheme: https
permanent: true
rate-limit:
ratelimit:
average: 200
burst: 100
default-headers:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 15552000
customFrameOptionsValue: SAMEORIGIN
customRequestHeaders:
X-Forwarded-Proto: https
default-headers-NoSniff-false:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: false
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 15552000
customFrameOptionsValue: SAMEORIGIN
customRequestHeaders:
X-Forwarded-Proto: https
default-whitelist:
ipWhiteList:
sourceRange:
- "10.0.0.0/8"
- "192.168.0.0/16"
- "172.16.0.0/12"
gzip:
compress: {}
secured:
chain:
middlewares:
- default-whitelist
- default-headers
- monitoring-whitelist
- gzip
- error-pages
tls:
options:
tls-options:
minVersion: VersionTLS12
sniStrict: true
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
curvePreferences:
- CurveP521
- CurveP384
|
1
| sudo docker-compose up -d
|