Wednesday, April 7, 2021

Basic RAID Levels

1. RAID 0 (striping)
  - minimum of 1 disks
  - striping
  - no mirroring
  - excellent performance
  - no fault tolerance

2. RAID 1 (mirroring)
  - minimum of 2 disks
  - mirroring
  - no striping
  - good performance
  - excellent fault tolerance

3. RAID 5 (striping with + distributed parity)
  - minimum of 3 disks
  - striping with distributed parity
  - good performance and fault tolerance

4. RAID 10 (mirroring + striping)
  - minimum of 4 disk
  - striping with mirroring
  - excellent performance and fault tolerance
  - expensive

Tuesday, April 6, 2021

Setup NIC Bonding in Linux in Centos 6

1. create bond0 config file
# vi /etc/sysconfig/network-scripts/ifcfg-bond0
--- START EDIT ---
DEVICE=bond0
IPADDR=10.10.10.11
NETWORK=10.10.10.0
NETMASK=255.255.255.0
USRCTL=no
BOOTPROTO=none
ONBOOT=yes
--- END EDIT ---

2. edit the following files:
# vi /etc/sysconfig/network-scripts/ifcfg-eth0
--- START EDIT ---
DEVICE=eth0
MASTER=bond0
SLAVE=yes
HWADDR=00:0C:29:8D:FB:EF
TYPE=Ethernet
UUID=5606b424-2186-410d-9dbc-dcb65b330bd9
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=none
--- END EDIT ---

# vi /etc/sysconfig/network-scripts/ifcfg-eth1
--- START EDIT ---
DEVICE=eth1
MASTER=bond0
SLAVE=yes
HWADDR=00:25:B5:0B:B1:00
TYPE=Ethernet
UUID=6353d563-0a85-47d2-b566-37f6c91c8973
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=none
--- END EDIT ---

3. create bond module file
# vi /etc/modprobe.d/modprobe.conf
--- START EDIT ---
alias bond0 bonding
options bond0 mode=balance-alb miimon=100
--- END EDIT ---

4. restart network
# service network restart

Monday, April 5, 2021

RPM and Debian Package Managers

In this post, we will discuss the 2 common package managers in Linux. They are the following:

1. RPM-based - rpm,yum
2. Debian-based - dpkg,apt-get,dselect,aptitude,apt-cache

RPM

Examples of systems that uses RPM-based package managers are Red Hat, Fedora, and Centos. The "rpm" command is to install packages directly. It doesn't handle dependency requirements so you need to install the needed packages (if there is any) before installing the package you want. For example, if you want to install packageA but it needs packageB, you need to install packageB first before proceeding with packageA. Here are the common uses of "rpm" command.

* Installing/Upgrading *

rpm -i <filename.rpm>  # installs a package (install only if it doesn't exist)
rpm -ivh <filename.rpm>  # same as the above, but increases verbosity (-v) and hashes as progress indicator (-h)
rpm -ivh <filename.rpm> --force  # installs a package even if it exists (package reinstall)
rpm -Fvh <filename.rpm>  # freshens a package (upgrade a package if ONLY an older version exists)
rpm -Uvh <filename.rpm>  # installs a package if that doesn't exist or upgrade a package if it exists
rpm -ivh <filename.rpm> --nodeps  # installs a package ignoring dependency checking (use this with caution because the program you will install might not work)
rpm -i <package name> --test  # do a dry-run instead of installing actual package

* Removing *

rpm -e <filename> -- removes a package

* Querying *

rpm -qi <package name>  # queries a package (-q) by printing information (-i); takes only package name and not filename (file.rpm)
rpm -ql <package name>  # lists files associated in the package (-l)
rpm -qf <package name>  # shows you on what package the file/directory/script came from; example is rpm -qf $(which cp)
rpm -qi <package name> --change-log  # prints change log of the given package
rpm -qi <package name> --scripts  # prints scripts that ran when the package was installed
rpm -q[other query options]p file_name.rpm  # queries a package filename instead (-p) of package name; example is rpm -qip my-program.rpm

YUM

There is also an RPM-based tool that handles dependency conflicts automatically and that is YUM (Yellowdog Updater Modified). "yum" command is the one we used which can also do what "rpm" command can. This is the best package management tool to use if you are using the Linux distributions mentioned above. The main disadvantage of this is you need a repository before you can do any transactions whereas RPM don't. Repositories are the ones inside /etc/yum.repos.d directory and will be discussed on a separate post in this blog. YUM commands that are commonly used are:

* Installing/Upgrading *

yum install # installs a package or multiple packages
yum install <package name(s)> -y  # same as above but answers "y" to all installation questions
yum update  # updates all installed packages on the system
yum update <package name(s)>  # updates a single or multiple packages
yum localinstall <filename.rpm>  # installs a local rpm file using your yum repository to resolve dependencies

* Removing *

yum remove <package name(s)>  # removes packages and all packages where the package depends on
yum erase <package name(s)>  # same as above

* Querying *

yum list  # lists ALL installed packages and shows you if there is a newer version for each of those
yum list <package name> # lists installed packages and shows you if there is a newer version for that
yum list available <package name> # lists all available packages for update
yum search *pattern*  # searches all package names that contains the string; prints both installed and available packages
yum search all *pattern*  # deeper search compare to the above command (searches also contents not only package names)
yum provides <file/directory>  # shows what package owns the file/directory
yum whatprovides */<file/directory>  # use this when you don't get a result from the above command
yum info <package name>  # shows info on a package (similar to rpm -qi)
yum check-update  # checks whether there are updates available
yum --disablerepo=* --eablerepo=<repo ID> list <pacakge name>  # list package on a particular repo

DPKG

Aside from RPM-based systems, we also have Debian-based systems. Examples of these are Ubuntu and of course Debian. The package management tools they use are apt-get, aptitude, dselect, and dpkg. "apt-get" is similar to yum where you need a repository which is defined under /etc/apt/sources.lst, "dpkg" is similar to rpm, "dselect" is a menu based tool, and aptitude is a combination of dselect's menu based and apt-get's cli features. Debian packages by convention ends with .deb. Let's start with dpkg. Here are the common commands for dpkg.

* Installing/Upgrading/Configuring*

dpkg -i <package name>  # installs a package
dpgk -i <package name> --ignore-depends=<package>  # ignore dependency conflict (similar to --nodeps in rpm)
dpkg -i <package name> --no-act  # tests for dependency only (similar to --test in rpm)
dpkg -iG <package name>  # doesn't install a package if a newer version of same package is already installed
dpkg -iE <package name>  # doesn't install a package if same version of package is already installed

* Removing *

dpkg -r <package name>  # removes a package while retaining its configuration files
dpkg -P <package name>  # removes a package and configuration files

* Querying *

dpkg -P <package name>  # displays information about an installed package
dpkg -I <uninstalled package name>  # displays information about an uninstalled package
dpkg --get-selections  # displays current installed packages
dpkg -l <pattern>  # list installed packages matching the pattern string
dpkg -L <package name>  # lists files associated with the package (similar to rpm -ql)

One command that is very useful if you want to return the package to its original state (fresh install with default settings) is "dpkg-reconfigure". For example, the command below will reconfigure the samba package, asking the packages initial installation questions and restarting its daemons.

dpkg-reconfigure samba

APT-GET

Similar to yum , Debian-based systems have the tool called "apt-get" which automatically handle dependency conflicts. Before using it, make sure you have the appropriate sources inside /etc/apt/sources.lst. Here are the common usage of that command:

* Installing/Upgrading *

apt-get install <package name>  # installs a package
apt-get install <package name> -y  # installs a package assuming "y" to all questions
apt-get install <package name> -s  # doesn't install, simulates a dry-run
apt-get install <package name> --no-upgrade  # don't upgrade a package if an older version exists
apt-get install <package name> -d  # downloads a package but doesn't install it
apt-get install <package name> -s  # performs a simulation/dry-run without installing any package or configuring any file
apt-get install /path/to/deb/package -f  # installs a .deb package and resolves dependencies through APT repositories
apt-get update  # obtains information on available packages inside /etc/apt/sources.lst
apt-get upgrade  # upgrades all installed packages to newer versions
apt-get dist-upgrade  # similar to above command but performs "smart" conflict resolution

* Removing *

apt-get remove <package name>  # removes a package

* Configuring *

apt-get dselect-upgrade  # performs any changes in package status left undone after running deselect
apt-get clean  # performs housekeeping (like yum clean)
apt-get autoclean  # similar to the above command but removes about packages that can no longer be downloaded

* Querying *

apt-get check  # checks package database for consistency and broken package installations
apt-file search /path/to/file  # searches for package containing a file

APT-CACHE

We also have apt-cache. Its only purpose is to provide information about Debian package database. Here are sample commands:



apt-cache show <package name>  # displays descripion of package
apt-cache showpkg <package name>  # same as above but displays dependency information instead


apt-cache show <package name>  # displays descripion of package
apt-cache stats  # displays package statistics (how many installed, dependencies recorded, etc..)
apt-cache unmet  # displays information about unmet dependencies
apt-cache depends <package name>  #  shows on what packages the one you specified depend on
apt-cache pkgnames  # displays all installed packages
apt-cache pkgnames <string>  # displays list of installed packages matching the string specified

DSELECT

A menu-based package manager also exists for Debian-based systems. That is "dselect". When invoked, it will display you the following menu.

0. [A]ccess Choose the access method to use.
1. [U]pdate Update list of available packages, if possible.
2. [S]elect Request which packages you want on your system.
3. [I]nstall Install and upgrade wanted packages.
4. [C]onfig Configure any packages that are unconfigured.
5. [R]emove Remove unwanted software.
6. [Q]uit Quit dselect.

APTITUDE

A tool that combines dselect's menu based gui and apt-get's cli is "aptitude". Here are the common usage:

aptitude search <package name>  # searches packages related to the one you specified (apt-get seems not to have this feature)
aptitude update  # update package list from APT repository
aptitude install <package name>  # installs a package
aptitude install <package name>-  # removes a package (w/ leading dash)
aptitude remove <package name>  # same as above
aptitude full-upgrade  # upgrades all installed packages
aptitude safe-upgrade  # conservative version of the above command
aptitude autoclean  # removes already-downloaded packages that are no longer available
aptitude help  # shows complete options

Sunday, April 4, 2021

Setup NGINX Proxy

Once in a while there are applications that needs to run in unprivileged port
(ports above 1024). What can you do to protect its identity from attacks? Aha!
Use HTTPS.. But how? We can setup another host in front of it (proxy server) to
accept incoming requests via encrypted channel (HTTPS, port 443/tcp) and
redirect that to the backend server (or proxied host) via an uncrypted channel.
In this post, we will use Nginx to have that setup.

1. First, let's say we have VM01 that runs an application on port 8081.







2. Now, let's spin up another host, VM02 (Centos 7.3 w/ SELinux in enforcing
mode), and install Nginx. First, be sure that the nginx repo is enabled.

[root@vm02 ~]# cat /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/x86_64/
gpgcheck=0
enabled=1
[root@vm02 ~]#

3. Install nginx package.

[root@vm02 ~]# yum install -y nginx

4. Start and enable nginx at boot

[root@vm02 ~]# systemctl start nginx
[root@vm02 ~]# systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
[root@vm02 ~]#

5. Create selfsigned certificates. In this part, you may use `genkey` or
`openssl`. I always wanted the openssl way because its faster. BTW, don't
memorize the command below. Just be familiar with it because you can always see
it inside `/etc/pki/tls/certs/make-dummy-cert`

[root@vm02 ~]# /usr/bin/openssl req -newkey rsa:2048 -keyout vm02.key -nodes -x509 -days 365 -out vm02.crt
Generating a 2048 bit RSA private key
.........+++
..........................................................................................+++
writing new private key to 'vm02.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:California
Locality Name (eg, city) [Default City]:Los Angeles
Organization Name (eg, company) [Default Company Ltd]:dummy
Organizational Unit Name (eg, section) []:dummy
Common Name (eg, your name or your server's hostname) []:vm02
Email Address []:dummy@nxdomain.com
[root@vm02 ~]#

6. Move the certificates to the correct paths and run `restorecon` to make sure
SELinux contexts are correct.

[root@vm02 ~]# mv *crt /etc/pki/tls/certs
[root@vm02 ~]# mv *key /etc/pki/tls/private/                                                                                                                                                                [root@vm02 ~]# restorecon -Rv /etc/pki/tls/
restorecon reset /etc/pki/tls/certs/vm02.crt context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:cert_t:s0
restorecon reset /etc/pki/tls/private/vm02.key context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:cert_t:s0
[root@vm02 ~]#

7. Update nginx configuration to use SSL, point to the correct certificates
(ssl_certificate_*), and activate reverse proxy (proxy_pass). We will just use
the default config and use the minimal directives needed for simplicity.

[root@vm02 ~]# cat /etc/nginx/conf.d/default.conf
server {
    listen       443;
    server_name  vm02;
    ssl on;
    ssl_certificate /etc/pki/tls/certs/vm02.crt;
    ssl_certificate_key /etc/pki/tls/private/vm02.key;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location / {
        proxy_pass   http://vm01:8081;
    }
}
[root@vm02 ~]#

8. Open up port 443/tcp on the firewall to allow incoming connections. You may
use firewall-cmd's "--add-service" or "--add-port". Let's use "--add-service"
since there is already an existing service defined for HTTPS.

[root@vm02 ~]# firewall-cmd --add-service=https --permanent
success
[root@vm02 ~]# firewall-cmd --reload
success
[root@vm02 ~]#

9. Activate this SELinux boolean to allow HTTP to forward requests to our
upstream server (VM01).

[root@vm02 ~]# setsebool -P httpd_can_network_connect on
[root@vm02 ~]#

10. Now, our proxy server is ready. Let's try connecting. It must display the
data from the upstream like in #1.







So that are the basics steps in hiding your application via a proxy server.
This is very important if your application accepts user details like username
and passwords. You never want your credentials to be sent in cleartext!

Hope you learned something from this post :)

Saturday, April 3, 2021

Building an RPM package

INTRODUCTION

  In this post, I will teach you how to create an RPM package from a source code. This tutorial assumes that
you already have the tarballed source code ready to be unpacked.

  As an example in our previous post about mrepo, we have installed it from source and not by using RPM
so that is a perfect way to demomstrate the RPM creation.

1. Install the needed packages
yum install -y rpm-build rpmdevtools
# rpm-build is required which contains "rpmbuild" command
# rpmdevtools is optional which is helpful in creating the directory tree


2. Create the directory tree
rpmdev-setuptree
# that command will create /root/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}


3. Copy the tarballed source file to SOURCES
cp mrepo-0.8.7.tar.bz2 /root/rpmbuild/SOURCES/


4. Copy the spec file to SPECS. It is usually included inside the tarball so unpack the tarball to /tmp first then
get the spec file from there.
tar xvf mrepo-0.8.7.tar.bz2 -C /tmp
cp /tmp/mrepo-0.8.7/mrepo.spec /root/rpmbuild/SPECS


INFO: A spec file describes the software and contains instructions on how to install the software. Creation
and detailed discussion of a spec file is not covered in this post but I might create one soon.

5. Now create the RPMs (src and binary)
rpmbuild -ba /root/rpmbuild/SPECS/mrepo.spec
# that command will create the following files
#  /root/rpmbuilds/RPMS/noarch/mrepo-0.8.7-1.noarch.rpm -> the actual rpm you can install
#  /root/rombuild/SRPMS/mrepo-0.8.7-1.src.rpm -> contains the original source code and the spec file


6. Validate by installing the rpm
rpm -ivh /root/rpmbuild/noarch/mrepo-0.8.7-1.noarch.rpm


SOURCES

Other tutorials:
http://www.tldp.org/HOWTO/RPM-HOWTO/build.html
http://www.thegeekstuff.com/2015/02/rpm-build-package-example/

Friday, April 2, 2021

Understanding Linux load average

We often hear the term “load average” but how much do we know about it? In this post, I will try my best to explain in the fewest letters everything we need to know about load average.


First, how do we determine the load average? We can use commands like uptime and top. Both will present you 3 values.


bash-3.2$ uptime
 03:46:39 up 703 days, 11:00,  2 users,  load average: 3.04, 3.10, 3.08
bash-3.2$


From the output above, 3.04, 3.10, and 3.08 is the load average for the past 1, 5, and 15 minutes respectively. You may also use “cat procloadavg” and will get same result for the 1st 3 columns.


Now, what is LOAD AVERAGE? It is the average of all cpu loads on your system.


What is a CPU LOAD? It is the NUMBER of processes using + NUMBER of processes in queue for a single cpu core. It is NOT the CPU usage.


What is CPU USAGE? It tells us how active is your cpu cores.


To determine CPU LOAD on each cpu core, we follow these 2 formulas:


load per cpu core = (load average) / (# of cpu cores)

load per cpu core = (processes using the cpu core) + (processes inqueue for that cpu core)


where:

load average = the one reported in procloadavg, uptime, top, etc ..

# of cores = grep -c ^proc proccpuinfo


To better illustrate, look at the scenarios below for a 1-core and 2-core machine.


1-core machine (CPU A only):


0 process using CPU A = load average of 0 (under capacity)

1 process using CPU A = load average of 1 (at max capacity)

1 process using CPU A, 1 process waiting in line = load average of 2 (overcapacity)

1 process using CPU A, 2 process waiting in line = load average of 3 (overcapacity)

… and so on ..


2-core machine (CPU A and CPU B):


0 process using CPU A, 0 process using CPU B = load average of 0 (under capacity)

1 process using CPU A, 0 process using CPU B = load average of 0.5 (under capacity)

1 process using CPU A, 1 process using CPU B = load average of 1 (max capacity)

1 process using CPU A, 1 process using CPU B, 1 processes waiting in line = load average of 1.5 (slightly overcapacity)

1 process using CPU A, 1 process using CPU B, 2 processes waiting in line = load average of 2 (overcapacity)

… and so on ..


Based from the examples above, a load average of 1 means all of your cpu cores are at max capacity. Load average of 2 means each cpu core has 1 process running and 1 process waiting in line.


There are instances where your load average is high but the CPU usage is low. An example is when you have several hunged processes occupying all your cpu cores. Sinced hunged, those processes doesn’t generate CPU activity but they still hold the CPU cores. When all CPU cores are being held, no other processes can use them. So if processes can’t get hold of the CPU, this can slow down your system.


In short, a system with LOW CPU USAGE but with HIGH LOAD AVERAGE can still slow down your system.

Thursday, April 1, 2021

SSL (Secure Sockets Layer)

What is SSL?


SSL stands for Secure Sockets Layer, a protocol developed by Netscape in 1994.
It provides a secure way of communication between computer systems by scrambling
the data to make it difficult to read while traversing the network.

Symmetric vs Asymmetric Key Cryptography


Before we learn how SSL process work, we must understand the 2 major
cryptographies used.

Symmetric Key Cryptography

  This is also known as Secret Key Cryptography. Both communicating parties uses
  same key in decrypting and encrypting data. The cryptographic algorithm to use
  in encrypting and decrypting data must be agreed by both ends. Example of
  these are Data Encryption Standard (DES), Triple-Strength DES (3DES), Rivest
  Cipher 2 (RC2), and Rivest Cipher 4 (RC4). Decryption/encryption of data is
  quick but transferring the secret/symmetric key to both ends can be
  intercepted by an attacker.

Asymmetric Key Cryptography

  This is also known as Public Key Cryptography. This make use of a private and
  public key to encrypt/decrypt data. Private key must never be shared to others
  while public key can be shared. If a data is encrypted using the private key,
  the data can be decrypted using its corresponding public key (and vice-versa).
  Some well known public key algorithms are Rivest Shamir Adleman (RSA) and
  Diffie-Hellman (DH) algorithm. Using this kind of cryptography requires more
  processing power which makes it slow. This is the reason why we only use this
  in ecnrypting small pieces of data like the symmetric key.

In the next sections, we will see how these 2 takes place in SSL handshake.

But first, here are some few items that are worth reading.

|  Terminology  |                           Definition                          |
|---------------|---------------------------------------------------------------|
| cipher suite  | A set if cryptographic algorithms and key sizes used that a   |
|               | computer can use to encrypt data. A cipher suite typically    |
|               | consists of respective algorithms used for key exchange,      |
|               | authentication, bulk encyrption, and Message Authentication   |
|               | Code (MAC). For in depth discussion on cipher suites, I will  |
|               | provide another post right after this.                        |
|---------------|---------------------------------------------------------------|
| cryptographic | These are math functions that aims to scramble data to hide   |
| algorithm     | its contents. 2 major types are Symmetric (uses 1 key) and    |
|               | Asymmetric (uses public and private keys) and different kinds |
|               | exists under those categories. E.g Symmetric has RC and DES   |
|               | while Asymmetric can be RSA or DH.                            |
|---------------|---------------------------------------------------------------|
| ciphertext    | This is another name for encrypted data. The opposite is      |
|               | the unencrypted data or cleartext.                            |
|---------------|---------------------------------------------------------------|


The fun part: SSL Protocol in depth


Here is a more detailed explanation on what is happening in the background.

|             CLIENT            |     |             SERVER             |
|-------------------------------|-----|--------------------------------|
| Client Hello                  | --> |                                |
|-------------------------------|-----|--------------------------------|
|                               | <-- | Server Hello                   |
|-------------------------------|-----|--------------------------------|
|                               | <-- | Certificate                    |
|-------------------------------|-----|--------------------------------|
|                               | <-- | Server Key Exchange (optional) |
|-------------------------------|-----|--------------------------------|
|                               | <-- | Server Hello Done              |
|-------------------------------|-----|--------------------------------|
| Client Certificate (optional) | --> |                                |
|-------------------------------|-----|--------------------------------|
| Client Key Exchange           | --> |                                |
|-------------------------------|-----|--------------------------------|
| Change Cipher Spec            | --> |                                |
|-------------------------------|-----|--------------------------------|
| Finished                      | --> |                                |
|-------------------------------|-----|--------------------------------|
|                               | <-- | Change Cipher Spec             |
|-------------------------------|-----|--------------------------------|
|                               | <-- | Finished                       |
|-------------------------------|-----|--------------------------------|
| encrypted data                | <-> | encrypted data                 |
|-------------------------------|-----|--------------------------------|


Let's focus on the required steps below leaving off the optional ones with some
few details.

Client Hello

  Client (in this case a browser like google chrome) initiates the connection by
  going to a secure site (URL starting in https://). At this moment, SSL is
  triggered automatically. Client sends the server (system on where the site is
  hosted) 4 important information - cipher suite it can use for both symmetric
  and asymmetric key encryptions, the SSL version it wish to use, session ID,
  and compression method.

  Protocol Version   - Version of SSL the client wants to use
  Session ID         - Session identifier the client wants to use. The 1st
                       client hello is always empty for every new sessions.
  Cipher Suite       - Contains list of cryptographic algorithms supported by
                       the client (in order of preference). The server selects
                       from these choices. If nothing is selected, server will
                       return a handshake failure.
  Compression Method - List of compression algorithms supported by the client.
                       If server doesn't support any method listed, connection
                       will fail.
             
  Here is an actual packet capture of Client Hello message from wireshark.


Server Hello

  The server now responds back to the client with the following information
  below.

  Protocol Version   - Vesion of SSL that is supported by the server and the
                       client. Server will choose the lowest version that match
                       e.g client supports 2.0 while server supports up to 3.0,
                       server will choose 2.0.
  Session ID         - This is the session identifier. If the session ID sent by
                       the client is not empty, server will look for it in its
                       cache then will try to reuse it. That means that the
                       client wishes to reuse an existing session instead of
                       opening a new one. Otherwise, this will contain another
                       value which will identify this new session.
  Cipher Suite       - This is the chosen cipher suite from the list provided by
                       the client.
  Compression Method - Similar to the previous which is chosen from the list
                       provided by the client.


Certificate

  If the server has a certificate, which is the usual scenario, it will send the
  client a list of certificates it has. The certificate must be appropriate for
  the selected cipher suite.


Server Key Exchange (optional)

  This is only sent if the server has NO certificate which is unusual for an
  HTTPS connection.


Server Hello Done

  This is pretty much a blank message indicating that the server is done sending
  the required information.


Client Certificate (optional)

  This is the 1st message sent by the client after it receives the Server Hello
  Done. However; this is only sent when the server requests a certificate from
  a client which is uncommon on web communications. Some cases where this is
  used is when an organization establishes a secure communication to another one
  which requires authentication.

Client Key Exchange

  This depends on the public key algorithm agreed, which is found inside the
  cipher suite, between both parties. If Diffie-Hellman is agreed, the packet
  will look like this:



  Otherwise, if RSA was chosen, client will generate a PreMaster secret, encrypt
  it using the server's public key, and send to the server. The server will
  decrypt it using its private key. Both parties now have the PreMaster and will
  generate a master key off that. For the purpose of this post, let's say RSA
  was chosen as the public key cryptography. The corresponding packet capture
  for RSA is:



Change Cipher Spec (client/server)

  This message signals the transition from Public (Asymmetric) key to Secret
  (Symmetric) Key cryptography. But why are we doing this? We know that
  Assymetric is resource intensive compared to Symmetric based from the initial
  discussions above. So in order not to degrade performance, we will use
  Symmetric Key Cryptography throughout the data exchange. What happens here is
  that the client copies the new Cipher Spec (pending) to the current Cipher
  Spec (the one to be replaced). This message is encrypted by the current Cipher
  Spec. When both parties receives each others Cipher Spec, they will copy the
  read pending state into the read current state.


Finished (client/server)

  This is sent right after the Client Key Exchange and is the first protected
  message by the most recent Cipher Spec chosen. There's no acknowledgement
  needed on both parties after they received this message and secure data
  exchange can now start.