Git
Chapters ▾ 2nd Edition

7.14 Orodja Git - Shramba poverilnic

Shramba poverilnic

Če uporabljate prenos SSH za povezovanje z oddaljenimi strežniki, je možno, da imate ključ brez gesla, kar vam omogoča varno prenašanje podatkov brez vpisovanja uporabniškega imena in gesla. Vendar to ni mogoče pri protokolih HTTP — vsaka povezava potrebuje uporabniško ime in geslo. To postane še težje za sisteme z dvostopenjskim overjanjem, kjer je žeton, ki ga uporabite za geslo, naključno generiran in neizgovorljiv.

Na srečo ima Git sistem poverilnic, ki lahko pomaga pri tem. Git ima vgrajenih nekaj možnosti:

  • Privzeto je, da ni nič shranjeno v predpomnilniku. Vsaka povezava vas bo pozvala k vpisu uporabniškega imena in gesla.

  • Način »cache« shrani poverilnice v pomnilnik za določen čas. Gesla nikoli niso shranjena na disku in iz predpomnilnika se izbrišejo po 15 minutah.

  • Način »store« shrani poverilnice v besedilno datoteko na disku in nikoli ne potečejo. To pomeni, da gesla ne boste več mogli vnesti, dokler ne spremenite gesla za gostitelja Git. Slabost tega pristopa je, da so vaša gesla shranjena v čisti besedilni datoteki v vaši domači mapi.

  • Če uporabljate macOS, ima Git način »osxkeychain«, ki poverilnice shrani v varni ključavnici, povezani z vašim sistemskim računom. Ta metoda poverilnice shrani na disk in ne potečejo, vendar so šifrirane s sistemom, ki shranjuje certifikate HTTPS, ter Safari jih samodejno izpolnjuje.

  • Če uporabljate Windows, lahko omogočite funkcijo Git Credential Manager pri namestitvi Git za Windows ali ločeno namestite najnovejši GCM kot samostojno storitev. To je podobno pomočniku »osxkeychain« opisanem zgoraj, vendar uporablja shrambo poverilnic sistema Windows za nadzor občutljivih informacij. Ponuja lahko tudi poverilnice za WSL1 ali WSL2. Za več informacij glejte navodila za namestitev GCM.

Izmed teh metod lahko izberete eno z nastavitvijo konfiguracijske vrednosti Git:

$ git config --global credential.helper cache

Nekateri od teh pomočnikov imajo možnosti. Pomočnik »store« lahko sprejme argument --file <path>, ki prilagodi, kje se shrani besedilna datoteka (privzeto je ~/.git-credentials). Pomočnik cache sprejme možnost --timeout <seconds>, ki spremeni čas delovanja njegovega prikritega procesa (privzeto je 900, ali 15 minut). Tukaj je primer, kako bi konfigurirali pomočnika »store« z lastnim imenom datoteke:

$ git config --global credential.helper 'store --file ~/.my-credentials'

Git vam celo omogoča, da konfigurirate več pomočnikov. Ko Git išče poverilnice za določenega gostitelja, bo naredil na njih poizvedbe v vrstnem redu in se ustavil po prvem prejetem odgovoru. Pri shranjevanju poverilnic bo Git poslal uporabniško ime in geslo vsem pomočnikom na seznamu in vsak od njih se lahko odloči, kaj želi storiti z njimi. Tukaj je primer datoteke .gitconfig, če imate datoteko s poverilnicami na ključu USB, vendar želite uporabiti predpomnilnik v pomnilniku, da prihranite nekaj tipkanja, če ključ ni priključen:

[credential]
    helper = store --file /mnt/thumbdrive/.git-credentials
    helper = cache --timeout 30000

Pod pokrovom

Kako to sploh deluje? Gitov vrhnji ukaz za sistem pomočnika za poverilnice je git credential, ki kot argument sprejme ukaz in nato več vnosov preko stdin.

Morda bo lažje razumeti s primerom. Recimo, da je bil konfiguriran pomočnik za poverilnice in da je pomočnik shranil poverilnice za mygithost. Tukaj je seja, ki uporablja ukaz »fill«, ki se sproži, ko Git poskuša najti poverilnice za gostitelja:

$ git credential fill (1)
protocol=https (2)
host=mygithost
(3)
protocol=https (4)
host=mygithost
username=bob
password=s3cre7
$ git credential fill (5)
protocol=https
host=unknownhost

Username for 'https://unknownhost': bob
Password for 'https://bob@unknownhost':
protocol=https
host=unknownhost
username=bob
password=s3cre7
  1. To je ukazna vrstica, ki sproži interakcijo.

  2. Git-credential nato čaka na vhod na stdin. Podamo mu stvari, ki jih poznamo: protokol in gostiteljsko ime.

  3. Prazna vrstica označuje, da je vnos zaključen, in sistem za poverilnice naj bi odgovoril s tistim, kar pozna.

  4. Git-credential prevzame nadzor in piše na stdout s podrobnostmi, ki jih je našel.

  5. Če poverilnice niso najdene, Gitovega uporabnika prosi za uporabniško ime in geslo ter ju posreduje nazaj prek stdout (tukaj sta priložena isti konzoli).

Sistem za poverilnice dejansko kliče program, ki je ločen od samega Gita; kateri program in kako, je odvisno od konfiguracijske vrednosti credential.helper. Obstaja več oblik, ki jih lahko vzame:

Konfiguracijska vrednost Obnašanje

foo

Požene git-credential-foo

foo -a --opt=bcd

Požene git-credential-foo -a --opt=bcd

/absolute/path/foo -xyz

Požene /absolute/path/foo -xyz

!f() { echo "password=s3cre7"; }; f

Koda za ! se izvede v lupini

Zgoraj opisani pomočniki so dejansko poimenovani git-credential-cache, git-credential-store in tako naprej ter lahko jih konfiguriramo tako, da sprejmejo argumente ukazne vrstice. Splošna oblika za to je git-credential-foo [args] <action>. Protokol stdin/stdout je enak kot pri git-credential, vendar uporablja nekoliko drugačen nabor akcij:

  • get je zahteva za par uporabniškega imena in gesla.

  • store je zahteva za shranjevanje nabora poverilnic v pomnilniku tega pomočnika.

  • erase izbriše poverilnice za določene lastnosti iz pomnilnika tega pomočnika.

Za akciji store in erase ni zahtevan noben odziv (Git ga vseeno ignorira). Za akcijo get pa je Git zelo zainteresiran, za kar ima pomočnik sporočiti. Če pomočnik ne ve ničesar uporabnega, lahko preprosto izstopi brez izhoda, če pa ve, bi moral ponuditi informacije, ki jih ima shranjene, in jih združiti s podatki, ki jih je Git že vedel. Izhod se obravnava kot niz dodelitvenih stavkov; karkoli je podano, bo nadomestilo, kar Git že ve.

Tukaj je isti primer kot zgoraj, vendar preskočimo git-credential in gremo naravnost na git-credential-store:

$ git credential-store --file ~/git.store store (1)
protocol=https
host=mygithost
username=bob
password=s3cre7
$ git credential-store --file ~/git.store get (2)
protocol=https
host=mygithost

username=bob (3)
password=s3cre7
  1. Tukaj povemo git-credential-store, naj shrani nekaj poverilnic: uporabniško ime bob in geslo s3cre7 bosta uporabljena, ko se bo dostopalo do https://mygithost.

  2. Sedaj bomo pridobili te poverilnice. Posredujemo dele povezave, ki jih že poznamo (https://mygithost), in prazen vrstični prelom.

  3. git-credential-store vrne uporabniško ime in geslo, ki smo ju shranili zgoraj.

Takole izgleda datoteka ~/git.store:

https://bob:s3cre7@mygithost

To je le niz vrstic, od katerih vsaka vsebuje URL s podatki okrašenimi s poverilnicami. Pomočnika osxkeychain in wincred uporabljata domači format svojih shramb, cache pa uporablja lasten pomnilniški format (ki ga noben drug proces ne more prebrati).

Predpomnilnik poverilnic po meri

Ker so git-credential-store in njegovi prijatelji ločeni programi od Gita, ni veliko skokov do spoznanja, da kateri koli program lahko deluje kot pomočnik pri preverjanju pristnosti v Gitu. Pomočniki, ki jih Git ponuja, pokrivajo veliko pogostih primerov uporabe, vendar ne vseh. Recimo, da ima vaša ekipa nekaj poverilnic, ki si jih deli vsa ekipa, morda za postavitev. Ti so shranjeni v skupni mapi, vendar jih ne želite kopirati v lastno shrambo poverilnic, ker se pogosto spreminjajo. Nobeden od obstoječih pomočnikov ne pokriva tega primera; poglejmo, kaj bi bilo potrebno, da napišemo svojega. Obstaja več ključnih funkcij, ki jih mora ta program imeti:

  1. Edina akcija, na katero moramo biti pozorni, je get; store in erase sta pisni operaciji, zato bomo ob njihovem prejemu gladko zaključili izvajanje.

  2. Oblika datoteke skupne poverilnice je enaka kot tista, ki jo uporablja git-credential-store.

  3. Lokacija te datoteke je dokaj standardna, vendar bi morali uporabniku omogočiti, da vnese lastno pot, če je to potrebno.

Ponovno bomo napisali razširitev v Rubyju, vendar bo delovala v katerem koli jeziku, ki ga Git lahko izvede. Tukaj je celotna izvorna koda našega novega pomočnika za overjanje:

#!/usr/bin/env ruby

require 'optparse'

path = File.expand_path '~/.git-credentials' # (1)
OptionParser.new do |opts|
    opts.banner = 'USAGE: git-credential-read-only [options] <action>'
    opts.on('-f', '--file PATH', 'Specify path for backing store') do |argpath|
        path = File.expand_path argpath
    end
end.parse!

exit(0) unless ARGV[0].downcase == 'get' # (2)
exit(0) unless File.exists? path

known = {} # (3)
while line = STDIN.gets
    break if line.strip == ''
    k,v = line.strip.split '=', 2
    known[k] = v
end

File.readlines(path).each do |fileline| # (4)
    prot,user,pass,host = fileline.scan(/^(.*?):\/\/(.*?):(.*?)@(.*)$/).first
    if prot == known['protocol'] and host == known['host'] then
        puts "protocol=#{prot}"
        puts "host=#{host}"
        puts "username=#{user}"
        puts "password=#{pass}"
        exit(0)
    end
end
  1. Tukaj razčlenjujemo možnosti ukazne vrstice in omogočamo uporabniku, da določi vhodno datoteko. Privzeto je ~/.git-credentials.

  2. Ta program odgovarja samo, če dejanje get in datoteka s podatkovno shrambo obstajata.

  3. Ta zanka bere iz stdin-a, dokler se ne doseže prazna vrstica. Vhodi so shranjeni v zgoščeni vrednosti known za kasnejšo referenco.

  4. Ta zanka bere vsebino datoteke za shranjevanje in išče ujemanja. Če se protokol, gostitelj in uporabniško ime iz known ujemajo s to vrstico, program natisne rezultate na stdout in se zaključi.

Pomožni pripomoček bomo shranili kot git-credential-read-only, ga postavili kamor koli v naš PATH in označili kot izvršljivega. Takole je videti interaktivna seja:

$ git credential-read-only --file=/mnt/shared/creds get
protocol=https
host=mygithost
username=bob

protocol=https
host=mygithost
username=bob
password=s3cre7

Ker se ime začne z »git-«, lahko uporabimo preprosto sintakso za nastavitveno vrednost konfiguracije:

$ git config --global credential.helper 'read-only --file /mnt/shared/creds'

Kot lahko vidite, je razširjanje tega sistema precej preprosto in lahko reši nekatere pogoste težave za vas in vašo ekipo.

scroll-to-top