Permissão negada para soquete unix montado no contêiner docker como volume

Permissão negada para soquete unix montado no contêiner docker como volume

Tento colocar em contêiner meu nginx em execução atualmente em meu servidor. Para isso criei o seguinte arquivo docker compose:

version: "3.8"
services:
  nginx:
    image: nginx:stable-alpine
    container_name: nginx
    restart: unless-stopped
    group_add: ["33"]
    volumes:
      - "/etc/nginx-docker:/etc/nginx/conf.d:ro"
      - "/run/php:/run/php"
      - "/var/www:/var/www:ro"
    ports:
      - "8111:80"
      - "8443:443"

Tudo funciona bem, mas o problema é que ainda tenho php-fpm rodando "nativamente" (não encaixado) em meu sistema host e quero usar seus soquetes para meu contêiner nginx (daí a linha volumes: - "/run/php:/run/php").

As permissões dos soquetes são srw-rw---- www-data:www-data. Portanto, adicionei o usuário contêiner ao grupo 33 (que é www-data no meu sistema host -> group_add: ["33"]). Quando eu verifico no contêiner os IDs do grupo, o ID 33é realmente adicionado ao usuário conectado no momento:

/ # id -G
0 1 2 3 4 6 10 11 20 26 27 33
/ # id -u
0
/ # whoami
root

No entanto, quando ligo para um site desenvolvido com PHP, recebo a seguinte mensagem de erro nos logs do nginx:

2024/01/21 08:58:53 [crit] 21#21: *1 connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.192.68, server: _, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "op---s:8111"

Alguma dica ou solução que possa estar faltando para que funcione?

Responder1

Eu fiz algumas pesquisas :)

Se você entrar no contêiner que executa a imagem nginx, poderá ver que há alguns processos nginx em execução:

docker exec -it 43b5b971c433 /bin/sh

/ # ps -ef |grep nginx
    1 root      0:00 nginx: master process nginx -g daemon off;
   21 nginx     0:00 nginx: worker process
   22 nginx     0:00 nginx: worker process
   23 nginx     0:00 nginx: worker process
   24 nginx     0:00 nginx: worker process
   42 root      0:00 grep nginx

Alguns são executados como roote outros como nginxusuário.

Você adicionou o usuário rootao www-datagrupo dentro do seu arquivo docker-compose, mas mesmo sem fazer isso, o usuário root deve ter todas as permissões necessárias para acessar o soquete php unix.

Você pode testar as permissões com o testcomando. Envie o código de saída para ver se o comando foi bem-sucedido ou não. Como você pode ver, o usuário root pode ler o arquivo socket, mas não executá-lo:

/run/php # whoami
root
/run/php # test -r  php8.1-fpm.sock; echo $?
0
/run/php # test -x  php8.1-fpm.sock; echo $?
1

Então o permission deniederro provavelmente vem do nginx workerprocesso executado como nginxusuário.

Vamos primeiro verificar as permissões dos arquivos dentro do contêiner do docker ...

ls -alfornece a seguinte saída:

srw-rw----    1 xfs      xfs              0 Jan 25 08:58 php8.1-fpm.sock

dizendo que o arquivo de soquete pertence ao "xfs". Uma rápida olhada no /etc/grouparquivo dentro do contêiner mostra que o ID do xfsgrupo é 33igual ao ID na máquina host do grupo www-data.

Dentro do contêiner, você pode adicionar o usuário nginx ao grupo xfs:

addgroup nginx xfs

O problema deve ser resolvido agora.

Não tenho certeza de como adicionar isso diretamente ao seu arquivo de composição (como você especifica qual usuário adicionar ao grupo?) - mas você pode fazer isso no seu Dockerfile se puder criar uma nova imagem.

Depois de reiniciar o contêiner, as permissões parecem persistir.

Responder2

Determine o usuário e o grupo que o PHP-FPM está executando no host. Geralmente você pode encontrar essas informações no arquivo de configuração do PHP-FPM (geralmente localizado em /etc/php/7.x/fpm/pool.d/www.conf)

Em seguida, atualize seu docker-compose e adicione isto

user: "your_php_user:your_php_group"

Responder3

Tudo funciona bem, mas o problema é que ainda tenho php-fpm rodando "nativamente" (não dockerizado) em meu sistema host e quero usar seus soquetes para meu contêiner nginx (daí a linha volumes: - "/run/php:/run/php").

Isso não é possível ou sensato.

O Docker gera seu próprio namespace de rede, para que você obtenha sua própria pilha de firewall, pilha de IP e pilha de rede Unix.

Mesmo se você corrigir o problema de permissões, digamos, por exemplo, que você faça login no contêiner manualmente com docker execo chmodarquivo de soquete 666 e, por uma questão de brevidade, vamos supor que não haja namespaces de usuário no caminho também.

O que você está pedindo para fazer é equivalente a:

  1. Executando uma php-fpminstância system1com um soquete Unix ativado/var/run/php-fpm.sock
  2. Exportando o /var/runcaminho por NFS no system1.
  3. Montagem system1:/var/runem system2. Um sistema completamente separado.
  4. Tentando connect()ligar o soquete Unix system2e esperando system1responder com php-fpm.

A maneira como você realmente deveria fazer isso (deveria realmentequererpara fazer isso, que é um assunto separado) é escutar a php-fpminstância usando IP - vinculando-a, host_system:12345por exemplo. Em seguida, use nginxin containerpara conectar-se a host_system:12345.


Isso tudo está errado. Não me escute. Se você criar um soquete unix bem nomeado, exposto em qualquer um dos namespaces e o caminho for compartilhado entre os dois namespaces, conectando-se a esse soquete unix, conecte-se ao outro namespace!

https://lore.kernel.org/all/[e-mail protegido]/T/

Este patch aborda especificamente isso. Claramente, quando testei, isso foi há muito tempo! :)

A única vez que isso não parece ser o caso é no caso de criação anônima de soquete Unix, no entanto, esse é um recurso bastante específico do Linux e pouco usado em soquetes Unix.

informação relacionada