Avoid setting `.tls=true` for every route - ssl

I'm using traefik as a reverse proxy. Clients connect to Traefik via HTTPS, but Traefik connects to the service via HTTP.
I decided to add a test service to my docker compose file:
test:
image: hashicorp/http-echo
command: -text="Hello, World!"
labels:
- "traefik.http.routers.test-domain.rule=Host(`test.localhost`)"
- "traefik.http.routers.test-domain.tls=true"
Everything works and I can see "Hello, World!" at https://test.localhost. However, if I remove traefik.http.routers.test-domain.tls=true it no longer works, and traefik start returning 404 at that URL.
I can see how the .rule label would need to be provided for every single service, because in each case the domain would be different. But the .tls label would always be exactly the same, since all of my services will use TLS termination with HTTP to backend. It seems tedious to keep adding traefik.http.routers.[ ... ].domain.tls=true to all my services. Is there a way to have traefik just assume all services will be .tls=true?

According to Ldez, this can be done by setting tls to true on the :443 entrypoint:
traefik:
# ...
command:
# ...
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls=true
# ...

Related

Traefik: How to configure route to direct every request to http service?

I'm too dumb and Google is not helpful.
I'm trying to set up the simplest configuration:
Traefik 2 (in latest Docker container), handling incoming requests...
should direct all incoming requests (http, https) to another service, the Traefik whoami demo container (which I've got already running)...
while terminating the SSL connection, calling the service via http on port 80...
while using a configuration file with explicitly defined routes
How would I configure this? Here's my try:
entryPoints:
web:
address: :80
websecure:
address: :443
log:
filePath: "/home/LogFiles/traefik.log"
level: DEBUG
accessLog:
filePath: "/home/LogFiles/trafik-access.log"
providers:
file:
filename: "/home/traefik.yml"
http:
routers:
route-https:
rule: "Host(`traefik-test.azurewebsites.net`) && PathPrefix(`/whoami`)"
service: "whoami"
tls: {}
route-http:
rule: "Host(`traefik-test.azurewebsites.net`) && PathPrefix(`/whoami`)"
service: "whoami"
services:
whoami:
loadBalancer:
servers:
- url: "http://whoami-test.azurewebsites.net/"
I am not sure about how the https to http conversion works. The documentation says that it's happening automatically. Another part of the doc says you have to use two routers and the tls: {} part tells to terminate the TLS connection. That's what I am doing above. (Is that correct?)
The whomami service URL can be accessed in the browser without problems, via http and https. But when calling it via Traefik (for the above sample this would be https://traefik-test.azurewebsites.net/whoami) I get a 400 and the Browser shows "Bad Request". I suspect the https->http part is not working.
Samples on the web commonly show how to orchestrate multiple containers that get discovered by Traefik. That's not what I'm doing here. I just want to tell Treafik about my already running service. Take every request, route everything to my service via http. Should be simple?
Any hints are appreciated.
There were two errors preventing my configuration from working.
Number one: nasty YAML. See the two spaces before "-"?
servers:
- url: "http://whoami-test.azurewebsites.net/"
They have to go for this to be valid:
servers:
- url: "http://whoami-test.azurewebsites.net/"
Number two: the Host header set by Traefik (which is set to the proxy host) makes the service web app redirect back to my proxy. The passHostHeader: false configuration was necessary:
services:
whoami:
loadBalancer:
passHostHeader: false # <------ added this
servers:
- url: "http://whoami-test.azurewebsites.net/"
Passing the proxy host as "Host" header causes some services to 301-redirect back to the proxy, causing a redirect loop between proxy and service. A .NET Core app (Kestrel) will respond with "Bad Request" instead. Omitting the header is the solution in my case.

Docker Swarm CE, Reverse-Proxy without shared config file on master nodes

I've been wrestling with this for several days now. I have a swarm with 9 nodes, 3 managers. I'm planning on deploying multiple testing environments to this swarm using Docker-Compose for each environment. We have many rest services in each environment that I would like to manage access to them through a reverse proxy so that access to the services comes through a single port per environment. Ideally I would like it do behave something like this http://dockerNode:9001/ServiceA and http:/dockerNode:9001/ServiceB.
I have been trying traefic, docker proxy, HAProxy, (I haven't tried NGINX yet). All of these have ran into issues where I can't even get their examples to work, OR they require me to drop a file on each masternode, or setup cloud storage of some sort).
I would like to be able to have something just work by droping it into a docker-compose file, but I am also comfortable configuring all the mappings in the compose file (these are not dynamically changing environments where services come and go).
What is there a working example of this type of setup, or what should I be looking into?
If you want to access your service using the server IP and the service port, then you need to setup dnsrr endpoint mode to override the docker swarm's service mesh. Here is a yaml so you know how to do it.
version: "3.3"
services:
alpine:
image: alpine
ports:
- target: 9100
published: 9100
protocol: tcp
mode: host
deploy:
endpoint_mode: dnsrr
placement:
constraints:
- node.labels.host == node1
Note the configuration endpoint_mode: dnsrr and the way the port has been defined. Also note the placement contraint that will make the service only be able to be schedule in the with the label node1. Thus, now you can access your service using node1's IP address and port 9100. With respect to the URI serviceA just add it.

How to add a simple routing rule to traefik

I'm trying to get started with traefik in the hopes I can replace my current reverse proxy (pound) with traefik.
How do I add a simple routing rule so that mysubdomain.mydomain.com routes to http://192.168.x.x:8080?
I'm following the quickstart here. I created the following docker compose yml file and started it with docker-compose up -d reverse-proxy
version: '3'
services:
reverse-proxy:
container_name: reverse-proxy
image: traefik #The official Traefik docker image
command: --api --docker #Enables the web UI and tells Træfik to listen to docker
ports:
- "80:80" #The HTTP port
- "8080:8080" #The Web UI (enabled by --api)
volumes:
- /var/run/docker.sock:/var/run/docker.sock #So that Traefik can listen to the Docker events
Great, the container is running, but now what? How would I go about adding the simply routing rule?
If my backend web service isn't running one of these supported backends will it not work? Surely traefik can simply route http requests to any http backend right?
For example my backend web service is a web interface for my synology NAS at home. Traefik should be able to route this right? If so, how?

HTTPS endpoints for local kubernetes backend service addresses, after SSL termination

I have a k8s cluster that sits behind a load balancer. The request for myapisite.com passes through the LB and is routed by k8s to the proper deployment, getting the SSL cert from the k8s load balancer ingress, which then routes to the service ingress, like so:
spec:
rules:
- host: myapisite.com
http:
paths:
- backend:
serviceName: ingress-605582265bdcdcee247c11ee5801957d
servicePort: 80
path: /
tls:
- hosts:
- myapisite.com
secretName: myapisitecert
status:
loadBalancer: {}
So my myapisite.com resolves on HTTPS correctly.
My problem is that, while maintaining the above setup (if possible), I need to be able to go to my local service endpoints within the same namespace on HTTPS, i.e. from another pod I should be able to curl or wget the following without a cert error:
https:\\myapisite.namespace.svc.cluster.local
Even if I were interested in not terminating SSL until the pod level, creating a SAN entry on the cert for a .local address is not an option, so that solution is not viable.
Is there some simple way I'm missing to make all local DNS trusted in k8s? Or some other solution here that's hopefully not a reinvention of the wheel? I am using kubernetes version 1.11 with CoreDNS.
Thanks, and sorry in advance if this is a dumb question.
If your application can listen on both HTTP and HTTPS, you can configure both. Meaning you will be able to access via both HTTP and HTTPS by your preference. Now, how you create and distribute certificate is a different story, but you must solve it on your own (probably by using your own CA and storing cert/key in secret). Unless you want to use something like Istio and its mutual tls support to secure traffic between services.
While you write what you want to achieve, we don't really know why. The reason for this need might actually help to suggest the best solution

Traefik - Unable to expose redis docker containers with the same port for different domains

I'm trying to set up a Redis with docker-compose for different environments.
Therefore I need to expose two domains with traefik on the same port:
domain.com:6379
domain-dev.com:6379
I can't expose those ports on the container, because they are running on the same server.
My docker-compose file (for domain-dev) looks like this:
version: '2'
services:
redis:
container_name: redis-signalr-dev
image: redis
volumes:
- ./redis-signalr-data:/data
restart: always
labels:
- traefik.enable=true
- traefik.backend=redis-signalr-dev
- traefik.frontend.rule=Host:domain-dev.com
- traefik.port=6379
- traefik.docker.network=traefik_default
- traefik.frontend.entryPoints=redis
networks:
- traefik_default
volumes:
redis-signalr-data:
networks:
traefik_default:
external: true
I also tried to configure the treafik to use the following endpoint:
--entrypoints='Name:redis Address::6379'
When connecting to "domain-dev.com:6379" a connection cannot be astablished.
Does anyone know a solution to this problem?
Traefik is a reverse proxy for http, not a tcp load balancer. So traefik itself (usually) opens ports 80 and 443 for ingress and forwards incoming http requests to the given http-able backends. The port you specify in your compose service labels is the port of the container, the traffic should be passed to.
So if you run a nodejs (http) server on port 3000, you would connect to http://yourdomain:80 and traefik would forward the requests to your nodejs container on port 3000. This means that by specifying a port on a compose service, you will not open this port on your host.
In your example running redis with its custom protocol, traefik is not a solution as traefik only does http proxying. To expose redis on your host (if you really want to do that), just use regular docker port mappings and point your domains to your docker hosts. Doing this, there is no way to use the same port with different domains, just specify two different ports for your both instances. For http this works by traefik inspecting the http requests and doing routing based on the host header.
Traefik 2.0 will have TCP support: https://github.com/containous/traefik/pull/4587
Until then you'd have to use NGINX or similar.