Refactor TLS code
This commit is contained in:
committed by
Stephen D Marshall
parent
ce184408df
commit
956b4a8e49
@@ -126,19 +126,19 @@ func doMain() error {
|
||||
// Print out versioning information
|
||||
logVersionInfo()
|
||||
|
||||
keylabel, cmsDB, p12Trust, _, err := tls.ConfigureTLSKeystores(keyDir, trustDir, keyStoreDir)
|
||||
keyLabel, cmsKeystore, p12Truststore, err := tls.ConfigureTLSKeystores()
|
||||
if err != nil {
|
||||
logTermination(err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = configureTLS(keylabel, cmsDB, *devFlag)
|
||||
err = tls.ConfigureTLS(keyLabel, cmsKeystore, *devFlag, log)
|
||||
if err != nil {
|
||||
logTermination(err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = postInit(name, keylabel, p12Trust)
|
||||
err = postInit(name, keyLabel, p12Truststore)
|
||||
if err != nil {
|
||||
logTermination(err)
|
||||
return err
|
||||
|
||||
@@ -22,23 +22,23 @@ import (
|
||||
)
|
||||
|
||||
// postInit is run after /var/mqm is set up
|
||||
func postInit(name, keylabel string, p12Trust tls.KeyStoreData) error {
|
||||
func postInit(name, keyLabel string, p12Truststore tls.KeyStoreData) error {
|
||||
enableWebServer := os.Getenv("MQ_ENABLE_EMBEDDED_WEB_SERVER")
|
||||
if enableWebServer == "true" || enableWebServer == "1" {
|
||||
// Configure the web server (if enabled)
|
||||
keystore, err := configureWebServer(keylabel, p12Trust)
|
||||
webKeystore, err := configureWebServer(keyLabel, p12Truststore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// If trust-store is empty, set reference to point to the key-store
|
||||
p12TrustStoreRef := "MQWebTrustStore"
|
||||
if len(p12Trust.TrustedCerts) == 0 {
|
||||
p12TrustStoreRef = "MQWebKeyStore"
|
||||
// If trust-store is empty, set reference to point to the keystore
|
||||
webTruststoreRef := "MQWebTrustStore"
|
||||
if len(p12Truststore.TrustedCerts) == 0 {
|
||||
webTruststoreRef = "MQWebKeyStore"
|
||||
}
|
||||
// Start the web server, in the background (if installed)
|
||||
// WARNING: No error handling or health checking available for the web server
|
||||
go func() {
|
||||
err = startWebServer(keystore, p12Trust.Password, p12TrustStoreRef)
|
||||
err = startWebServer(webKeystore, p12Truststore.Password, webTruststoreRef)
|
||||
if err != nil {
|
||||
log.Printf("Error starting web server: %v", err)
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 2018, 2019
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/ibm-messaging/mq-container/internal/command"
|
||||
"github.com/ibm-messaging/mq-container/internal/keystore"
|
||||
"github.com/ibm-messaging/mq-container/internal/mqtemplate"
|
||||
"github.com/ibm-messaging/mq-container/internal/tls"
|
||||
)
|
||||
|
||||
// Location to store the keystores
|
||||
const keyStoreDir = "/run/runmqserver/tls/"
|
||||
|
||||
// KeyDir is the location of the certificate keys to import
|
||||
const keyDir = "/etc/mqm/pki/keys"
|
||||
|
||||
// TrustDir is the location of the Certifates to add
|
||||
const trustDir = "/etc/mqm/pki/trust"
|
||||
|
||||
// configureWebTLS configures TLS for Web Console
|
||||
func configureWebTLS(label string) error {
|
||||
// Return immediately if we have no certificate to use as identity
|
||||
if label == "" && os.Getenv("MQ_GENERATE_CERTIFICATE_HOSTNAME") == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
webConfigDir := "/etc/mqm/web/installations/Installation1/servers/mqweb"
|
||||
tls := "tls.xml"
|
||||
|
||||
tlsConfig := filepath.Join(webConfigDir, tls)
|
||||
newTLSConfig := filepath.Join(webConfigDir, tls+".tpl")
|
||||
err := os.Remove(tlsConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not delete file %s: %v", tlsConfig, err)
|
||||
}
|
||||
// we symlink here to prevent issues on restart
|
||||
err = os.Symlink(newTLSConfig, tlsConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not create symlink %s->%s: %v", newTLSConfig, tlsConfig, err)
|
||||
}
|
||||
mqmUID, mqmGID, err := command.LookupMQM()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not find mqm user or group: %v", err)
|
||||
}
|
||||
err = os.Chown(tlsConfig, mqmUID, mqmGID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could change ownership of %s to mqm: %v", tlsConfig, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// configureTLSDev configures TLS for developer defaults
|
||||
func configureTLSDev() error {
|
||||
const mqsc string = "/etc/mqm/20-dev-tls.mqsc"
|
||||
const mqscTemplate string = mqsc + ".tpl"
|
||||
|
||||
if os.Getenv("MQ_DEV") == "true" {
|
||||
err := mqtemplate.ProcessTemplateFile(mqscTemplate, mqsc, map[string]string{}, log)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
_, err := os.Stat(mqsc)
|
||||
if !os.IsNotExist(err) {
|
||||
err = os.Remove(mqsc)
|
||||
if err != nil {
|
||||
log.Errorf("Error removing file %s: %v", mqsc, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// configureTLS configures TLS for queue manager
|
||||
func configureTLS(certLabel string, cmsKeystore tls.KeyStoreData, devmode bool) error {
|
||||
log.Debug("Configuring TLS")
|
||||
|
||||
const mqsc string = "/etc/mqm/15-tls.mqsc"
|
||||
const mqscTemplate string = mqsc + ".tpl"
|
||||
|
||||
err := mqtemplate.ProcessTemplateFile(mqscTemplate, mqsc, map[string]string{
|
||||
"SSLKeyR": strings.TrimSuffix(cmsKeystore.Keystore.Filename, ".kdb"),
|
||||
"CertificateLabel": certLabel,
|
||||
}, log)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if devmode && certLabel != "" {
|
||||
err = configureTLSDev()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// configureWebKeyStore configures the key stores for the web console
|
||||
func configureWebKeyStore(p12TrustStore tls.KeyStoreData) (string, error) {
|
||||
// TODO find way to supply this
|
||||
// Override the webstore variables to hard coded defaults
|
||||
webKeyStoreName := tls.WebDefaultLabel + ".p12"
|
||||
|
||||
// Check keystore exists
|
||||
ks := filepath.Join(keyStoreDir, webKeyStoreName)
|
||||
_, err := os.Stat(ks)
|
||||
// Now we know if the file exists let's check whether we should have it or not.
|
||||
// Check if we're being told to generate the certificate
|
||||
genHostName := os.Getenv("MQ_GENERATE_CERTIFICATE_HOSTNAME")
|
||||
if genHostName != "" {
|
||||
// We've got to generate the certificate with the hostname given
|
||||
if err == nil {
|
||||
log.Printf("Replacing existing keystore %s - generating new certificate", ks)
|
||||
}
|
||||
// Keystore doesn't exist so create it and populate a certificate
|
||||
newKS := keystore.NewPKCS12KeyStore(ks, p12TrustStore.Password)
|
||||
err = newKS.Create()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to create keystore %s: %v", ks, err)
|
||||
}
|
||||
|
||||
err = newKS.CreateSelfSignedCertificate("default", fmt.Sprintf("CN=%s", genHostName), genHostName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to generate certificate in keystore %s with DN of 'CN=%s': %v", ks, genHostName, err)
|
||||
}
|
||||
} else {
|
||||
// Keystore should already exist
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to find existing keystore %s: %v", ks, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Check truststore exists
|
||||
_, err = os.Stat(p12TrustStore.Keystore.Filename)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to find existing truststore %s: %v", p12TrustStore.Keystore.Filename, err)
|
||||
}
|
||||
|
||||
return webKeyStoreName, nil
|
||||
}
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"github.com/ibm-messaging/mq-container/internal/tls"
|
||||
)
|
||||
|
||||
func startWebServer(keystore, keystorepw, p12TrustStoreRef string) error {
|
||||
func startWebServer(webKeystore, webkeystorePW, webTruststoreRef string) error {
|
||||
_, err := os.Stat("/opt/mqm/bin/strmqweb")
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
log.Debug("Skipping web server, because it's not installed")
|
||||
@@ -50,10 +50,10 @@ func startWebServer(keystore, keystorepw, p12TrustStoreRef string) error {
|
||||
}
|
||||
|
||||
// TLS enabled
|
||||
if keystore != "" {
|
||||
cmd.Env = append(cmd.Env, "AMQ_WEBKEYSTORE="+keystore)
|
||||
cmd.Env = append(cmd.Env, "AMQ_WEBKEYSTOREPW="+keystorepw)
|
||||
cmd.Env = append(cmd.Env, "AMQ_WEBTRUSTSTOREREF="+p12TrustStoreRef)
|
||||
if webKeystore != "" {
|
||||
cmd.Env = append(cmd.Env, "AMQ_WEBKEYSTORE="+webKeystore)
|
||||
cmd.Env = append(cmd.Env, "AMQ_WEBKEYSTOREPW="+webkeystorePW)
|
||||
cmd.Env = append(cmd.Env, "AMQ_WEBTRUSTSTOREREF="+webTruststoreRef)
|
||||
}
|
||||
|
||||
uid, gid, err := command.LookupMQM()
|
||||
@@ -119,50 +119,53 @@ func configureSSO(p12TrustStore tls.KeyStoreData) (string, error) {
|
||||
}
|
||||
|
||||
// Configure SSO TLS
|
||||
return configureWebKeyStore(p12TrustStore)
|
||||
return tls.ConfigureWebKeystore(p12TrustStore)
|
||||
}
|
||||
|
||||
func configureWebServer(keyLabel string, p12Trust tls.KeyStoreData) (string, error) {
|
||||
var keystore string
|
||||
func configureWebServer(keyLabel string, p12Truststore tls.KeyStoreData) (string, error) {
|
||||
var webKeystore string
|
||||
|
||||
// Configure TLS for Web Console first if we have a certificate to use
|
||||
err := configureWebTLS(keyLabel)
|
||||
err := tls.ConfigureWebTLS(keyLabel)
|
||||
if err != nil {
|
||||
return keystore, err
|
||||
return "", err
|
||||
}
|
||||
if keyLabel != "" {
|
||||
keystore = keyLabel + ".p12"
|
||||
webKeystore = keyLabel + ".p12"
|
||||
}
|
||||
|
||||
// Configure Single-Sign-On for the web server (if enabled)
|
||||
enableSSO := os.Getenv("MQ_BETA_ENABLE_SSO")
|
||||
if enableSSO == "true" || enableSSO == "1" {
|
||||
keystore, err = configureSSO(p12Trust)
|
||||
webKeystore, err = configureSSO(p12Truststore)
|
||||
if err != nil {
|
||||
return keystore, err
|
||||
return "", err
|
||||
}
|
||||
} else if keyLabel == "" && os.Getenv("MQ_GENERATE_CERTIFICATE_HOSTNAME") != "" {
|
||||
keystore, err = configureWebKeyStore(p12Trust)
|
||||
webKeystore, err = tls.ConfigureWebKeystore(p12Truststore)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = os.Stat("/opt/mqm/bin/strmqweb")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return keystore, nil
|
||||
return "", nil
|
||||
}
|
||||
return keystore, err
|
||||
return "", err
|
||||
}
|
||||
const webConfigDir string = "/etc/mqm/web"
|
||||
_, err = os.Stat(webConfigDir)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return keystore, nil
|
||||
return "", nil
|
||||
}
|
||||
return keystore, err
|
||||
return "", err
|
||||
}
|
||||
uid, gid, err := command.LookupMQM()
|
||||
if err != nil {
|
||||
return keystore, err
|
||||
return "", err
|
||||
}
|
||||
const prefix string = "/etc/mqm/web"
|
||||
err = filepath.Walk(prefix, func(from string, info os.FileInfo, err error) error {
|
||||
@@ -206,5 +209,6 @@ func configureWebServer(keyLabel string, p12Trust tls.KeyStoreData) (string, err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return keystore, err
|
||||
|
||||
return webKeystore, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user