Ansible è uno strumento open source di fornitura di software, gestione della configurazione e distribuzione di applicazioni che abilita l'infrastruttura come codice. Funziona su molti sistemi simili a Unix e può configurare sia sistemi simili a Unix che Microsoft Windows.
Prerequisiti
Per seguire questa guida è necessario quanto segue:
- python installato nel sistema locale
- Pip Python installato
- Ansible installato localmente
Passaggi
- Installa dipendenze
- Genera la password usando il pacchetto passlib
- Crea il playbook ansible definendo le attività richieste
- L'intero playbook
1. Installa le dipendenze
Affinché funzioni, abbiamo bisogno di ansible e del pacchetto passlib.
Installa il pacchetto ansible passlib:
sudo pip install passlib
Installa ansible
sudo pip install ansible
2. Genera la password usando il pacchetto passlib
Ansible aggiungerà la password così come è per l'utente. La password è crittografata, quindi la password predefinita non funzionerà.
Ottieni la password crittografata con questo comando:
python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))"
Uscita:
➜ python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))"
Password:
$6$8IAGh7Gu2ugAB.sF$zHldDAEBMoiFUPq2RsGpQ.TRwbPOz3/S5ATs5TbfWDLypYjLGfKN8SNxu1Sx5nNfzQgDJqBh37jT9ln7EIHcq0
3. Crea il playbook ansible definendo le attività richieste
Ora che tutte le dipendenze sono installate, definiamo il nostro playbook.
Per prima cosa devi definire il nome, gli host e le informazioni extra come le variabili:
- name: Create user on a linux server
hosts: remote-server
become: yes
gather_facts: false
vars:
- user: <username here>
- password: <Password hash generated>
La prossima sezione è per le attività.
Attività ragionevole per creare un utente Linux
Dal momento che vogliamo creare un utente, utilizzeremo l'ansible user
modulo. Scopri di più sul modulo utente qui.
Questa attività creerà un utente con il name
fornito e password
che verranno interpolati dalle variabili definite in precedenza:
- name: Create a login user
user:
name: "{{ user }}"
password: "{{ password }}"
groups:
- wheel
state: present
Facoltativo:attività Ansible per aggiungere la chiave pubblica a authorized_keys per l'utente
Per consentire l'accesso al server senza password, possiamo aggiungere la nostra chiave ssh pubblica alle chiavi autorizzate nel server. Il modulo ansible authorized_key viene utilizzato per raggiungere questo obiettivo.
- name: Add public key to authorized_keys
authorized_key:
user: "{{ user }}"
state: present
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
Facoltativo:attività Ansible per negare l'accesso root ssh
Il prossimo passo è negare l'accesso come root tramite ssh. È buona norma consentire agli utenti non root di accedere. Usiamo il lineinfile
modulo che assicurerà che sia presente una riga specifica nel file specificato. Usiamo un'espressione regolare per abbinare la linea.
- name: Deny root from logging in
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
regexp: '^(#)?PermitRootLogin \w*$'
line: 'PermitRootLogin no'
state: present
Facoltativo:attività adatta per aggiungere un utente all'elenco Utenti consentiti
Una buona pratica di sicurezza consiste nel consentire solo agli utenti specificati di accedere al sistema. Questa attività lo farà.
- name: Allow specific users to log in
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
regexp: '^AllowUsers'
line: 'AllowUsers {{ user }}'
state: present
Facoltativo:aggiungi l'utente al file sudoers in modo che possano eseguire i comandi sudo:
Se desideri che l'utente creato esegua il comando sudo senza richiesta di password, includi questa attività.
Qui stiamo usando il lineinfile
modulo per cercare un'espressione regolare che corrisponda all'utente, quindi convalidare che tutto funzioni come previsto con il comando visudo -cf %s
:
- name: Add {{ user }} to sudoers file
ansible.builtin.lineinfile:
path: /etc/sudoers
regexp: '^{{ user }}'
line: '{{ user }} ALL=(ALL) NOPASSWD: ALL'
validate: 'visudo -cf %s'
4. L'intero playbook
Ecco come apparirà l'intero playbook. Salva questo contenuto in un .yaml
o .yml
file. Nel mio caso create-user.yaml
:
---
- name: Create user on a linux server
hosts: remote-server
become: yes
gather_facts: false
vars:
- user: user1
- password: $6$8IAGh7Gu2ugAB.sF$zHldDAEBMoiFUPq2RsGpQ.TRwbPOz3/S5ATs5TbfWDLypYjLGfKN8SNxu1Sx5nNfzQgDJqBh37jT9ln7EIHcq0
tasks:
- name: Create a login user
user:
name: "{{ user }}"
password: "{{ password }}"
groups:
- wheel
state: present
- name: Add public key to authorized_keys
authorized_key:
user: "{{ user }}"
state: present
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- name: Deny root from logging in
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
regexp: '^(#)?PermitRootLogin \w*$'
line: 'PermitRootLogin no'
state: present
- name: Allow specific users to log in
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
regexp: '^AllowUsers'
line: 'AllowUsers {{ user }}'
state: present
- name: Add {{ user }} to sudoers file
ansible.builtin.lineinfile:
path: /etc/sudoers
regexp: '^{{ user }}'
line: '{{ user }} ALL=(ALL) NOPASSWD: ALL'
validate: 'visudo -cf %s'
5. Esecuzione del playbook
Ora che abbiamo il playbook creato nel file create-user.yaml
nella directory corrente, dobbiamo fornire un file hosts che definirà la connessione al nostro server. Dalla definizione del playbook, definiamo il nostro server come remote-server
. Ora aggiungiamolo al file hosts.
Crea un file hosts.yaml
con il seguente contenuto che definisce il remote-server
:
all:
hosts:
remote-server:
ansible_ssh_host: 138.68.150.24
ansible_ssh_user: root
Ora dobbiamo invocare il ansible-playbook
comando in questo modo:
ansible-playbook -i hosts.yaml create-user.yaml -vv
Nel comando precedente, -i
specifica il file di inventario. Il -vv
abilita la verbosità.
Questo è l'output del mio server:
➜ ansible-playbook -i hosts.yaml create-user.yaml -vv
ansible-playbook [core 2.11.1]
config file = None
configured module search path = ['/Users/citizix/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.9/site-packages/ansible
ansible collection location = /Users/citizix/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible-playbook
python version = 3.9.5 (default, May 4 2021, 03:36:27) [Clang 12.0.0 (clang-1200.0.32.29)]
jinja version = 2.11.3
libyaml = False
No config file found; using defaults
redirecting (type: modules) ansible.builtin.authorized_key to ansible.posix.authorized_key
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
PLAYBOOK: create-user.yaml *********************************************************************************************************************************************************************************
1 plays in create-user.yaml
PLAY [Create user on a linux server] ***********************************************************************************************************************************************************************
META: ran handlers
TASK [Create a login user] *********************************************************************************************************************************************************************************
task path: /Users/citizix/projects/ansible/create-user.yaml:9
changed: [remote-server] => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "comment": "", "create_home": true, "group": 1000, "groups": "wheel", "home": "/home/rocky", "name": "rocky", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1000}
TASK [Add public key to authorized_keys] *******************************************************************************************************************************************************************
task path: /Users/citizix/projects/ansible/create-user.yaml:17
redirecting (type: modules) ansible.builtin.authorized_key to ansible.posix.authorized_key
changed: [remote-server] => {"changed": true, "comment": null, "exclusive": false, "follow": false, "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6gM14zM0+L+ERQFVFYbHBAjtyghKKx/N+qsFXxrcJqVqsyn1lp/erPqg3g6WSu/bwiAB+E22RyG9icS7Td8ssWi9vDE73DHgC5NGLm4KeP2FospEFjY6v8XVjkwQZJ+8YyCfXJ4E5cm0FGKZREakDlYeaonTaIjxkXlsZB3Yl93+KZvZ0g1WiBOU6N6NWpEQVvxYccWK4+EuQiCryELL0o4dCNrwLaYOyv/NbSYQ09m3+mvN0VRnTzo7qSOqy1U6oCVA9bhd+tRyoUsUqp3Up8jdfzEGfWr/Pqskjtl8YXySPHLEROXX/Om4AyT62EQxcPMzedPJ6HGLHnlk4EO9cBLawymdWO7AlghujksVBu9S+alOkAmJkkPzeq76WOjCTmoNxlQmEDlucukiujfWKl4hACdNVtARptvuc5+4uMYA4j4Ql+XtQ964UQa4HiGiNpoiDegzDq9GMEsQW4W5frRuOIm4R7thYGatRBkNFw+uemE5HclF8LXOuPkShhFqpDPgI1oH99covroXggV8/ovEf9ZSoshNLMHX5kXWGAWF983Cn2N5RpmqN8rfcGVq6C93njExvHDfl7bHkhT10axOLV/V4vX4lSktWVV4//vq2wMQLi5F1l7ai8scA3eYeSaWnDaJj2jnz6V5JBOPIOH/3lf7qq4oquZhmuWq3w== citizix", "key_options": null, "keyfile": "/home/rocky/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": "present", "user": "rocky", "validate_certs": true}
TASK [Deny root from logging in] ***************************************************************************************************************************************************************************
task path: /Users/citizix/projects/ansible/create-user.yaml:23
changed: [remote-server] => {"backup": "", "changed": true, "msg": "line replaced"}
TASK [Allow specific users to log in] **********************************************************************************************************************************************************************
task path: /Users/citizix/projects/ansible/create-user.yaml:30
changed: [remote-server] => {"backup": "", "changed": true, "msg": "line added"}
TASK [Add my pub key to authorized_keys] *******************************************************************************************************************************************************************
task path: /Users/citizix/projects/ansible/create-user.yaml:37
ok: [remote-server] => {"changed": false, "comment": null, "exclusive": false, "follow": false, "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6gM14zM0+L+ERQFVFYbHBAjcsTGZKKx/N+qsFXxrcJqVqsyn1lp/erPqg3g6WSu/bwiAB+E22RyG9icS7Td8ssWi9vDE73DHgC5NGLm4KeP2FospEFjY6v8XVjkwQZJ+8YyCfXJ4E5cm0FGKZREakDlYeaonTaIjxkXlsZB3Yl93+KZvZ0g1WiBOU6N6NWpEQVvxYccWK4+EuQiCryELL0o4dCNrwLaYOyv/NbSYQ09m3+mvN0VRnTzo7qSOqy1U6oCVA9bhd+tRyoUsUqp3Up8jdfzEGfWr/Pqskjtl8YXySPHLEROXX/Om4AyT62EQxcPMzedPJ6HGLHnlk4EO9cBLawymdWO7AlghujksVBu9S+alOkAmJkkPzeq76WOjCTmoNxlQmEDlucukiujfWKl4hACdNVtARptvuc5+4uMYA4j4Ql+XtQ964UQa4HiGiNpoiDegzDq9GMEsQW4W5frRuOIm4R7thYGatRBkNFw+uemE5HclF8LXOuPkShhFqpDPgI1oH99covroXggV8/ovEf9ZSoshNLMHX5kXWGAWF983Cn2N5RpmqN8rfcGVq6C93njExvHDfl7bHkhT10axOLV/V4vX4lSktWVV4//vq2wMQLi5F1l7ai8scA3eYeSaWnDaJj2jnz6V5JBOPIOH/3lf7qq4oquZhmuWq3w== [email protected]", "key_options": null, "keyfile": "/home/rocky/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": "present", "user": "rocky", "validate_certs": true}
TASK [Add rocky to sudoers file] ***************************************************************************************************************************************************************************
task path: /Users/citizix/projects/ansible/create-user.yaml:43
changed: [remote-server] => {"backup": "", "changed": true, "msg": "line replaced"}
META: ran handlers
META: ran handlers
PLAY RECAP *************************************************************************************************************************************************************************************************
remote-server : ok=6 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0