Executando verificação de segurança...
2

Deploy de Docker que impossibilita acesso ao bash

Olá pessoal, espero que todos estejam bem. Gostaria de fazer uma pergunta e antes vou dar um contexto sobre o que eu faço atualmente.

Contexto

Atualmente sou líder técnico de uma equipe que desenvolve um produto de IA na área de Visão Computacional. Nosso produto possui duas partes. A primeira parte é o software escrito em C++ que é executado dentro de um Docker. Este software roda em um computador com hardware dedicado para processamento de modelos de IA, ou seja, ele possui uma GPU, que utilizamos para decodificar vídeo, e uma NPU (Neural Processing Unit) para executar o modelo de IA. Existe alguns scripts escritos em Python que se comunicam com o software em C++ por meio de sockets.

A segunda parte do software é o front e back, hospedados na cloud, que são escritos em React.js e FastAPI, respectivamente. Temos também Docker para as duas aplicações.

Vimos uma grande demanda de empresas querendo executar o software on-premise em servidores próprios. Atualmente, a gente envia o dispositivo já configurado para os clientes. Entretanto, o cliente usar a própria máquina é algo novo para nós em quesitos de segurança. O cliente gostaria de executar toda a infraestrutura, ou seja, o software em C++, o front e o backend em seus próprios servidores.

Pergunta

Em quesito de segurança e sigilo do nosso código, existe algum meio que impossibilite uma pessoa mal intencionada em simplesmente rodar um docker exec -it {NOME_DO_CONTAINER} bash e inspecionar o código? Os executáveis em C++ sei que não vai conseguir, porque a gente só coloca o executável do C++, porém o que é escrito em JavaScript, Python e afins não vejo uma maneira de escondê-los.

Alguém tem uma sugestão ou já passou por algo similar?

Observação

Temos contrato de confidencialidade, propriedade intelectual e etc... porém eu, honestamente, fico muito receoso quanto a deixar o código ali e confiar na boa fé das pessoas.

Grato desde já!

@edit

Fiz uma pesquisa mais a fundo e percebi que não tem uma forma que impossibilite alguém de realizar o crack do binário, mesmo sendo escrito em C++, Rust, Go, ou escrito em bytecode: Java, Python, JavaScript.

O jeito mesmo é fazer isso que o pessoal sugeriu, de obfuscar o código e, também, compilá-lo para bytecode, no caso do Python usando o .pyc ou o PyInstaller que, também, consegue gerar um binário único para usar.

Resolvi o problema utilizando o PyInstaller que me agradou bastante e foi bem simples de usá-lo.

Carregando publicação patrocinada...
6

Você pode procurar por sobre container distroless (isso mesmo como se fosse sem uma distro, vem apenas as libs basicas sem nenhum utilitário), mas isso é uma faca de dois gumes, pois ao mesmo tempo que impede alguém mal intencionando, vai impedir alguém bem intencionado você dificilmente conseguiria depurar um problema ou ataque em produção.

Sobre javascript existe minificação/obfuscação, ainda é possivel com IA entender o funcionamento projeto em alguns casos, porém o trabalho de deixar legivel para humanos novamente é muito custoso e demorado.

Sobre python, você pode transformar 100% do projeto em bytecode e apagar o source com o comando python -m compileall, mas tome cuidado existe a maneira certa de fazer isso.

FROM python:3.11-slim
WORKDIR /app
COPY src/ /app/src/
RUN python -m compileall src && rm -rf src
WORKDIR /app/src/__pycache__
CMD ["python", "script.cpython-311.pyc"]
  • correto (multi stage)
FROM python:3.11-slim AS builder
WORKDIR /build
COPY src/ /build/src/
RUN python -m compileall src


FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /build/src/__pycache__/ /app/
CMD ["python", "script.cpython-311.pyc"]

Porque usar multi stage? o processo de build do docker funciona como um git, a cada linha ele comita um estado do container imutavel, ou seja assim como existe git reset --hard aaaaaa para voltar commits atrás, é possivel também ir para um estado possivel de um container, no qual por exemplo estaria a copia de todo código fonte. caso você fazer isso em 2 estagios, o de build sera descartado e a unica imagem visivel tem apenas a copia do bytecode.

1
2

Eu tbm tenho um sistema que roda direto nas máquinas dos clientes, quanto ao código javascript, eu uso o rollup com o plugin minifyrollup-plugin-esbuild-minify que fica praticamente impossível de entender alguma coisa kkkkkk. Nunca tive problema quanto a isso.

0
1

impossibilitar de rodar docker exec

Se a pessoa tem acesso ao Root não há nada que a impossibilite.

Se só você tem acesso ao root aí a pessoa não teria acesso.

porém o que é escrito em JavaScript, Python e afins não vejo uma maneira de escondê-los.

Acredito que não exista maneira de iumpossibilitá-la de ler. O que você pode fazer é usar alguma ferramenta de ofuscação de código.

Um código ofuscado fica difícil de ler e dificilmente uma pessoa saberá o que ele faz.

1

É de fato se a pessoa tem acesso Root, o leque de possibilidades fica realmente bem restrito.

Mas é interessante essa técnica de ofuscação que eu não conhecia. Vou dar uma olhada, obrigado!

1

esse é o tipo de discussão que é sempre bom levantar quando se cria qualquer tipo de produto.

  1. quais são as tecnologias utilizadas?
  2. o que pode ser ou não público?
  3. via de regra tecnologias que são interpretadas normalmente são difíceis ou muito custosas para se ofuscar e proteger o código, pois sempre parte desse código vai ter que ser enviado de forma "desprotegida" pro cliente.
  4. onde e quem vai ter acesso ao código?
  5. meu código é o meu diferencial ou a forma que eu comercializo e estratégia que adoto para captação de cliente.

a recomendação é sempre proteger o cerne do seu negócio em linguagens que permitam essa proteção no código de forma nativa além de sempre conferir os acessos e boas práticas de segurança, mas licitamente ou ilícitamente proteger o código é muito complexo principalmente quando você é um líder técnico e tem pessoas que estão dentro da sua empresa ou colaboradores externos que vão precisar dar manutenção neste código, porque nada impede de ter uma pessoa de má índole, que vai pegar aquele código e usar de forma indevida.

por anos o meu sócio e eu discutimos sobre isso, trabalhando principalmente com linguagens web, houve uma época que a gente contratou os serviços de criptografia de código fonte quando fazer entregas no servidor do cliente mas hoje em dia a gente percebeu que o custo-benefício não se paga, além de que o grande diferencial do nosso produto e serviço é o nosso atendimento qualidade de entrega, relacionamento com o cliente entre outros aspectos que estão muito menos ligado a código do que o código em si.

quando falamos de produto, mantenha em infraestrutura própria e limite o acesso para pessoas espeficias, arquitetura de microsserviços pode fazer com que apenas pessoas autorizadas mexam em código muito sigiloso ao custo de complexidade de gestão.

no demais as outras respostas já contribuiram com aspectos mais técnicos, espero ter contribuído de alguma forma.

1

Já trabalhei numa empresa que teve um problema parecido. As soluções abordadas que lembro foram:

  • Ofuscar e comprimir o artefato com packer e anti debugger durante a compilação.

  • Fazer consultas periódicas em outras partes/módulos, mesmo que isso não fizesse sentido (criar uma dll dedicada pra isso não ajudaria, então dlls de "gfxrender" faziam essa checagem, e no que era de web, usamos endpoints como CheckUpdate e até GetBooks pra validar licença e enviar logs).

  • Usar logs e alertas caso o cliente tentasse descompilar ou tentasse mudar alguma configuração manualmente dentro do diretório do programa (nunca tivemos alerta kkkk).

Isso tudo pra um sistema ERP que não durou muito.

1

usar distroless como uma forma de impedir executar um shell no container não vai impedir o acesso, a pessoa poderia extrair a imagem do container e acessar os arquivos como se fosse um mero pendrive

mesmo limitando o acesso root, se a pessoa tem acesso físico a máquina poderia usar um live USB Linux, fazer acesso chroot e substituir a senha root e assim ter acesso completo

no final a melhor opção é a obfuscação mesmo kk

-1

Fiz uma pesquisa mais a fundo e percebi que não tem uma forma que impossibilite alguém de realizar o crack do binário, mesmo sendo escrito em C++, Rust, Go, ou escrito em bytecode: Java, Python, JavaScript.

O jeito mesmo é fazer isso que o pessoal sugeriu, de obfuscar o código e, também, compilá-lo para bytecode, no caso do Python usando o .pyc ou o PyInstaller que, também, consegue gerar um binário único para usar.

Resolvi o problema utilizando o PyInstaller que me agradou bastante e foi bem simples de usá-lo.