Configure ansible-vault to use gopass

This commit is contained in:
Adriano Caloiaro 2020-10-20 16:26:25 -06:00
parent 3b9f2c1dcc
commit 987cb61f52
No known key found for this signature in database
GPG key ID: 9FFD0E7601F166AB
3 changed files with 256 additions and 68 deletions

View file

@ -1,2 +1,8 @@
[defaults] [defaults]
inventory = ./local inventory = ./local
vault_identity_list=zenity@scripts/gopass-client.py
[vault]
mount=
directory=ansible

View file

@ -1,68 +1,142 @@
# davfs2 secrets file 2009-10-18 $ANSIBLE_VAULT;1.2;AES256;zenity
# version 4 31393939383737636665366630353562333231313430313164373433633035343163316263616136
# ------------------------------- 6339376630346637666137306635323439383766613665350a326536306161303263643365373536
62326231383937343265336335613334336535383839336539616233656365623063663037666435
# Copyright (C) 2006, 2007, 2008, 2009 Werner Baumann 3930353466613130350a663061616330373561646361396139333433393863326366383563393735
62613261306332643364633463666632633932383730663235313863643739336435353432366461
# Copying and distribution of this file, with or without modification, are 33326665656661623937643061626432366230303832356338353934616235346662316163613939
# permitted in any medium without royalty provided the copyright notice 35363632653431663432623237663132333862653161623461343138346437643366356366346536
# and this notice are preserved. 66323862626139393662383936383233363231626633373261303361303962373039373363343762
65663464323665326261616338363132656366653839623565373465373363666163363834326238
34396639656561376533616637653963323634666566336433353834383538363636303133613034
# # This file must be readable and writeable by the owner only (mode 0600). 33613834386237613165306264363464393863633336623737353437613062326464333836333138
62633433303837396633326632666435643735363336633535356237383137333962323833633662
# This file contains user-name and password for the proxy, the 32353430356163353737616466666137353165363164316635333366346330306336643936396235
# WebDAV resources and decryption passwords for client certificates. 33303130306363646165633364646663376235383230666132393235303934326565356439396237
36626636313633363539663030393030623831616663666539353061306338653236366139366563
# Comments are indicated by a '#' character and the rest of the line 65636666653265366466336338366266346635333334663339393365633733336338326130343436
# is ignored. Empty lines are ignored too. 38326238303666303464636339663864353537653437633035323362366231323462386338343862
65373539643037613031333439653865303039386562343765346339313931663138383863353033
# Each line consists of two or three items separated by spaces or tabs. 32303165306462623539646133383532626533306230663139363264333666633961376535343437
# If an item contains one of the characters space, tab, #, \ or ", this 36386330643265613035313433333466653234336463326265373036373533616330356364623137
# character must be escaped by a preceding \. Alternatively, the item 37383166633536383964383935643531653238666335383066363336633163343362336261383930
# may be enclosed in double quotes. (see also the davfs2.conf (5) man page) 63623234343333396563653130353062653366336135383233376662623561363535323566383038
33386363363463666465643465363935333462643966306366626432353539373035653766633563
32336539326631613666636432346663303237303364386561333939303931396236623839336534
# Proxy Line 35633931633235363761313963346435626535316232656163343963616561323232316432626236
# ---------- 36383763383765363537383766313137653165316464343930646135623538623838643936356132
# A proxy line consists of the fully qualified domain name of the proxy, 39383064333663653066646131366432323566326261663234653037353166613839333639653038
# the user-name and the password. The proxy name must not contain a scheme 30316136663433643664313134346364393335376333363264316134373866353437646336306239
# or path segment, but a port number should be added, separated by a colon. 37333332656437376662386634346665656133656663613163623331386163393732616237643563
# The password my be omitted. 36376338613266623963623732353036376631333431333235656337323939353062386164656463
# Instead of the name of the proxy, the keyword "proxy" may be used. 66376132383932323732346435336330353237393939303834663336303632366463306465346535
65643862363736363930333833666230663163613064316139616361343431656238323839633566
# Examples 62353161343864663662666263323465383965386538313134613236333431313837363966383836
# foo.bar:3245 otto my\ secret 39643638666536623931306638653561633262363463626638386363656635663435616339333737
# foo.bar otto "my secret" 33303561633834646162383336333463346536656534666166643035353133623539643435336239
# proxy otto "my secret" 31346466326334666365663438663964623435316133666534656431373138373334303035363665
66336632616466333737336630393837323634376230333261663266343739316166326133306335
64303336623263373034373633623132353764613135663730353062303034643635396162363764
# Credential Line 33623761653464666434623336333731383163363666356163306234336635343233316435613831
# --------------- 64393438663231646635666536363737663034336438643639336335336566393231316433353431
# A credential line consists of the mount-point, the user-name and 36316230333931666264303765613935663339393331613363393931386166373361363461333030
# the password. The mount-point must be an absolute path, starting 34326563333561623936363336633166386363343937643831663035636331383234373831646161
# with /. The password may be omitted. 63306361663262623465663264616264386630373134393561633665373062333639336364653931
# For compatibility with older versions, instead of the mount-point 37316637623762313533333931383965373932363762386532626135656162303435393130663063
# the URL may be given. The URL must contain scheme, fully qualified 31393338333961393933623165346236346562323864626230643163363264343264623461393638
# domain name and path. If the path segment is missing, / is assumed. 32666337663131633833653932656334396563393032623765356336303030396262393166653730
63393564393739663264313166383337366438313932353566363261376337346166633333353030
# Examples 32633431366161623062613633303662346139636464393864313831393333343666346461306337
# /home/otto/foo otto g3H\"x\ 7z\\ 34356262313661363031613630643462303939393733306464303263623362323333663163643838
# /media/dav/bar otto geheim 31313838363363353332383030306234636633396563353338663738653934643636326132343335
# Old style 35646530613537343663323663616436663736303133616263323339316231636564646432633938
# "http://foo.bar/my documents" otto "geh # heim" 62383162396536646630346532633135343735663765396565393635623836323037616164363235
# https://foo.bar:333/dav otto geh\ \#\ heim 39646163613062663663303535303139373537363132626165303362326434373430303437623965
31366339653362633034373037333863306638643561333263383239313663323165313964343835
33396235633337663764383962366539396132333335313234373365313463343434303532653033
# Password for Client Certificate 66363664383536326339373233303531626565326631336130313533353466323038376137353032
# ------------------------------- 34643934653761343263656538643138656437653438626137373132303038656165646632653561
# It must contain the name of the certificate file and the encryption 31333637373330343639353931313932623138623433663664336663393830373437323834373161
# password. The name must be either absolute (starting with /) or the 33633330626163623331346331633737373337393831633632393363393938366165396435363230
# file-name only. If it is not absolute, it is assumed to be in the 35323162306162383866353863663337366364316232396437383564656261306135353264313232
# standard directory for client certificates. 35366638323561336437323764363763333663663066363362613839396662363036353663363231
35393334386335353033376439363563613534643863326130626130303963333230393830386239
# Examples 63393762346337336632376138333264653534623330356564323565303665363834353139373733
# /home/otto/.davfs2/certs/private/otto.crt geheim 35366431326236626666353237623237336133396663646130363462303564333663636533343732
# otto_private.crt "this is extraordinary secret" 32346164633138323932383662643861336139383034376432393564326634633438663861346165
# "otto private.crt" this\ is\ secret,\ too. 64363863376635626530333030353937383063353462636437343161653937663635313037303737
64373031663064346239386233333566306332356435353361656534323838656632323431373762
61356162613762366363373036643934346262613761326632636362376131373361346164623338
61333838643461666634333131333366386431313566303131346634356466653333356430323766
36393139653138666561326165623539313165393238306661666331396661323663326130356232
37366539383862373937633364373337383938323661663435393031306530303538376633333966
61633062666463636535303031373733646564653938336165373730373639343432363162353266
36393238663064623037343162336334373562306635343733663036336138336161333136663666
61346634396235303765653061386265353165303264613061383338306439383331383937376337
33623664383039316434353466666566633237666138656237623461306437386231326639633939
66303338383066333733333832356463366137383264616461356537623631373939663165623334
36623365303162646238386463613734343062656137356335633434336234396532336261633131
65353038323661393762663066613936653361386234396133623836326430393863616232323335
66666162613130326262636231313562303132336134386432393936333461613031326135653463
31356637633165623536643733303035383530613932353165656430353333313331393830653937
31646337356165393538316265633832633731653166356566613265613866356165633633346237
32653135376164343039366330303564653437326539643730303530366361663937393731636666
38623165613365346161643261633831363437333931366466393336323162633431623436636138
62346634363638333336393262333765373737653364306538326231396630653633326335333865
31306632323539303335643262353734303566346639643039386230356132646462666666383261
61386565323936663135666565663535653234333130616263336566353333306464343764396533
66613063373838623765656531333235366330616638653434656237323133393533326334613131
34366439393730613038353863313138336436656239323666356530363936363563343264366161
32303065626163626163336435666565653931323839626233643938393961663461663935653365
62386236386661303562393566663965333130376164323764376562303964613536643066336664
34343337376430316638353564666565353864626637373966316561663861313062373636383036
38376636643934653534666636363539653339303139636633623635613261633735656166623364
63383536313764323562633236346236393935303561373230363561633164646531313565346364
33613734326437393763656137623139643564396133333130323766613437383532393563366430
33653838363432353561393837386166356663323731613239306565333033373139313733303734
31323662646464333539303033613637333563323232393939303162666435643631633837613234
66306532633236666564393837356165623463316338626561356261666165326364313762346637
65656138303865623032666334616366653332646265376566333530386239333132386630343939
64376535323864613430336236633330663362613432373537313237333735653765383564366262
66613331306136373162623964383535336438633665393363383261666136653435646538623333
35636233636133653733626163376332653965333536653963316461666261626364353231313830
34313766376364616162633039393865376161623930363638373730313336343436323865336230
33303461313933643234326436323832326537336333316333643566346433346532313833356464
32376262636339303666383934643430386661363164323132343737323830363532393565383637
37653838633930303337316165613836373434613333633463613264346334346436626439643539
62343030626634313334633131346339333730343437366437616436396563656131346531656561
32626432376133326135663732323733386534366132363539393365656362333431383537313166
39613035386565646339636336613962613935303739666465353061343065663238373435306162
34643763636533373431386130356436373334336466613037313335653432393739323131653962
30303165653439353565636531643739343563313634636434326433323130306534336261643361
64333965366338316264353730373833336464353738626364653938626539616132643939663362
36393464626637643938633134663766333165663133656664636630373964396564396165353836
31313365643631343261343966356164613835393866333561363366333964363730666136646464
66386330316334653136313638623336336661366235616537646333616361663732336137666164
65636237633335623937663866313666366232313635376532623332373731633738316431633336
66613963326531626166613532383138633039313630613031303031323163653139383335333061
38666466313234623864373738303535386466326337343561353132323637643466643439363234
38336164353030376263333963613037356233366661386636646266613431336437383831353266
61366333633264646561323664656231343663343133633932326561353266623862656166626665
65616136616639313165303032383532613931336161313637303639333336373238313938373934
66316234666366343832363131383236316237393765636531323832386661373932346531393862
36393161383235306339326339333631353133323961343461306161356437326336616237383239
33663031303466353163393034386333326466666231623662356239303939623638393066386463
32616231643435303062313238343631373964373135393563336366646365353332663230313237
63653432633236356164623735633763333435653632646639656436626331616436643236616639
64326331373730376539313564663836623363396464653265313666666638306139363265313334
61653737656138626432323737616632373739316334366463353333613161393432343861626562
61373335393864333432396532616261306337623432636536636661666330346631653862393633
38376639643534646265636435393232393063356236643838363666656333393361653361356466
62316536333030616663633937316165623438316462363063353265393266666366646130653730
34393566613137363761363934626238366263666562616432386131653231646563633239333935
35336161313433636334653663643365643631616439343035626532336165623530646335613865
61363565393431376134366466646332623631633364396531663937633631306630313335636335
34383766666236376435386635346332396530653133313239386666376633323162663366633736
39366432636531393737333362363563343561643630626236373636316236393731336265336665
34376339633731343333393132636166396661353636376238663264333631343661396535336664
65376139383232303865626663316136663730386432353133643830346336313663326331326361
65626264623932623332333335396437613233646465393836653964333138303535326665333039
37373237346438386163633138303363303931313036323239373164656432346331613138643066
34336331643661613462663238366238373030356636643838653464393233396339366637333862
65396263643165366430326436363633623935356630613965626661306363326565

108
scripts/gopass-client.py Executable file
View file

@ -0,0 +1,108 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Assuming you have a working gopass installation. I personally use multiple mounts and I store all the passwords under a
# single directory.
#
# Add the following section to your `ansible.cfg`
#
# [vault]
# mount='store-X' # replace `store-x` with your actual store, if using the root set to an empty string
# directory='ansible' # replace `ansible` with the folder, or folder structure to your storage
#
# To use this script, make sure it is is readable by ansible. I assume going foward it is in the `scripts` folder in the
# root directory of your ansible playbooks. The file is assumed to be saved as gopass-client.py. The only condition on the name
# is that it MUST end with `-client.py` or else it is never passed the `--vault-id` parameter.
#
# If your file is not stored in the scripts directory one level down from the root you will need to update the following:
#
# config.read(os.path.join(curdir, "../ansible.cfg"))
#
# make sure the path is pointing the the ansible.cfg or some other ini file you want to store the settings in.
#
# To manually specify vault ids to add, simply add `--vault-id password-name@scripts/gopass-client.py`.
# You can add as many of these as you need. But this quickly becomes unweildly.
#
# In your `ansible.cfg` make sure your default section has the following line
#
# [defaults]
# vault_identity_list=dev@scripts/gopass-client.py, staging@scripts/gopass-client.py
#
# vault_identity_list is a comma seperated list. replace dev and staging and add as many more as you need to fit your needs.
#
# In a production situation, you may be sharing the ansible code with many users and all may not have the same permissions to
# read the password from the gopass store.
#
# By default this client will error if it can't decrypt the password. Unfortunately, on initialization ansible tries to load
# all the vault ids you specify even if they aren't needed. Therefore if a user doesn't have access to one of the passwords
# all ansible commands will just error if you use the `vault_identity_list` fields.
#
# By adding the following to the vault configuration if a password is unabled to be determined, random data will be returned
#
# [vault]
# suppress_gopass_errors = True
#
# This is a double edged sword, this gets around errors running playbooks when a user mightn ot be able to decrypt the
# password. But using `ansible-vault ecrypt --encrypt-vault-id X ....` when you don't have access to X will result in a random
# password being used. Since it is random and not saved, you won't be able to decrypt the information again.
#
# Use this option at your own discression, but I think the advantages outweigh the costs.
#
# If someone knows how to make config manager work like in the example client in the ansible directory let me know and I will
# happily make the adjustments.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import argparse
import subprocess
import os
import configparser
import random
import string
def build_arg_parser():
parser = argparse.ArgumentParser(description='Get a vault password from user keyring')
parser.add_argument('--vault-id', action='store', default=None,
dest='vault_id',
help='name of the vault secret to get from keyring')
return parser
def main():
curdir = os.path.dirname(__file__)
config = configparser.ConfigParser()
config.read(os.path.join(curdir, "../ansible.cfg"))
mount = config['vault']['mount']
if mount is None:
sys.exit(1)
directory = config['vault']['directory']
if directory is None:
sys.exit(1)
suppress_gopass_errors = config['vault'].getboolean('suppress_gopass_errors')
arg_parser = build_arg_parser()
args = arg_parser.parse_args()
keyname = args.vault_id
result = subprocess.run(["gopass", "show", "%s/%s/%s" % (mount, directory, keyname)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0 and not suppress_gopass_errors:
sys.stderr.write(result.stderr.decode("utf-8"))
sys.exit(result.returncode)
elif suppress_gopass_errors:
sys.stdout.write(''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(20))+'\n')
else:
sys.stdout.write(f'{result.stdout.decode("utf-8")}\n')
sys.exit(0)
if __name__ == '__main__':
main()