Tenho um repositório git hospedado no GitHub e um servidor Git LFS giftless auto-hospedado na minha própria nuvem pública. Eu uso um .lfsconfig
para apontar os hooks de commit para minha instância lfs em vez da do GitHub. Isso funciona corretamente por si só.
No entanto, meus serviços de nuvem são protegidos por mTLS usando um certificado e uma chave privada gerados pelo Cloudflare, que eu então uso OpenSSL para empacotar em um keystore protegido por senha PKCS#12 para distribuição. Isso funciona para acessar meus serviços baseados na web por meio de navegadores, onde posso importar qualquer .pfx
arquivo facilmente, mas não tenho certeza de como usar esse keystore com o git para permitir acesso ao servidor LFS (que é protegido pelo mesmo certificado).
Trabalhando com esta resposta , tentei uma série de transformações no .p12
arquivo usando OpenSSL e diferentes permutações da configuração de rede do Git , mas estou tendo alguma dificuldade em descobrir onde cada parte do keystore precisa ser definida nas http
opções. Toda vez, recebo a seguinte saída ao tentar enviar para o LFS do meu repositório:
(test-ca.crt e test-cl.crt são derivados do arquivo .p12 anteriormente)
$ git -c http.sslcainfo=test-ca.crt -c http.sslCert=test-cl.crt \
-c http.sslCertPasswordProtected lfs push origin main
Password for 'cert:///test-cl.crt':
warning: Authentication error: Authentication required:
Authorization error: https://git-lfs.my-cloud.com/user/repo/locks/verify
Check that you have proper access to the repository
Isso faz com que os arquivos rastreados pelo LFS não sejam enviados para o armazenamento de objetos.
Tenho clientes confiáveis na minha nuvem que também precisam de acesso a este servidor LFS, que usam diferentes sistemas operacionais, incluindo Ubuntu e Windows. Não tenho certeza se git-bash
o Windows usaria o repositório global de certificados de usuário do SO para LFS, e não consigo descobrir como instalar um certificado de cliente em todo o sistema no Ubuntu também.
O núcleo do Git usa libcurl para HTTP(S), com seus vários backends TLS. Não sei o que o Git-LFS usa para TLS, mas se ele depende da mesma
http.ssl*
configuração que o núcleo do Git de acordo com sua pergunta, então não seria sensato usar um formato que o Git-LFS suporta, mas o núcleo do Git não. Então, vou assumir que você está configurando o núcleo do Git e que o Git-LFS espera exatamente o mesmo tipo de configuração.De acordo com
git help config
, o Git agora oferece suporte ao PKCS#12 com certos backends TLS (praticamente todos eles, desde que sejam suficientemente recentes):http.sslCertType
ouGIT_SSL_CERT_TYPE
deve ser definido comoP12
.http.sslCert
ouGIT_SSL_CERT
então precisa apontar para seu arquivo .pfx ou .p12.Se isso não funcionar (e provavelmente não funcionará porque o Git-LFS é escrito em Go e provavelmente não usará libcurl), então o "estilo OpenSSL" tradicional é ter dois arquivos separados para o certificado e a chave privada:
http.sslCertType
deve permanecer indefinido.O caminho para o certificado vai para
http.sslCert
ouGIT_SSL_CERT
.Espera-se que a cadeia de certificados esteja no formato de texto "PEM", ou seja, cada certificado individualmente codificado em Base64 usando o enquadramento "BEGIN CERTIFICATE", e o certificado folha (cliente ou servidor) geralmente sendo o mais alto.
O caminho para o arquivo de chave vai para
http.sslKey
aGIT_SSL_KEY
variável de ambiente.Espera-se que o arquivo de chave esteja no formato de texto "PEM", ou seja, PKCS#8 usando o mesmo tipo de enquadramento Base64 "BEGIN [ENCRYPTED] PRIVATE KEY" do certificado, ou PKCS#1 "legado" usando um enquadramento muito semelhante "BEGIN RSA PRIVATE KEY".
Executar apenas
openssl pkcs12 -in $file
produzirá a cadeia de certificados e a chave privada no formato correto.Adicionar
-nokeys
fará com que ele produza apenas certificados, adicionar-nocerts
fará com que ele produza apenas chaves, e você também pode dividi-los usando um editor de texto. (O texto extra entre os certificados e as chaves é ignorado e age apenas como um comentário.)Opcionalmente, você pode tentar usar
-noenc
ou-nodes
para gerar a chave não criptografada para teste; mais tarde, você pode usaropenssl pkey -aes128
para (re)criptografá-la.Existe a possibilidade de que apontar
http.sslCert
para um arquivo combinado "certificado + chave PKCS#8" funcione, mas eu não apostaria nisso.git-bash é irrelevante. É um shell de linha de comando.
A parte importante é a libcurl para o núcleo do Git, pois ela pode ser criada com o SChannel ou o OpenSSL como backend TLS, e o pacote "Git para Windows" parece habilitar ambos com a
http.sslBackend
opção de selecionar entre os dois rapidamente - se você escolher,http.sslBackend=schannel
estará usando a biblioteca TLS fornecida pelo Windows, que usará o certificado CAPI do Windows e o armazenamento de chaves, enquanto se você escolher,openssl
ela espera os arquivos no formato PEM, conforme descrito acima.Como o Git-LFS é um programa separado, não sei se ele usa a mesma libcurl e se suporta os mesmos backends TLS, mas, considerando que foi escrito em Go e não em C, suspeito fortemente que não.
Até onde eu sei, não há um armazenamento de certificados de cliente para todo o sistema no Ubuntu.
Há um framework baseado em PKCS#11 (p11-kit) que deveria permitir que ele fosse implementado, mas no momento ele não tem um backend baseado em software padrão que realmente funcionaria (em teoria, o GNOME Keyring deveria ter um; na prática, não me lembro de realmente fazê-lo funcionar) – e mais importante, o OpenSSL é simplesmente... ruim ... em usar PKCS#11. Em versões mais antigas, você precisaria especificar
http.sslKeyType=ENG
(engine), mas então parece não haver opção para dizer ao Git ou libcurl qual engine carregar (você precisaria do engine 'pkcs11' do pacote libp11). Em versões mais recentes, uma situação semelhante existe com "provedores" (com 'pkcs11-provider' ou 'libp11' fornecendo um provedor PKCS#11, esses agora sendo carregáveis de openssl.cnf globalmente, mas quebrando o SSH ao fazer isso).