Skip to content

Commit

Permalink
(SIMP-4160) Add IP Addresses to subjectAltNames (#58)
Browse files Browse the repository at this point in the history
k8s requires the IP addresses of the nodes to be in the subjectAltNames
list. This adds that, as well as the hostname to the subjectAltNames
list for completeness.

SIMP-4160 #comment Add IP Addresses to subjectAltNames for testing
  • Loading branch information
trevor-vaughan authored Jan 2, 2018
1 parent 3c1cb04 commit fa7ad73
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 17 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### 1.9.0 / 2018-01-01
* Ensure that all host IP addresses get added to the internally generated PKI
keys as subjectAltNames. Kubernetes needs this and it does not hurt to have
in place for testing.

### 1.8.10 / 2017-11-02
* Fix bug in which dracut was not run on CentOS6, when dracut-fips was
installed for a FIPS-enabled test.
52 changes: 48 additions & 4 deletions files/pki/make.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# For ruby
export PATH=/opt/puppetlabs/puppet/bin:$PATH

DAYS="-days 365"
REQ="openssl req $SSLEAY_CONFIG"
CA="openssl ca $SSLEAY_CONFIG -config ca.cnf"
CA="openssl ca $SSLEAY_CONFIG"
VERIFY="openssl verify"
X509="openssl x509"

Expand Down Expand Up @@ -31,17 +34,58 @@ touch ${CATOP}/index.txt
echo "== Making CA certificate ..."
sed "s/^\([[:space:]]*commonName_default\).*/\1 \t\t= Fake Org Fake CA - ${CASERIAL}/" template_ca.cnf > ca.cnf

export OPENSSL_CONF=ca.cnf

$REQ -verbose -batch -passout file:cacertkey -new -x509 -keyout ${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT $DAYS

echo "== Making Client certificates ..."
for hname in $*; do
for hosts in $*; do
hosts=`echo $hosts | sed -e 's/[ \t]//g'`
hname=`echo $hosts | cut -d',' -f1`

echo "-- $hname"
mkdir -p "${keydist}/${hname}/cacerts"
sed -e "s/#HOSTNAME#/$hname/" template_host.cnf > "working/${hname}.cnf"

sed -e "s/#HOSTNAME#/${hname}/" template_host.cnf > "working/${hname}.cnf"

if [ "$hname" != "$hosts" ];
then
alts=`echo $hosts | cut -d',' -f1-`
altnames=''
for i in `echo $alts | tr ',' '\n'`
do
ruby -r ipaddr -e "begin IPAddr.new('$i') rescue exit 1 end"
if [ $? -eq 0 ]; then
# This is required due to some applications not properly supporting the
# IP version of subjectAltName.
prefixes='IP DNS'
else
prefixes='DNS'
fi

for prefix in $prefixes; do
if [ "$altnames" != '' ]
then
altnames+=",$prefix:$i"
else
altnames+="$prefix:$i"
fi
done
done

sed -i "s/# subjectAltName = #ALTNAMES#/subjectAltName = ${altnames}/" "working/${hname}.cnf"
fi

echo "-- running openssl req"
$REQ -config "working/${hname}.cnf" -new -nodes -keyout ${keydist}/${hname}/${hname}.pem -out working/"${hname}"req.pem -days 360 -batch;

export OPENSSL_CONF="working/${hname}.cnf"

$REQ -new -nodes -keyout ${keydist}/${hname}/${hname}.pem -out working/"${hname}"req.pem -days 360 -batch;

echo "-- running openssl ca"

$CA -passin file:cacertkey -batch -out ${keydist}/${hname}/${hname}.pub -infiles working/"${hname}"req.pem

cat ${keydist}/${hname}/${hname}.pub >> ${keydist}/${hname}/${hname}.pem
done

Expand Down
1 change: 1 addition & 0 deletions files/pki/template_host.cnf
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ authorityKeyIdentifier=keyid,issuer:always
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# subjectAltName = #ALTNAMES#

# Copy subject details
# issuerAltName=issuer:copy
Expand Down
81 changes: 69 additions & 12 deletions lib/simp/beaker_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -401,15 +401,61 @@ def run_fake_pki_ca_on( ca_sut = master, suts = hosts, local_dir = '' )
puts "== Fake PKI CA"
pki_dir = File.expand_path( "../../files/pki", File.dirname(__FILE__))
host_dir = '/root/pki'
fqdns = fact_on(hosts, 'fqdn')

ca_sut.mkdir_p(host_dir)
Dir[ File.join(pki_dir, '*') ].each{|f| copy_to( ca_sut, f, host_dir)}

# Collect network information from all SUTs
#
# We need this so that we don't insert any common IP addresses into certs
suts_network_info = {}

hosts.each do |host|
fqdn = fact_on(host, 'fqdn').strip

host_entry = { fqdn => [] }

# Ensure that all interfaces are active prior to collecting data
activate_interfaces(host)

# Gather the IP Addresses for the host to embed in the cert
interfaces = fact_on(host, 'interfaces').strip.split(',')
interfaces.each do |interface|
ipaddress = fact_on(host, "ipaddress_#{interface}")

next if ipaddress.nil? || ipaddress.empty? || ipaddress.start_with?('127.')

host_entry[fqdn] << ipaddress.strip

unless host_entry[fqdn].empty?
suts_network_info[fqdn] = host_entry[fqdn]
end
end
end

# Get all of the repeated SUT IP addresses:
# 1. Create a hash of elements that have a key that is the value and
# elements that are the same value
# 2. Grab all elements that have more than one value (therefore, were
# repeated)
# 3. Pull out an Array of all of the common element keys for future
# comparison
common_ip_addresses = suts_network_info
.values.flatten
.group_by{ |x| x }
.select{|k,v| v.size > 1}
.keys

# generate PKI certs for each SUT
Dir.mktmpdir do |dir|
pki_hosts_file = File.join(dir, 'pki.hosts')
File.open(pki_hosts_file, 'w'){|fh| fqdns.each{|fqdn| fh.puts fqdn}}

File.open(pki_hosts_file, 'w') do |fh|
suts_network_info.each do |fqdn, ipaddresses|
fh.puts ([fqdn] + (ipaddresses - common_ip_addresses)) .join(',')
end
end

copy_to(ca_sut, pki_hosts_file, host_dir)
# generate certs
on(ca_sut, "cd #{host_dir}; cat #{host_dir}/pki.hosts | xargs bash make.sh")
Expand Down Expand Up @@ -489,6 +535,26 @@ def copy_keydist_to( ca_sut = master, host_keydist_dir = nil )
end


# Activate all network interfaces on the target system
#
# This is generally needed if the upstream vendor does not activate all
# interfaces by default (EL7 for example)
#
# Can be passed any number of hosts either singly or as an Array
def activate_interfaces(hosts)
Array(hosts).each do |host|
interfaces = fact_on(host, 'interfaces').strip.split(',')
interfaces.delete_if { |x| x =~ /^lo/ }

interfaces.each do |iface|
if fact_on(host, "ipaddress_#{iface}").strip.empty?
on(host, "ifup #{iface}", :accept_all_exit_codes => true)
end
end
end
end


## Inline Hiera Helpers ##
## These will be integrated into core Beaker at some point ##

Expand All @@ -505,16 +571,7 @@ def copy_keydist_to( ca_sut = master, host_keydist_dir = nil )
# We can't guarantee that the upstream vendor isn't disabling interfaces so
# we need to turn them on at each context run
c.before(:context) do
hosts.each do |host|
interfaces = fact_on(host, 'interfaces').strip.split(',')
interfaces.delete_if { |x| x =~ /^lo/ }

interfaces.each do |iface|
if fact_on(host, "ipaddress_#{iface}").strip.empty?
on(host, "ifup #{iface}", :accept_all_exit_codes => true)
end
end
end
activate_interfaces(hosts)
end

c.after(:all) do
Expand Down
2 changes: 1 addition & 1 deletion lib/simp/beaker_helpers/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Simp; end

module Simp::BeakerHelpers
VERSION = '1.8.10'
VERSION = '1.9.0'
end

0 comments on commit fa7ad73

Please sign in to comment.