Dev (Back & Front)ARTIGO

Redução de Privilégios em Programas Go para Aumentar a Segurança

Redução de Privilégios em Programas Go para Aumentar a Segurança
Imagem: Cesar Gimenes

Uma boa prática para aumentar a segurança de um sistema é reduzir os privilégios de execução de um programa. Idealmente, um programa deve rodar com o mínimo de privilégios possíveis.

Em sistemas UNIX-like, é possível alterar o usuário e o grupo em que um programa é executado. Vamos ver um passo a passo de como fazer isso em GolangGo23 conteúdosEntendendo o Green Tea GC do Go 1.26Dev (Back & Front) · mai 2026Função recursiva em Go para acessar valores em mapas aninhadosDev (Back & Front) · set 2025Publicando projeto desenvolvido em Golang em um server grátisDev (Back & Front) · mar 2025Ver tudo em Dev (Back & Front) .

Verificando se o Programa está Rodando como Root

Primeiro, verifique se o programa está sendo executado como root. Isso é importante porque usaremos chamadas de sistema que necessitam de privilégios de root. (Existem outras maneiras de conceder esses privilégios, mas abordaremos isso em outro artigo.)

No exemplo abaixo, usamos os.Getuid() para verificar se o programa está rodando como root. Se não estiver, o programa é encerrado.

go
if os.Getuid() != 0 {
    fmt.Println("execute como root")
    return
}

Claro que você pode fazer exatamente o oposto, ou seja, inverter a condição para que o programa só rode se não estiver como root. Mas a ideia aqui é que o programa altere sozinho para outro usuário, então vamos continuar.

Verificando o ID do Usuário e do Grupo

Você pode verificar o ID do usuário e do grupo em qualquer momento usando as funções os.Getuid() e os.Getgid().

go
fmt.Printf(
    "executando como uid: %v, gid: %v\n",
    os.Getuid(),
    os.Getgid(),
)

Alterando para o Usuário “nobody”

Agora, vamos alterar nosso programa que está rodando como root para mudar para o usuário nobody. Primeiro, obtenha as informações do usuário nobody com a função user.Lookup.

go
u, err := user.Lookup("nobody")
if err != nil {
    fmt.Println(err)
    return
}

Com as informações do usuário nobody, altere o ID do usuário e do grupo em que o programa está rodando usando as chamadas de sistema syscall.Setgid e syscall.Setuid.

go
uid, _ := strconv.Atoi(u.Uid)
gid, _ := strconv.Atoi(u.Gid)

// Ajusta o ID do grupo
err = syscall.Setgid(gid)
if err != nil {
    fmt.Println(err)
    return
}

// Ajusta o ID do usuário
err = syscall.Setuid(uid)
if err != nil {
    fmt.Println(err)
    return
}

A partir desse ponto, o programa está rodando com os privilégios do usuário nobody, ou seja, com o mínimo de privilégios. Você pode criar usuários específicos para cada serviço e rodar o serviço com o privilégio específico dependendo do serviço.

Nota: Reduzir privilégios é uma boa prática, mas não impede um ataque. O que ela faz é reduzir os danos de um ataque que explore uma falha no seu programa.

O código completo está disponível no GitHub.

Trabalha com tecnologia desde a década de 90. Já atuou na área de educação e participou de projetos de mobilidade de grande volume para laboratórios farmacêuticos. Criou games tanto para PC, como para iOS. Hoje está direcionando seus esforços em plataformas de Sistemas Embarcados, IoT, microservices e cloud computing. É um entusiasta de tecnologias como Golang e Docker.

Ver perfil