How do I stop access by IP address, only FQDN

Very sorry for the post if this is a documented or straightforward solution.

Have Traefik 3.3, it is working fine. Debian 12.9, public IP on a VPS.

I have several services working with it, that is OK, all are docker containers.

My problem is that I can still access my service (let's use portainer, as an example, port 9000 UI) using just the IP address and the port in the URL, i.e. http://x.x.x.x:9000

I have ufw running, allowing 80,443 and blocking 9000, but that is not solving the issue.

The goal is that the only access to my containers is with a FQDN going through the traefik proxy.

Any direction or help is appreciated.

Thanks,

Dan

Care to share your Docker compose file(s) and Traefik static and dynamic config?

Thanks for the response bluepuma.

folder structure:
root@vmi242:/opt/stacks/traefik# ls -la
total 48
drwxr-xr-x 3 root root 4096 Feb 27 08:51 .
drwxr-xr-x 4 root root 4096 Feb 26 14:55 ..
-rw------- 1 root root 13286 Feb 26 15:59 acme.json
-rw-r--r-- 1 root root 41 Feb 26 15:48 cf-token
-rw-r--r-- 1 root root 1167 Feb 26 15:47 config.yaml
-rw-r--r-- 1 root root 2309 Feb 26 15:30 docker-compose.yaml
-rw-r--r-- 1 root root 100 Feb 26 15:53 .env
drwxr-xr-x 2 root root 4096 Feb 26 15:58 logs
-rw-r--r-- 1 root root 1402 Feb 26 15:39 traefik.yaml

Files below.

OK, trying to find an 'attach file' here somewhere. Will get the files posted ASAP

R Regards,

Dan

Paste your compose and Traefik static and dynamic files. Use 3 backticks before and after, for readability and to preserve spacing.

Thanks for the advice bluepuma.

B Regards,

Dan

Files follow:

TRAEFIK:

docker-compose.yaml:

\\secrets:
cf-token:
file: ./cf-token
services:
traefik:
image: traefik:latest # or traefik:v3.3 to pin a version
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true # helps to increase security
secrets:
- cf-token # the secret at the top of this file
env_file:
- .env # store other secrets e.g., dashboard password
networks:
xxxxxxxxxxx:
ports:
- 80:80
- 443:443
# - 10000:10000 # optional
# - 33073:33073 # optional
environment:
- TRAEFIK_DASHBOARD_CREDENTIALS=${TRAEFIK_DASHBOARD_CREDENTIALS}
- CF_API_EMAIL=xxx@xxx.com # Cloudflare email
- CF_DNS_API_TOKEN_FILE=/run/secrets/cf-token # see Traefik Let's Encrypt Documentation - Traefik
# token file is the proper way to do it
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /opt/stacks/traefik/traefik.yaml:/traefik.yaml:ro
- /opt/stacks/traefik/acme.json:/acme.json
- /opt/stacks/traefik/config.yaml:/config.yaml:ro
- /opt/stacks/traefik/logs:/var/log/traefik
labels:
- traefik.enable=true
- traefik.http.routers.traefik.entrypoints=http
- traefik.http.routers.traefik.rule=Host(tfk.xxxx.xxx)
- traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_DASHBOARD_CREDENTIALS}
- 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(`tfk.xxxx.xxx)
- traefik.http.routers.traefik-secure.middlewares=traefik-auth
- traefik.http.routers.traefik-secure.tls=true
- traefik.http.routers.traefik-secure.tls.certresolver=cloudflare
- traefik.http.routers.traefik-secure.tls.domains[0].main=xxxx.xxx
- traefik.http.routers.traefik-secure.tls.domains[0].sans=*.xxxx.xxx
- traefik.http.routers.traefik-secure.service=api@internal
networks:
xxxxxxxxxxxx:
external: true # or comment this line to auto create the network\\

config.yaml:

\\http:
middlewares:
default-security-headers:
headers:
customBrowserXSSValue: 0 # X-XSS-Protection=1; mode=block
contentTypeNosniff: true # X-Content-Type-Options=nosniff
forceSTSHeader: true # Add the Strict-Transport-Security header even when the connection is HTTP
frameDeny: false # X-Frame-Options=deny
referrerPolicy: "strict-origin-when-cross-origin"
stsIncludeSubdomains: true # Add includeSubdomains to the Strict-Transport-Security header
stsPreload: true # Add preload flag appended to the Strict-Transport-Security header
stsSeconds: 3153600 # Set the max-age of the Strict-Transport-Security header (63072000 = 2 years)
contentSecurityPolicy: "default-src 'self'"
customRequestHeaders:
X-Forwarded-Proto: https\\

traefik.yaml:

\\api:
dashboard: true
debug: true
entryPoints:
http:
address: ":80"
http:
redirections:
entrypoint:
to: https
scheme: https
https:
address: ":443"
serversTransport:
insecureSkipVerify: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /config.yaml # example provided gives A+ rating SSL Server Test (Powered by Qualys SSL Labs)
certificatesResolvers:
cloudflare:
acme:
caServer: https://acme-v02.api.letsencrypt.org/directory # production (default)
# caServer: https://acme-staging-v02.api.letsencrypt.org/directory # staging (testing)
email: xxx@xxx.com # Cloudflare email (or other provider)
storage: acme.json
dnsChallenge:
provider: cloudflare # change as required
# disablePropagationCheck: true # Some people using Cloudflare note this can solve DNS propagation issues.
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"
log:
level: "INFO"
filePath: "/var/log/traefik/traefik.log"
accessLog:
filePath: "/var/log/traefik/access.log"\\

PORTIANER:

docker-compose.yaml:

\\services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
ports:
- 8000:8000
- 9443:9443
- 9000:9000 # for http
volumes:
- portainer_data:/data
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
networks:
xxxxxxxxxxxxxx: null
labels:
- "traefik.enable=true"
- "traefik.docker.network=xxxxxxxxxxxxxxx"
- "traefik.http.routers.portainer.entrypoints=http"
- "traefik.http.routers.portainer.rule=Host(port.xxxxx.xxx)"
- "traefik.http.middlewares.portainer-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.portainer.middlewares=portainer-https-redirect"
- "traefik.http.routers.portainer-secure.entrypoints=https"
- "traefik.http.routers.portainer-secure.rule=Host(port.xxxxx.xxx)"
- "traefik.http.routers.portainer-secure.tls=true"
- "traefik.http.routers.portainer-secure.service=portainer"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"

volumes:
portainer_data: null
networks:
xxxxxxxxxxxx:
external: true\\

Please:

Or select content and press </> button.