Docker – Quick Reference

A quick reference guide to common Docker commands.

# to pull a container image
docker pull nginx

# to make container - persistant container that mounts conf and webroot
docker run --name repo-nginx -p 80:80 --restart unless-stopped -v /data/scratch/repo-nginx:/usr/share/nginx/html -v /data/docker/repo-nginx/default.conf:/etc/nginx

# Remove all stopped containers
docker system prune -f

#to all list containers
docker ps -a

#to list active containers
docker ps

# to start
docker start <container name>

# to stop
docker start <container name>

# to remove
docker rm <container name>

# if you are having issues with a container - views last 50 log entries
docker logs --tail 50 --follow --timestamps <container name>

# list docker networks
docker network ls

Ansible – Creating playbook that sets user password to vault stored variable

This will use ansible vault that allows the storage of sensitive information in an encrypted state within playbooks.

Step 1 – create password that is stored in ansible vault

mkdir -p ~/ansible/vault
touch ~/ansible/vault/N0s3kr1t
cd ~/ansible/vault

## encrypt secret file and prompts for a password 

ansible-vault encrypt N0s3kr1t

## run the following after installing passlib to create hash value of password:
pip install passlib
python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))"

example output: $6$T7vpO60Gvn478QzE$B7UXoVThsoBwFzWvrY5yFyLHsOVgw89QPC.uB1N6DPuCHZzQnfTcyCVg1Er/B/jkmApvvQbOJTHfwEVQlEFik.

## add password to vault file 
ansible-vault edit N0s3kr1t

## N0s3kr1t file contents after edit - adjust to your requirements
userName: greplog
userPass: $6$T7vpO60Gvn478QzE$B7UXoVThsoBwFzWvrY5yFyLHsOVgw89QPC.uB1N6DPuCHZzQnfTcyCVg1Er/B/jkmApvvQbOJTHfwEVQlEFik.

Step 2 – create playbook that changes user’s password to stored value

## make changePassword.yml  - located in ~/ansible
---
- hosts: devSys
  vars_files:
  - vault/N03kr1t
  tasks:
  - name: update user password
    user: 
      name: "{{userName}}"
      update_password: always
      password: "{{userPass}}"

Step 3 – run playbook

# Option 1 - prompt for pass at playbook run
ansible-playbook changePassword.yml --ask-vault-pass
# Option 2 - uses password file - this is stored plain txt (not nearly as secure)
ansible-playbook changePassword.yml --vault-password-file ~/.pwd

Vagrant setup – centos7 / docker

# install docker
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce

# configure docker
systemctl enable docker
systemctl start docker

# configuring current user in docker group
sudo usermod -aG docker $(whoami)


# install vagrant
yum install -y https://releases.hashicorp.com/vagrant/2.2.3/vagrant_2.2.3_x86_64.rpm

Vagrant – VagrantFile

VagrantFile is in ruby syntax. This is configuration that is used when vagrant creates vms. If no directory is given vagrant will mount vagrant folder as shared folder between host and container/vm .

To setup custom sync folder

Vagrant.configure("2") do |config|
  config.vm.box = 'centos/7'
  # configures synced folder
  config.vm.synced_folder "./content", "/vagrant"
end 

To setup multi VMs in one vagrant file

Vagrant.configure("2") do |config|

  config.vm.define "web" do |web|
    web.vm.box = "centos/7"
  end

  config.vm.define "db" do |db| 
    db.vm.box = "centos/7"
  end
end

To create and start up VMs

cd to the folder you hace your VagrantFile in and run the following command:

vagrant up

These are really simple configuration files but can get complex fast with network / provider config. Virtualbox is the easiest to use. Libvirt seems to take the most tweaking especially with networks.

Vagrant boxes

Vagrant boxes are preconfigured images that can be downloaded from vagrant to create your own homogeneous test environment across multisystems and platforms.

using vagrantup to get boxes

you can download vagrant boxes (image) from vagrantup.com or create your own use version control if developing your own

#vagrant box commands

vagrant box add <URL>
vagrant box list
vagrant box remove <name>
vagrant box update # you must destroy and recreate if you want to use it

vagrant init centos/7  # creates Vagrantfile with box centos/7

creating basebox

  • Virtualbox – – hdd as vmdk – install ISO – disable audio and usb –
    setup port forward ssh 2222 22

  • create users – vagrant/vagrant and root/vagrant and setup
    /etc/sudoers.d/vagrant

  • copy key from
    https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant.pub
    authorized_keys for vagrant user

  • modify sshd AuthorizedKeysFiles %h/.ssh/authorized_keys

  • install guest tools vm

  • clear up free space – dd if=/dev/zero of=/EMPTY bs=1M rm -r /EMPTY

on host machine – To package and add to boxes

 vagrant package --base <my-virtual-machine>
 vagrant box add <my-virtual-machine> package.box

Vagrant Overview

Vagrant builds and manages VM environment which allows multi vms to be configured at once and then destroyed and recreated again before you can manually setup one vm.

Vagrant uses already configured images to deploy thus speeding up deployment time.You have the option to make your own box but there are loads of pre-made images that are regularly updated.

Vagrant interfaces with providers (Docker/VirtualBox/hyperv) and allows provisioning tools(Chef, Puppet, Ansible, shell scripts) to be ran when the Vm is created.

Other custom plugins can be used to allow additional providers to be used.

Basic Commands

# initializes current directory as vagrant environment (creates Vagrantfile)
vagrant init 

# create and configs VM
vagrant up

# halts VM 
vagrant halt

# destroys VM
vagrant destroy

# validate Vagrantfile
vagrant validate

# runs configured provisioners 
vagrant provision

# status 
vagrant status

### ssh into vagrant vm 
vagrant ssh
# or the equivalent ssh  
ssh vagrant@localhost -p2222 -i ~/.vagrant.d/insecure_private_key  # vagrant is the password

### ssh config of vagrant 
vagrant ssh-config

RHCA – Ansible Automation – Exam 407 – Use Ansible Vault in playbooks to protect sensitive data

Ansible vault allows for sensitive information to be stored encrypted within playbooks.

This section I recommend making some playbooks that uses vault. Such as make user and assign password. Store ssh key as ansible vault.

ansible vault – using external file:

# to encrypt file
ansible-vault encrypt <file>

# to edit file - this will use a vi to edit the file - will prompt for password
ansible-vault edit <file>

# to view the file
ansible-vault view <file>

# to decrypt file
ansible-vault decrypt <file>

# Example vault file:
usrName: greplog
## create password hash with:
## pip install passlib && python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))" 
usrPass: $6$rXCmdaG602DrbL5u$jr.2icdj3a559OOaMHU4Q4rhwmwlj3pNG0ngdyEP9UOlVfH5Wa1aO2X7Wkr03uQ10ir8nAT0swECgQT4zudr2/


# To reference external file, secure, from playbook: 
---
- hosts: localhost
  vars_files:
  - vault/secure
  tasks:
  - name: update user password
    user: 
      name: "{{usrName}}"
      update_password: always
      password: "{{usrPass}}"

ansible vault – in-line:

# to encrypt a var in-line - will ask for input to enter your string  
ansible-vault encrypt_string -p -n SecretVar   

To run playbook that uses vault use:

## providing only a single vaule

# prompt for pass
ansible-playbook site.yml --ask-vault-pass
# uses password file
ansible-playbook site.yml --vault-password-file ~/.pwd



## to use specify multi vaults password files

# To run a play with encrypted file (prod and dev) with password prompt
ansible-playbook test.yml --vault-id prod@prompt --vault-id dev@prompt

git-guide

git – Version control system (VCS)

git Workflow – 3 trees – From the working directory files are added to the index that are then committed to the HEAD.

1.  working directory: actual files 
2.  index : staging are
3.  HEAD : points to last commit

Basic commands

## To create repo 
git init  

## To Check out/clone repo
git clone <username>@<host>:/path/of/repo


## add and commit changes
## To add single file
git add <filename>  

## To add all changed/new files
git add .

## To add commit
git commit -am "Tell of the changes made since last commit"

## Adding local repo to remote server
git remote add origin <URL-of-.git>

## pushing changes
git push origin master

## after the first push you can use:
git push


## pull updates from repo
git pull origin master

## replace local changes
git checkout -- <filename> # changes already added to index and new files will be kept

## To drop all local changes and commits
git fetch origin
git reset --hard origin/master


## to show changes
git show
git diff

RHCE – Network service – HTTP/HTTPS

Install the packages needed to provide the service

# installs apache webserver
yum install httpd 

Configure SELinux to support the service

## Common file context types ##
# static website folders
httpd_sys_content_t
# dynamic website folders - where writes need to occur via apache user
httpd_sys_rw_content_t
# cgi folder
httpd_sys_script_exec_t
# httpd config
httpd_config_t
# httpd logs
httpd_log_t
# to see all options use
semanage fcontext --list | grep httpd

## common - sebools ##
# running cgi scripts
httpd_enable_cgi
httpd_enable_ftp_server 
# enable use of homedirs for site roots
httpd_enable_homedirs
# to see all 


## SELinux configure ports - next section.

Use SELinux port labeling to allow services to use non-standard ports

# shows the default ports for http
semanage port -l | grep http

# step 1 - modify config to use an alternate port
Listen 1080

# step 2 - Configure SELinux to use alternate port
# you have 2 options here you can just use 

    # option 1 - try to access site via alternate port then run the following
    sealert -a /var/log/audit/audit.log
    # this should return Plugin bind_port error and give you the command to run ( option2)

    # option 2 - remember the following command 
    semanage port -a -t http_port_t -p tcp 1080

Configure the service to start when the system is booted

# enables httpd at boot 
systemctl enable httpd

Configure the service for basic operation

# starts httpd service
systemctl start httpd 

# firewall configuration
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

# browse to hostname/ip to make sure you see the welcome page from apache

Configure host-based and user-based security for the service

# host-based - firewall
## add firewall rule to allow http(s) access
firewall-cmd --permanent --add-service={http,https}

## require all section of /etc/httpd/conf/httpd.conf
<RequireAll>
# to add a host with permission to access 
Require host <hostname>
# to reject host 
Require not <hostname>
</RequireAll>
#####################################################

# user-based - virtual host config
see below - Configure access restrictions on directories

Configure a virtual host

# Step 1 - add file to /etc/httpd/conf.d/<vhostname.conf>
# vhosname.conf
<VirtualHost *:80>
    DocumentRoot "/www/example2"
    ServerName www.example.org
    # Other directives here
</VirtualHost>


# Step 2 - restart httpd service
systemctl restart httpd

Configure access restrictions on directories

# step 1 - make directory and add index.html
mkdir /var/www/html/restricted
echo "You have entered a restricted zone" > /var/www/html/restricted/index.html
restorecon -Rv /var/www/html/restricted

# step 2 - add configuration for /var/www/html/restricted/ - in /etc/httpd/conf/httpd.conf or /etc/httpd/conf.d/<file.conf>
<Directory "/var/www/html/restricted">
  AuthType Basic
  AuthName "Password protected area"
  AuthUserFile /etc/httpd/conf/passwd
  # require user
  Require user unrestrictedusr
  # require host - note you can also limit access via host as well
  # Require host lab.dev
</Directory>

# step 3 - create passwd file and adjust permissions
htpasswd -c /etc/httpd/conf/passwd unrestrictedusr
chmod 600 /etc/httpd/conf/passwd
chown apache:apache /etc/httpd/conf/passwd

# step 4 - check config and restart httpd
apachectl configtest
systemctl restart httpd 

# step 5 - verify you can authenticate with your password or hostname
open up browser or use curl (curl -u unrestrictedusr:pword http://127.0.0.1/restricted)

Deploy a basic CGI application – Not completed

# step 1 - add script in cgi-bin
#/var/www/cgi-bin/test.py

# step 2 - turn on httpd_enable_cgi 
setsebool httpd_enable_cgi on

# step 3 - test by browsing to the site
<site>/cgi-bin/<name>

Configure group-managed content

# mkdir for group and restore context
mkdir /var/www/html/<groupName>
restorecon -Rv /var/www/html/<groupName>

# add to /etc/httpd/conf/httpd.conf
<Directory "/var/www/html/<groupName>">
AuthType Basic
AuthName "Password protected area"
AuthGroupFile /etc/httpd/conf/<groupName>
AuthUserFile /etc/httpd/conf/passwd
Require group <groupName>
</Directory>

# /etc/httpd/conf/<groupName> 
team: <usr1> <usr2>

# config pwd for users
htpasswd -c /etc/httpd/conf/passwd <usr(1/2)>

# test then restart service    
apachectl configtest
systemctl restart httpd

Configure TLS security

# open ports
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

# generate cert
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout mysitename.key -out mysitename.crt

#  Add as .conf file /etc/httpd/conf.d  
<VirtualHost 443>
DocumentRoot /var/www/website
ServerName yourdomain.com
SSLEngine on
SSLCertificateFile /etc/ssl/crt/mysitename.crt
SSLCertificateKeyFile /etc/ssl/crt/mysitename.key
</VirtualHost> 

# test then restart service 
apachectl configtest
systemctl restart httpd

RHCE – Database Services

Install and configure MariaDB

# install / configure MariaDB #
yum groupinstall mariadb
systemctl start mariadb
systemctl enable mariadb

# configure MariaDB - complete the wizard - sets up root pwd and other security settings #
## root password / anon user / disable remote root login /  remove test db / reloads privilege tables ##
mysql_secure_installation  

# configure bind address in /etc/my.cnf #
## place at the bottom of [mysqld] block in /etc/my.cnf ##
bind-address=10.0.0.250

# configure firewalld - if remote connection are required #
firewall-cmd --permanent --add-service=mysql
systemctl restart firewalld

# basic usage #
## log in as root local
mysql -u root -p

## log in as root via network
mysql -u root -p'password' -h <DBhostname> 

## show available dbs
show databases;

## select db to use
use <databaseName>;

## to show tables of selected database  
show tables;

## to quit
quit

Backup and restore a database

## Backup single DB
mysqldump -u root -p'password' -h <hostname> <DBName> > <DBname>.sql

## Backup multiple DB
mysqldump -u root -p'password' -h <hostname> --databases <DBName1> <DBName2> > <DBname>.sql

## Backup all DBs
mysqldump -u root -p'password' -h <hostname> --all-databases > <DBname>.sql

## restore DBs
# note the DB you are restoring must have an empty DB with the same name to restore too. 
# This only applies to when a single DB is restored
mysql -u root -p'password' -h <hostname> <DBName> < DB_Name.sql

Create a simple database schema

# to create DB
create database <DBname>;

# to create User
CREATE USER <user>@localhost IDENTIFIED BY '<userPwd>';

# grant permission to user
grant all on test.* to <user>@localhost identified by '<userPwd>';
flush privileges;

# to select DB
use <DBname>;

# to create table
create table <TableName> (<fieldName1> VARCHAR(50) NOT NULL, <fieldName2> VARCHAR(50));

# to show tables
show tables;

# to get schema 
describe <TableName>

# to insert data into database
insert into <tableName>  (<fieldName1>,<fieldName2>) values ("<fieldName1Value>","<fieldName2Value>");

# to update data in database
update <tableName> set <fieldName1>=<newFieldName1> where <fieldName1>= "<fieldName1Value>";

Perform simple SQL queries against a database

select <fieldName> from <tableName> where <FieldName>=<FieldNmaeValue>;