I tried multiple user management (granting access rights) with ansible

Premise

--The virtual environment (target host) has already been built with vagrant. --I have ʻansible` installed, but I don't have a playbook to run.

Thing you want to do

ʻUser01 has access authority under ʻuser02, ʻUser02 wants to realize a state where there is no access authority under ʻuser01.

Add ʻuser01 to the group sample2`.

[root@websvr ~]# usermod -aG sample2 user01

Verification

[root@websvr ~]# groups user01
user01 : sample1 sample2
[root@websvr ~]# groups user02
user02 : sample2

Also, since I want to set the access authority under ʻuser02 to ʻuser01 only to Read authority for files and directories ʻFor the user02` directory, do the following:

[root@websvr ~]# chmod 750 /home/user02
[root@websvr ~]# ll /home/
total 4
drwx------.  3 user01  sample1   78 Jan  1 14:56 user01
drwxr-x---.  3 user02  sample2   78 Jan  1 14:56 user02
drwx------. 17 vagrant vagrant 4096 Dec 31 19:31 vagrant

If you do not give x to the group, ʻuser01 cannot move to / home / user02`.

I was able to confirm that ʻuser01 cannot delete the file created by ʻuser02.

[user01@websvr user02]$ whoami
user01
[user01@websvr user02]$ pwd
/home/user02
[user01@websvr user02]$ ll
total 0
-rw-r--r--. 1 user02 sample2 0 Jan  1 15:03 test.txt
[user01@websvr user02]$ rm test.txt
rm: remove write-protected regular empty file ‘test.txt’? y
rm: cannot remove ‘test.txt’: Permission denied

I want to realize such a thing with ʻansible`.

Public key registration

From the control node (host environment), set to log in to the target node (guest environment) with ssh without a password. Register the public key created in the control node in the target node.

ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key ($HOME/.ssh/id_rsa):
$HOME/.ssh/id_rsa already exists.
Overwrite (y/n)? n

I have already created it, so I will interrupt it. Register the public key with the target node.

ssh-copy-id [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "$HOME/.ssh/id_rsa.pub"
The authenticity of host '192.168.33.10 (192.168.33.10)' can't be established.
ECDSA key fingerprint is SHA256:mjGym7gkqWjPvW2JXhKjqWl4XC6wuhgNIukldSVtkFk.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:

Number of key(s) added:        1

Now try logging into the machine, with:   "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.

Make sure you can log in without a password.

ssh [email protected]
Last login: Tue Dec 31 18:41:18 2019 from 10.0.2.2
[vagrant@websvr ~]$ exit
Log out
Connection to 192.168.33.10 closed.

ʻAnsible.cfg` settings

Prepare ʻansible.cfg on the control node side. Since ʻansible.cfg may be set individually, create it below.

pwd
$HOME/Desktop/workspace/ansible/ansible-study
touch ansible.cfg

Set as follows in .ansible.cfg.

[defaults]
forks = 10
log_path = $HOME/.ansible/ansible.log
host_key_checking = False
gathering = smart
inventory = ./inventory.ini
remote_user = vagrant
private_key_file = /path/vagrant_private_key

[ssh_connection]

The above private_key_file is obtained from the following ʻIdentity File`.

cd $HOME/Desktop/workspace/vagrant
vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /path/vagrant_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Inventory preparation

Describe the target node information in ʻinventory.ini`.

touch inventory.ini
cat inventory.ini
[test_servers]
192.168.33.10

ʻAnsible` command execution

Execute the ping command on the target node.

$ ansible -i inventory.ini test_servers -m ping -u vagrant
192.168.33.10 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

Since the necessary information is described in ʻansible.cfg`, the following command may be used.

$ ansible test_servers -m ping
192.168.33.10 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

Preparing to rollback the target node

To be able to roll back the target node, do the following: Even if you make a mistake when running the playbook, you can start over again.

$ vagrant sandbox status
[default] Sandbox mode is off

Enable settings

$ vagrant sandbox on
[default] Starting sandbox mode...
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

Check settings

$ vagrant sandbox status
[default] Sandbox mode is on

Playbook execution

The playbook that realizes what you want to do above is as follows.

create_user.yml


---
- hosts: test_servers
  become: yes
  vars_files:
    - user_list.yml
  tasks:
    - name: Create group
      group:
        name: "{{ item.name }}"
      with_items:
        - "{{ group_list }}"
      when: group_list

    - name: Create user
      user:
        name: "{{ item.name }}"
        group: "{{ item.group }}"
        groups: "{{ item.groups }}"
        password: "{{ item.password }}"
        shell: /bin/bash
        state: present
      with_items:
        - "{{ users_list }}"
      when: users_list

    - name: Permission of directory /home/user02 is '0750'
      file:
        dest: /home/{{ item.name }}
        mode: "0750"
      with_items:
        - "{{ subordinate_authority }}"

user_list.yml


group_list:
  - { name: sample1 }
  - { name: sample2 }

users_list:
  - {
      name: "user01",
      group: "sample1",
      groups: "sample1, sample2",
      password: "{{ 'password'|password_hash('sha512') }}",
      comment: "user01",
    }
  - {
      name: "user02",
      group: "sample2",
      groups: "sample2",
      password: "{{ 'password'|password_hash('sha512') }}",
      comment: "user02",
    }

superior_authority:
  - { name: user01 }

subordinate_authority:
  - { name: user02 }

Execute.

ansible-playbook create_user.yml

PLAY [test_servers] *************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [192.168.33.10]

TASK [Create group] *************************************************************************************************************************************************************************************************************************
[DEPRECATION WARNING]: evaluating [{'name': 'sample1'}, {'name': 'sample2'}] as a bare variable, this behaviour will go away and you might need to add |bool to the expression in the future. Also see CONDITIONAL_BARE_VARS configuration
toggle.. This feature will be removed in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [192.168.33.10] => (item={'name': 'sample1'})
changed: [192.168.33.10] => (item={'name': 'sample2'})

TASK [Create user] **************************************************************************************************************************************************************************************************************************
[DEPRECATION WARNING]: evaluating [{'name': 'user01', 'group': 'sample1', 'groups': 'sample1, sample2', 'password': '$6$cuuPF7HsudjoJ9/v$G1zztM4ZLPs6UJk/fxwgjbOAkXJ32pszjjw.J.M2t.KTlO99Bus2D1AzucT.872WBs7oqp.RfOIEjf187X6cR1', 'comment':
 'user01'}, {'name': 'user02', 'group': 'sample2', 'groups': 'sample2', 'password': '$6$cuuPF7HsudjoJ9/v$G1zztM4ZLPs6UJk/fxwgjbOAkXJ32pszjjw.J.M2t.KTlO99Bus2D1AzucT.872WBs7oqp.RfOIEjf187X6cR1', 'comment': 'user02'}] as a bare variable,
this behaviour will go away and you might need to add |bool to the expression in the future. Also see CONDITIONAL_BARE_VARS configuration toggle.. This feature will be removed in version 2.12. Deprecation warnings can be disabled by
setting deprecation_warnings=False in ansible.cfg.
changed: [192.168.33.10] => (item={'name': 'user01', 'group': 'sample1', 'groups': 'sample1, sample2', 'password': '$6$VpS/Wgs9fy5KDTI8$ZXwfSsnz4jeQ6rAOX4X8HP4xu3ndeVtasHiY0SOaeZoYUvPU3CQQQ4ww3y6VfEJAlS4jJPpXn7rRxUljY.Sc60', 'comment': 'user01'})
[DEPRECATION WARNING]: evaluating [{'name': 'user01', 'group': 'sample1', 'groups': 'sample1, sample2', 'password': '$6$wjPKJca0K2oKgwFY$5JzcugEn1.kc1KXN9XYBJVub9e.AzUT28S4ZOGy.vwKhRVkSB9dqUjUcs/sqRPf8kDG94nqAT3.S8YaA3cime1', 'comment':
 'user01'}, {'name': 'user02', 'group': 'sample2', 'groups': 'sample2', 'password': '$6$wjPKJca0K2oKgwFY$5JzcugEn1.kc1KXN9XYBJVub9e.AzUT28S4ZOGy.vwKhRVkSB9dqUjUcs/sqRPf8kDG94nqAT3.S8YaA3cime1', 'comment': 'user02'}] as a bare variable,
this behaviour will go away and you might need to add |bool to the expression in the future. Also see CONDITIONAL_BARE_VARS configuration toggle.. This feature will be removed in version 2.12. Deprecation warnings can be disabled by
setting deprecation_warnings=False in ansible.cfg.
changed: [192.168.33.10] => (item={'name': 'user02', 'group': 'sample2', 'groups': 'sample2', 'password': '$6$VpS/Wgs9fy5KDTI8$ZXwfSsnz4jeQ6rAOX4X8HP4xu3ndeVtasHiY0SOaeZoYUvPU3CQQQ4ww3y6VfEJAlS4jJPpXn7rRxUljY.Sc60', 'comment': 'user02'})

TASK [Permission of directory /home/user02 is '0750'] ***************************************************************************************************************************************************************************************
changed: [192.168.33.10] => (item={'name': 'user02'})

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.33.10              : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

The execution result of the target node is as follows.

[root@websvr ~]# ll /home/
total 4
drwx------.  3 user01  sample1   78 Jan  1 15:11 user01
drwxr-x---.  3 user02  sample2   78 Jan  1 15:11 user02
drwx------. 17 vagrant vagrant 4096 Dec 31 19:31 vagrant
[root@websvr ~]# cat /etc/group | grep user01
sample1:x:1002:user01
sample2:x:1003:user01,user02

Create a file with ʻuser02. After that, it becomes ʻuser01 and the access right is confirmed.

[root@websvr ~]# su - user02
[user02@websvr ~]$ touch test.txt
[user02@websvr ~]$ ll
total 0
-rw-r--r--. 1 user02 sample2 0 Jan  1 15:32 test.txt
[user02@websvr ~]$ su - user01
Password: 
Last login: Wed Jan  1 15:32:11 UTC 2020 on pts/0
[user01@websvr ~]$ cd /home/user02/
[user01@websvr user02]$ ll
total 0
-rw-r--r--. 1 user02 sample2 0 Jan  1 15:32 test.txt

I can't delete the file either.

[user01@websvr user02]$ rm test.txt 
rm: remove write-protected regular empty file ‘test.txt’? y
rm: cannot remove ‘test.txt’: Permission denied

reference

-Vagrant + Ansible environment construction memo -I tried to list the items of ansible.cfg -Create Linux user with Ansible

Recommended Posts

I tried multiple user management (granting access rights) with ansible
I tried multiple regression analysis with polynomial regression
When I tried to change the root password with ansible, I couldn't access it.
I tried fp-growth with python
I tried scraping with Python
I tried Learning-to-Rank with Elasticsearch!
I tried clustering with PyCaret
I tried follow management with Twitter API and Python (easy)
I tried gRPC with Python
I tried scraping with python
I tried trimming efficiently with OpenCV
I tried summarizing sentences with summpy
I tried web scraping with python.
I tried moving food with SinGAN
I tried implementing DeepPose with PyTorch
I tried face detection with MTCNN
I tried running prolog with python 3.8.2.
I tried SMTP communication with Python
I tried sentence generation with GPT-2
I tried learning LightGBM with Yellowbrick
I tried face recognition with OpenCV
I tried sending an SMS with Twilio
I tried using Amazon SQS with django-celery
I tried to implement Autoencoder with TensorFlow
I tried to visualize AutoEncoder with TensorFlow
I tried to get started with Hy
I tried scraping Yahoo News with Python
I tried using Selenium with Headless chrome
I tried factor analysis with Titanic data!
I tried learning with Kaggle's Titanic (kaggle②)
I tried sending an email with python.
I tried non-photorealistic rendering with Python + opencv
I tried a functional language with Python
I tried batch normalization with PyTorch (+ note)
I tried recursion with Python ② (Fibonacci sequence)
I tried implementing DeepPose with PyTorch PartⅡ
I tried to implement CVAE with PyTorch
I tried playing with the image with Pillow
I tried to solve TSP with QAOA
I tried simple image recognition with Jupyter
I tried CNN fine tuning with Resnet
I tried natural language processing with transformers.
Record user last access time with Redis
I tried to summarize Ansible modules-Linux edition
#I tried something like Vlookup with Python # 2