Hi (bluepuma),
I have all my Traefik working on local with local DNS resolver. I can access to my containers with a reverse proxy but I'm struggling to make it working over internet.
Traefik is running on a macvlan local IP 192.168.0.102 under a Synology
When I'm trying to access over internet I have those errors in the logs :
level=debug msg="http: TLS handshake error from XXX.XXX.XXX.XXX:2149: write tcp 192.168.0.102:443->XXX.XXX.XXX.XXX:2149: write: connection reset by peer"
level=debug msg="http: TLS handshake error from XXX.XXX.XXX.XXX:2150: write tcp 192.168.0.102:443->XXX.XXX.XXX.XXX:2150: write: connection reset by peer"
level=debug msg="http: TLS handshake error from XXX.XXX.XXX.XXX:2151: tls: client offered only unsupported versions: [301]"
I've tried to lower the minimum value for TLS to 1.1 but still not working. I would not even need this as I try to access from an up to date device.
Of course I have a valid cert in acme.json that Traefik sees
I'm wondering if it comes from the home router, as I forward incoming requests from port 80 and 443 TCP to 192.168.0.102 port 80 and 443
Here is the config :
docker-compose.yml
version: '3'
secrets:
ovh_application_key:
file: blabla
ovh_application_secret:
file: blabla
ovh_consumer_key:
file: blabla
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
networks:
macvlan:
traefik:
volumes:
- /volume1/docker/traefik/config:/etc/traefik
- /etc/localtime:/etc/localtime:ro
labels:
traefik.enable: true
traefik.http.routers.dashboard.rule: Host(`traefik.mydomain.com`)
traefik.http.routers.dashboard.service: api@internal
traefik.http.routers.dashboard.middlewares: auth
traefik.http.routers.dashboard.entrypoints: websecure
traefik.http.middlewares.auth.basicauth.users: XXXXXXXXXXXXX
depends_on:
- socket-proxy
secrets:
- ovh_application_key
- ovh_application_secret
- ovh_consumer_key
environment:
OVH_ENDPOINT: ovh-eu
OVH_APPLICATION_KEY_FILE: /run/secrets/ovh_application_key
OVH_APPLICATION_SECRET_FILE: /run/secrets/ovh_application_secret
OVH_CONSUMER_KEY_FILE: /run/secrets/ovh_consumer_key
socket-proxy:
image: tecnativa/docker-socket-proxy
container_name: traefik_docker_socket-proxy
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
CONTAINERS: 1
networks:
- traefik
networks:
macvlan:
name: macvlan
traefik:
name: traefik
static config traefik.yml
global:
checkNewVersion: true
sendAnonymousUsage: false
entrypoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: :443
http:
tls:
certResolver: letsencrypt
domains:
- main: mydomain.com
sans: "*.mydomain.com"
forwardedHeaders:
traefik:
address: :8080
ping : {}
log:
level: debug
accessLog:
filePath: "/etc/traefik/access.log"
serversTransport:
insecureSkipVerify: true
api:
dashboard: true
debug: true
providers:
docker:
endpoint: tcp://socket-proxy:2375
exposedByDefault: false
file:
filename: /etc/traefik/rules.yml
certificatesResolvers:
letsencrypt:
acme:
email: XXXXX
storage: /etc/traefik/acme.json
caServer: "https://acme-v02.api.letsencrypt.org/directory"
dnsChallenge:
provider: ovh
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
Nothing special in rules.yml (dynamic config)(maybe that's why it is not working)
One container I'm trying to access :
version: '3.8'
services:
pingvin-share:
image: stonith404/pingvin-share
container_name: pingvin-share
restart: unless-stopped
environment:
- PORT:3000
volumes:
- blabla
- blabla
networks:
traefik:
labels:
traefik.enable: true
traefik.http.routers.pingvin-share.rule: Host(`share.mydomain.com`)
traefik.http.routers.pingvin-share.entrypoints: websecure
traefik.http.routers.pingvin-share.tls: true
traefik.http.routers.pingvin-share.tls.certresolver: letsencrypt
networks:
traefik:
external: true
Thank you
Check with curl -v
what a client tells you.
It seems you try to improve security, but are maybe not aware that
-
tecnativa/docker-socket-proxy
image (with default tag latest
) is already 3 years old (link), using outdated haproxy
-
the volume
- /var/run/docker.sock:/var/run/docker.sock:ro
is not read-only, as the configuration implies
Thank you for taking time, here are
curl -v share.mydomain.com
curl -v share.mydomain.com
* Trying XXX.XXX.XXX.XXX:80... #Public IP
* Connected to share.mydomain.com (XXX.XXX.XXX.XXX) port 80
> GET / HTTP/1.1
> Host: share.mydomain.com
> User-Agent: curl/8.4.0
> Accept: */*
>
* Recv failure: Connection was reset
* Closing connection
curl: (56) Recv failure: Connection was reset
and curl -v https://share.mydomain.com
curl -v https://share.mydomain.com
* Trying XXX.XXX.XXX.XXX:443...
* Connected to share.mydomain.com (XXX.XXX.XXX.XXX) port 443
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* Recv failure: Connection was reset
* schannel: failed to receive handshake, SSL/TLS connection failed
* Closing connection
* schannel: shutting down SSL/TLS connection with share.mydomain.com port 443
* Send failure: Connection was reset
* schannel: failed to send close msg: Failed sending data to the peer (bytes written: -1)
curl: (35) Recv failure: Connection was reset
Working fine on local, HTTP redirected to HTTPS
curl -v share.mydomain.com
* Trying 192.168.0.102:80...
* Connected to share.mydomain.com (192.168.0.102) port 80
> GET / HTTP/1.1
> Host: share.mydomain.com
> User-Agent: curl/8.4.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Location: https://share.mydomain.com/
< Date: Wed, 27 Mar 2024 10:40:06 GMT
< Content-Length: 17
< Content-Type: text/plain; charset=utf-8
<
Moved Permanently* Connection #0 to host share.mydomain.com left intact
One thing I may need to mention is that the host (Synology) has an other certificate running. It's the same domain and wildcard domain by Let's Encrypt but it was generated earlier, should i switch to default cert ?
About security,
- what image should I use then ?
- Should I add
read_only: true
to docker-compose ?
Thank you
Step 1 would be getting port 80 only to work. Maybe with a plain whoami container on port 80.
I understand you are trying to connect home, maybe your provider does not allow connections to port 80.
I added a whoami container to traefik, working great on local
Hostname: 775cb58a7602
IP: 127.0.0.1
IP: 192.168.208.4 #Docker IP of whoami container
RemoteAddr: 192.168.208.3:49628 #Docker IP of traefik container
GET / HTTP/1.1
Host: whoareyou.mydomain.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: fr-FR,fr;q=0.9,en;q=0.8
Sec-Ch-Ua: "Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 192.168.0.20 #My local IP
X-Forwarded-Host: whoareyou.mydomain.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: xxxx
X-Real-Ip: 192.168.0.20
But got same result from internet :
level=debug msg="http: TLS handshake error from XXX.XXX.XXX.XXX:9950: write tcp 192.168.0.102:443->XXX.XXX.XXX.XXX:9950: write: connection reset by peer"
level=debug msg="http: TLS handshake error from XXX.XXX.XXX.XXX:9951: write tcp 192.168.0.102:443->XXX.XXX.XXX.XXX:9951: write: connection reset by peer"
level=debug msg="http: TLS handshake error from XXX.XXX.XXX.XXX:9952: tls: client offered only unsupported versions: [301]"
whoami container
whoami:
image: "traefik/whoami"
container_name: "whoami"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoareyou.mydomain.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
networks:
- traefik
I'm seriously lost, I do not know what to do
I can use NAT to redirect 80 and 443 to traefik, it worked before with Synology reverse proxy
It seems you never use ports
in docker-compose.yml
to let Traefik listen on the ports outside of the container.
Compare to simple Traefik example.
So probably another service is listening (and responding) on ports 80+443.
Quick reply,
If I set ports 80 and 443, I get this error :
Error response from daemon: driver failed programming external connectivity on endpoint traefik (blabla_containerID_blabla): Error starting userland proxy: listen tcp4 0.0.0.0:443: listen: address already in use
That's why I did macvlan so Traefik can use all the ports it wants
If Traefik couldn't listen on port 80 and 443, I wouldn't get those TLS handshake errors from Traefik, would it ?
I do have this error too sometimes :
http: TLS handshake error from XXX.XXX.XXX.XXX:38788: EOF
If Synology has already something listening, then the port is occupied. Sorry I ignored your macvlan, but how do you set the IP?
Yes it's occupied for the IP of the Syno, but Traefik has an other IP
It's defined in the docker-compose (I removed it on the original post)
macvlan:
name: macvlan
driver: macvlan
driver_opts:
parent: eth0
ipam:
config:
- subnet: 192.168.0.0/24
ip_range: 192.168.0.102/32
gateway: 192.168.0.1
Here, the container has no other choice than having the 192.168.0.102 IP and that's what it does
So you can reach Traefik on Syno from another node in the local network, but not from the Internet via your router?
You do forward external router ports 80+443 to the macvlan Traefik IP?
Your domain is set to the external router IP?
That's it, I do not have TLS handshake errors on local
That's it
Yes
On local it's doing :
local PC (192.168.0.20)
-> Syno as a local DNS resolver (192.168.0.48)
-> "IP of mydomain.com is 192.168.0.102"
-> Connect to Traefik (192.168.0.102)
From internet :
External PC (XXX.XXX.XXX.XXX)
-> Home Router (My public IP)
-> Port 443/80 from Home Router redirects to
-> 192.168.0.102 Port 443/80 (Traefik)
We are sure traffic from public IP is coming to Traefik as Traefik logs the handshake error of a public IP
There might have something I'm doing wrong with the certificate but I can't know what it is
Is the router doing a redirect (send HTTP redirect to client to use a different address) or is it forwarding the request to Syno?
I do not really know, it’s a NAT rule set : external port 443(/80) TCP going to 192.168.0.102 port 443(/80)
If I set the ports for the docker-compose of Traefik like
ports:
- 80:80
- 443:443
after disabling ports 80 and 443 on Syno
Traefik is running on both macvlan and Syno IP (so I could just remove macvlan)
I change the NAT rule to
External PC (XXX.XXX.XXX.XXX)
-> Home Router (My public IP)
-> Port 443/80 from Home Router redirects to
-> 192.168.0.48 Port 443/80 (Syno but Traefik using those ports)
it works but not ideal. The macvlan has been made useless and that's not what I want.
So it's working well from outside if Traefik is under Syno IP but as soon as I put the macvlan IP, I have those TLS handshake errors, it doesn't make sense, any idea ?
Maybe try the Docker Forum regarding macvlan
and Synology.
I'll try on there thank you.
For now, what I've done is following this : Free 80,443 Ports - 3os
and set
ports:
- 80:80
- 443:443
while removing macvlan so it's working for now but not what I wanted. At least with this config I can use the Syno firewall
Thank you for trying to help