Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Commit

Permalink
Merge pull request #64 from jtmulvey/master
Browse files Browse the repository at this point in the history
Deliver docs for Kabanero 060 security features
  • Loading branch information
jtmulvey authored Feb 10, 2020
2 parents e3822fa + d609b60 commit 26d2aa6
Show file tree
Hide file tree
Showing 18 changed files with 644 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions certmanager/samples/openliberty/createSample.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#Create a self-signing ClusterIssuer
oc create -f libertySelfSignedClusterIssuer.yaml
#Create a self-signed Certificate
oc create -f libertySelfSignedCert.yaml
#Create an OpenLibertyApplication deployment
oc create -f libertyApp.yaml
#Create network route for the deployment
oc create -f libertyAppSecureRoute.yaml
4 changes: 4 additions & 0 deletions certmanager/samples/openliberty/deleteSample.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
oc delete olapp libapp
oc delete route libapp
oc delete certificate liberty-cert
oc delete clusterIssuer liberty-selfsigning-issuer
143 changes: 143 additions & 0 deletions certmanager/samples/openliberty/generateKeystoreFromCertificate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/bin/bash

keystoreXML="/config/configDropins/defaults/keystore.xml"
keystoreDir="/output/resources/security"
tmpKeystoreDir="/tmp/resources/security"
keystore="$tmpKeystoreDir/key.p12"
truststore="$tmpKeystoreDir/trust.p12"

configDir="/etc/wlp/config"
customKeystore="$configDir/customKeystore/customkeystore.p12"
customKeystorePwdFile="$configDir/customKeystore/customkeystorepwd.txt"
customTruststore="$configDir/customTruststore/customtruststore.p12"
customTruststorePwdFile="$configDir/customTruststore/customtruststorepwd.txt"

caCert="$configDir/certificates/ca.crt"
publicCert="$configDir/certificates/tls.crt"
privateKey="$configDir/certificates/tls.key"

ocpCertExists=false
customKeystoreExists=false
customTruststoreExists=false
keystoreXMLExists=false
createSSLServerXML=false

checkOCPCerts () {
if [ -e $publicCert ] && [ -e $privateKey ];then
ocpCertExists=true
fi
}

checkCustomKeystore () {
if [ -e $customKeystore ] && [ -e $customKeystorePwdFile ];then
customKeystoreExists=true
elif [ -e $customKeystore ] && [ ! -e $customKeystorePwdFile ];then
echo 'error: Found custom keystore, but No custom keystore password file.'
exit 0
fi
}

checkCustomTruststore () {
if [ -e $customTruststore ] && [ -e $customTruststorePwdFile ];then
customTruststoreExists=true
elif [ -e $customTruststore ] && [ ! -e $customTruststorePwdFile ];then
echo 'error: Found custom truststore, but No custom truststore password file.'
exit 0
fi
}

checkKeystoreXML () {
if [ -e $keystoreXML ];then
keystoreXMLExists=true
fi
}

processKeystoreXML () {
#Retrieve passwords for the keystore and truststore
if [ $ocpCertExists = true ];then
if [ $keystoreXMLExists = true ];then
passwords=($(grep -oP 'password="\K[^"]*' $keystoreXML ))
KEYSTORE_PASSWORD=${passwords[0]}
#todo: add logic for only one password in keystore file
TRUSTSTORE_PASSWORD=${passwords[0]}
#todo add logic to create serverxml when only keystore part exists
createSSLServerXML=true
else
KEYSTORE_PASSWORD=$(openssl rand -base64 32)
TRUSTSTORE_PASSWORD=$KEYSTORE_PASSWORD
createSSLServerXML=true
fi
fi

if [ $customKeystoreExists = true ];then
KEYSTORE_PASSWORD=$(cat $customKeystorePwdFile)
createSSLServerXML=true
fi

if [ $customTruststoreExists = true ];then
TRUSTSTORE_PASSWORD=$(cat $customTruststorePwdFile)
createSSLServerXML=true
fi

#generate keystore XML
if [ $createSSLServerXML = true ];then
if [ $keystoreXMLExists = true ];then
#delete old keystore to avoid thrashing
rm $keystoreXML
fi
XML="<server description=\"Default Server\"><ssl id=\"defaultSSLConfig\" keyStoreRef=\"defaultKeyStore\" trustStoreRef=\"defaultTrustStore\"/><keyStore id=\"defaultKeyStore\" location=\"$keystoreDir/key.p12\" type=\"PKCS12\" password=\"$KEYSTORE_PASSWORD\" /><keyStore id=\"defaultTrustStore\" location=\"$keystoreDir/trust.p12\" type=\"PKCS12\" password=\"$TRUSTSTORE_PASSWORD\" /></server>"
mkdir -p $(dirname $keystoreXML)
echo $XML > $keystoreXML
fi

}

processKeystore () {
#create a temporary dir for keystore and truststore to avoid thrashing
mkdir -p $tmpKeystoreDir
#generate keystore from OCP Cert
if [ $ocpCertExists = true ];then
openssl pkcs12 -export -in $publicCert -inkey $privateKey -out $keystore -name default -passout pass:$KEYSTORE_PASSWORD
openssl pkcs12 -in $keystore -nokeys -clcerts -passin pass:$KEYSTORE_PASSWORD -nomacver | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > $tmpKeystoreDir/cl.crt
#openssl pkcs12 -in $keystore -nokeys -chain -cacerts -passin pass:$KEYSTORE_PASSWORD -nomacver | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > $tmpKeystoreDir/ocp_ca_issuer.crt
fi
#override OCP keystore if customKeystore exists
if [ $customKeystoreExists = true ];then
#normalize keystore name and location
mv -f $customKeystore $keystore
fi
mkdir -p $keystoreDir
mv -f $keystore $keystoreDir/key.p12
}

processTruststore () {
#generate truststore from OCP Cert if it exists
if [ $ocpCertExists = true ];then
keytool -importcert -keystore $truststore -storetype pkcs12 -storepass $TRUSTSTORE_PASSWORD -file $tmpKeystoreDir/cl.crt -alias defaultServer -noprompt
keytool -importcert -keystore $truststore -storetype pkcs12 -storepass $TRUSTSTORE_PASSWORD -file $caCert -noprompt
fi
#combine OCP Cert and custom truststore
if [ $ocpCertExists = true ] && [ $customTruststoreExists = true ];then
#merge truststores together
keytool -importkeystore -srckeystore $customTruststore -srcstoretype pkcs12 -srcstorepass $TRUSTSTORE_PASSWORD -destkeystore $truststore -deststoretype pkcs12 -deststorepass $TRUSTSTORE_PASSWORD -noprompt
#custom truststore only
elif [ $customTruststoreExists = true ];then
#normalize name and location
mv -f $customTruststore $truststore
fi
mv -f $truststore $keystoreDir/trust.p12
}

cleanUp () {
#Delete the temporary directory and the files within
rm -r $tmpKeystoreDir
}

checkOCPCerts
checkCustomKeystore
checkCustomTruststore
checkKeystoreXML
processKeystoreXML
processKeystore
processTruststore
cleanUp
Binary file not shown.
21 changes: 21 additions & 0 deletions certmanager/samples/openliberty/libertyApp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: openliberty.io/v1beta1
kind: OpenLibertyApplication
metadata:
name: libapp
spec:
applicationImage: quay.io/my-repo/my-app:1.0
service:
type: ClusterIP
port: 9443
expose: false

volumes:
- name: certificates
secret:
secretName: liberty-cert-secret

volumeMounts:
- name: certificates
mountPath: /etc/wlp/config/certificates
readOnly: true

19 changes: 19 additions & 0 deletions certmanager/samples/openliberty/libertyAppSecureRoute.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
kind: Route
apiVersion: route.openshift.io/v1
metadata:
name: libapp
labels:
app.kubernetes.io/instance: libapp
app.kubernetes.io/managed-by: open-liberty-operator
app.kubernetes.io/name: libapp
spec:
to:
kind: Service
name: libapp
weight: 100
port:
targetPort: 9443-tcp
tls:
termination: passthrough
insecureEdgeTerminationPolicy: Redirect
wildcardPolicy: None
14 changes: 14 additions & 0 deletions certmanager/samples/openliberty/libertySelfSignedCert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: liberty-cert
spec:
secretName: liberty-cert-secret
issuerRef:
name: liberty-selfsigning-issuer
kind: ClusterIssuer
commonName: "defaultServer"
organization:
- Example CA
dnsNames:
- defaultServer
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: liberty-selfsigning-issuer
spec:
selfSigned: {}

156 changes: 156 additions & 0 deletions certmanager/samples/openliberty/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Sample - Enabling SSL using a certificate created and managed by cert-manager for an Open Liberty Application
This sample installs and uses [cert-manager](https://cert-manager.io/docs/) to create a self-signed certificate. It uses the certificate to enable SSL in an Open-Liberty application running on OCP 4.2+


## Cert-Manager Flow
![Cert-manager Flow](cert-manager-flow.jpg)

## Prerequisites
1. Have an OCP 4.2+ Cluster already setup
2. Have a terminal logged in as admin to the OCP cluster using the `oc` CLI
3. Already have operator-based Kabanero Foundation installed.

## Install Steps
1. From your terminal, Install cert-manager using the [Installation Steps](https://cert-manager.io/docs/installation/openshift/)
2. From Your Browser, go to the OpenShift portal for your OCP system.
3. Go to the OperatorHub and Install the `Open Liberty Operator`
4. Verify the status of installing the `Open Liberty Operator` is `InstallSucceeded`


## Modify the Open-Liberty kernal docker image
This sample mounts a self-signed certificate created by cert-manager to the `OpenLibertyApplication` pod in the `/etc/wlp/config/certificates/` directory. You must modify the docker image to create a keystore from the certificate so that Open Liberty can utilize it for SSL.
Follow these steps for configuring your docker image:
1. Clone the OpenLiberty/ci.docker github repo:
`git clone git@github.com:OpenLiberty/ci.docker.git`
2. Modify ci.docker/releases/latest/kernel/helpers/runtime/docker-server.sh
Before the line with `exec "$@"`
Add the following lines:
```
publicCert="/etc/wlp/config/certificates/tls.crt"
privateKey="/etc/wlp/config/certificates/tls.key"
# If the CA tls.crt and tls.key exist, convert to P12 and use
if [ -e $publicCert ] && [ -e $privateKey ]
then
#Always generate on startup
/opt/ol/helpers/runtime/createKeystoreFromCert.sh
fi
```

3. Copy the `createKeystoreFromCert.sh` from this repo to your `ci.docker/releases/latest/kernel/helpers/runtime/` directory

4. Build the kernal image, from the `ci.docker/` directory
Run the following command:
```
./build/build.sh --dir=releases/latest/kernel --dockerfile=Dockerfile.ubi.adoptopenjdk8 --tag=<yourKernalTag>
```
\*Optional: You can also replace `Dockerfile.ubi.adoptopenjdk8` with any available image at this [repository](https://github.com/OpenLiberty/ci.docker/tree/master/releases/latest/kernel)
\*Replace `<yourKernalTag>` with any name you want to tag the modified kernal image


## Creating your docker image
Build an Open-Liberty Docker image for your application following the [Steps](https://github.com/OpenLiberty/ci.docker#building-an-application-image)
* Note: you must replace `FROM open-liberty:kernel` with `FROM <yourKernalTag>:latest`

## Create a self-signed certificate for an OpenLibertyApplication
1. Create `libertySelfSignedClusterIssuer.yaml` with the following yaml:
```
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: liberty-selfsigning-issuer
spec:
selfSigned: {}
```
2. Create `libertySelfSignedCert.yaml` with the following yaml:
```
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: liberty-cert
spec:
secretName: liberty-cert-secret
issuerRef:
name: liberty-selfsigning-issuer
kind: ClusterIssuer
commonName: "defaultServer"
organization:
- Example CA
dnsNames:
- defaultServer
```
3. Run the following commands to create the cluster resources for the yaml files above:
- Create a self-signing ClusterIssuer: `oc create -f libertySelfSignedClusterIssuer.yaml`
- Create a self-signed Certificate: `oc create -f libertySelfSignedCert.yaml`

## Create an OpenLibertyApplication Deployment
1. Create `libertyApp.yaml` with the following yaml:
```
apiVersion: openliberty.io/v1beta1
kind: OpenLibertyApplication
metadata:
name: libapp
spec:
applicationImage: quay.io/my-repo/my-app:1.0
service:
type: ClusterIP
port: 9443
expose: false
volumes:
- name: certificates
secret:
secretName: liberty-cert-secret
volumeMounts:
- name: certificates
mountPath: /etc/wlp/config/certificates
readOnly: true
```
* Replace `quay.io/my-repo/my-app:1.0` in the yaml above with your liberty docker image's docker registry location.
2. Create `libertyAppSecureRoute.yaml` with the following yaml:
```
kind: Route
apiVersion: route.openshift.io/v1
metadata:
name: libapp
labels:
app.kubernetes.io/instance: libapp
app.kubernetes.io/managed-by: open-liberty-operator
app.kubernetes.io/name: libapp
spec:
to:
kind: Service
name: libapp
weight: 100
port:
targetPort: 9443-tcp
tls:
termination: passthrough
insecureEdgeTerminationPolicy: Redirect
wildcardPolicy: None
```
3. Run the following commands to create the cluster resources for the yaml files above:
- Create your OpenLibertyApplication deployment: `oc create -f libertyApp.yaml`
- Create a networking route to your deployment: `oc create -f libertyAppSecureRoute.yaml`

Note: All of the commands for creating the ClusterIssuer, Certificate, OpenLibertyApplication, and Route are run in the `createSample.sh` script.

## Accessing Your OpenLibertyApplication after deployment
1. From your browser, go to your OpenShift cluster portal
2. In the menu on the left side of the screen, go to _Networking_ > _Routes_ and the link to your deployment will be listed under _Location_.

## Sample Scripts
Create the Demo OpenLibertyApplication and the required resources
`. createSample.sh`

The `createSample.sh` script listed above will do the following:
1. Create a `ClusterIssuer`
2. Create a `Certificate`
3. Create an `OpenLibertyApplication`
4. Create a networking `Route` to map your application to a public url and port.

Delete the demo application instance and its resources
`. deleteSample.sh`


Binary file added design/Kabanero_scan_sign.pdf
Binary file not shown.
Loading

0 comments on commit 26d2aa6

Please sign in to comment.