I have a problem with mtls in traefik,
I need to enter traefik as a client with mtls but the configuration that I tried is not working for me since it enters the link without any certificate
http:
routers:
crypto-router:
tls:
options: testmtls
rule: "PathPrefix(`/CryptoTest`)"
entryPoints:
- websecure
service: cryptoTest-service
middlewares:
- cryptoTest-stripprefix
tls:
options:
testmtls:
clientAuth:
caFiles:
- /etc/traefik/cryptolocal.crt
clientAuthType: RequireAndVerifyClientCert
I expected that it would give me some error when connecting the request without a certificate but this not happens and I need only requests with client certificates to entry
Related
I am deploying the standard Kubernetes Dashboard (Jetstack) to the K3s cluster I have deployed on my RPI cluster, I am using lets-encrypt to provision the TLS cert and setting the following options on the dashboard deployment:
spec:
args:
- --tls-cert-file=/tls.crt
- --tls-key-file=/tls.key
volumeMounts:
- mountPath: /certs
name: kubernetes-dashboard-certs
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: cluster.smigula.com-tls
The cert is valid when I visit the URL in my browser, however the pod raises this:
http: TLS handshake error from 10.42.0.8:43704: remote error: tls: bad certificate
It appears that the ingress is terminating the TLS connection when the pod expects to terminate it. What should I do? Thanks.
[edit] I changed the resource kind from Ingress to IngressRouteTCP and set passthrough: true in the tls: section. Still same result.
I am currently trying to figure out how to enable istio to use a client certificate to authenticate to an external https service that requires client authentication. The client is a pod deployed in a kubernetes cluster that has istio installed. It currently accesses the external service using http, and cannot be changed. I know and have verified that istio can perform TLS origination so that the client can still use http to refer to the service, and istio will perform the TLS connection. But if the service also requires client certificate authentication, is there a way for me to configure istio to utilize a given certificate to do that?
I have tried by creating a ServiceEntry as described in some tutorials, as well as DestinationRules for that ServiceEntry. Is there a configuration in the DestinationRule, or elsewhere that will allow me to do that?
This is my current attempt. The hostname that requires client authentication is app.k8s.ssg-masamune.com. I have already verified that all the certificates I'm using appear to work through curl.
The certificates though are signed by a custom CA.
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-svc-https
spec:
hosts:
- api.dropboxapi.com
- www.googleapis.com
- developers.facebook.com
- app.k8s.ssg-masamune.com
- bookinfo.k8s.ssg-masamune.com
- edition.cnn.com
- artifactory.pds-centauri.com
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
targetPort: 443
resolution: DNS
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: app-dr
spec:
host: app.k8s.ssg-masamune.com
trafficPolicy:
portLevelSettings:
- port:
number: 80
tls:
mode: SIMPLE
credentialName: app-secret
insecureSkipVerify: true
sni: app.k8s.ssg-masamune.com
subjectAltNames:
- app
I have a couple of microservices and our backend is opendj/ldap. It has been configured to use SSL. Now we are trying to use ISTIO as our k8s service mesh. Every other service works fine but the ldap server - opendj - is not. My gues is it's because of the ssl configuration. It's meant to use self-signed cert.
I have a script that creates a self-signed cert in istio namespace and I have tried to use it like this on the gateway.yaml
- port:
number: 4444
name: tcp-admin
protocol: TCP
hosts:
- "*"
tls:
mode: SIMPLE # enable https on this port
credentialName: tls-certificate # fetch cert from k8s secret
I also have tried to use
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: opendj-istio-mtls
spec:
host: opendj.{{.Release.Namespace }}.svc.cluster.local
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
credentialName: tls-certificate
---
apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
name: opendj-receive-tls
spec:
targets:
- name: opendj
peers:
- mtls: {}
For the ldap server but it's not connecting. While trying to use the tls spec in gateway.yaml I am getting this error
Error: admission webhook "pilot.validation.istio.io" denied the request: configuration is invalid: server cannot have TLS settings for non HTTPS/TLS ports
And the logs from opendj server
INFO - entrypoint - 2020-06-17 12:49:44,768 - Configuring OpenDJ.
WARNING - entrypoint - 2020-06-17 12:49:48,987 -
Unable to connect to the server at
"oj-opendj-0.opendj.default.svc.cluster.local" on port 4444
WARNING - entrypoint - 2020-06-17 12:49:53,293 -
Unable to connect to the server at
"oj-opendj-0.opendj.default.svc.cluster.local" on port 4444
Can someone please help me out how I should approach this.
To Enable non-https traffic over TLS connections you have to use Protocol TLS. TLS implies the connection will be routed based on the SNI header to the destination without terminating the TLS connection. You can check this.
- port:
number: 4444
name: tls
protocol: TLS
hosts:
- "*"
tls:
mode: SIMPLE # enable https on this port
credentialName: tls-certificate # fetch cert from k8s secret
Please check this istio documentation also.
I have a VM0 where Traefik is running as a docker and two target system VM1 and VM2 which both have a webserver running.
All domainA.com requests should go to VM1 via TCP router and tls passthrough, because this webservice is handling the certificates itself.
All domainB.com requests should go to VM2 via http router and Traefik should generate the tls certs for this domain.
My problem now is, as soon as I add any tls config to the http router, it seems tcp passthrough doesn't work anymore. In the logs I see this messages:
time="2020-03-15T21:46:18Z" level=debug msg="Serving default certificate for request: \"subdomain.DomainA.com\""
time="2020-03-15T21:46:18Z" level=debug msg="http: TLS handshake error from 192.168.1.116:55103: remote error: tls: unknown certificate"
time="2020-03-15T21:46:18Z" level=debug msg="Serving default certificate for request: \"subdomain.DomainA.com\""
time="2020-03-15T21:46:18Z" level=debug msg="http: TLS handshake error from 192.168.1.116:55104: remote error: tls: unknown certificate"
And if I visit the website through Traefik, it shows me a self signed certificate from Traefik.
If I remove then all tls settings under the http router, passthrough is working again.
My Dynamic File:
http:
routers:
HTTProuter0:
rule: "HostRegexp(`{subdomain:[a-z]+}.domainA.com`)"
service: "domainA"
entryPoints:
- "websecure"
tls:
certResolver: "myresolver"
domains:
- main: "domainA.com"
sans:
- "*.domainA.com"
services:
domainA:
loadBalancer:
servers:
- url: "https://192.168.1.13:4433"
tcp:
routers:
TCProuter0:
rule: "HostSNI(`*`)"
service: "domainB"
entryPoints:
- "websecure"
tls:
passthrough: true
services:
domainB:
loadBalancer:
servers:
- address: "192.168.1.11:443"
My static file:
serversTransport:
insecureSkipVerify: true
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
spain:
address: ":4443"
certificatesResolvers:
myresolver:
acme:
email: email#email.com
storage: /etc/traefik/acme/acme.json
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 60
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
api:
insecure: true
dashboard: true
providers:
docker: {}
file:
directory: /etc/traefik/config
watch: true
log:
filePath: /etc/traefik/traefik.log
level: DEBUG
I'm stuck at this problem now for hours. I am not sure if it is a bug or if I do something wrong?
Any help would be very appreciated!
Thanks a lot
I found the problem. Unbelievable I wasted so much time for this...
It seems Traefik does not support wildcards in combination with domains in HostSNI.
HostSNI(`*`) => Works
HostSNI(`*.mydomain.com`) => DOESN'T WORK !!!!
HostSNI(`www.mydomain.com`,`web.mydomain.com`) => Work
So I added every domain explicit and now it works.
I have an application deployment at foo.example.com running on Kubernetes (GKE). The ingress definition looks like this:
spec:
tls:
- hosts:
- "foo.example.com"
secretName: foo-example-com
rules:
- host: "foo.example.com"
http:
paths:
- path: /*
backend:
serviceName: web
servicePort: 80
When I navigate to http://foo.example.com/ I get (correctly) redirected to https://foo.example.com/ with the proper certificate in place.
However, I have example.com in my Search Domains. So a ping foo correctly resolves to the Kubernetes ingress.
But when I go to https://foo/ in my browser, I get the following error message in Chrome:
Your connection is not private
Attackers might be trying to steal your information from foo (for example, passwords, messages, or credit cards). Learn more
NET::ERR_CERT_AUTHORITY_INVALID
Subject: Kubernetes Ingress Controller Fake Certificate
Issuer: Kubernetes Ingress Controller Fake Certificate
Expires on: Oct 1, 2019
Current date: Oct 9, 2018
How would you get this working?
Obviously, I can't get a certificate for foo without some self-signing hackery, which I'd rather not attempt.
This will work the same even outside of the Kubernetes.
First of all each web browser (including Chrome) has a list of Authorities out of the box:
and so on.
Your CA certs (in your Secret) are self-signed by your own Certificate Authority , which is not trusted for Chrome, that's why you see the error. You probably can import your CA to Chrome, and your Chrome instance will trust it, but...
as you know TLS (SSL) certificate usually issued for a particular domain or a wildcard (CN), so foo likely won't match the wildcard expression of your certificate and you will see another SSL error:NET::ERR_CERT_COMMON_NAME_INVALID.
So, you will have to use rewrite rule to make it work.
So the way I solved this was to add a redirect ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: redirect-ingress
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "false"
ingress.kubernetes.io/configuration-snippet: |
if ($host ~ ^foo$) {
return 301 https://foo.example.com$request_uri;
}
spec:
rules:
- host: "foo"
http:
paths:
- backend:
serviceName: web
servicePort: 80
I'm not sure if it's optimal, but it did work.