Technologist

Tech stuff about Cloud, DevOps, SysAdmin, Virtualization, SAN, Hardware, Scripting, Automation and Development

In this post I will go over the installation and usage of the AWS CLI to deploy EC2 machines, also combined with AWS user-data to automate actions/scripts that will run on the EC2 machines at install time.

Install the AWS CLI
You can install the AWS CLI in many ways (e.g. zip file, brew, PIP, etc) for details you can follow http://docs.aws.amazon.com/cli/latest/userguide/installing.html
I will install via the Python package manager (PIP) inside a virtual environment

Create virtual environment

$ virtualenv env
New python executable in env/bin/python2.7
Also creating executable in env/bin/python
Installing setuptools, pip…done.

Activate virtual environment

$ source env/bin/activate

Install the awscli

$ pip install awscli
Collecting awscli
Downloading awscli-1.10.53-py2.py3-none-any.whl (970kB)
100% |################################| 970kB 582kB/s
Collecting botocore==1.4.43 (from awscli)
Downloading botocore-1.4.43-py2.py3-none-any.whl (2.5MB)
100% |################################| 2.5MB 206kB/s
Collecting s3transfer<0.2.0,>=0.1.0 (from awscli)
Downloading s3transfer-0.1.1-py2.py3-none-any.whl (49kB)
100% |################################| 49kB 1.4MB/s
Collecting rsa<=3.5.0,>=3.1.2 (from awscli)
Downloading rsa-3.4.2-py2.py3-none-any.whl (46kB)
100% |################################| 49kB 6.2MB/s
Collecting colorama<=0.3.7,>=0.2.5 (from awscli)
Downloading colorama-0.3.7-py2.py3-none-any.whl
Collecting docutils>=0.10 (from awscli)
Downloading docutils-0.12.tar.gz (1.6MB)
100% |################################| 1.6MB 312kB/s
Collecting jmespath<1.0.0,>=0.7.1 (from botocore==1.4.43->awscli)
Downloading jmespath-0.9.0-py2.py3-none-any.whl
Collecting python-dateutil<3.0.0,>=2.1 (from botocore==1.4.43->awscli)
Downloading python_dateutil-2.5.3-py2.py3-none-any.whl (201kB)
100% |################################| 204kB 1.9MB/s
Collecting futures<4.0.0,>=2.2.0 (from s3transfer<0.2.0,>=0.1.0->awscli)
Downloading futures-3.0.5-py2-none-any.whl
Collecting pyasn1>=0.1.3 (from rsa<=3.5.0,>=3.1.2->awscli)
Downloading pyasn1-0.1.9-py2.py3-none-any.whl
Collecting six>=1.5 (from python-dateutil<3.0.0,>=2.1->botocore==1.4.43->awscli)
Downloading six-1.10.0-py2.py3-none-any.whl
Installing collected packages: six, pyasn1, futures, python-dateutil, jmespath, docutils, colorama, rsa, s3transfer, botocore, awscli
Running setup.py install for docutils
changing mode of build/scripts-2.7/rst2html.py from 644 to 755
changing mode of build/scripts-2.7/rst2s5.py from 644 to 755

Successfully installed awscli-1.10.53 botocore-1.4.43 colorama-0.3.7 docutils-0.12 futures-3.0.5 jmespath-0.9.0 pyasn1-0.1.9 python-dateutil-2.5.3 rsa-3.4.2 s3transfer-0.1.1 six-1.10.0

Verify installation (and review help documentation)

$ aws help

Configure the AWS CLI to use AWS credentials
You will need to provide an AWS Access Key ID and AWS secreate Access Key, these will map to a AWS user and the privileges this user have. The user can (probably should have) been created from the AWS console.

$ aws configure
AWS Access Key ID [****************XYYY]: XXXXXXXXYYY
AWS Secret Access Key [****************ZOOO]:ZZZZZZZOOO
Default region name [us-east-1]:us-east-1
Default output format [None]: json

The above will create a default configuration and set of credentials under ~/.aws/{config,credentials}

Launching an EC2 Instance from awscli

To connect to the EC2 instance you will need at least a SSH keypair and allow access to SSH into the EC2 instance

Create key pair

$ aws ec2 create-key-pair –key-name john-keypair –query ‘KeyMaterial’ –output text > ~/.ssh/john-keypair.pem

$ chmod 400 ~/.ssh/john-keypair.pem

Verify key existence

$ aws ec2 describe-key-pairs –key-name john-keypair
KEYPAIRS 03:eb:3a:d3:13:ba:d3:e3:03:13:b3:f1:43:83:cc:03:ec:d8:4b:43 john-keypair

Create a Security group that allows ingress SSH (tcp 22)

$ aws ec2 create-security-group –group-name allow_tcp_22 –description “Allow SSH”

sg-b1740cd5

// TAG it, I cannot stress enough how important it is to tag every resource with at least a Name

$ aws ec2 create-tags –resources sg-b1740cd5 –tags Key=Name,Value=allow_tcp_22

Add rules, for example: allow inbound (ingress) tcp port 22 to all (0.0.0.0/0)

$ aws ec2 authorize-security-group-ingress –group-id sg-b1740cd5 –protocol tcp –port 22 –cidr 0.0.0.0/0

Select the AWS AMI (aka template) you will use to clone and create your EC2 instance.

See your images (For example I have two Encrypted Ubuntu images) These are using output=text in ~/.aws/config, just to show you what that looks like as oposed to JSON.

$ aws ec2 describe-images –owners self
IMAGES x86_64 2016-07-30T13:16:39.000Z xen ami-a64403c2 /Encrypted Ubuntu Linux 14.04 (HVM) machine Encrypted Red Hat Enterprise Linux (HVM) False /dev/sda1 ebs simple available hvm
BLOCKDEVICEMAPPINGS /dev/sda1
EBS True True snap-bc158f41 10 gp2
IMAGES x86_64 2016-07-30T13:22:03.000Z xen ami-a74403c3 /Encrypted Ubuntu Linux 16.04 (HVM) machine Encrypted Red Hat Enterprise Linux (HVM) False /dev/sda1 ebs simple available hvm
BLOCKDEVICEMAPPINGS /dev/sda1
EBS True True snap-900aa0a1 10 gp2

Or see available images from Redhat

$ aws ec2 describe-images –owners 309956199498 –filters “Name=architecture,Values=x86_64” | grep RHEL-7.1
IMAGES x86_64 2015-02-26T16:27:33.000Z Provided by Red Hat, Inc. xen ami-a540a5e1 309956199498/RHEL-7.1_HVM_GA-20150225-x86_64-1-Hourly2-GP2 machine RHEL-7.1_HVM_GA-20150225-x86_64-1-Hourly2-GP2 309956199498 True /dev/sda1 ebs available hvm
IMAGES x86_64 2015-08-04T17:22:47.000Z Provided by Red Hat, Inc. xen ami-c1996685 309956199498/RHEL-7.1_HVM-20150803-x86_64-1-Hourly2-GP2 machine RHEL-7.1_HVM-20150803-x86_64-1-Hourly2-GP2309956199498 True /dev/sda1 ebs simple available hvm

Or even the images from Amazon, which are FREE – this is the one I will use

$ aws ec2 describe-images –owners amazon –filters “Name=root-device-type,Values=ebs” “Name=architecture,Values=x86_64” | grep ‘Amazon Linux AMI 2016’

IMAGES x86_64 2016-06-22T08:08:12.000Z Amazon Linux AMI 2016.03.3 x86_64 HVM GP2 xen ami-31490d51 amazon/amzn-ami-hvm-2016.03.3.x86_64-gp2 amazon machine amzn-ami-hvm-2016.03.3.x86_64-gp2 137112412989 True /dev/xvda ebs simple available hvm

Launch/Run the instance based on the chosen AMI (e.g. ami-31490d51)

$ aws ec2 run-instances –image-id ami-31490d51 –count 1 –instance-type m3.medium –key-name john-keypair –security-group-ids sg-b1740cd5

TAG IT

$ aws ec2 create-tags –resources i-e1aeaf54 –tags Key=Name,Value=JohnInstance1

Check its status

$ aws ec2 describe-instance-status –instance-ids i-e1aeaf54

Check its details

$ aws ec2 describe-instances –instance-ids i-e1aeaf54

Retrive from its details specifc information using jq (jq is a lightweight and flexible command-line JSON processor)

$ aws ec2 describe-instances –instance-ids i-e1aeaf54 | jq ‘.Reservations[].Instances[].PublicDnsName’

“ec2-54-183-59-200.us-west-1.compute.amazonaws.com”

Connect to the EC2 instance using your SSH key-pair

Destroy EC2 instance

$ aws ec2 terminate-instances –instance-ids i-e1aeaf54


Create EC2 instance with user data script

Now let’s create an EC2 instance that will be ready to serve a website, we will do that by adding user data content that installs a webserver and adds some content.

Notes:
Amazon EC2 limits the size of user-data to 16KB (This limit applies to the data in raw form, not base64-encoded form.)
You can download a larger script and run it, from S3 for example.
You can run any language that supports the shabang(#!) (e.g. Bash, Python, Ruby, Perl)

//user_data.sh

Launch/run instance with user-data:

$ aws ec2 run-instances –image-id ami-31490d51 –count 1 –instance-type m3.medium –key-name john-keypair –security-group-ids sg-b1740cd5 –user-data file://user_data.sh

TAG it

$ aws ec2 create-tags –resources i-e1aeaf54 –tags Key=Name,Value=JohnInstance

1

Get its public DNS name

$ aws ec2 describe-instances –instance-ids i-e974745c | jq ‘.Reservations[].Instances[].PublicDnsName’

“ec2-52-53-165-15.us-west-1.compute.amazonaws.com”

Connect to it

$ ssh -i ~/.ssh/john-keypair.pem ec2-user@ec2-52-53-165-15.us-west-1.compute.amazonaws.com

Verify that httpd is running and the right content is displayed

[ec2-user@ip-172-31-9-131 ~]$ curl http://localhost

Hello from i-e974745c

Troubleshooting: Check the /var/log/cloud-init-output.log file

[ec2-user@ip-172-31-9-131 ~]$ sudo tail /var/log/cloud-init-output.log

Extra:
To allow access to it from the public you will need to add a security group that allows ports 80 and 443.
You can create one as we did for the SSH access, or you can see if you already have a group.

Look at the descriptions of you security groups (this is why it is important to add good descriptions)
“allow SSH access”
“Allow SSH”
“Allow Web tcp 80 and 443 from 0.0.0.0/0”

Looks like “Allow Web tcp 80 and 443 from 0.0.0.0/0” will do the trick, let’s verify

$ aws ec2 describe-security-groups | jq ‘.SecurityGroups[2]’

Let’s add this security group (sg-a3672ac7) to our EC2 instance (i-e974745c)
// This does not append, you have to specify all groups, in this case I am adding the SSH and WEB security groups to the instance

$ aws ec2 modify-instance-attribute –instance-id i-e974745c –groups sg-b1740cd5 sg-a3672ac7

Verify that the instance has both security groups

$ aws ec2 describe-instances –instance-ids i-e974745c | jq ‘.Reservations[].Instances[].SecurityGroups[]’

You can now verify that the content is publicly available
awscli_userdata1

In a previous post I wrote about how to Create a custom Vagrant Box from scratch.

In this post I will walk through the usage of Packer to automate the creation of a CentOS 7 image that can be used in Vagrant or even vSphere.

Packer is a cool Hashicorp tool that helps you automate the creation of machine images.

You can download the project/git repo at https://github.com/parcejohn/packer-centos7

From their website:
“Packer is easy to use and automates the creation of any type of machine image. It embraces modern configuration management by encouraging you to use automated scripts to install and configure the software within your Packer-made images. Packer brings machine images into the modern age, unlocking untapped potential and opening new opportunities.”

I use Packer to continue the journey to Infrastructure As Code, where even my golden images/templates are automated and source controlled (on Git).

Requirements:

* Packer // I installed on Mac using $ brew install packer
* vagrant // I installed on Mac using $ brew install vagrant
* vmware fusion // I installed using $ brew cask install vmware-fusion
* CentOS 7 ISO file

Packer uses a JSON template file to orchestrate the image creation and there are different stages in the process, I will concentrate on the below three, but you should familiarize with all of them (https://www.packer.io/docs/basics/terminology.html)

Builders: Packer component to create a machine image for a single platform, in this case I will be using the VMware builder.
Provisioners: Packer component that installs and configures software within a running machine prior to that machine being turned into a static image. Example provisioners include shell scripts, Chef, Puppet, etc. I will be using the shell provisioner.
Post-Processors: Packer component that takes the result of the builder or another post-processor and process that to create a new artifact. Examples of post-processors are compress to compress artifacts, upload to upload artifacts, etc. I will be creating a Vagrant box as the artifact, and also demonstrate how to upload the image to vSphere.

It’s time to walk through the process of creating a CentOS 7 image using Packer.

1) Create directory structure
The http folder will host a kickstart file, Packer will use its built in web server to serve this kickstart file
The scripts folder will host the provisioning scripts that will define the machine

centos/
├── http
└── scripts

2) Populate with the following configuration files and scripts (the contents of these files are shown in the next steps)

centos/
├── centos-7.1-x64-vmware.json
├── http
│   └── ks.cfg
├── scripts
│   ├── base.sh
│   ├── cleanup.sh
│   ├── hgfs.sh
│   ├── vmware.sh
│   └── zerodisk.sh
├── template.json
└── vagrant_rsa_key

3) Create a SSH key pair, you will need this to login to the server to complete install and configuration

The Private Key will be part of the Kickstart and will be the key given to the created vagrant user
The Public Key will be in the Packer JSON template, to allow Packer to login to the machine

4) Create a Packer JSON Template file (template.json)

Packer Components/Sections:

Variables:
This is just to centralize variables that will be used by other components (e.g. Builder, provisioner, etc)
I can also set a variable to use Environment variables or command line provided values:
User provided values:
“iso_url”: “{{user iso_url}}”,

Environment variable values:
“iso_url”: “{{env ISO_URL}}”,

Builders:
Here is an array of builders and the needed parameters for each builder, in this case the only builder is of type vmware-iso.
Parameters and some comments about them.

Provisioners:
This section uses the shell provisioner and runs all of those scripts listed, which are located in the scripts folder.

Post-processor:
This section states that I want a vagrant box and I am giving it the name.

5) Kickstart file (should be http/ks.cfg based on the template.json file)
This is a minimal install of CentOS 7
Note: The private key (XXXX) given to the vagrant user, that is the key that we created in a previous step

6 ) Provisioning Scrips
Packer calls these scripts (from the JSON template) on the created machine before making it a template/image.

base.sh // Install basic packages

vmware.sh // Install VMTools, I separated this from base as I may want to call different scripts on a VirtualBox/etc builder.

hgfs.sh // For vagrant to work properly with folders

cleanup.sh // Clean up before converting to image

zerodisk.sh // This is so that the resulting box is as small as possible

7) Run Packer against the template.json file created earlier and watch it build the machine image

$ packer build -var ‘iso_url=/Users/john/iso/CentOS-7-x86_64-Minimal-1511.iso’ -only=vmware-iso template.json
vmware-iso output will be in this color.

==> vmware-iso: Downloading or copying ISO
vmware-iso: Downloading or copying: file:///Users/john/iso/CentOS-7-x86_64-Minimal-1511.iso
==> vmware-iso: Creating virtual machine disk
==> vmware-iso: Building and writing VMX file
==> vmware-iso: Starting HTTP server on port 8101
==> vmware-iso: Starting virtual machine…
vmware-iso: The VM will be run headless, without a GUI. If you want to
vmware-iso: view the screen of the VM, connect via VNC without a password to
vmware-iso: 127.0.0.1:5989
==> vmware-iso: Waiting 10s for boot…
==> vmware-iso: Connecting to VM via VNC
==> vmware-iso: Typing the boot command over VNC…
==> vmware-iso: Waiting for SSH to become available…
==> vmware-iso: Connected to SSH!
==> vmware-iso: Uploading the ‘linux’ VMware Tools
==> vmware-iso: Provisioning with shell script: scripts/base.sh
vmware-iso: + sed -i ‘s/^.*requiretty/#Defaults requiretty/’ /etc/sudoers



==> vmware-iso: Provisioning with shell script: scripts/zerodisk.sh
vmware-iso: + dd if=/dev/zero of=/EMPTY bs=1M
vmware-iso: dd: error writing ‘/EMPTY’: No space left on device
vmware-iso: 5488+0 records in
vmware-iso: 5487+0 records out
vmware-iso: 5754265600 bytes (5.8 GB) copied, 5.27091 s, 1.1 GB/s
vmware-iso: + rm -f /EMPTY
==> vmware-iso: Gracefully halting virtual machine…
vmware-iso: Waiting for VMware to clean up after itself…
==> vmware-iso: Deleting unnecessary VMware files…
vmware-iso: Deleting: output-vmware-iso/564de113-2fc5-2010-8e5d-63fec92f12f7.vmem
vmware-iso: Deleting: output-vmware-iso/packer-vmware-iso.plist
vmware-iso: Deleting: output-vmware-iso/vmware.log
==> vmware-iso: Cleaning VMX prior to finishing up…
vmware-iso: Unmounting floppy from VMX…
vmware-iso: Detaching ISO from CD-ROM device…
vmware-iso: Disabling VNC server…
==> vmware-iso: Compacting the disk image
==> vmware-iso: Running post-processor: vagrant
==> vmware-iso (vagrant): Creating Vagrant box for ‘vmware’ provider
vmware-iso (vagrant): Copying: output-vmware-iso/disk-s001.vmdk
vmware-iso (vagrant): Copying: output-vmware-iso/disk-s002.vmdk
vmware-iso (vagrant): Copying: output-vmware-iso/disk-s003.vmdk
vmware-iso (vagrant): Copying: output-vmware-iso/disk.vmdk
vmware-iso (vagrant): Copying: output-vmware-iso/packer-vmware-iso.nvram
vmware-iso (vagrant): Copying: output-vmware-iso/packer-vmware-iso.vmsd
vmware-iso (vagrant): Copying: output-vmware-iso/packer-vmware-iso.vmx
vmware-iso (vagrant): Copying: output-vmware-iso/packer-vmware-iso.vmxf
vmware-iso (vagrant): Compressing: Vagrantfile
vmware-iso (vagrant): Compressing: disk-s001.vmdk
vmware-iso (vagrant): Compressing: disk-s002.vmdk
vmware-iso (vagrant): Compressing: disk-s003.vmdk
vmware-iso (vagrant): Compressing: disk.vmdk
vmware-iso (vagrant): Compressing: metadata.json
vmware-iso (vagrant): Compressing: packer-vmware-iso.nvram
vmware-iso (vagrant): Compressing: packer-vmware-iso.vmsd
vmware-iso (vagrant): Compressing: packer-vmware-iso.vmx
vmware-iso (vagrant): Compressing: packer-vmware-iso.vmxf
Build ‘vmware-iso’ finished.

==> Builds finished. The artifacts of successful builds are:
–> vmware-iso: ‘vmware’ provider box: centos-7.1-x64-vmware.box

8) Add box to Vagrant

$ vagrant box add –name centos-7.1-010-x64-vmware.box centos-7.1-x64-vmware.box
==> box: Adding box ‘centos-7.1-010-x64-vmware.box’ (v0) for provider:
box: Downloading: file:///Users/john/packer/centos/centos-7.1-x64-vmware.box
==> box: Successfully added box ‘centos-7.1-010-x64-vmware.box’ (v0) for ‘vmware_desktop’!

The above is all you need to have your Infrastructure be Code that can be versioned and automatically create your images and use them on Vagrant.
The next item will show you how to use Packer to move the same image to your vSphere environment.

9) Sending Image to vSphere
To send the image created by Packer to vSphere you will need to add another post-provisioning entry to the JSON array:

As you can see I am using variables to make this portable, so that means you have to add variables to the variables section as well, below is the new template to do both vagrant and vSphere image provisioning.

10) Re-Run Packer against the template.json file and watch it build the machine image an

$ packer build \
> -var ‘iso_url=/Users/john/iso/CentOS-7-x86_64-Minimal-1511.iso’ \
> -var ‘vm_host=vc.example.com’ \
> -var ‘vm_user=john@example.com’ \
> -var ‘vm_pass=XXXXXXX’ \
> -var ‘vm_dc=vDC’ \
> -var ‘vm_cluster=Folder/Cluster’ \
> -var ‘vm_datastore=store’ \
> -var ‘vm_folder=Images’ \
> -var ‘vm_name=centos71’ \
> -var ‘vm_network=dvs-net1’ \
> -only=vmware-iso template.json

vmware-iso output will be in this color.

==> vmware-iso: Downloading or copying ISO
vmware-iso: Downloading or copying: file:///Users/john/iso/CentOS-7-x86_64-Minimal-1511.iso
==> vmware-iso: Creating virtual machine disk


==> vmware-iso: Running post-processor: vagrant
==> vmware-iso (vagrant): Creating Vagrant box for ‘vmware’ provider
vmware-iso (vagrant): Copying: output-vmware-iso/disk-s001.vmdk
vmware-iso (vagrant): Copying: output-vmware-iso/disk-s002.vmdk
vmware-iso (vagrant): Copying: output-vmware-iso/disk-s003.vmdk
vmware-iso (vagrant): Copying: output-vmware-iso/disk.vmdk
vmware-iso (vagrant): Copying: output-vmware-iso/packer-vmware-iso.nvram
vmware-iso (vagrant): Copying: output-vmware-iso/packer-vmware-iso.vmsd
vmware-iso (vagrant): Copying: output-vmware-iso/packer-vmware-iso.vmx
vmware-iso (vagrant): Copying: output-vmware-iso/packer-vmware-iso.vmxf
vmware-iso (vagrant): Compressing: Vagrantfile
vmware-iso (vagrant): Compressing: disk-s001.vmdk
vmware-iso (vagrant): Compressing: disk-s002.vmdk
vmware-iso (vagrant): Compressing: disk-s003.vmdk
vmware-iso (vagrant): Compressing: disk.vmdk
vmware-iso (vagrant): Compressing: metadata.json
vmware-iso (vagrant): Compressing: packer-vmware-iso.nvram
vmware-iso (vagrant): Compressing: packer-vmware-iso.vmsd
vmware-iso (vagrant): Compressing: packer-vmware-iso.vmx
vmware-iso (vagrant): Compressing: packer-vmware-iso.vmxf
==> vmware-iso: Running post-processor: vsphere
vmware-iso (vsphere): Uploading output-vmware-iso/packer-vmware-iso.vmx to vSphere
vmware-iso (vsphere): Opening VMX source: output-vmware-iso/packer-vmware-iso.vmx
vmware-iso (vsphere): Opening VI target: vi://john%40example.com@vc.exmaple.com:443/vDC/host/Cluster/Resources/
vmware-iso (vsphere): Deploying to VI: vi://john%40example.com@vc.example.com:443/vDC/host/Cluster/Resources/
Transfer Completed
vmware-iso (vsphere): Completed successfully
vmware-iso (vsphere):
Build ‘vmware-iso’ finished.

==> Builds finished. The artifacts of successful builds are:
–> vmware-iso: ‘vmware’ provider box: centos-7.1-x64-vmware.box
–> vmware-iso:

Now you should have the same image running on both Vagrant and vSphere.

Have you had issues with an application complaining about SSL/TLS connectivity to a server?

If the server is using a valid third party signed certificate you should not see issues connecting from a web browser, but maybe you will issues connecting from the command line or from an application.

The way SSL/TLS work in short, is that the client(web browser, command line shell, application, etc) connects to the server and the server responds with a certificate.
This server certificate is signed by a Certificate Authority (CA) and the client checks if the CA is in its trusted Certificate Authorities local database to be able to trust the server certificate.

Web browsers have their own trusted Certifcate Authority databases or use the Operating Systems’ and that is why your browser does rarely complain if the server certificate is signed by a valid CA.

Flow:
Client —-> Server
Server — SSL/TLS certificate –> Client
Client checks server certificate against its CA database to trust or not

Now let’s test from the Linux command line:
// The items in RED are the errors we are getting
// The items in BOLD is the information we need, the certificate and the issuer

We are missing the Issuer (CA) certificate:
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3

…which is what we need to be able to trust the server certificate:
s:/C=US/ST=California/L=City/O=Example Corporation/OU=CIT/CN=*.example.com

[vagrant@vagrant ~]$ openssl s_client -connect site.example.com:443
CONNECTED(00000003)
depth=0 C = US, ST = California, L = City, O = Example Corporation, OU = CIT, CN = *.example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = California, L = City, O = Example Corporation, OU = CIT, CN = *.example.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 C = US, ST = California, L = City, O = Example Corporation, OU = CIT, CN = *.example.com
verify error:num=21:unable to verify the first certificate
verify return:1

Certificate chain
0 s:/C=US/ST=California/L=City/O=Example Corporation/OU=CIT/CN=*.example.com
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3

Server certificate
—–BEGIN CERTIFICATE—–
XXXFTjCCBDagAwIBAgIQGtNpqqohGc6UzXNUYvmQMTANBgkqhkiG9w0BAQUFADCB
tTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMm
VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwHhcNMTUwNjI1
MDAwMDAwWhcNMTYwOTIzMjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExFzAVBgNVBAcUDlJlZHdvb2QgU2hvcmVzMRswGQYDVQQKFBJP
cmFjbGUgQ29ycG9yYXRpb24xDDAKBgNVBAsUA0NJVDEgMB4GA1UEAxQXKi5vcmFj
bGVvdXRzb3VyY2luZy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDTDH4+V9VK1ri9uh5zFpV6+VzpIYQOEHmd4Rg68uS3lzMV/xD+HBVEkenarpVP
uXSQnlP79hguSWfOpX1LpNjHeiy68pWMLMUuXmZiXS8BI0ctyGYb7LntAsGe6Y0N
YTBybpxS8szLPXQ6u+wa+6dfHxswEY6CUc+4wFyFgAVqWaKOKoJwaIUd//BoaGMv
E2Jj4ygnesolWWdqTWURsFS3X08P0nNKbXMCQoMvSp3f3rS+p+q/xVXqfJuAo7wZ
yTEBkTxWI2wDnjyWw3hrkfuxrdrs0YhmddHtchNTt3if3Q1LerDOaR3Hhc+H9fVB
cZYgsuNmSABBqQ30T0B8ZSz1AgMBAAGjggGDMIIBfzA5BgNVHREEMjAwghcqLm9y
YWNsZW91dHNvdXJjaW5nLmNvbYIVb3JhY2xlb3V0c291cmNpbmcuY29tMAkGA1Ud
EwQCMAAwDgYDVR0PAQH/BAQDAgWgMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9z
ZC5zeW1jYi5jb20vc2QuY3JsMGEGA1UdIARaMFgwVgYGZ4EMAQICMEwwIwYIKwYB
BQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkMF2h0
dHBzOi8vZC5zeW1jYi5jb20vcnBhMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjAfBgNVHSMEGDAWgBQNRFwWU0TBgn4dIKsl9AFj2L55pTBXBggrBgEFBQcB
AQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zZC5zeW1jZC5jb20wJgYIKwYBBQUH
MAKGGmh0dHA6Ly9zZC5zeW1jYi5jb20vc2QuY3J0MA0GCSqGSIb3DQEBBQUAA4IB
AQBrQknzr4wntvKOGc8YK6RfqaXS+r4XH34DlEPp2kFleNRaiJpo2DTVXr1a+WXQ
omrKl9j4Irbf0Jq4vI0XqYw5Ei8WsvqCMoFXqnCwY2MazYVHRF/IYvCWfjIcySGu
tR/RS+bvpN1+ATt8vNnW7imdca3LjkM0Fw2GVjmaX2CeINpCRkuQ/d28ob46o9D9
VF+/kjc2tVwfabQQCNykRlhYLJDmhKcVI5+swD10+JjddbSAsXpIQFy3FI77idvC
rngbwc0G36Rj3DvcoypUbXoFzsnisy58oieFWRzHPe9DVYh0o/uJj40NJDOLuyEA
EIV237/q67gIYEn6LM8CLXXX
—–END CERTIFICATE—–
subject=/C=US/ST=California/L=City/O=Example Corporation/OU=CIT/CN=*.example.com
issuer=/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3


No client certificate CA names sent

SSL handshake has read 1547 bytes and written 591 bytes

New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : AES128-SHA
Session-ID: 6A6F797F1318EC872CBD4DD899493DB949E08F78A050580F70F9621ABB0ACE0C
Session-ID-ctx:
Master-Key: 4E12620FCE8592D4D272E58D9DC9C313D4A6D83B2956880279F58526526B9AB0AF8A9660AEB40F03FF46CDDFCB970A74
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1439626705
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)

DONE

# Get CA Issuer Certificate(s)

Now that we know we are missing the Issuer certificate we need to get it from the Certificate Authority website. In this specific case we need:
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3

Later you will have the exact same issue with the ‘VeriSign Class 3 Secure Server CA – G3’ certificate because it will be asking for its Issuer certificate ‘VeriSign Class 3 Public Primary Certification Authority – G5’, so you will need to get that Certificate as well.

I searched online for both and found them at:
https://www.tbs-certificates.co.uk/FAQ/en/565.html
https://www.tbs-certificates.co.uk/FAQ/en/599.html

Take everything from —–BEGIN CERTIFICATE—– to —–END CERTIFICATE—– and put them in files (e.g. verisign_class_3_secure_server_ca_g3.pem) and (e.g. verisign_class_3_secure_server_ca_g5.pem)

Having both files will ensure you have the entire Trust Chain:
*.example.com CERT trusted by ‘VeriSign Class 3 Secure Server CA – G3’ CERT trusted by ‘VeriSign Class 3 Public Primary Certification Authority – G5’

—–BEGIN CERTIFICATE—–
MIIF7DCCBNSgAwIBAgIQbsx6pacDIAm4zrz06VLUkTANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBtTEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMmVmVy
aVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCxh4QfwgxF9byrJZenraI+nLr2wTm4i8rCrFbG
5btljkRPTc5v7QlK1K9OEJxoiy6Ve4mbE8riNDTB81vzSXtig0iBdNGIeGwCU/m8
f0MmV1gzgzszChew0E6RJK2GfWQS3HRKNKEdCuqWHQsV/KNLO85jiND4LQyUhhDK
tpo9yus3nABINYYpUHjoRWPNGUFP9ZXse5jUxHGzUL4os4+guVOc9cosI6n9FAbo
GLSa6Dxugf3kzTU2s1HTaewSulZub5tXxYsU5w7HnO1KVGrJTcW/EbGuHGeBy0RV
M5l/JJs/U0V/hhrzPPptf4H1uErT9YU3HLWm0AnkGHs4TvoPAgMBAAGjggHfMIIB
2zA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlz
aWduLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4
RQEHFwMwVjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2Nw
czAqBggrBgEFBQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQG
A1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzUu
Y3JsMA4GA1UdDwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglp
bWFnZS9naWYwITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNo
dHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjAoBgNVHREEITAfpB0w
GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItNjAdBgNVHQ4EFgQUDURcFlNEwYJ+
HSCrJfQBY9i+eaUwHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwDQYJ
KoZIhvcNAQEFBQADggEBAAyDJO/dwwzZWJz+NrbrioBL0aP3nfPMU++CnqOh5pfB
WJ11bOAdG0z60cEtBcDqbrIicFXZIDNAMwfCZYP6j0M3m+oOmmxw7vacgDvZN/R6
bezQGH1JSsqZxxkoor7YdyT3hSaGbYcFQEFn0Sc67dxIHSLNCwuLvPSxe/20majp
dirhGi2HbnTTiN0eIsbfFrYrghQKlFzyUOyvzv9iNw2tZdMGQVPtAhTItVgooazg
W+yzf5VK+wPIrSbb5mZ4EkrZn0L74ZjmQoObj49nJOhhGbXdzbULJgWOw27EyHW4
Rs/iGAZeqa6ogZpHFt4MKGwlJ7net4RYxh84HqTEy2Y=
—–END CERTIFICATE—–

—–BEGIN CERTIFICATE—–
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
—–END CERTIFICATE—–

# Check CA Issuer Certificates Details

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
6e:cc:7a:a5:a7:03:20:09:b8:ce:bc:f4:e9:52:d4:91
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. – For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority – G5
Validity
Not Before: Feb 8 00:00:00 2010 GMT
Not After : Feb 7 23:59:59 2020 GMT
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)10, CN=VeriSign Class 3 Secure Server CA – G3
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:b1:87:84:1f:c2:0c:45:f5:bc:ab:25:97:a7:ad:
a2:3e:9c:ba:f6:c1:39:b8:8b:ca:c2:ac:56:c6:e5:
bb:65:8e:44:4f:4d:ce:6f:ed:09:4a:d4:af:4e:10:
9c:68:8b:2e:95:7b:89:9b:13:ca:e2:34:34:c1:f3:
5b:f3:49:7b:62:83:48:81:74:d1:88:78:6c:02:53:
f9:bc:7f:43:26:57:58:33:83:3b:33:0a:17:b0:d0:
4e:91:24:ad:86:7d:64:12:dc:74:4a:34:a1:1d:0a:
ea:96:1d:0b:15:fc:a3:4b:3b:ce:63:88:d0:f8:2d:
0c:94:86:10:ca:b6:9a:3d:ca:eb:37:9c:00:48:35:
86:29:50:78:e8:45:63:cd:19:41:4f:f5:95:ec:7b:
98:d4:c4:71:b3:50:be:28:b3:8f:a0:b9:53:9c:f5:
ca:2c:23:a9:fd:14:06:e8:18:b4:9a:e8:3c:6e:81:
fd:e4:cd:35:36:b3:51:d3:69:ec:12:ba:56:6e:6f:
9b:57:c5:8b:14:e7:0e:c7:9c:ed:4a:54:6a:c9:4d:
c5:bf:11:b1:ae:1c:67:81:cb:44:55:33:99:7f:24:
9b:3f:53:45:7f:86:1a:f3:3c:fa:6d:7f:81:f5:b8:
4a:d3:f5:85:37:1c:b5:a6:d0:09:e4:18:7b:38:4e:
fa:0f
Exponent: 65537 (0x10001)
X509v3 extensions:
Authority Information Access:
OCSP – URI:http://ocsp.verisign.com

X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Certificate Policies:
Policy: 2.16.840.1.113733.1.7.23.3
CPS: https://www.verisign.com/cps
User Notice:
Explicit Text: https://www.verisign.com/rpa

X509v3 CRL Distribution Points:
URI:http://crl.verisign.com/pca3-g5.crl

X509v3 Key Usage: critical
Certificate Sign, CRL Sign
1.3.6.1.5.5.7.1.12:
0_.].[0Y0W0U..image/gif0!0.0…+…………..k…j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
X509v3 Subject Alternative Name:
DirName:/CN=VeriSignMPKI-2-6
X509v3 Subject Key Identifier:
0D:44:5C:16:53:44:C1:82:7E:1D:20:AB:25:F4:01:63:D8:BE:79:A5
X509v3 Authority Key Identifier:
keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33

Signature Algorithm: sha1WithRSAEncryption
0c:83:24:ef:dd:c3:0c:d9:58:9c:fe:36:b6:eb:8a:80:4b:d1:
a3:f7:9d:f3:cc:53:ef:82:9e:a3:a1:e6:97:c1:58:9d:75:6c:
e0:1d:1b:4c:fa:d1:c1:2d:05:c0:ea:6e:b2:22:70:55:d9:20:
33:40:33:07:c2:65:83:fa:8f:43:37:9b:ea:0e:9a:6c:70:ee:
f6:9c:80:3b:d9:37:f4:7a:6d:ec:d0:18:7d:49:4a:ca:99:c7:
19:28:a2:be:d8:77:24:f7:85:26:86:6d:87:05:40:41:67:d1:
27:3a:ed:dc:48:1d:22:cd:0b:0b:8b:bc:f4:b1:7b:fd:b4:99:
a8:e9:76:2a:e1:1a:2d:87:6e:74:d3:88:dd:1e:22:c6:df:16:
b6:2b:82:14:0a:94:5c:f2:50:ec:af:ce:ff:62:37:0d:ad:65:
d3:06:41:53:ed:02:14:c8:b5:58:28:a1:ac:e0:5b:ec:b3:7f:
95:4a:fb:03:c8:ad:26:db:e6:66:78:12:4a:d9:9f:42:fb:e1:
98:e6:42:83:9b:8f:8f:67:24:e8:61:19:b5:dd:cd:b5:0b:26:
05:8e:c3:6e:c4:c8:75:b8:46:cf:e2:18:06:5e:a9:ae:a8:81:
9a:47:16:de:0c:28:6c:25:27:b9:de:b7:84:58:c6:1f:38:1e:
a4:c4:cb:66
—–BEGIN CERTIFICATE—–
MIIF7DCCBNSgAwIBAgIQbsx6pacDIAm4zrz06VLUkTANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBtTEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg
aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMmVmVy
aVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCxh4QfwgxF9byrJZenraI+nLr2wTm4i8rCrFbG
5btljkRPTc5v7QlK1K9OEJxoiy6Ve4mbE8riNDTB81vzSXtig0iBdNGIeGwCU/m8
f0MmV1gzgzszChew0E6RJK2GfWQS3HRKNKEdCuqWHQsV/KNLO85jiND4LQyUhhDK
tpo9yus3nABINYYpUHjoRWPNGUFP9ZXse5jUxHGzUL4os4+guVOc9cosI6n9FAbo
GLSa6Dxugf3kzTU2s1HTaewSulZub5tXxYsU5w7HnO1KVGrJTcW/EbGuHGeBy0RV
M5l/JJs/U0V/hhrzPPptf4H1uErT9YU3HLWm0AnkGHs4TvoPAgMBAAGjggHfMIIB
2zA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlz
aWduLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4
RQEHFwMwVjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2Nw
czAqBggrBgEFBQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQG
A1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzUu
Y3JsMA4GA1UdDwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglp
bWFnZS9naWYwITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNo
dHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjAoBgNVHREEITAfpB0w
GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItNjAdBgNVHQ4EFgQUDURcFlNEwYJ+
HSCrJfQBY9i+eaUwHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwDQYJ
KoZIhvcNAQEFBQADggEBAAyDJO/dwwzZWJz+NrbrioBL0aP3nfPMU++CnqOh5pfB
WJ11bOAdG0z60cEtBcDqbrIicFXZIDNAMwfCZYP6j0M3m+oOmmxw7vacgDvZN/R6
bezQGH1JSsqZxxkoor7YdyT3hSaGbYcFQEFn0Sc67dxIHSLNCwuLvPSxe/20majp
dirhGi2HbnTTiN0eIsbfFrYrghQKlFzyUOyvzv9iNw2tZdMGQVPtAhTItVgooazg
W+yzf5VK+wPIrSbb5mZ4EkrZn0L74ZjmQoObj49nJOhhGbXdzbULJgWOw27EyHW4
Rs/iGAZeqa6ogZpHFt4MKGwlJ7net4RYxh84HqTEy2Y=
—–END CERTIFICATE—–

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
18:da:d1:9e:26:7d:e8:bb:4a:21:58:cd:cc:6b:3b:4a
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. – For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority – G5
Validity
Not Before: Nov 8 00:00:00 2006 GMT
Not After : Jul 16 23:59:59 2036 GMT
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. – For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority – G5
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b:
4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57:
08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8:
2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe:
8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d:
a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59:
54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49:
d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69:
7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96:
bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5:
f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02:
ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6:
f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19:
21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d:
63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95:
ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f:
9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8:
25:15
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
1.3.6.1.5.5.7.1.12:
0_.].[0Y0W0U..image/gif0!0.0…+…………..k…j.H.,{..0%.#http://logo.verisign.com/vslogo.gif
X509v3 Subject Key Identifier:
7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33
Signature Algorithm: sha1WithRSAEncryption
93:24:4a:30:5f:62:cf:d8:1a:98:2f:3d:ea:dc:99:2d:bd:77:
f6:a5:79:22:38:ec:c4:a7:a0:78:12:ad:62:0e:45:70:64:c5:
e7:97:66:2d:98:09:7e:5f:af:d6:cc:28:65:f2:01:aa:08:1a:
47:de:f9:f9:7c:92:5a:08:69:20:0d:d9:3e:6d:6e:3c:0d:6e:
d8:e6:06:91:40:18:b9:f8:c1:ed:df:db:41:aa:e0:96:20:c9:
cd:64:15:38:81:c9:94:ee:a2:84:29:0b:13:6f:8e:db:0c:dd:
25:02:db:a4:8b:19:44:d2:41:7a:05:69:4a:58:4f:60:ca:7e:
82:6a:0b:02:aa:25:17:39:b5:db:7f:e7:84:65:2a:95:8a:bd:
86:de:5e:81:16:83:2d:10:cc:de:fd:a8:82:2a:6d:28:1f:0d:
0b:c4:e5:e7:1a:26:19:e1:f4:11:6f:10:b5:95:fc:e7:42:05:
32:db:ce:9d:51:5e:28:b6:9e:85:d3:5b:ef:a5:7d:45:40:72:
8e:b7:0e:6b:0e:06:fb:33:35:48:71:b8:9d:27:8b:c4:65:5f:
0d:86:76:9c:44:7a:f6:95:5c:f6:5d:32:08:33:a4:54:b6:18:
3f:68:5c:f2:42:4a:85:38:54:83:5f:d1:e8:2c:f2:ac:11:d6:
a8:ed:63:6a
—–BEGIN CERTIFICATE—–
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
—–END CERTIFICATE—–

# Trust the CA Issuer Certificates

There are several ways to do it, see below for some and their pros/cons.

1) Put the CA Issuer certificates in pem format in a folder, and use them directly from the application

This is good for a quick test, but I don’t recommended it as standard operating procedure because you have to manage each set of certs and have the applications point to hardcoded paths.

// Create dir to hold certs

// Put the CA issuer cert in the directory

// Create symbolic links needed

// Verify successful connectivity by passing the CApath

CONNECTED(00000003)
depth=2 C = US, O = “VeriSign, Inc.”, OU = VeriSign Trust Network, OU = “(c) 2006 VeriSign, Inc. – For authorized use only”, CN = VeriSign Class 3 Public Primary Certification Authority – G5
verify return:1
depth=1 C = US, O = “VeriSign, Inc.”, OU = VeriSign Trust Network, OU = Terms of use at https://www.verisign.com/rpa (c)10, CN = VeriSign Class 3 Secure Server CA – G3
verify return:1
depth=0 C = US, ST = California, L = City, O = Example Corporation, OU = CIT, CN = *.Example.com
verify return:1

Certificate chain
0 s:/C=US/ST=California/L=City/O=Example Corporation/OU=CIT/CN=*.Example.com
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3

Server certificate
—–BEGIN CERTIFICATE—–
MIIFTjCCBDagAwIBAgIQGtNpqqohGc6UzXNUYvmQMTANBgkqhkiG9w0BAQUFADCB
tTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMm
VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwHhcNMTUwNjI1
MDAwMDAwWhcNMTYwOTIzMjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExFzAVBgNVBAcUDlJlZHdvb2QgU2hvcmVzMRswGQYDVQQKFBJP
cmFjbGUgQ29ycG9yYXRpb24xDDAKBgNVBAsUA0NJVDEgMB4GA1UEAxQXKi5vcmFj
bGVvdXRzb3VyY2luZy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDTDH4+V9VK1ri9uh5zFpV6+VzpIYQOEHmd4Rg68uS3lzMV/xD+HBVEkenarpVP
uXSQnlP79hguSWfOpX1LpNjHeiy68pWMLMUuXmZiXS8BI0ctyGYb7LntAsGe6Y0N
YTBybpxS8szLPXQ6u+wa+6dfHxswEY6CUc+4wFyFgAVqWaKOKoJwaIUd//BoaGMv
E2Jj4ygnesolWWdqTWURsFS3X08P0nNKbXMCQoMvSp3f3rS+p+q/xVXqfJuAo7wZ
yTEBkTxWI2wDnjyWw3hrkfuxrdrs0YhmddHtchNTt3if3Q1LerDOaR3Hhc+H9fVB
cZYgsuNmSABBqQ30T0B8ZSz1AgMBAAGjggGDMIIBfzA5BgNVHREEMjAwghcqLm9y
YWNsZW91dHNvdXJjaW5nLmNvbYIVb3JhY2xlb3V0c291cmNpbmcuY29tMAkGA1Ud
EwQCMAAwDgYDVR0PAQH/BAQDAgWgMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9z
ZC5zeW1jYi5jb20vc2QuY3JsMGEGA1UdIARaMFgwVgYGZ4EMAQICMEwwIwYIKwYB
BQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkMF2h0
dHBzOi8vZC5zeW1jYi5jb20vcnBhMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjAfBgNVHSMEGDAWgBQNRFwWU0TBgn4dIKsl9AFj2L55pTBXBggrBgEFBQcB
AQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zZC5zeW1jZC5jb20wJgYIKwYBBQUH
MAKGGmh0dHA6Ly9zZC5zeW1jYi5jb20vc2QuY3J0MA0GCSqGSIb3DQEBBQUAA4IB
AQBrQknzr4wntvKOGc8YK6RfqaXS+r4XH34DlEPp2kFleNRaiJpo2DTVXr1a+WXQ
omrKl9j4Irbf0Jq4vI0XqYw5Ei8WsvqCMoFXqnCwY2MazYVHRF/IYvCWfjIcySGu
tR/RS+bvpN1+ATt8vNnW7imdca3LjkM0Fw2GVjmaX2CeINpCRkuQ/d28ob46o9D9
VF+/kjc2tVwfabQQCNykRlhYLJDmhKcVI5+swD10+JjddbSAsXpIQFy3FI77idvC
rngbwc0G36Rj3DvcoypUbXoFzsnisy58oieFWRzHPe9DVYh0o/uJj40NJDOLuyEA
EIV237/q67gIYEn6LM8CLah9
—–END CERTIFICATE—–
subject=/C=US/ST=California/L=City/O=Example Corporation/OU=CIT/CN=*.Example.com
issuer=/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3

No client certificate CA names sent

SSL handshake has read 1547 bytes and written 591 bytes

New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : AES128-SHA
Session-ID: 6A6F797F1318E8462CBD4DD899493DB949E08F78A0505C4E70F9621ABB0AA280
Session-ID-ctx:
Master-Key: 50D309E782DF245FA36BD1028197459FE1A56B976D947D2994BBB75A0754D18AD44A90F29AC818DB28562F0E9E2E5442
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1439631686
Timeout : 300 (sec)
Verify return code: 0 (ok)

2) Append the CA Issuer Certificates to the OS certificate bundle (/etc/pki/tls/certs/ca-bundle.crt)

This is not recommended as standard operating procedure because patches/updates will overwrite the certificate bundle file (/etc/pki/tls/certs/ca-bundle.crt) and the certificates you had added wont be trusted anymore

// Verify successful connectivity

CONNECTED(00000003)
depth=2 C = US, O = “VeriSign, Inc.”, OU = VeriSign Trust Network, OU = “(c) 2006 VeriSign, Inc. – For authorized use only”, CN = VeriSign Class 3 Public Primary Certification Authority – G5
verify return:1
depth=1 C = US, O = “VeriSign, Inc.”, OU = VeriSign Trust Network, OU = Terms of use at https://www.verisign.com/rpa (c)10, CN = VeriSign Class 3 Secure Server CA – G3
verify return:1
depth=0 C = US, ST = California, L = City, O = Example Corporation, OU = CIT, CN = *.Example.com
verify return:1

Certificate chain
0 s:/C=US/ST=California/L=City/O=Example Corporation/OU=CIT/CN=*.Example.com
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3

Server certificate
—–BEGIN CERTIFICATE—–
MIIFTjCCBDagAwIBAgIQGtNpqqohGc6UzXNUYvmQMTANBgkqhkiG9w0BAQUFADCB
tTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMm
VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwHhcNMTUwNjI1
MDAwMDAwWhcNMTYwOTIzMjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExFzAVBgNVBAcUDlJlZHdvb2QgU2hvcmVzMRswGQYDVQQKFBJP
cmFjbGUgQ29ycG9yYXRpb24xDDAKBgNVBAsUA0NJVDEgMB4GA1UEAxQXKi5vcmFj
bGVvdXRzb3VyY2luZy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDTDH4+V9VK1ri9uh5zFpV6+VzpIYQOEHmd4Rg68uS3lzMV/xD+HBVEkenarpVP
uXSQnlP79hguSWfOpX1LpNjHeiy68pWMLMUuXmZiXS8BI0ctyGYb7LntAsGe6Y0N
YTBybpxS8szLPXQ6u+wa+6dfHxswEY6CUc+4wFyFgAVqWaKOKoJwaIUd//BoaGMv
E2Jj4ygnesolWWdqTWURsFS3X08P0nNKbXMCQoMvSp3f3rS+p+q/xVXqfJuAo7wZ
yTEBkTxWI2wDnjyWw3hrkfuxrdrs0YhmddHtchNTt3if3Q1LerDOaR3Hhc+H9fVB
cZYgsuNmSABBqQ30T0B8ZSz1AgMBAAGjggGDMIIBfzA5BgNVHREEMjAwghcqLm9y
YWNsZW91dHNvdXJjaW5nLmNvbYIVb3JhY2xlb3V0c291cmNpbmcuY29tMAkGA1Ud
EwQCMAAwDgYDVR0PAQH/BAQDAgWgMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9z
ZC5zeW1jYi5jb20vc2QuY3JsMGEGA1UdIARaMFgwVgYGZ4EMAQICMEwwIwYIKwYB
BQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkMF2h0
dHBzOi8vZC5zeW1jYi5jb20vcnBhMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjAfBgNVHSMEGDAWgBQNRFwWU0TBgn4dIKsl9AFj2L55pTBXBggrBgEFBQcB
AQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zZC5zeW1jZC5jb20wJgYIKwYBBQUH
MAKGGmh0dHA6Ly9zZC5zeW1jYi5jb20vc2QuY3J0MA0GCSqGSIb3DQEBBQUAA4IB
AQBrQknzr4wntvKOGc8YK6RfqaXS+r4XH34DlEPp2kFleNRaiJpo2DTVXr1a+WXQ
omrKl9j4Irbf0Jq4vI0XqYw5Ei8WsvqCMoFXqnCwY2MazYVHRF/IYvCWfjIcySGu
tR/RS+bvpN1+ATt8vNnW7imdca3LjkM0Fw2GVjmaX2CeINpCRkuQ/d28ob46o9D9
VF+/kjc2tVwfabQQCNykRlhYLJDmhKcVI5+swD10+JjddbSAsXpIQFy3FI77idvC
rngbwc0G36Rj3DvcoypUbXoFzsnisy58oieFWRzHPe9DVYh0o/uJj40NJDOLuyEA
EIV237/q67gIYEn6LM8CLah9
—–END CERTIFICATE—–
subject=/C=US/ST=California/L=City/O=Example Corporation/OU=CIT/CN=*.Example.com
issuer=/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3

No client certificate CA names sent

SSL handshake has read 1547 bytes and written 591 bytes

New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : AES128-SHA
Session-ID: 6A6F797F1318E8462CBD4DD899493DB949E08F78A0505C4E70F9621ABB0AA280
Session-ID-ctx:
Master-Key: 50D309E782DF245FA36BD1028197459FE1A56B976D947D2994BBB75A0754D18AD44A90F29AC818DB28562F0E9E2E5442
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1439631686
Timeout : 300 (sec)
Verify return code: 0 (ok)

3) Use the SharedSystemCertificates (*** Recommended ***)
This is the recommended way of adding trusted CA certificates to your RHEL/CentOS systems.
The idea is to make NSS, GnuTLS, OpenSSL and Java share a default source for retrieving system certificate anchors and black list information, details @ https://fedoraproject.org/wiki/Features/SharedSystemCertificates

// Enable the CA trust capability

// Copy/Move the Issuer CA certificates to /etc/pki/ca-trust/source/anchors/

// Update the CA trust

// Verify successful connectivity

CONNECTED(00000003)
depth=2 C = US, O = “VeriSign, Inc.”, OU = VeriSign Trust Network, OU = “(c) 2006 VeriSign, Inc. – For authorized use only”, CN = VeriSign Class 3 Public Primary Certification Authority – G5
verify return:1
depth=1 C = US, O = “VeriSign, Inc.”, OU = VeriSign Trust Network, OU = Terms of use at https://www.verisign.com/rpa (c)10, CN = VeriSign Class 3 Secure Server CA – G3
verify return:1
depth=0 C = US, ST = California, L = City, O = Example Corporation, OU = CIT, CN = *.Example.com
verify return:1

Certificate chain
0 s:/C=US/ST=California/L=City/O=Example Corporation/OU=CIT/CN=*.Example.com
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3

Server certificate
—–BEGIN CERTIFICATE—–
MIIFTjCCBDagAwIBAgIQGtNpqqohGc6UzXNUYvmQMTANBgkqhkiG9w0BAQUFADCB
tTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMm
VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwHhcNMTUwNjI1
MDAwMDAwWhcNMTYwOTIzMjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
CkNhbGlmb3JuaWExFzAVBgNVBAcUDlJlZHdvb2QgU2hvcmVzMRswGQYDVQQKFBJP
cmFjbGUgQ29ycG9yYXRpb24xDDAKBgNVBAsUA0NJVDEgMB4GA1UEAxQXKi5vcmFj
bGVvdXRzb3VyY2luZy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDTDH4+V9VK1ri9uh5zFpV6+VzpIYQOEHmd4Rg68uS3lzMV/xD+HBVEkenarpVP
uXSQnlP79hguSWfOpX1LpNjHeiy68pWMLMUuXmZiXS8BI0ctyGYb7LntAsGe6Y0N
YTBybpxS8szLPXQ6u+wa+6dfHxswEY6CUc+4wFyFgAVqWaKOKoJwaIUd//BoaGMv
E2Jj4ygnesolWWdqTWURsFS3X08P0nNKbXMCQoMvSp3f3rS+p+q/xVXqfJuAo7wZ
yTEBkTxWI2wDnjyWw3hrkfuxrdrs0YhmddHtchNTt3if3Q1LerDOaR3Hhc+H9fVB
cZYgsuNmSABBqQ30T0B8ZSz1AgMBAAGjggGDMIIBfzA5BgNVHREEMjAwghcqLm9y
YWNsZW91dHNvdXJjaW5nLmNvbYIVb3JhY2xlb3V0c291cmNpbmcuY29tMAkGA1Ud
EwQCMAAwDgYDVR0PAQH/BAQDAgWgMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9z
ZC5zeW1jYi5jb20vc2QuY3JsMGEGA1UdIARaMFgwVgYGZ4EMAQICMEwwIwYIKwYB
BQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkMF2h0
dHBzOi8vZC5zeW1jYi5jb20vcnBhMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjAfBgNVHSMEGDAWgBQNRFwWU0TBgn4dIKsl9AFj2L55pTBXBggrBgEFBQcB
AQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zZC5zeW1jZC5jb20wJgYIKwYBBQUH
MAKGGmh0dHA6Ly9zZC5zeW1jYi5jb20vc2QuY3J0MA0GCSqGSIb3DQEBBQUAA4IB
AQBrQknzr4wntvKOGc8YK6RfqaXS+r4XH34DlEPp2kFleNRaiJpo2DTVXr1a+WXQ
omrKl9j4Irbf0Jq4vI0XqYw5Ei8WsvqCMoFXqnCwY2MazYVHRF/IYvCWfjIcySGu
tR/RS+bvpN1+ATt8vNnW7imdca3LjkM0Fw2GVjmaX2CeINpCRkuQ/d28ob46o9D9
VF+/kjc2tVwfabQQCNykRlhYLJDmhKcVI5+swD10+JjddbSAsXpIQFy3FI77idvC
rngbwc0G36Rj3DvcoypUbXoFzsnisy58oieFWRzHPe9DVYh0o/uJj40NJDOLuyEA
EIV237/q67gIYEn6LM8CLah9
—–END CERTIFICATE—–
subject=/C=US/ST=California/L=City/O=Example Corporation/OU=CIT/CN=*.Example.com
issuer=/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA – G3

No client certificate CA names sent

SSL handshake has read 1547 bytes and written 591 bytes

New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : AES128-SHA
Session-ID: 6A6F797F1318E8462CBD4DD899493DB949E08F78A0505C4E70F9621ABB0AA280
Session-ID-ctx:
Master-Key: 50D309E782DF245FA36BD1028197459FE1A56B976D947D2994BBB75A0754D18AD44A90F29AC818DB28562F0E9E2E5442
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1439641898
Timeout : 300 (sec)
Verify return code: 0 (ok)

When developing in Python I enjoy using Sublime Text, especially its ability to run/build right from Sublime by simply pressing COMMAND+B. Meaning that I dont have to go out of the editor to the terminal to run the Python program.

Sample Python Program:

In sublime, I can program, run the program and see the result, increasing my productivity:

sublime_venv1

But what if I want to run a Python Virtual Environment and its benefits (see developing-in-python-using-python-virtual-environments).
Once the virtual environment is activated your terminal will use the Python Virtual Environment just fine, but Sublime Text will not, it will continue to use the system-wide Python environment by default.

Example: Having a Python module (e.g. IPy) installed in your virtual environment, but not system-wide, and having the Python virtual environment active:

# Python code:

# Running from terminal – (OK):

# Running from Sublime – (NOT OK):

sublime_venv2

To make Sublime Text use the virtual environment you need to create a Sublime project and edit its properties to use the Virtual Env.

# Create Sublime Project
Go to Project -> Save Project As…
// I named mine blog.sublime-project

# Edit project properties by editing the file in sublime to be as follows:
Note:
Remember the name: label as this is how you will use the build with… option
The shell_cmd: label is the command that will run when you build. It is far from perfect as you have to hardcode the Python program in the configuration, but at least works.

# Prepare Sublime to use your new build system:
Tools -> Build Systems -> PYTHON_VENV

# Now you can now continue to code and use COMMAND+B to build/run your programs without leaving your Sublime Text editor:

sublime_venv3

When developing in Python you most likely will need to install Python modules that will provide some type of functionality, the process is very simple:

Install the Python package manager:

Install modules, for example ‘yaml’, this is without virtual environments, this is basically installing a Python module system-wide:

The above will install Python modules for the system, but to do so you need ‘root’ privileges (e.g. sudo), and there is a possibility that developers don’t have ‘root’ privileges.
Another important scenario to consider is that installing/updating/modifying system-wide Python modules could affect other existing Python projects in the same system.

A way to overcome the system-wide python dependencies is to work with your own virtual environment, which allows you to install Python modules in a Python virtual environment and without the need for ‘root’ privileges.

What this accomplishes is to have your Python projects have their specific dependencies met without affecting anyone else.

To develop using Python virtual environments, the system should have the virtualenv Python package first:

Now as a regular user (no root or sudo needed):
# Create (or cd into) your Python project folder

# Create Python Virtual Environment, you can name it what you want, I chose to name it ‘env’

# Activating the virtual environment
To use the virtual environment (as opposed to the system-wide Python environment) you need to activate it first. After it is activated you will see it in the left your command prompt.

# System-wide Python

# Activate Virtual Env

# Ready to use Python Virtual Env

# Installing modules in the virtual environment

# Uninstalling modules in the virtual environment

# Install multiple python modules from a requirements file
If your project has multiple Python modules required, it is better to create a requirements.txt file with the list of Python modules.

Then you can install all the listed Python modules in your virtual environment as follows:

# Deactivate virtual environment (go back to using system-wide Python)

From time to time I get questions about how to check differences between two Git commits or two branches, I will answer those questions in this post.

How to check differences between two branches:

Example:
you have a dev branch and a master branch. You develop in the dev branch and would like to know if you were to merge the dev changes to master, what will those changes be:
Please note the order of the branch this states differences that will be added to master from dev.

How to check differences between two commits:

Example:
When you do git log you will see your different commits over time, you need to check the differences between two commits.

commit eab54d0ec21a1d7e351fee4c67139ada740e7e6b
Author: John
Date: Wed Jul 8 22:18:05 2015 -0400

Add feature 2

commit b722f1650b9fb33e0990beec027c097526c61478
Author: John
Date: Wed Jul 8 22:31:18 2015 -0400

Add feature 1

// Remember the order the first argument is the point in time, and the second item is what is added to the first argument’s commit

How to check differences between the HEAD (current state/latest revision) and a previous commit:

Or you can specify the last commit or a number of commits:

// Last commit

//Last 2 commits

How to check what changed since yesterday or a specific date:

// OR a specific date

How to check all changes to a specific file:

How to check size differences between two trees

I found this one in stackoverflow and has been very useful:

Reference Source: http://stackoverflow.com/questions/10845051/git-show-total-file-size-difference-between-two-commits/10847242#10847242

“git cat-file -s will output the size in bytes of an object in git. git diff-tree can tell you the differences between one tree and another. Putting this together into a script called git-file-size-diff located somewhere on your PATH will give you the ability to call git file-size-diff . Putting this together we can try something like the following” – Stackoverflow

// Using it to check size differences between two branches:

// Using it to check size differences between the local master branch and the remote master branch, this is useful to know how much data will be downloaded when doing a ‘git pull’:

While working on my video library I noticed that I had to rename a bunch of files to have correct file names that include Show name and Episode name and number.

I have about 275 files named from 000-274, but I needed to rename them to specify the season and episode they correspond to.

For example, files from 125 – 150 are from season 5 of said show, and that is what I will use for this post.

An example of a file in the 125 – 150 range:
‘SHOW – 135 – Some Episode _www.unneededStuff.mp4’

As you can see the filename has the following structure (which I will modify later in this post)

(ShowName) – (filename #) – (EpisodeName)_(Extra unneeded stuff).(extension)

I will be using the Linux/Mac rename command to perform the renaming of these files (125-150).
The end result should be that these files are renamed to have numbers from 501- 526 (for Season 5), so I will use arithmetic manipulate the numbers to be what I want.
I will also clean up the name a little bit so that it does not include the ‘extra unneeded stuff’.
The name of a file should be of form:
‘SHOW – 511 – Some Episode.mp4’

First make sure you work with the specific files you want to modify and nothing else:

// The above will show only files between 125 – 150 will be touched/modified.
// Using Bash brace expansion will help create the list between 125 – 150
// the brace expansion will use anything that has numbers 125-129, and any 13*, 14*, 150

Use the rename command with a RegEx expression that will modify the name the way you want.
I have the following regex expression:

Explanation:
// (^.+)\s-\s is the Show name plus ‘ – ‘, I am grouping just the name of the show to use it later
// (\d\d\d) is the incorrect episode number used in the filename
// (.+)_www.+ is the Episode name plus ‘unneeded stuff’, I am grouping just the episode name to use it later
// (\..+$) is the file extension, I am grouping it to use it later

// Now what was found with the above Regex will be substituted as follows:
$1 will have the Show name
“ – ” I am concatenating literal “ – “ after the show name
($2+376) I am adding the episode number + 376, which will give me the correct episode number. For example for 135, now it will be 511 (which is Season 5 episode 11)
$3 The Episode name captured from the previous regex
$4 The file extension captured from the previous regex

Run rename with -n (dry run) using the regex and file list created above to verify it will give you what you want/expect.

Output:

‘SHOW – 135 – Some Episode_www.unneededStuff.mp4’ would be renamed to ‘SHOW – 511 – Some Episode.mp4’

Now run it again without -n:

In this post I am showing how to use generate a MySQL 5 password-hash that can be used to create MySQL GRANTS using a hash instead of a password.

To use a password-hash to create GRANTs:

A good use case is the Puppet puppetlabs-mysql module to automate the MySQL environment, You can automate/define USER and GRANT creation by using the code below, but notice that it requires a password-hash instead of a password:

OR:

They recommend using mysql_password() for creating such a hash. But that means you need to have a MySQL server available.
In this post I am writing about getting those hashes using Python, I wrote a program/script to get the password-hash programatically.

The Python program/script can be found at:
https://github.com/parcejohn/mysql_password_hash

Usage

# Using Command line arguments – User provided password (e.g. ‘secret’)

# Using Command line arguments – Random password with length=20 (default length=12)

# interactive mode (no arguments)

One of the most important things you should do to your systems is to ensure they have the right time.
In this post I will show how to check and ensure your systems have the correct time using PowerCli.

==> Login to vCenter:

$admin = Get-Credential –Credential EXAMPLE\john
Connect-VIServer -Server vc.example.com -Credential $admin

==> Check time settings:

Output:

==> Set time to correct time:

==> Remove old NTP servers (if any):

Output:

==> Change NTP to desired configuration:

Output:

==> Enable Firewall Exception

==> Start NTPd service

==> Ensure NTPd service starts automatically (via policy)

==> Verify all is set the way you expected

Output:

In a previous post I showed how to create a vagrant box from scratch and add it to Vagrant: Creating a custom Vagrant Box

Traditionally you will place the Vagrant Box in a web server, and then use it in a Vagrantfile as follows:

In this post I will show you how to add versioning to your vagrant boxes, so that whenever the base box is changed/updated/patched your end-users/developers will be automatically notified and will be able to get the latest vagrant box with a simple ‘vagrant box update’ command.

1) Create the updated Vagrant Box
(e.g. vagrant_rhel6_vanilla_010.box for version 0.1.0) – you can use the procedure: Creating a custom Vagrant Box

2) Get a checksum of the box – You will need it later for the JSON Box catalog

OR

3) Upload the Box to the Vagrant Box web server repository:

I recommend to use the following web directory structure:
../vagrant/boxes serves the actual boxes/VMs
../vagrant serves the Box metadata JSON file (I explain what this is below)

Also, ensure the web server returns json as the Content-Type.
For Apache you need to check/add that the following configuration is present:
AddType application/json .json

To verify if your webserver is returning the correct Content-Type:

4) Create a Box catalog to be served by the web server:

The box catalog is a JSON metadata file allows you to server multiple versions of a box and enable update status notification.
Fields:
name: Name of the Vagrant Box, this is what you will put under config.vm.box on the Vagrantfile
Versions: This is an array/list/collection where you will put the different versions you are hosting/serving
url: This is the actual location of the box, this is what you will put under config.vm.box_url on the Vagrantfile

5) Modify the Vagrantfile to use the json box catalog file, instead of the actual box name

The first time you move from traditional box to versioned box, you need to delete the traditional box that is cached on your system.
This is only needed if you have a traditional box cached.

6) Vagrant up and see Vagrant download the versioned Box

7) Verify cached Vagrant Box is the correct version

At this point you have a Vagrant environment that supports versions and update status notifications, let’s create a new version of the Box and see it in action.

8) The Vagrant administrator creates an updated box
(e.g. vagrant_rhel6_vanilla_010.box for version 0.1.1) – you can use the procedure: Creating a custom Vagrant Box

9) The Vagrant administrator places the Vagrant Box in the web server

10) The Vagrant administrator adds the new Vagrant Box to the Box manifest Catalog

That’s it! from a Vagrant administrator perspective

11) End user/developer experience: User gets notified on the next Vagrant up and can easily update:

Everytime there is an update the end user gets notified and he/she can upgrade by simply:
vagrant box update

To verify, check cached Vagrant Boxes:

To delete older cached Vagrant Box no longer needed:

This improves the user/developer experience because they just need to do ‘vagrant box update‘ anytime there is an updated box from the Vagrant administrator.