Azcopy sert à copier des fichiers depuis ou vers un service de stockage Azure. En tant que développeur moderne, j’aimerais utiliser l’outil dans un conteneur. Manque de bol, il n’existe aucune image Docker proposée par Microsoft pour son outil azcopy
. D’ailleurs il se trouve que je ne suis pas le premier à souffrir de ce manque, comme en témoigne cette issue GitHub qui réclame à Microsoft une image docker azcopy. Et bien justement, parlons-en !
En 2020, rien d’étonnant à demander à un éditeur logiciel de fournir une image Docker avec son outil. Malheureusement, dans notre cas la réponse a été :
Bonne idée mais on verra plus tard
L’issue est maintenant ouverte depuis plus d’1 an. C’est dommage, je vais devoir me contenter de l’image non officielle postée par l’auteur de l’issue.
Il faut savoir que azcopy
propose 3 modes d’authentification :
- Manuellement avec son compte AD en rentrant un code généré à la commande
- Utiliser un
Service Principal Authentication
qui est un compte de service - Utiliser un
token SAS
(Shared Access Signature)
Dans mon contexte et pour diverses raisons, je suis contraint d’utiliser le Service Principal
. Pour ce faire, j’ai 2 commandes à lancer :
- Me connecter à Azure avec la commande :
azcopy login --service-principal ....
- Copier mon fichier avec la commande :
azcopy cp …
Je commence par instancier l’image azcopy que j’ai trouvée et j’y ouvre un bash. Je teste alors ma commande azcopy login
et…
$ export AZCOPY_SPA_CLIENT_SECRET=<client-secret> $ azcopy login --service-principal --application-id <application-id> --tenant-id <tenant-id> Failed to perform login command: failed to get keyring during saving token, operation not permitted
Ça ne marche pas ! Bah alors, il y a quand même 100 000 téléchargements sur cette image. Vous allez pas me dire que derrière il n’y a eu que des erreurs ou que personne n’a réellement utilisé l’image ??
En réessayant en local sans conteneur avec succès et en relisant attentivement la ligne 4, je comprends que le problème vient de syscalls non autorisés. D’ailleurs quelqu’un en parle dans l’issue. Il paraîtrait que seule la méthode d’authentification par token SAS
fonctionne sans problème !
Mais alors quelle est la différence entre l’authentification par token SAS
et le service principal
? Lorsqu’on utilise le service principal
, on doit utiliser la commande azcopy login …
pour s’authentifier avant de faire son azcopy cp …
alors que token SAS
s’ajoute directement dans la commande de copy. Il se trouve que azcopy login
utilise l’outil keyctl
, information confirmée par John Rusk, ancien responsable sur ce projet. Le problème, c’est que keyctl
utilise entre autre le
du même nom. Or, une CVE concernant une faille dans le syscall keyctl a provoqué sa suppression dans la configuration seccomp par défaut livrée par le CRI Docker.
syscall
En effet, afin d’offrir un comportement sécurisé aux utilisateurs de Docker, celui-ci a décidé de livrer avec son CRI une configuration seccomp
par défaut. Cette configuration est représentée par un fichier json qui liste tous les syscalls
qu’un conteneur aura le droit d’appeler.
Presque 1 an plus tard, John Rusk annonce qu’il est enfin envisagé d’avoir une image officielle pour
et qu’il sera prévu d’y supporter l’authentification par
azcopytoken SAS
et par Service Principal
, je l’espère sans avoir à bidouiller le seccomp
. Bonne nouvelle ! Mais ça fait 5 mois et l’issue n’a toujours pas changé de statut.
Bref, en attendant comment je fais ? Pas le choix, je cherche quels sont les syscalls
à ajouter à notre config seccomp
. Pour cela, la commande strace
est notre amie (à exécuter en dehors d’un conteneur évidemment) !
$ strace -f -c azcopy login --service-principal --application-id <application_id> --tenant-id <tenant_id> <skip> % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 87.12 2.058904 309 6666 1061 futex 5.76 0.136209 994 137 epoll_pwait 5.61 0.132665 116 1143 nanosleep <skip> 0.00 0.000000 0 1 add_key 0.00 0.000000 0 2 keyctl ------ ----------- ----------- --------- --------- ---------------- 100.00 2.363251 12565 2032 total
En sortie nous avons beaucoup de syscalls affichés, il nous reste plus qu’à chercher par rapport à la configuration seccomp par défaut lesquels manquent à l’appel. Résultat, voici les blocks à ajouter à notre configuration :
{ "name": "add_key", "action": "SCMP_ACT_ALLOW", "args": [] }, { "name": "keyctl", "action": "SCMP_ACT_ALLOW", "args": [] }
On a plus qu’à utiliser notre nouveau fichier seccomp dans notre commande docker :
docker run -it --entrypoint bash --security-opt seccomp=seccomp.json datenbetrieb/azcopy
Et lorsqu’on relance notre commande de login cette fois-ci c’est un succès !
Pour info : Si vous voulez déployer un conteneur azcopy
sur Kubernetes vous n’aurez pas ce problème de seccomp
. Kubernetes utilise CRI-O par défaut à la place de Docker en CRI et que celui-ci est configuré différemment.