Sécuriser DockerC’est un reproche qu’on entend souvent: Docker c’est pas secure. C’est vrai, par défaut Les conteneurs Docker s’exécutent avec le compte root, de même que les programmes qui s’exécutent à l’intérieur du conteneur.
Mais il existe des solutions permettant de sécuriser l’utilisation de Docker.
Revenons sur le problème
Le mieux c’est d’utiliser un exemple qui va vous parler.
Par exemple en utilisant le container
chrisfosterelli/rootplease https://hub.docker.com/r/chrisfosterelli/rootplease/ il est possible d’ouvrir un shell avec les droits roots sur la machine hote. Donc vous imaginez, si vous utiliser une image docker sans en connaître le contenu. Vous encourez de graves problèmes! Un script malveillant pourrait exploiter cette surface pour accéder à des fichiers sensibles, des images, des certificats, voir pire !
Mais
il est important de savoir que le simple fait d’ajouter un user au groupe docker donne des droits root sur la machine hôte à celui-ci.
Je vous propose de voir quelques solutions.
Utilisation de la directive USER
Si vous voulez jouer avec ces exemples je vous conseille dans le faire dans une VM, créé avec vagrant.
En ajoutant simplement la directive USER à vos Dockerfile vous allez restreindre les droits du container :
# Pour un debian/ubuntu
curl -O https://releases.hashicorp.com/vagrant/2.2.14/vagrant_2.2.14_x86_64.deb
sudo dpkg -i vagrant_2.2.14_x86_64.deb
# Pour un redhat/oraclelinux/centos
curl -O https://releases.hashicorp.com/vagrant/2.2.14/vagrant_2.2.14_x86_64.rpm
sudo yum localinstall vagrant_2.2.14_x86_64.rpm
Pour l’installer sur windows :
https://www.vagrantup.com/downloadsPremiers tours de rouePour vérifier que cela fonctionne il suffit de lancer le provisionnement de votre première VM :
vagrant box add centos/8
vagrant init centos/8
vagrant up
vagrant ssh
La première commande télécharge l’image box, vous pouvez en trouver en grand nombre sur ce site, mais faites bien attention à utiliser des images sûres. Nous proposerons bientôt des images que nous construirons avec packer et contentant tout ce qu’il faut pour développer rapidement.
Pour éviter de définir à chaque fois votre hyperviseur vous pouvez ajouter ceci à votre .bashrc:
export VAGRANT_DEFAULT_PROVIDER=libvirt
La seconde commande, `vagrant init centos\8 créé le fichier de configuration Vagrantfile par défaut avec le minimum syndical en utilisant une des box ajouté avec la commande box add.
vagrant up lance le provisionnement en lui même. Attention beaucoup de données sont ajouté à un dossier caché .vagrant dans votre répertoire de travail !
vagrant ssh permet de se connecter à votre VM.
Pour détruire une VM il suffit de lancer la commande
vagrant destroyLe fichier de déclaration VagranfileCe fichier de déclaration Vagrantfile utilise un langage proche de ruby.
Quelques règles de syntaxe pour les fichiers Vagranfile Les commentaires sur une seule ligne commencent avec un #
Les commentaires sur plusieurs lignes sont encadrés par /* et */
Les variables Vagrantfile sont assignées avec la syntaxe key = value (aucune importance concernant les espaces). Les valeurs peuvent être des primitives string, number ou boolean ou encore une list ou une map.
Les chaînes de caractères sont encadrées par des doubles-quotes.
Les valeurs booléennes peuvent être
true ou
false.
Premières lignes de VagrantfileVagrant.configure("2") do |config|
config.vm.box = "hashicorp/precise32"
end
Ici on ne fait que configurer avec la version (“2”) de vagrant un objet config qui utilise une image ubuntu precise 32 bits.
A partir de la on configurer plus finement notre vm avec différentes sections :
config.vm : pour paramétrer la machine
config.ssh : pour définir commande vagrant accédera à votre machine
config.vagrant : pour modifier le comportement de vagrant en lui même.
En fait on se limitera pour le moment à la partie paramétrage de la VM.
Paramétrage de la VM config.vmVous pouvez retrouver toute la documentation de cette partie sur le site de vagrant (
https://www.vagrantup.com/docs/vagrantfile/machine_settings). Je vais vous expliquer quelques-uns de ces paramètres :
Prenons cet exemple de fichier Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.box = "ol8"
config.vm.provider "libvirt" do |hv|
hv.cpus = "1"
hv.memory = "512"
end
config.vm.synced_folder '.', '/vagrant', disabled: true
config.vm.define "host1" do |host1|
host1.vm.network :private_network, ip: "192.168.3.10"
host1.vm.hostname = "host1"
end
end
network
On configure ici la partie réseau. Dans notre exemple on fixe l’adresse ip.
boxJe vous dit plus qu’on retrouve ici la box que l’on va utiliser. Ces box peuvent être installé avec la commande
vagrant box add. Pour les lister
vagrant box list et
vagrant box remove pour les retirer.
providerAttention ici bien indiqué l’hyperviseur utilisé. On ouvre une autre boucle pour configurer propre à chaque hyperviseur. La doc de celui de libvirt est ici :
https://www.vagrantup.com/docs/providers/hyperv/configurationconfig.vm.provider "libvirt" do |hv|
hv.cpus = "1"
hv.memory = "512"
provisionCette partie permet de définir ce qu’il se passe une fois que la machine est démarrée. Vous avez le choix d’utiliser langage dont les plus courants sont le shell, ansible et bien d’autre encore.
Dans notre exemple on utilise Ansible avec comme paramètre le playbook et le niveau de verbosité utilisé. Le playbook doit se trouver à la racine ou si vous lui indiqué le chemin relatif dans un sous dossier.
Quelques tips VagrantfileBoucle sur plusieurs machines(1..3).each do |i|
config.vm.define "node-#{i}" do |node|
node.vm.provision "shell",
inline: "echo hello from node #{i}"
end
end
Ajouter votre VM dans votre fichier /etc/hosts
Vagrant dispose de pas mal de plugins dont un des plus intéressant est hostsupdater. Pour l’installer il suffit de taper la commande suivante :
vagrant plugin install vagrant-hostsupdater
Lancer un playbook sur vos vms lors de leur création
Pour permettre d’utiliser plus facilement vos vms vous pouvez lancer un playbook pour autorisé la connexion par mots de passe, copier votre propre clés ssh. Tout est envisageable.
---
- hosts: all
gather_facts: no
become: true
# Vagrant provison runs this file, so you don't actually need an inventory
# it does that for you.
# Basically we setup a bunch of environment stuff so we can ssh into the host
# Using all the data from all.yml
tasks:
- name: Allow password authentication
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^PasswordAuthentication"
line: "PasswordAuthentication yes"
state: present
notify: restart sshd
- name: Set authorized key took from file
authorized_key:
user: vagrant
state: present
key: "{{ lookup('file', '/home/ubuntu/.ssh/id_rsa.pub') }}"
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
Ensuite il ne reste plus qu’à modifier votre config ssh dans le fichier ~/.ssh/config pour indiquer que pour se connecter aux vms on utilise le user vagrant.
Host 192.168.121.*
User vagrant
IdentityFile /home/ubuntu/.ssh/id_rsa.pub
Une autre solution serait d’utiliser la conf vagrant retourné par la commande ssh-config. Mais c’est moins générique. A vous de voir.
Host host1
HostName 192.168.121.246
User vagrant
Port 22
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /home/ubuntu/Projets/ansible/playbooks/izyview/.vagrant/machines/host1/libvirt/private_key
IdentitiesOnly yes
LogLevel FATAL
Source blog.stephane-robert.info