Differences

This shows you the differences between two versions of the page.

Link to this comparison view

scgc:laboratoare:07 [2020/04/06 20:20]
darius.mihai [7. [BONUS - 10p] Ansible Commands]
scgc:laboratoare:07 [2021/10/27 14:09] (current)
maria.mihailescu
Line 1: Line 1:
-====== ​Laboratory 07. Configuration Management: Puppet, Ansible ======+====== Configuration Management: Puppet, Ansible ======
 ===== Lab Setup ===== ===== Lab Setup =====
  
-  * We will be using a virtual machine in the [[http://​cloud.curs.pub.ro/​|faculty'​s cloud]]. +  * We will be using a virtual machine in the [[http://​cloud.grid.pub.ro/​|faculty'​s cloud]].
-  * When creating a virtual machine follow the steps in this [[https://​cloud.curs.pub.ro/​about/​tutorial-for-students/​|tutorial]].+
   * When creating a virtual machine in the Launch Instance window:   * When creating a virtual machine in the Launch Instance window:
-    * For **Availability zone**, choose **CAMPUS**, **CI** or **hp** 
     * Select **Boot from image** in **Instance Boot Source** section     * Select **Boot from image** in **Instance Boot Source** section
     * Select **SCGC Template** in **Image Name** section     * Select **SCGC Template** in **Image Name** section
Line 31: Line 29:
 ===== Tasks ====== ===== Tasks ======
  
-==== 1. [20p] Puppet Resources ====+==== 1. [10p] Puppet Resources ====
 Puppet is a configuration management tool. In order to describe the necessary configurations,​ Puppet uses its own declarative language. Puppet can manage both Linux and Windows systems. Puppet is a configuration management tool. In order to describe the necessary configurations,​ Puppet uses its own declarative language. Puppet can manage both Linux and Windows systems.
  
Line 150: Line 148:
 Chech the **/​etc/​passwd** file to see if the user was actually removed. Chech the **/​etc/​passwd** file to see if the user was actually removed.
  
-==== 2. [20p] Puppet Manifests ====+==== 2. [10p] Puppet Manifests ====
 Even though we can create, modify or remove resources from the command line, using **puppet resource** commands, this is not a scalable approach and not appropriate for complex scenarios. Even though we can create, modify or remove resources from the command line, using **puppet resource** commands, this is not a scalable approach and not appropriate for complex scenarios.
  
Line 238: Line 236:
 <note important>​If it doesn'​t already exist, the key pair for the **student** user must be generated beforehand. <note important>​If it doesn'​t already exist, the key pair for the **student** user must be generated beforehand.
  
-Then, run the command ''​ssh-add ~/.ssh.id_rsa''</​note>​+Then, run the command ''​ssh-add ~/.ssh/id_rsa''</​note>​
  
 <​note>​Use the Puppet documentation for the resource type [[https://​puppet.com/​docs/​puppet/​5.5/​types/​ssh_authorized_key.html|ssh_authorized_key]].</​note>​ <​note>​Use the Puppet documentation for the resource type [[https://​puppet.com/​docs/​puppet/​5.5/​types/​ssh_authorized_key.html|ssh_authorized_key]].</​note>​
Line 297: Line 295:
   ensure => file,   ensure => file,
   mode   => '​0600',​   mode   => '​0600',​
-  source => '/​root/​examples/​sshd_config',​+  source => '/​root/​config-files/​sshd_config',​
 } }
 service { '​sshd':​ service { '​sshd':​
Line 439: Line 437:
 } }
 </​code>​ </​code>​
 +
 +<note important>​
 +Puppet has a modular implementation,​ and some functionality is provided through classes, some of which may be provided by certain modules. To use the ''​%%str2bool%%''​ function, you must install the ''​%%puppet-module-puppetlabs-stdlib%%''​ module using the ''​%%apt%%''​ package manager.
 +</​note>​
 +
 Apply the manifest and notice the state of the NTP service. Apply the manifest and notice the state of the NTP service.
  
Line 461: Line 464:
 </​note>​ </​note>​
  
-==== 6. [BONUS - 5p] Ansible Install & Configuration ====+==== 6. [10p] Ansible Install & Configuration ====
 Ansible is a configuration management and provisioning tool, similar to Puppet. It uses SSH to connect to servers and run the configured tasks. Ansible is a configuration management and provisioning tool, similar to Puppet. It uses SSH to connect to servers and run the configured tasks.
  
Line 472: Line 475:
 student@scgc:​~$ sudo apt install -y ansible student@scgc:​~$ sudo apt install -y ansible
 # Required to use password authentication. By default, ansible requires authentication through SSH keys # Required to use password authentication. By default, ansible requires authentication through SSH keys
-student@scgc:​~$ sudo apt install -y ansible+student@scgc:​~$ sudo apt install -y sshpass
 </​code>​ </​code>​
  
Line 534: Line 537:
   * ''​%%--ask-pass --user=student%%''​ - SSH connection parameters: interactive password input, login as **student** user   * ''​%%--ask-pass --user=student%%''​ - SSH connection parameters: interactive password input, login as **student** user
  
-==== 7. [BONUS - 5p] Ansible ​Commands ​====+==== 7. [10p] Ansible ​Facter ​====
  
 Ansible has a fact gathering system similar to Puppet. To extract facts about the remote host we can use the ''​%%setup%%''​ module. The information is returned as Python dictionaries,​ where values can be strings, arrays, or other dictionaries. Ansible has a fact gathering system similar to Puppet. To extract facts about the remote host we can use the ''​%%setup%%''​ module. The information is returned as Python dictionaries,​ where values can be strings, arrays, or other dictionaries.
Line 557: Line 560:
 ... ...
 </​code>​ </​code>​
 +
 +The information in the facter, can be used in playbooks - configuration files written in YAML that act as scripts for ansible. The syntax used to expand all variables - including those created by the facter - is ''​%%"​{{ variable }}"​%%''​. For example, ''​%%"​{{ ansible_facts.hostname }}"​%%''​ will be expanded to the hostname, as identified by the facter.
 +
 +
 +==== 8. [BONUS - 20p] Two-factor Authentication for SSH ====
 +
 +We plan to enable the use of two-factor authentication for SSH through the use of Google'​s Authenticator mobile application. To do this, we need to create a Google Authenticator configuration file on the host. To create one with sensible defaults, you can use the following commands:
 +<code bash>
 +student@scgc:​~$ sudo apt install libpam-google-authenticator qrencode
 +student@scgc:​~$ echo -e "​y\ny\ny\nn\ny"​ | google-authenticator
 +</​code>​
 +
 +The commands above will create a configuration file for the authenticator,​ that will generate time-based codes, will update the ''​%%~/​.google-authenticator%%''​ file, disallow multiple users and enable rate limiting. The fourth option (the **n** in the string passed to the ''​%%google-authenticator%%''​ binary ) disables longer-lasting codes (this option is only useful when the phone and/or the server'​s time sync protocols are not working properly). For more details, consult DigitalOcean'​s tutorial on how to set it up [[https://​www.digitalocean.com/​community/​tutorials/​how-to-set-up-multi-factor-authentication-for-ssh-on-ubuntu-16-04|here]].
 +
 +After running the command, the terminal will display the secret key as both a large QR code, and text. Please open the Google Authenticator app on your phone, and scan the QR code or enter it manually.
 +
 +We will copy the Google Authenticator'​s configuration file, the configuration for the SSH daemon, and the PAM configuration file for the SSH service:
 +<code bash>
 +student@scgc:​~$ mkdir config-files
 +student@scgc:​~$ cd config-files
 +student@scgc:​~/​config-files$ cp /​home/​student/​.google_authenticator .
 +student@scgc:​~/​config-files$ cp /​etc/​pam.d/​sshd .
 +student@scgc:​~/​config-files$ cp /​etc/​ssh/​sshd_config .
 +</​code>​
 +
 +<note warning>
 +The Authenticator configuration file is sensitive information! It MUST have ''​%%0600%%''​ permissions (only the user must be able to access it), and it is usually not a good idea to copy it to another server. From a security point of view, it is similar to copying a private SSH key to another server. Make sure you copy the configuration only to servers you trust.
 +</​note>​
 +
 +We will use the files created above as templates to replicate on the server(s). This example will only use the ''​%%10.0.0.2%%''​ VM as a target machine. We must set up the configuration files to use password + the a One Time Password (OTP) generated by the authenticator. Make sure the configuration files for sshd and PAM look as below:
 +<code bash>
 +student@scgc:​~/​config-files$ grep -B 5 -A 3 '​pam_google_authenticator.so'​ sshd
 +# PAM configuration for the Secure Shell service
 +
 +# Standard Un*x authentication.
 +@include common-auth
 +# 2-FA authentication with Google Authenticator
 +auth       ​required ​    ​pam_google_authenticator.so
 +
 +# Disallow non-root logins when /​etc/​nologin exists.
 +account ​   required ​    ​pam_nologin.so
 +</​code>​
 +The changes to the PAM configuration file above make using the Google Authenticator module mandatory. It is placed after '​common-auth',​ so the code will be required **after** entering the password.
 +
 +<code bash>
 +student@scgc:​~/​config-files$ grep -B 5 -A 3 '​^ChallengeResponseAuthentication'​ sshd_config ​
 +#​PasswordAuthentication yes
 +#​PermitEmptyPasswords no
 +
 +# Change to yes to enable challenge-response passwords (beware issues with
 +# some PAM modules and threads)
 +ChallengeResponseAuthentication yes
 +AuthenticationMethods publickey keyboard-interactive
 +
 +# Kerberos options
 +</​code>​
 +The changes to the configuration file above make using the challenge response to allow PAM to use multiple modules with challenge responses (i.e., password and authentication code in our case); the use of keyboard-interactive authentication is mandatory if more than just the password is required.
 +
 +Ansible can use privilege escalation using the **become** keyword at certain tasks, or all tasks. If the user cannot run sudo with a password, the ''​%%ansible_become_password%%''​ variable must be set. To do this we will use a vault - a type of file that encrypts strings through a password - to store the password, instead of adding it as plain text to the playbook. To create a vault, use the following command, and write the key-value pair for the password in the file it opens using the default editor:
 +<code bash>
 +student@scgc:​~/​config-files$ ansible-vault create puppet.vault
 +New Vault password: # Enter vault password
 +Confirm New Vault password: # Confirm vault password
 +
 +# In the opened file
 +ansible_become_password:​ student
 +</​code>​
 +
 +After closing the vault, you can see that the information in it is encrypted.
 +
 +To install the SSH daemon on the remote machine, and set it up for use with the Google Authenticator we will use the following playbook, saved as ''​%%sshd.yaml%%'':​
 +<code yaml>
 +---
 +- hosts: remote
 +  remote_user:​ student
 +
 +  tasks:
 +  # include sudo password vault
 +  - name: Set host variables
 +    include_vars:​ "{{ ansible_facts.hostname }}.vault"​
 +
 +  # Install sshd and make sure it is at the latest version using the package
 +  # manager identified by ansible
 +  - name: Ensure sshd is at the latest version
 +    package:
 +      name: openssh-server
 +      state: latest
 +    become: yes
 +
 +  # Install google authenticator module and make sure it is at the latest version
 +  - name: Ensure google-authenticator is at the latest version
 +    package:
 +      name: libpam-google-authenticator
 +      state: latest
 +    become: yes
 +
 +  # Copy the google authenticator configuration file
 +  # The file MUST be located in the user's home directory with permissions 0600
 +  - name: Copy Google Authenticator config file
 +    copy:
 +      src: /​home/​student/​config-files/​.google_authenticator
 +      dest: /​home/​student/​.google_authenticator
 +      mode: 0600
 +      owner: student
 +      group: student
 +
 +  # Overwrite sshd configuration file. Make sure the challenge response setting
 +  # is enabled, and keyboard-interactive is a valid authentication method
 +  - name: Write the sshd configuration file
 +    template:
 +      src: /​home/​student/​config-files/​sshd_config
 +      dest: /​etc/​ssh/​sshd_config
 +    become: yes
 +    notify:
 +      - restart sshd
 +
 +  # Overwrite the PAM configuration file. Make sure that authentication through
 +  # google authenticator is required
 +  - name: Write the PAM configuration file
 +    template:
 +      src: /​home/​student/​config-files/​sshd
 +      dest: /​etc/​pam.d/​sshd
 +    become: yes
 +    notify:
 +      - restart sshd
 +
 +  handlers:
 +  # Handlers that are invoked when the configuration files change -
 +  # restart the sshd service
 +  - name: restart sshd
 +    service:
 +      name: sshd
 +      state: restarted
 +    become: yes
 +</​code>​
 +
 +The playbook attempts to include the file named ''​%%{{ ansible_facts.hostname }}.vault%%''​ - which resolves to ''​%%puppet.vault%%''​ for the VM. To run it, we use the ''​%%ansible-playbook%%''​ command, with the ''​%%--ask-pass%%'',​ to ask for the SSH authentication password, and the ''​%%--ask-vault-pass%%''​ to provide the decryption password for the vault.
 +<code bash>
 +student@scgc:​~/​config-files$ ansible-playbook --ask-vault-pass --ask-pass sshd.yml
 +SSH password:
 +Vault password:
 +
 +PLAY [remote] *********************************************************************
 +
 +TASK [Gathering Facts] ************************************************************
 +ok: [10.0.0.2]
 +
 +TASK [Set host variables] *********************************************************
 +ok: [10.0.0.2]
 +
 +TASK [Ensure sshd is at the latest version] ***************************************
 +ok: [10.0.0.2]
 +
 +TASK [Ensure google-authenticator is at the latest version] ***********************
 +changed: [10.0.0.2]
 +
 +TASK [Copy Google Authenticator config file] **************************************
 +changed: [10.0.0.2]
 +
 +TASK [Write the sshd configuration file] ******************************************
 +changed: [10.0.0.2]
 +
 +TASK [Write the PAM configuration file] *******************************************
 +changed: [10.0.0.2]
 +
 +RUNNING HANDLER [restart sshd] ****************************************************
 +changed: [10.0.0.2]
 +                                                                                                                                              ​
 +PLAY RECAP ************************************************************************
 +10.0.0.2 ​                  : ok=8    changed=5 ​   unreachable=0 ​   failed=0
 +</​code>​
 +
 +You should now be able to login using the password and the Google Authenticator.
 +<code bash>
 +student@scgc:​~$ ssh student@10.0.0.2
 +Password: ​
 +Verification code: 
 +Password: ​
 +Verification code: 
 +Linux puppet 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64
 +
 +The programs included with the Debian GNU/Linux system are free software;
 +the exact distribution terms for each program are described in the
 +individual files in /​usr/​share/​doc/​*/​copyright.
 +
 +Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
 +permitted by applicable law.
 +student@puppet:​~$ ​
 +</​code>​
 +
 +<note important>​
 +After adding two-factor authentication,​ Ansible will no longer be able to access the VM using password authentication,​ since the password is read by ansible before actually attempting to access the server, and ''​%%sshpass%%''​ is not aware it is required.
 +</​note>​
scgc/laboratoare/07.1586193622.txt.gz · Last modified: 2020/04/06 20:20 by darius.mihai
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0