Construções Reprodutíveis do Fedora
Esta documentação acompanha o esforço para implementar construções reprodutíveis (reproducible builds) no Fedora.
O objetivo é obter "construções reprodutíveis" para pacotes RPM no Fedora e, posteriormente, no restante do ecossistema. Isso permitiria aos nossos usuários verificar de forma independente se os pacotes RPM não foram adulterados (seja de forma maliciosa ou devido a hardware não confiável): qualquer pessoa poderia realizar uma reconstrução independente de um pacote e confirmar a obtenção de binários idênticos ao utilizar as mesmas versões do compilador e de outras ferramentas.
Contexto
O conceito de "construções reproduzíveis" foi definido originalmente pela iniciativa reproducible-builds.org no contexto do Debian:
Uma construção é reprodutível se, a partir do mesmo código-fonte, ambiente de construção e instruções de construção, qualquer parte puder recriar cópias idênticas, bit a bit, de todos os artefatos especificados.
No Fedora, todos os pacotes distribuídos aos usuários são transformados uma infraestrutura centralizada e rigorosamente controlada. Todos os pacotes de código-fonte (source RPMs) são gerados a partir do "dist-git" — um repositório Git que contém a "receita" de construção e um hash criptográfico dos códigos-fonte do pacote —, tornando relativamente fácil verificar as alterações entre versões do pacote, quais "entradas" foram utilizadas em um determinado pacote de código-fonte e em que ambiente os pacotes binários foram construídos.
Devido a esse forte controle sobre o processo de construção, builds reprodutíveis historicamente não têm sido uma prioridade no Fedora.
Benefícios
Vamos imaginar o que aconteceria se o hardware apresentasse falhas: uma memória superaquecida em uma máquina de construção causaria inversões de bits (bit flips), corrompendo os pacotes RPM resultantes de maneira sutil. Se pudéssemos refazer qualquer construção, seria relativamente fácil verificar se esse é o caso. Se tivéssemos um processo de execução de construções reprodutíveis "sombra" para todos os pacotes, poderíamos até detectar tais situações antes mesmo de recebermos relatos de bugs dos usuários. Da mesma forma, poderíamos detectar se uma máquina de construção tivesse sido comprometida por algum tipo de ataque à cadeia de suprimentos visando injetar código malicioso nos pacotes RPM. A reprodutibilidade permite uma verificação independente de que os códigos-fonte no dist-git correspondem, de fato, aos binários entregues. Com essas verificações, seria muito difícil realizar qualquer tipo de ataque à cadeia de suprimentos sem ser detectado.
A reprodutibilidade também é interessante porque facilita a depuração. Essencialmente, quando as compilações são estáveis, qualquer alteração inesperada nos artefatos gerados é muito mais fácil de diagnosticar. Já identificamos e submetemos diversas correções óbvias que, de outra forma, não teríamos encontrado. Além disso, com compilações estáveis, ao trabalhar nas ferramentas, é fácil recompilar utilizando as ferramentas modificadas e observar as diferenças. Se a construção for "instável" — ou seja, se houver várias outras alterações não relacionadas —, diferenças interessantes muitas vezes acabam perdidas em meio ao ruído.
Ressalvas
No ecossistema Fedora, não conseguimos alcançar a reprodutibilidade conforme a definição do reproducible-builds.org. Não é possível obter um resultado totalmente idêntico, pois os pacotes RPM são distribuídos após a assinatura, com esta incorporada ao próprio pacote (enquanto o Debian utiliza assinaturas destacadas). Uma reconstrução de um pacote (tal como distribuído aos usuários) sempre diferirá, no mínimo, pela ausência dessa assinatura. Em teoria, quem recompila o pacote poderia gerar um RPM idêntico e, em seguida, transferir a assinatura do RPM original para o novo; no entanto, isso também não atenderia aos requisitos, visto que a premissa é que a reconstrução deve ser reproduzida sem acesso aos artefatos da construção original. O uso de assinaturas destacadas no RPM também já foi proposto e rejeitado anteriormente.
Além disso, as construções de pacotes RPM inserem nos artefatos gerados algumas informações sobre o momento e o local da construção: BUILDTIME e BUILDHOST no cabeçalho do RPM. Embora fosse possível implementar substituições no RPM, essas informações são úteis e, na prática, pode não ser desejável perdê-las.
Embora haja uma discussão em andamento sobre isso, estamos caminhando para uma definição revisada que atenda melhor aos requisitos do Fedora:
Uma construção é reprodutível se, a partir do mesmo código-fonte, ambiente de construção, instruções de construção e metadados dos artefatos gerados, qualquer parte puder recriar cópias dos artefatos que sejam idênticas, exceto pelas assinaturas e por partes dos metadados.
Acreditamos que isso ainda seria útil para os usuários, pois permitiria verificar se a construção realizada no sistema oficial é confiável, mediante uma comparação que desconsidera a pequena lista de campos que sabidamente variam.
Status
Este trabalho teve início a partir de uma discussão inicial no encontro de desenvolvedores RPM durante a DevConf.CZ 2023. Isso levou à organização de um hackfest durante Flock 2023, onde formalizamos objetivos, definimos uma abordagem geral e começamos a documentar problemas conhecidos no rastreador do Pagure. Um resumo desse evento foi publicado no Discourse e serviu como ponto de partida para esta documentação. O projeto em si foi formalmente anunciado na lista de discussão de desenvolvimento (Devel) em março de 2024.
Want to help? Learn how to contribute to Fedora Docs ›