У меня проблема с безопасностью SELinux на /run/docker.sock с использованием traefik в докере. docker ps
работает правильно, проблема только в том, что traefik должен отображать том /var/run/docker.sock
Вот что я пробовал:
git clone https://github.com/jamct/traefik-example.git
cd traefik-example/04_config_files
sudo setenforce 0
docker-compose up
#it works
sudo setenforce 1
docker-compose up
# it fails
$ ls -lsZ /run/docker.sock
0 srw-rw-rw-. 1 root docker system_u:object_r:container_file_t:s0:c134,c237 0 4 mars 11:38 /run/docker.sock
У меня есть этот журнал ошибок
traefik_1 | time="2020-03-04T15:46:16Z" level=error msg="Provider connection error Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version: dial unix /var/run/docker.sock: connect: permission denied, retrying in 4.506218855s" providerName=docker
и войти в разрешающий мод в /var/log/audit/audit.log:
type=AVC msg=audit(1583336776.607:1931): avc: denied { connectto } for pid=16969 comm="traefik" path="/run/docker.sock" scontext=system_u:system_r:container_t:s0:c134,c237 tcontext=system_u:system_r:container_runtime_t:s0 tclass=unix_stream_socket permissive=0
docker-compose.yml
version: "3.7"
services:
traefik:
image: traefik:v2.0
command: --providers.docker
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
- ./traefik.yml:/etc/traefik/traefik.yml
- ./dynamic.yml:/etc/traefik/dynamic/traefik.yml
web1:
image: nginx:alpine
labels:
- traefik.http.routers.web1.rule=Host(`web1.localhost`)
web2:
image: containous/whoami
labels:
- traefik.http.routers.web2.rule=Host(`web2.localhost`) || ( Host(`localhost`) && PathPrefix(`/web2`) )
- traefik.http.routers.web2.middlewares=demo-whitelist@file
Есть ли чистый способ заставить traefik работать с включенным selinux? Есть ли интерфейс командной строки "chcon", который я могу использовать для файла /run/docker.sock?
Редактировать и отказ от ответственности: это решение не рекомендуется, поскольку оно нарушает правила безопасности в докере. Решения здесь: https://stackoverflow.com/questions/29089023/var-run-docker-sock-unaccessible-in-container-running-on-centos-7/30368817#30368817
Благодаря отчету об ошибке redhat, предоставленному @Bert, я смог получить решение:
Ошибка 1495053 - SELinux не позволяет traefik подключиться к сети. Этот отчет об ошибке классифицируется как «не ошибка» по следующей причине:
Вы пытаетесь подключить ограниченный домен к сокету докера. В этом нет смысла, поскольку возможность разговаривать с сокетом докера позволяет вам полностью контролировать хост. Либо это очень серьезный прорыв вашего контейнера, либо вы должны запускать привилегированный контейнер. SELinux делает именно то, что должен, блокируя доступ к сокету докера.
Поэтому мне не следует изменять доступ к docker.sock, так как это будет то же самое, что отключить selinux. Вместо этого я мог работать в «привилегированном» контейнере.
Я просто изменил файл docker-compose.yml, чтобы он работал в провилированном режиме (такой же режим можно получить в других программах запуска докеров).
Вот рабочий файл docker-compose.yml
version: "3.7"
services:
traefik:
image: traefik:v2.1.6
command: --providers.docker
ports:
- "80:80"
- "8080:8080"
privileged: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
- ./traefik.yml:/etc/traefik/traefik.yml
- ./dynamic.yml:/etc/traefik/dynamic/traefik.yml
web1:
image: nginx:alpine
labels:
- traefik.http.routers.web1.rule=Host(`web1.localhost`) || PathPrefix(`/web1`)
web2:
image: containous/whoami
labels:
- traefik.http.routers.web2.rule=Host(`web2.localhost`) || ( Host(`localhost`) && PathPrefix(`/web2`) )
- traefik.http.routers.web2.middlewares=demo-whitelist@file
Важная линия привилегированный: правда в контейнере траэфик.
С участием привилегированный: правда и selinux включен, он работает, если я вернусь к privileged: false
, Я возвращаю журнал ошибок, чего и ожидал.