Category Archives: security

How to whitelist Google IP address ranges in firewall using iptables

As an administrator, when you need to obtain a range of IP addresses for Google APIs and services’ default domains, you can refer to the following sources of information.

The default domains’ IP address ranges for Google APIs and services fit within the list of ranges between these 2 sources. (Subtract the usable ranges from the complete list.)

Once you get the IP address ranges, use the “`xargs“` command to update iptables.

echo "" | xargs -I% iptables -I INPUT -p tcp -s % -j ACCEPT

How to setup SOCKS proxy in Linux

SOCKS server is a general purpose proxy server that establishes a TCP connection to another server on behalf of a client, then routes all the traffic back and forth between the client and the server. It works for any kind of network protocol on any port. SOCKS Version 5 adds additional support for security and UDP.

Use of SOCKS is as a circumvention tool, allowing traffic to bypass Internet filtering to access content otherwise blocked, e.g., by governments, workplaces, schools, and country-specific web services

Using SSH

SOCKS proxies can be created without any special SOCKS proxy software if you have Open SSH installed on your server and an SSH client with dynamic tunnelling support installed on your client computer.

ssh -D 1080 user@<IP Address or Domain of your Server>

Now, enter your password and make sure to leave the Terminal window open. You have now created a SOCKS proxy at localhost:1080. Only close this window if you wish to disable your local SOCKS proxy.

Using Microsocks program

MicroSocks is a multithreaded, small, efficient SOCKS5 server.

It’s very lightweight, and very light on resources too:

for every client, a thread with a stack size of 8KB is spawned. the main process basically doesn’t consume any resources at all.

the only limits are the amount of file descriptors and the RAM.

It’s also designed to be robust: it handles resource exhaustion gracefully by simply denying new connections, instead of calling abort() as most other programs do these days.

another plus is ease-of-use: no config file necessary, everything can be done from the command line and doesn’t even need any parameters for quick setup.

Installing microsocks

“`git clone“`

“`cd microsocks“`


Starting socks service

microsocks -1 -i listenip -p port -u user -P password -b bindaddr

all arguments are optional. by default listenip is and port 1080.

option -1 activates auth_once mode: once a specific ip address authed successfully with user/pass, it is added to a whitelist and may use the proxy without auth. this is handy for programs like firefox that don’t support user/pass auth. for it to work you’d basically make one connection with another program that supports it, and then you can use firefox too.

Howto use ssh as VPN tunnel

SSH is typically used to log into a remote machine and execute commands, but it also supports tunneling, forwarding TCP ports and X11 connections.

What is SSH Tunneling?

A tunneling protocol may, for example, allow a foreign protocol to run over a network that does not support that particular protocol, such as running IPv6 over IPv4.

SSH tunneling is a method of transporting arbitrary networking data over an encrypted SSH connection. It can be used to add encryption to legacy applications. … It also provides a way to secure the data traffic of any given application using port forwarding, basically tunneling any TCP/IP port over SSH.


sshuttle is not exactly a VPN, and not exactly port forwarding. It’s kind of both, and kind of neither.

It’s like a VPN, since it can forward every port on an entire network, not just ports you specify. Conveniently, it lets you use the “real” IP addresses of each host rather than faking port numbers on localhost.

On the other hand, the way it works is more like ssh port forwarding than a VPN. Normally, a VPN forwards your data one packet at a time, and doesn’t care about individual connections; ie. it’s “stateless” with respect to the traffic. sshuttle is the opposite of stateless; it tracks every single connection.


“` sudo pip install sshuttle“`


“`$ sshuttle –dns -v -r <remote-host> 0/0“`

* This will forward all connections including DNS requests…


usage: sshuttle [-l [ip:]port] [-r [user@]sshserver[:port]] <subnets...>

positional arguments:
 capture and forward traffic to these subnets
 (whitespace separated)

optional arguments:
 -h, --help show this help message and exit
 -l [IP:]PORT, --listen [IP:]PORT
 transproxy to this ip address and port number
 -H, --auto-hosts continuously scan for remote hostnames and update
 local /etc/hosts as they are found
 -N, --auto-nets automatically determine subnets to route
 --dns capture local DNS requests and forward to the remote
 DNS server
 --ns-hosts IP[,IP] capture and forward DNS requests made to the following
 --to-ns IP[:PORT] the DNS server to forward requests to; defaults to
 servers in /etc/resolv.conf on remote side if not
 --method TYPE auto, nat, nft, tproxy, pf, ipfw
 --python PATH path to python interpreter on the remote server
 ssh hostname (and optional username) of remote
 sshuttle server
 -x IP/MASK[:PORT[-PORT]], --exclude IP/MASK[:PORT[-PORT]]
 exclude this subnet (can be used more than once)
 -X PATH, --exclude-from PATH
 exclude the subnets in a file (whitespace separated)
 -v, --verbose increase debug message verbosity
 -V, --version print the sshuttle version number and exit
 -e CMD, --ssh-cmd CMD
 the command to use to connect to the remote [ssh]
 --seed-hosts HOSTNAME[,HOSTNAME]
 comma-separated list of hostnames for initial scan
 (may be used with or without --auto-hosts)
 --no-latency-control sacrifice latency to improve bandwidth benchmarks
 --wrap NUM restart counting channel numbers after this number
 (for testing)
 --disable-ipv6 disable IPv6 support
 -D, --daemon run in the background as a daemon
 -s PATH, --subnets PATH
 file where the subnets are stored, instead of on the
 command line
 --syslog send log messages to syslog (default if you use
 --pidfile PATH pidfile name (only if using --daemon) [./]
 --user USER apply all the rules only to this linux user
 --firewall (internal use only)
 --hostwatch (internal use only)
 --no-sudo-pythonpath do not set PYTHONPATH when invoking sudo

Openvas installation in CentOS 7

What is Openvas?

OpenVAS (Open Vulnerability Assessment System, originally known as GNessUs) is a software framework of several services and tools offering vulnerability scanning and vulnerability management.

All OpenVAS products are free software, and most components are licensed under the GNU General Public License (GPL). Plugins for OpenVAS are written in the Nessus Attack Scripting Language, NASL.

The primary reason to use this scan type is to perform comprehensive security testing of an IP address. It will initially perform a port scan of an IP address to find open services. Once listening services are discovered they are then tested for known vulnerabilities and misconfiguration using a large database (more than 53000 NVT checks). The results are then compiled into a report with detailed information regarding each vulnerability and notable issues discovered.

Once you receive the results of the tests, you will need to check each finding for relevance and possibly false positives. Any confirmed vulnerabilities should be re-mediated to ensure your systems are not at risk.

Vulnerability scans performed from externally hosted servers give you the same perspective as an attacker. This has the advantage of understanding exactly what is exposed on external-facing services.

Step 1: Disable SELinux


sed -i ‘s/=enforcing/=disabled/’ /etc/selinux/config


and reboot the machine.

Step 2:  Install dependencies


yum -y install wget rsync curl net-tools


Step 3: Install OpenVAS repository

install the official repository so that OpenVAS works appropriately in the analysis of vulnerabilities.


wget -q -O – |sh


Step 4: Install OpenVAS


yum -y install openvas


Step 5: Run OpenVAS

Once OpenVAS is installed, we continue to start it by executing the following command:




Once downloaded it will be necessary to configure the GSAD IP address, Greenbone Security Assistant, which is a web interface to manage system scans.

Step 6: Configure OpenVAS Connectivity

We go to our browser and enter the IP address of the CentOS 7 server where we have installed OpenVAS, and we will see that the following message is displayed:

Openvas dashboard


Automatic NVT Updates With Cron


35 1 * * * /usr/sbin/greenbone-nvt-sync > /dev/null
5 0 * * * /usr/sbin/greenbone-scapdata-sync > /dev/null
5 1 * * * /usr/sbin/greenbone-certdata-sync > /dev/null



How to use ipset command on linux to block bulk IPs

ipset is a companion application for the iptables Linux firewall. It allows you to setup rules to quickly and easily block a set of IP addresses, among other things.


Debian based system

“`# apt install ipset“`

Redhat based system

“`# yum install ipset“`

Blocking a list of network

Start by creating a new “set” of network addresses. This creates a new “hash” set of “net” network addresses named “myset”.

# ipset create myset hash:net


# ipset -N myset nethash

Add any IP address that you’d like to block to the set.

# ipset add myset
# ipset add myset
# ipset add myset
# ipset add myset

Finally, configure iptables to block any address in that set. This command will add a rule to the top of the “INPUT” chain to “-m” match the set named “myset” from ipset (–match-set) when it’s a “src” packet and “DROP”, or block, it.

# iptables -I INPUT -m set --match-set myset src -j DROP

Blocking a list of IP addresses

Start by creating a new “set” of ip addresses. This creates a new “hash” set of “ip” addresses named “myset-ip”.

# ipset create myset-ip hash:ip


# ipset -N myset-ip iphash

Add any IP address that you’d like to block to the set.

# ipset add myset-ip
# ipset add myset-ip

Finally, configure iptables to block any address in that set.

# iptables -I INPUT -m set --match-set myset-ip src -j DROP

Making ipset persistent

The ipset you have created is stored in memory and will be gone after reboot. To make the ipset persistent you have to do the followings:

First save the ipset to /etc/ipset.conf:

# ipset save > /etc/ipset.conf

Then enable ipset.service, which works similarly to iptables.service for restoring iptables rules.

Other Commands

To view the sets:

# ipset list


# ipset -L

To delete a set named “myset”:

# ipset destroy myset


# ipset -X myset

To delete all sets:

# ipset destroy

How to configure IPsec/L2TP VPN Clients on Linux

After setting up your own VPN server, follow these steps to configure your devices. In case you are unable to connect, first, check to make sure the VPN credentials were entered correctly.

Commands must be run as root on your VPN client.

To set up the VPN client, first install the following packages:

# For Ubuntu & Debian
apt-get update
apt-get -y install strongswan xl2tpd

# For RHEL/CentOS
yum -y install epel-release
yum --enablerepo=epel -y install strongswan xl2tpd

yum -y install strongswan xl2tpd

Create VPN variables (replace with actual values):


Configure strongSwan:

cat > /etc/ipsec.conf <<EOF
# ipsec.conf - strongSwan IPsec configuration file

# basic configuration

config setup
  # strictcrlpolicy=yes
  # uniqueids = no

# Add connections here.

# Sample VPN connections

conn %default

conn myvpn

cat > /etc/ipsec.secrets <<EOF

chmod 600 /etc/ipsec.secrets

# For CentOS/RHEL & Fedora ONLY
mv /etc/strongswan/ipsec.conf /etc/strongswan/ipsec.conf.old 2>/dev/null
mv /etc/strongswan/ipsec.secrets /etc/strongswan/ipsec.secrets.old 2>/dev/null
ln -s /etc/ipsec.conf /etc/strongswan/ipsec.conf
ln -s /etc/ipsec.secrets /etc/strongswan/ipsec.secrets

Configure xl2tpd:

cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[lac myvpn]
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tpd.client
length bit = yes

cat > /etc/ppp/options.l2tpd.client <<EOF
mtu 1280
mru 1280
connect-delay 5000
name $VPN_USER
password $VPN_PASSWORD

chmod 600 /etc/ppp/options.l2tpd.client

The VPN client setup is now complete. Follow the steps below to connect.

Note: You must repeat all steps below every time you try to connect to the VPN.

Create xl2tpd control file:

mkdir -p /var/run/xl2tpd
touch /var/run/xl2tpd/l2tp-control

Restart services:

service strongswan restart
service xl2tpd restart

Start the IPsec connection:

# Ubuntu & Debian
ipsec up myvpn

# CentOS/RHEL & Fedora
strongswan up myvpn

Start the L2TP connection:

echo "c myvpn" > /var/run/xl2tpd/l2tp-control

Run ifconfig and check the output. You should now see a new interface ppp0.

Check your existing default route:

ip route

Find this line in the output: default via X.X.X.X .... Write down this gateway IP for use in the two commands below.

Exclude your VPN server’s IP from the new default route (replace with actual value):

route add YOUR_VPN_SERVER_IP gw X.X.X.X

If your VPN client is a remote server, you must also exclude your Local PC’s public IP from the new default route, to prevent your SSH session from being disconnected (replace with actual value):


Add a new default route to start routing traffic via the VPN server:

route add default dev ppp0

The VPN connection is now complete. Verify that your traffic is being routed properly:

wget -qO-; echo

The above command should return Your VPN Server IP.

To stop routing traffic via the VPN server:

route del default dev ppp0

To disconnect:

# Ubuntu & Debian
echo "d myvpn" > /var/run/xl2tpd/l2tp-control
ipsec down myvpn

# CentOS/RHEL & Fedora
echo "d myvpn" > /var/run/xl2tpd/l2tp-control
strongswan down myvpn

Fusebill AJAX Transparent Redirect

To facilitate PCI compliant credit card collections Fusebill provides a AJAX Transparent Redirect endpoint which you can use to securely capture customer’s credit cards. If you are adding the first payment method on a customer, it will be set to the default payment method automatically.

This API action is authenticated with a separate Public API Key. If you do not have that key, please contact Fusebill Support. The Public Key can only be used to authenticate the Transparent Redirect action.

Google reCAPTCHA required.

Fusebill leverages reCAPTCHA technology to ensure payment method data captured is provided by a human and to protect against bots and scripting.

We use Google reCAPTCHA V2 in order to accomplish this.
The basic workflow for how this is accomplished is as follows:

  • Using Fusebill’s public site key, the client is presented with a captcha widget.
  • The user then verifies that they are human, starting with a check box. The user may be presented with additional verification steps such as an image recognition task.
  • The captcha widget then verifies with Google that the user is human, and returns a response token.
  • That response token is then sent to Fusebill with the payment method data for our system to validate and verify.
Fusebill Environment
reCAPTCHA Public Site Key

Staging (


Sandbox and Production (


Create Credit Card Payment Method

Field Name


This is the Fusebill customer ID of the customer you wish to add the card to




This is your public API key.
This is found in fusebill account under Settings > Integrations > Transparent Redirect.




This is the credit card number.





The first name of the cardholder.




The last name of the card holder.




Expiration month on the credit card.




Expiration on the credit card.




The credit card verification number.




Recaptcha token response.




WePay Risk token




Client/Customer IP address




Customer Email address




First line of payment method address.




Second line of payment method address.




City of the payment method




State ID of the Payment method.
These can be found by performing a GET to v1/countries




Country ID of the payment method.
These can be found by performing a GET to v1/countries




PostalZip of the payment method




Object that allows specifying an amount to collect when creating the card.

Only works through Json
"collectionAmount": 1.0



+ Denotes a field required for Fusebill Payments API Risk Fields
* Denotes fields required for AVS and may be required by your account’s Gateway. These fields are also required if using Fusebill Payments accounts as AVS is mandatory.

Notes:- Address information can optionally be captured as well.

Sample Code

<!DOCTYPE html>
<html xmlns="">
		<title>AJAX Transparent Redirect</title>
      var verifyCallback = function(response) {
        document.getElementById("mySubmit").disabled = false;
      var expCallback = function () {
        document.getElementById("mySubmit").disabled = true;
      var onloadCallback = function() {
        grecaptcha.render('exampleWithCallback', {
          'sitekey': '',
          'callback': verifyCallback,
          'expired-callback': expCallback
			function AJAXTransparentRedirect() {                                 
				var dataString = 'CustomerId='+ $('input#CustomerId').val() + 
						'&PublicApiKey=' + $('input#PublicApiKey').val() + 
						'&SuccessUri='+$('input#SuccessUri').val() +
						'&FailUri='+$('input#FailUri').val() + 
						'&CardNumber='+$('input#CardNumber').val() + 
						'&FirstName='+$('input#FirstName').val() + 
						'&LastName='+$('input#LastName').val() + 
						'&ExpirationMonth='+$('input#ExpirationMonth').val() + 
						'&ExpirationYear='+$('input#ExpirationYear').val() + 
						'&makeDefault='+$('input#MakeDefault').val() + 
						'&Cvv='+$('input#Cvv').val() +
						'&recaptcha=' + $('input#recaptcha_token').val();

				//Set up the request
				var request = $.ajax({
					type: "POST",
					url: "",                   
					data: dataString 

				//Set up the callback functions
				request.done(function (msg) {


"); alert("success"); //document.location.replace = ''; }); (jqXHR) { // $('#response').append("


"); alert(parseAndBuildErrorMessage(jqXHR)); //document.location.replace = ''; expCallback(); }); } function htmlEscape(msg) { return document.createElement('span') .appendChild(document.createTextNode(msg)) .parentNode .innerHTML; } function buildErrorMessage (errors) { if (errors.length == 0) { return ""; } var message; if (errors.length > 1) { message = "
    "; for (var i = 0; i " + htmlEscape(errors[i].Value) + ""; } } message += "
"; } else { var internalErrors = errors[0].Value; internalErrors = internalErrors.split("\r\n"); if (internalErrors.length > 1) { message = "
    "; for (var i = 0; i " + htmlEscape(internalErrors[i]) + ""; } message += "
"; } } else { message = htmlEscape(errors[0].Value); } } return message; } function parseAndBuildErrorMessage (xhr) { if (xhr.status >= 500) return "An error occurred, please try again"; else return buildErrorMessage(xhr.responseJSON.Errors); } </head> <body> <form id="allfields"> <fieldset> <div> <label for="CustomerId">Customer Id</label> <input autofocus="autofocus" id="CustomerId" name="CustomerId" type="text" value="your customer id here" /> </div> <div> <label for="PublicApiKey">Public Api Key</label> <input id="PublicApiKey" name="PublicApiKey" type="text" value="your key here" /> </div> <div> <label for="CardNumber">Card number</label> <input id="CardNumber" name="CardNumber" type="text" value="4111111111111111" /> </div> <div> <label for="FirstName">First name</label> <input id="FirstName" name="FirstName" type="text" value="John" /> </div> <div> <label for="LastName">Last name</label> <input id="LastName" name="LastName" type="text" value="Doe" /> </div> <div> <label for="ExpirationMonth">Expiry month</label> <input id="ExpirationMonth" name="ExpirationMonth" type="text" value="12" /> </div> <div> <label for="ExpirationYear">Expiry year</label> <input id="ExpirationYear" name="ExpirationYear" type="text" value="20" /> </div> <div> <label for="Cvv">CVV</label> <input id="Cvv" name="Cvv" type="text" value="123" /> </div> <input id="MakeDefault" name="MakeDefault" type="hidden" value="true" /> <div class="g-recaptcha" id="exampleWithCallback"></div> <input id="recaptcha_token" name="recaptcha_token" type="hidden" /> <fieldset> </form> <input type="button" onCLick="AJAXTransparentRedirect();" value="Submit Card" id="mySubmit" disabled /> <div id="response"/> </body> </html>

Sample Response

    "maskedCardNumber" : "************1111",
    "cardType" : "Visa",
    "expirationMonth" : 10,
    "expirationYear" : 23,
    "customerId" : 50975,
    "firstName" : "a",
    "lastName" : "a",
    "address1" : null,
    "address2" : null,
    "countryId" : null,
    "country" : "",
    "stateId" : null,
    "state" : "",
    "city" : null,
    "postalZip" : null,
    "makeDefault" : true,
    "id" : 5933,
    "uri" : null

Fusebill Payments

When using Fusebill Payments as your gateway processing account, some additional processing and data is required.

These are the ClientIP and a Risk token.

Additional information is available here.

Fusebill Test Gateways

Available here.

How to modify permissions(booleans) of SELinux for deamons(programs)

SELinux offers more enhanced security for linux. It is always recommended not to disable SELinux for servers which are more delicate, instead you can control the permissions for the deamons, programms or users using SELinux.

SELinux maintains the status of permissions for all deamons with attributes called booleans.

Get SELinux booleans

$ getsebool -a

The above command will give you lot of variables with status either on or off. If you want to fetch for particular process or context use grep 

To get all booleans regarding httpd(apache web server)

$ getsebool -a | grep httpd
allow_httpd_anon_write --> off
allow_httpd_mod_auth_ntlm_winbind --> off
allow_httpd_mod_auth_pam --> off
allow_httpd_sys_script_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> on
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_manage_ipa --> off
httpd_read_user_content --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_tmp_exec --> off
httpd_tty_comm --> on
httpd_unified --> on
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_verify_dns --> off


Set SELinux Booleans

To set selinux booleans we use the command setsebool

$ setsebool

Usage:  setsebool [ -PV ] boolean value | bool1=val1 bool2=val2...

Here is how you can change

$ setsebool -P <boolean> <on|off>

For suppose if you want to allow httpd to allow sending mail

setsebool -VP httpd_can_sendmail on

If you want to enable ftp server on httpd,

setsebool -P httpd_enable_ftp_server on

To enable apache to connect with external database

setsebool -P httpd_can_network_connect_db on

Like wise you can change the required booleans status. To query the modified status ues getsebool with grep.


How to enable or disable SELinux and check status on centOS

The SELinux stands for Security-Enhanced Linux where it is a linux kernel security module. It is enabled by default on most of the linux distribution that we use for servers like centOS. It provides  enhanced security measurements. It gives you fine control over all programs and daemons  on their activities like communicating with out side programs  or controlling whether to establish a outside connections for a particular program.

It is always recommended to have SELinux enabled on a server to avoid common security glitches.

To query the current status of SELinux  use the following commands


The above command will report the current status  of SELinux. Whether SELinux is enforcing, permissive, or disabled. If it is already disabled.

Disabling SELinux

Open the file  /etc/selinux/config  and change the option SELINUX to disabled

if you open file you would see something like

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# mls - Multi Level Security protection.

If SELinux is enabled you would see enforcing replace it with disabled.

You should restart the machine to take effect If you change SELINUX status from Enabled to Disabled or vice versa.

Enabling SELInux

To enable SELinux follow the below instructions,

  1. Open the file /etc/selinux/config  
  2. Change option SELINUX from disabled to enforcing
  3. Restart the machine

Change mode

To change the mode of SELinux which is running

$ setenforce
usage:  setenforce [ Enforcing | Permissive | 1 | 0 ]
$ #To Set mode to Permissive
$ setenforce Permissive

Check Status

SELinux is the linux  kernel module for enhanced security. SELinux stands for Security-Enhanced Linux. If SELinux is installed on your machine or server you can check the current status  by using following commands

[root@lintel ~]# getenforce

The above command will give you one of the following as an output

enforcing, permissive, or disabled

You use the below command which will give simple overview

[root@lintel ~]# sestatus

If enabled you will output something like

# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   permissive
Mode from config file:          permissive
Policy version:                 24
Policy from config file:        targeted


You can also check the configuration which is located at /etc/selinux/config.

In above config file  the option SELINUX  describes the status of SELinux. But it’s not precise to determine the status from the configuration file, it’s better to determine the status by using commands mentioned above.

*Note: You need administrator privileges to either enable or disable SELinux

How to check certificate information of web server using openssl

In this article we will see how to check certificate information of webserver using command line tool openssl

The below command will get you the valid period of the ssl certificate.

naveen@lintel:~$ echo | openssl s_client -connect 2>/dev/null | openssl x509 -noout -dates
notBefore=Dec 10 18:03:47 2015 GMT
notAfter=Mar  9 00:00:00 2016 GMT

To check the certificate information of web server, use the following command. Here I’m using in this example

naveen@lintel:~$ echo | openssl s_client -connect -showcerts

Export certificate into a file

naveen@lintel:~$ openssl s_client -connect -showcerts < /dev/null  | openssl x509 -inform PEM  -text -out cert

If you want to extract the public key from the certificate, here is how you can do

naveen@lintel:~$ openssl s_client -connect -showcerts < /dev/null  | openssl x509 -inform PEM  -pubkey
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
-----END PUBLIC KEY-----


[1] Certificates and Encodings