Closed RogueGhost93 closed 1 year ago
Hello!
and it also works like a charm, the only difference is that you initially have to have domain pointing to your public IP and open the ports, once you get the certificate you can point your domain back to local IP and close the ports.
hm, why? With the DNS01 challenge, you don't need to open any ports and it works without pointing to a public IP. I understand not wanting to use CloudFlare, but there's many different providers that support this challenge: https://go-acme.github.io/lego/dns/
Overall, this seems like a much more complicated and less secure way to do things.
traefik.http.routers.heimdall.rule=(Host(${HOSTNAME}) && PathPrefix(/heimdall) || PathPrefix(/heimdall)) turns into 404, any idea why or how to fix that?
If you want Heimdall to be accessible at HOSTNAME/heimdall
, this seems like the right configuration indeed. From what I saw, additional tinkering is required as Heimdall does not support this out of the box (subfolder method is currently not supported
: https://github.com/linuxserver/Heimdall#reverse-proxy). This will probably help: https://github.com/linuxserver/reverse-proxy-confs and especially https://github.com/linuxserver/reverse-proxy-confs/blob/master/heimdall.subfolder.conf.sample
Alternatively, you may have some luck trying out a custom Traefik middleware, similar to what was done for qBittorrent:
# https://community.traefik.io/t/middleware-to-add-the-if-needed/1895/19
- traefik.http.middlewares.qbittorrent-strip-slash.redirectregex.regex=(^.*\/qbittorrent$$)
- traefik.http.middlewares.qbittorrent-strip-slash.redirectregex.replacement=$$1/
- traefik.http.middlewares.qbittorrent-strip-slash.redirectregex.permanent=false
Let me know if it works!
And if one were to add nextcloud or photoprism or similar, how would that same path be replaced? just like
- traefik.http.routers.heimdall.rule=(Host(${HOSTNAME}) && PathPrefix(/nextcloud) || PathPrefix(/nextcloud))
Yes, just make sure to replace the router name by the application name (it should read traefik.http.routers.nextcloud.rule
)
Since heimdall is not working why would nextcloud and would you have any idea how to fix it and make nextcloud/heimdall stil accessible? My idea is to add a few more services to this and make it one giant media stack.
That depends on the application. Some will fare better being in a subfolder. For example, the *arrs and Jellyfin will work, but only after specifying the base URL configuration.
Good luck!
Yes, the reason was primarily to avoid using cloudflare since i already have some paid domains from No-IP and with No-IP dns challenge doesnt work as far as i know. Also, i really dont get those API keys from cloudflare xD
So, ive been experimenting with your setup all day and since this path prefix causes different issue from app to app I decided to use
nextcloud.<my_domain>
)"
and so far it works really good, just like with your setup except that this works on every app regardless of little tweaks. The only difference is that for each new app new certificate needs to be issued (in my case that means temporarily opening ports again).
I easily added photoprism, tubesync, nextcloud, portainer etc etc and they all work. With your setup i already tried many tweaks just like you proposed for qbittorrent and in most cases it doesnt work so i resorted to Host(container_name.<my_domain>
)".That's good to hear! I also saw this SO post relevant to your issue: https://stackoverflow.com/questions/65280910/traefik-v2-redirect-http-servername-foo-to-http-servernameport
Yes, the reason was primarily to avoid using cloudflare since i already have some paid domains from No-IP and with No-IP dns challenge doesnt work as far as i know.
What do you mean? Did you register a "real" (ie not a free subdomain) at No-IP and are using their admin panel to manage your DNS records?
If that is the case, then yes No-IP does not seem to be supported. Interestingly, it looks like you can run the challenges manually, maybe from a different Docker image: https://go-acme.github.io/lego/dns/manual/
The issue with your method is that auto renewal may not work until you open the ports again - not ideal.
I guess you could change your domain's DNS servers and point to CloudFlare or a different DNS provider that is supported by Lego if you wanted to automate your process.
Yes im managing paid domains at no-ip and point them to whichever ip i want, sometimes public sometimes local ip. Yes, for renewal i would have to open the ports again. When subscription expires i might switch to cloudflare and make it how you originally intended but still keep the Host(container_name.
You said if we use tailscale we will have to use it at home too, but, is there a way to add for example two different domains that would point to yur host? I just started with traefik so idk. Something like this
container_name.<my_domain>
) || Host(container_name.<my_second_domain>
))im not sure what || represents in traefik but if this would work then if you are controling two different domains you could easily have one for tailscale and one for local network. Would you know by any chance?
Intead of tailscale, you can run an open source project like https://github.com/Nyr/wireguard-install which installs a private vpn server, similar to PiVPN, although you would have to have that port open in order to connect to your server, which in my view in combination with geoIP block and fail2ban etc etc is safer than closed source tailscale. Just a thought for enthusiasts, tailscale is easier ofc.
You are right, subdomains are easier and work fine. I just thought it would be cleaner to use subpaths for *arrs apps, but otherwise there's absolutely no drawbacks using those, in fact this is how most people do it from what I saw.
Yes, you can do this in Traefik and it should work for two domains. Let me know if it doesn't!
The alternative would be to rewrite the DNS record locally, so that if you are home the domain resolves to 192.168.x.x, and if you are out it does not. Adguard Home lets you do that. That was my initial approach, but I resorted to keeping Tailscale running on all my devices at all time, with the added benefit of getting an ad blocker on all my devices, anywhere ;)
You are right that there's many Tailscale alternatives. I guess I just fell in love with the product, it's so easy to use and well thought. The company really is developer friendly on top of that.
By the way, only the server code is closed source. If Tailscale ever goes rogue or I really wanted to only use open source software, I would use headscale, an OSS implementation of the server (similar to what Vaultwarden is to Bitwarden) with the added benefit of official client apps still working: https://github.com/juanfont/headscale
I havent heard of headscale, thanks for that. Yes i was aware of rewriting DNS record locally as im using OPNsense (which also comes with adguar plugin) but most people arent so i think it would be easier if it was possible to just use two different domains, i will try and let you know!
I created a domain at cloudflare to test these things out. Im using it with wildcard so my Host(container_name.
level=error msg="Unable to obtain ACME certificate for domains \"heimdall.MYDOMAIN.COM\": unable to generate a certificate for the domains [heimdall.MYDOMAIN.COM]: error: one or more domains had a problem:\n[heimdall.MYDOMAIN.COM] [heimdall.MYDOMAIN.COM] acme: error presenting token: cloudflare: failed to create TXT record: Authentication error (10000)\n" providerName=myresolver.acme routerName=heimdall@docker rule="Host(heimdall.MYDOMAIN.COM
)" ACME CA="https://acme-v02.api.letsencrypt.org/directory"
I also tried using their global API as it is suggested by lets encrypt https://doc.traefik.io/traefik/v1.6/configuration/acme/ CLOUDFLARE_EMAIL, CLOUDFLARE_API_KEY - The Global API Key needs to be used, not the Origin CA Key But then i get this error
level=error msg="Unable to obtain ACME certificate for domains \"heimdall.MYDOMAIN.COM\": unable to generate a certificate for the domains [heimdall.MYDOMAIN.COM]: error: one or more domains had a problem:\n[heimdallMYDOMAIN.COM] time limit exceeded: last error: read udp 172.18.0.16:41753->173.245.58.101:53: i/o timeout\n" ACME CA="https://acme-v02.api.letsencrypt.org/directory" providerName=myresolver.acme routerName=heimdall@docker rule="Host(heimdall.MYDOMAIN.COM
)"
Domain name is pointing to my local IP, i havent tried with public IP and open ports as you said it should work this way too which made me buy one domain and try it out :D if i go to heimdall.MYDOMAIN.com it works just fine but the connection is insecure so i know the hostname works just fine, the problem is either API keys or something else with cloudflare or something else i cant think of. I would appreciate your help with this as im sure others would and will run into the same problem. Maybe my API are setup in a wrong way? Here are some screenshots from cloudflare but i do believe i set them up right.
bd.png)
I also tried to regenerate APIs
Another error i get sometimes is this
level=error msg="Unable to obtain ACME certificate for domains \"photoprism.MYDOMAIN.COM\": unable to generate a certificate for the domains [photoprism.MYDOMAIN.COM]: error: one or more domains had a problem:\n[photoprism.MYDOMAIN.COM] [photoprismMYDOMAIN.COM] acme: error presenting token: cloudflare: failed to create TXT record: Record already exists. (81057)\n" providerName=myresolver.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" rule="Host(photoprism.MYDOMAIN.COM
)" routerName=photoprism@docker
But if i visit photoprism.mydomain.com it is still insecure, there is no certificate.
Thanks!
Hi, it looks like the tokens were not created properly. The full documentation is here: https://go-acme.github.io/lego/dns/cloudflare/
Create a token with Zone / Zone / Read
and Zone / DNS / Edit
rights:
Then specify it in CLOUDFLARE_DNS_API_TOKEN
and CLOUDFLARE_ZONE_API_TOKEN
. Don't forget to set your CLOUDFLARE_EMAIL
too.
I did make it exactly the same as in your screenshot, i suppose i use that one API key and populate those two variables with the same API basically. Just wanted to clarify there are not two different API keys involved.
However, i still get this error
level=error msg="Unable to obtain ACME certificate for domains \"calibreweb.MYDOMAIN.COM\": unable to generate a certificate for the domains [calibreweb.MYDOMAIN.COM]: error: one or more domains had a problem:\n[calibreweb.MYDOMAIN.COM] time limit exceeded: last error: read udp 172.22.0.9:58439->108.162.193.243:53: i/o timeout\n" ACME CA="https://acme-v02.api.letsencrypt.org/directory" providerName=myresolver.acme routerName=calibreweb@docker rule="Host(calibreweb.MYDOMAIN.COM
)"
Just to clarify, i have a container also listening on MYDOMAIN.COM without any subdomain, to make sure the wildcard is not the problem and i get the same error in both cases.
Looks like a different error this time, you had Authentication error
, now time limit exceeded
so you may want to retry later or investigate if something is preventing Traefik from reaching the web.
docker exec qbittorrent sh -c "ping 1.1.1.1" docker exec gluetun sh -c "ping 1.1.1.1" both work and ping just fine
but traefik cant ping for anything some reason docker exec traefik sh -c "ping 1.1.1.1" docker exec traefik sh -c "ping 8.8.8.8"
I had this same setup without dns challenge and it worked, all i did was add 3 variables to traefik, CF email CF APIs. And switched
for
im really confused at this point. Are you sure we are using exactly the same API key for both of those variables?
environment:
- LETS_ENCRYPT_EMAIL=${LETS_ENCRYPT_EMAIL}
- CLOUDFLARE_EMAIL=${CLOUDFLARE_EMAIL}
- CLOUDFLARE_DNS_API_TOKEN=${CLOUDFLARE_DNS_API_TOKEN}
- CLOUDFLARE_ZONE_API_TOKEN=${CLOUDFLARE_ZONE_API_TOKEN}
command:
#- --api.dashboard=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.web-secure.address=:443
- --entrypoints.web.http.redirections.entryPoint.to=web-secure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
- --certificatesresolvers.myresolver.acme.dnschallenge=true
- --certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare
#- --certificatesresolvers.myresolver.acme.tlschallenge=true
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.myresolver.acme.email=${LETS_ENCRYPT_EMAIL}
ports:
- "80:80"
- "443:443"
#- "8080:8080"
volumes:
- ${INSTALL_LOCATION}/config/letsencrypt:/letsencrypt
- "/var/run/docker.sock:/var/run/docker.sock:ro"
.env LETS_ENCRYPT_EMAIL=myemail@provider.com CLOUDFLARE_EMAIL=myemail@provider.com CLOUDFLARE_DNS_API_TOKEN=xxx # note that these apis are the same CLOUDFLARE_ZONE_API_TOKEN=xxx # note that these apis are the same
EDIT: After turning off my network wide VPN i ran docker-compose down then up and now traefik gives this
level=error msg="Unable to obtain ACME certificate for domains \"radarr.MYDOMAIN.COM\": unable to generate a certificate for the domains [radarr.MYDOMAIN.COM]: failed to post JWS message: failed to sign content: failed to sign content: go-jose/go-jose: Error generating nonce: failed to get nonce from HTTP HEAD: Head \"https://acme-v02.api.letsencrypt.org/acme/new-nonce\": net/http: timeout awaiting response headers" ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=radarr@docker rule="Host(radarr.MYDOMAIN.COM
)" providerName=myresolver.acme
and this one
level=error msg="Unable to obtain ACME certificate for domains \"heimdall.MYDOMAIN.COM\": unable to generate a certificate for the domains [heimdall.MYDOMAIN.COM]: error: one or more domains had a problem:\n[heimdall.MYDOMAIN.COM] failed to initiate challenge: Post \"https://acme-v02.api.letsencrypt.org/acme/chall-v3/209812013857/cxos5g\": read tcp 172.25.0.19:43306->172.65.32.248:443: read: connection reset by peer\n" ACME CA="https://acme-v02.api.letsencrypt.org/directory" providerName=myresolver.acme routerName=heimdall@docker rule="Host(heimdall.MYDOMAIN.COM
)"
However now traefik pings just fine docker exec traefik sh -c "ping 1.1.1.1"
EDIT2: AAAND they are obtained, somehow, the errors are still there but certificates too, i have no idea how or why.... Maybe, just maybe the reason could be something like this https://www.reddit.com/r/Traefik/comments/n9pjcz/how_to_increase_time_limit_when_generating_a/ I have all traffic to port 53 forwarded to AdGuard and then to Unbound so maybe thats why, even though that doesnt make any sense since the regular tls (no DNS01) challenge was working just fine....weird Im sorry to bother you, i saw on reddit you are trying to learn traefik so i just bombarded you :P
It seems like Traefik's access to the web is flaky at best, possibly because of DNS issues as you suggested. I am glad it works now!
I am closing this since it is now resolved.
First of all thank you for this, it works like a charm! just fyi I raplaced cloudflare part with
changing path prefix for heimdall to
traefik.http.routers.heimdall.rule=(Host(
${HOSTNAME}
) && PathPrefix(/heimdall
) || PathPrefix(/heimdall
)) turns into 404, any idea why or how to fix that?And if one were to add nextcloud or photoprism or similar, how would that same path be replaced? just like
${HOSTNAME}
) && PathPrefix(/nextcloud
) || PathPrefix(/nextcloud
))Since heimdall is not working why would nextcloud and would you have any idea how to fix it and make nextcloud/heimdall stil accessible? My idea is to add a few more services to this and make it one giant media stack.
Thanks!