Compare commits

...

28 Commits

Author SHA1 Message Date
Rob Parker
869ee6492d Merge pull request #291 from parrobe/sing2
Add non-root to singularity branch
2019-03-19 16:06:26 +00:00
Robert Parker
cad3eb5dd9 fix broken devsecure test 2019-03-19 14:46:42 +00:00
Robert Parker
7b5e34e59e update copyright dates 2019-03-19 13:45:40 +00:00
Rob Parker
3ae41d52d3 Merge branch 'singularity' into sing2 2019-03-19 13:19:54 +00:00
Robert Parker
c3f40c84a7 Extra changes to support non-root in CIP 2019-03-19 11:29:33 +00:00
Stephen Marshall
350b8318ee Add TLS support (#243)
* Add TLS support

* Security fix for libsystemd0 systemd systemd-sysv libudev1
2019-03-18 13:21:39 +00:00
Stephen Marshall
fd262b173e Add uniqueUserIdentifier 2019-03-18 13:18:58 +00:00
Stephen Marshall
227db5875a Fix for iframe issue with web console (#238) 2019-03-18 13:18:58 +00:00
Rob Parker
6f1268ffec add integration into the docker tag (#233) 2019-03-18 13:18:58 +00:00
Stephen Marshall
c455d696b2 Split SSO admin user list on newlines (#229) 2019-03-18 13:18:06 +00:00
Stephen Marshall
4c1d124484 Configure Single-Sign-On for the web server 2019-03-18 13:18:06 +00:00
Stephen Marshall
9b3b1f7b9e Move template and keystore functions to internal packages 2019-03-18 13:16:44 +00:00
Stephen Marshall
568ae6e34e Enable web console for mqadvanced-server 2019-03-18 13:16:44 +00:00
Arthur Barr
0dd5f9c818 Replace master with singularity 2019-03-18 13:05:46 +00:00
Rob Parker
00a0ce0e0a Merge pull request #254 from parrobe/sing
update perl-base to fix security vulnerability
2018-12-05 13:55:50 +00:00
Robert Parker
e74ba3fd75 update perl-base to fix security vulnerability 2018-12-05 13:34:58 +00:00
Stephen Marshall
3064699198 Add TLS support (#243)
* Add TLS support

* Security fix for libsystemd0 systemd systemd-sysv libudev1
2018-11-07 11:47:41 +00:00
Stephen Marshall
b8227abf7f Add uniqueUserIdentifier 2018-10-29 13:48:25 +00:00
Stephen Marshall
c88329d779 Fix for iframe issue with web console (#238) 2018-10-25 10:17:02 +01:00
Rob Parker
e6049ecb93 add integration into the docker tag (#233) 2018-10-18 13:43:48 +01:00
Stephen Marshall
574386fe82 Split SSO admin user list on newlines (#229) 2018-10-12 14:13:20 +01:00
Robert Parker
5ba73c1d2a update apparmor 2018-10-09 09:39:12 +01:00
Stephen Marshall
149915d587 Configure Single-Sign-On for the web server 2018-10-03 16:34:28 +01:00
Stephen Marshall
77eb7381e7 Move template and keystore functions to internal packages 2018-10-03 16:34:28 +01:00
Stephen Marshall
6abbbb0394 Enable web console for mqadvanced-server 2018-10-01 11:27:52 +01:00
Stephen Marshall
e7ba32d849 Merge pull request #215 from arthurbarr/singularity
Fix .gitignore and README
2018-10-01 11:05:55 +01:00
Arthur Barr
0e567ccea7 Remove dynamic Prometheus files 2018-10-01 10:18:49 +01:00
Arthur Barr
80e7707deb Replace master with singularity 2018-10-01 10:17:38 +01:00
38 changed files with 424 additions and 179 deletions

View File

@@ -70,12 +70,16 @@ RUN chmod ug+x /usr/local/bin/runmqserver \
&& chown mqm:mqm /usr/local/bin/*mq* \
&& chmod ug+xs /usr/local/bin/chkmq* \
&& install --directory --mode 0775 --owner mqm --group root /run/runmqserver \
&& install --directory --mode 0775 --owner mqm --group root /run/tls \
&& touch /run/termination-log \
&& chown mqm:root /run/termination-log \
&& chmod 0660 /run/termination-log
# Always use port 1414 for MQ & 9157 for the metrics
EXPOSE 1414 9157
# Always use port 1414 for MQ, 9157 for the metrics & 9443 for the web console
EXPOSE 1414 9157 9443
# Copy web XML files
COPY web /etc/mqm/web
ENV LANG=en_US.UTF-8 AMQ_DIAGNOSTIC_MSG_SEVERITY=1 AMQ_ADDITIONAL_JSON_LOG=1 LOG_FORMAT=basic

View File

@@ -1,4 +1,4 @@
# © Copyright IBM Corporation 2018
# © 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.

View File

@@ -32,15 +32,15 @@ MQ_SDK_ARCHIVE ?= 9.1.1.0-IBM-MQC-Redist-LinuxX64.tar.gz
# Options to `go test` for the Docker tests
TEST_OPTS_DOCKER ?=
# MQ_IMAGE_ADVANCEDSERVER is the name and tag of the built MQ Advanced image
MQ_IMAGE_ADVANCEDSERVER ?=mqadvanced-server:$(MQ_VERSION)-RHEL-$(ARCH)
MQ_IMAGE_ADVANCEDSERVER ?=mqadvanced-server:$(MQ_VERSION)-integration-$(ARCH)
# MQ_IMAGE_DEVSERVER is the name and tag of the built MQ Advanced for Developers image
MQ_IMAGE_DEVSERVER ?=mqadvanced-server-dev:$(MQ_VERSION)-RHEL-$(ARCH)
MQ_IMAGE_DEVSERVER ?=mqadvanced-server-dev:$(MQ_VERSION)-integration-$(ARCH)
# MQ_IMAGE_SDK is the name and tag of the built MQ Advanced for Developers SDK image
MQ_IMAGE_SDK ?=mq-sdk:$(MQ_VERSION)-$(ARCH)-$(BASE_IMAGE_TAG)
# MQ_IMAGE_GOLANG_SDK is the name and tag of the built MQ Advanced for Developers SDK image, plus Go tools
MQ_IMAGE_GOLANG_SDK ?=mq-golang-sdk:$(MQ_VERSION)-$(ARCH)-$(BASE_IMAGE_TAG)
# MQ_PACKAGES specifies the MQ packages to install. Defaults vary on base image.
MQ_PACKAGES ?= MQSeriesRuntime-*.rpm MQSeriesServer-*.rpm MQSeriesJava*.rpm MQSeriesJRE*.rpm MQSeriesGSKit*.rpm MQSeriesMsg*.rpm MQSeriesSamples*.rpm MQSeriesAMS-*.rpm
MQ_PACKAGES ?= MQSeriesRuntime-*.rpm MQSeriesServer-*.rpm MQSeriesJava*.rpm MQSeriesJRE*.rpm MQSeriesGSKit*.rpm MQSeriesMsg*.rpm MQSeriesSamples*.rpm MQSeriesAMS-*.rpm MQSeriesWeb-*.rpm
###############################################################################
# Other variables
@@ -166,7 +166,6 @@ build-advancedserver: check-prereqs downloads/$(MQ_ARCHIVE) build-go-programs
.PHONY: build-devserver
build-devserver: MQDEV=TRUE
build-devserver: MQ_PACKAGES=MQSeriesRuntime-*.rpm MQSeriesServer-*.rpm MQSeriesJava*.rpm MQSeriesJRE*.rpm MQSeriesGSKit*.rpm MQSeriesMsg*.rpm MQSeriesSamples*.rpm MQSeriesAMS-*.rpm MQSeriesWeb-*.rpm
build-devserver: check-prereqs downloads/$(MQ_ARCHIVE_DEV) build-go-programs
$(info $(SPACER)$(shell printf $(TITLE)"Build $(MQ_IMAGE_DEVSERVER)"$(END)))
sudo mq-advanced-server-rhel/mq-buildah.sh "$(MQ_ARCHIVE_DEV)" "$(MQ_PACKAGES)" "$(MQ_IMAGE_DEVSERVER_BASE)" "$(MQ_VERSION)" "$(MQDEV)"

View File

@@ -32,9 +32,9 @@ MQ_SDK_ARCHIVE ?= $(MQ_ARCHIVE_DEV_$(MQ_VERSION))
# Options to `go test` for the Docker tests
TEST_OPTS_DOCKER ?=
# MQ_IMAGE_ADVANCEDSERVER is the name and tag of the built MQ Advanced image
MQ_IMAGE_ADVANCEDSERVER ?=mqadvanced-server:$(MQ_VERSION)-$(ARCH)-$(BASE_IMAGE_TAG)
MQ_IMAGE_ADVANCEDSERVER ?=mqadvanced-server:$(MQ_VERSION)-integration-$(ARCH)
# MQ_IMAGE_DEVSERVER is the name and tag of the built MQ Advanced for Developers image
MQ_IMAGE_DEVSERVER ?=mqadvanced-server-dev:$(MQ_VERSION)-$(ARCH)-$(BASE_IMAGE_TAG)
MQ_IMAGE_DEVSERVER ?=mqadvanced-server-dev:$(MQ_VERSION)-integration-$(ARCH)
# MQ_IMAGE_SDK is the name and tag of the built MQ Advanced for Developers SDK image
MQ_IMAGE_SDK ?=mq-sdk:$(MQ_VERSION)-$(ARCH)-$(BASE_IMAGE_TAG)
# MQ_IMAGE_GOLANG_SDK is the name and tag of the built MQ Advanced for Developers SDK image, plus Go tools
@@ -134,7 +134,7 @@ downloads/$(MQ_ARCHIVE_DEV):
downloads/$(MQ_SDK_ARCHIVE):
$(info $(SPACER)$(shell printf $(TITLE)"Downloading IBM MQ Advanced for Developers "$(MQ_VERSION)$(END)))
mkdir -p downloads
cd downloads; curl -LO https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/$(MQ_SDK_ARCHIVE)
cd downloads; curl -LO https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/$(MQ_SDK_ARCHIVE)
.PHONY: downloads
downloads: downloads/$(MQ_ARCHIVE_DEV) downloads/$(MQ_SDK_ARCHIVE)
@@ -236,12 +236,6 @@ build-advancedserver: downloads/$(MQ_ARCHIVE) docker-version build-golang-sdk-ex
$(call docker-build-mq,$(MQ_IMAGE_ADVANCEDSERVER),Dockerfile-server,$(MQ_ARCHIVE),"4486e8c4cc9146fd9b3ce1f14a2dfc5b","IBM MQ Advanced",$(MQ_VERSION))
.PHONY: build-devserver
# Target-specific variable to add web server into devserver image
ifeq "$(findstring ubuntu,$(BASE_IMAGE))" "ubuntu"
build-devserver: MQ_PACKAGES=ibmmq-server ibmmq-java ibmmq-jre ibmmq-gskit ibmmq-msg-.* ibmmq-samples ibmmq-ams ibmmq-web
else
build-devserver: MQ_PACKAGES=MQSeriesRuntime-*.rpm MQSeriesServer-*.rpm MQSeriesJava*.rpm MQSeriesJRE*.rpm MQSeriesGSKit*.rpm MQSeriesMsg*.rpm MQSeriesSamples*.rpm MQSeriesAMS-*.rpm MQSeriesWeb-*.rpm
endif
build-devserver: MQ_SDK_ARCHIVE=$(MQ_ARCHIVE_DEV)
build-devserver: downloads/$(MQ_ARCHIVE_DEV) docker-version build-golang-sdk-ex
$(info $(shell printf $(TITLE)"Build $(MQ_IMAGE_DEVSERVER_BASE)"$(END)))
@@ -267,7 +261,7 @@ build-sdk: downloads/$(MQ_SDK_ARCHIVE) build-sdk-ex
.PHONY: build-sdk-ex
ifeq "$(findstring ubuntu,$(BASE_IMAGE))" "ubuntu"
build-sdk-ex: MQ_PACKAGES=ibmmq-sdk ibmmq-samples build-essential
else
else
build-sdk-ex: MQ_PACKAGES=MQSeriesRuntime-*.rpm MQSeriesSDK-*.rpm MQSeriesSamples*.rpm
endif
build-sdk-ex: docker-version docker-pull
@@ -280,9 +274,7 @@ build-golang-sdk: downloads/$(MQ_SDK_ARCHIVE) build-golang-sdk-ex
.PHONY: build-golang-sdk-ex
build-golang-sdk-ex: docker-version build-sdk-ex
$(info $(shell printf $(TITLE)"Build $(MQ_IMAGE_GOLANG_SDK)"$(END)))
@echo hello
$(DOCKER) build --build-arg BASE_IMAGE=$(MQ_IMAGE_SDK) -t $(MQ_IMAGE_GOLANG_SDK) -f incubating/mq-golang-sdk/Dockerfile .
@echo goodbye
.PHONY: docker-pull
docker-pull:

View File

@@ -2,8 +2,8 @@
[![Build Status](https://travis-ci.org/ibm-messaging/mq-container.svg?branch=master)](https://travis-ci.org/ibm-messaging/mq-container)
**Note**: The `master` branch may be in an *unstable or even broken state* during development.
To get a stable version, please use the correct [branch](https://github.com/ibm-messaging/mq-container/branches) for your MQ version, instead of the `master` branch.
**Note**: The `singularity` branch may be in an *unstable or even broken state* during development.
To get a stable version, please use the correct [branch](https://github.com/ibm-messaging/mq-container/branches) for your MQ version, instead of the `singularity` branch.
<img src="https://raw.githubusercontent.com/IBM/charts/master/logo/ibm-mq-icon.svg?sanitize=true" width="100" alt="IBM MQ logo" />

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017
© Copyright IBM Corporation 2017, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2018
© Copyright IBM Corporation 2017, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -24,6 +24,7 @@ import (
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/logger"
"github.com/ibm-messaging/mq-container/internal/mqtemplate"
"github.com/ibm-messaging/mq-container/internal/name"
)
@@ -90,7 +91,7 @@ func configureLogger() error {
func configureWeb(qmName string) error {
out := "/etc/mqm/web/installations/Installation1/angular.persistence/admin.json"
return processTemplateFile("/etc/mqm/admin.json.tpl", out, map[string]string{"QueueManagerName": qmName})
return mqtemplate.ProcessTemplateFile("/etc/mqm/admin.json.tpl", out, map[string]string{"QueueManagerName": qmName}, log)
}
func logTerminationf(format string, args ...interface{}) {

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© 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.
@@ -17,6 +17,8 @@ package main
import (
"os"
"github.com/ibm-messaging/mq-container/internal/mqtemplate"
)
func updateMQSC(appPasswordRequired bool) error {
@@ -30,7 +32,7 @@ func updateMQSC(appPasswordRequired bool) error {
if os.Getenv("MQ_DEV") == "true" {
const mqscTemplate string = mqsc + ".tpl"
// Re-configure channel if app password not set
err := processTemplateFile(mqsc+".tpl", mqsc, map[string]string{"ChckClnt": checkClient})
err := mqtemplate.ProcessTemplateFile(mqsc+".tpl", mqsc, map[string]string{"ChckClnt": checkClient}, log)
if err != nil {
return err
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© 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.
@@ -21,20 +21,22 @@ import (
"path/filepath"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/keystore"
"github.com/ibm-messaging/mq-container/internal/mqtemplate"
)
func configureWebTLS(cms *KeyStore) error {
func configureWebTLS(cms *keystore.KeyStore) error {
dir := "/run/runmqdevserver/tls"
ks := NewJKSKeyStore(filepath.Join(dir, "key.jks"), cms.Password)
ts := NewJKSKeyStore(filepath.Join(dir, "trust.jks"), cms.Password)
ks := keystore.NewJKSKeyStore(filepath.Join(dir, "key.jks"), cms.Password)
ts := keystore.NewJKSKeyStore(filepath.Join(dir, "trust.jks"), cms.Password)
log.Debug("Creating key store")
err := ks.Create()
err := ks.Create(log)
if err != nil {
return err
}
log.Debug("Creating trust store")
err = ts.Create()
err = ts.Create(log)
if err != nil {
return err
}
@@ -56,24 +58,19 @@ func configureWebTLS(cms *KeyStore) error {
if err != nil {
return err
}
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(tlsConfig, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
return nil
}
func configureTLS(qmName string, inputFile string, passPhrase string) error {
err := createDevTLSDir()
if err != nil {
return err
}
log.Debug("Configuring TLS")
_, err := os.Stat(inputFile)
_, err = os.Stat(inputFile)
if err != nil {
return err
}
@@ -82,37 +79,14 @@ func configureTLS(qmName string, inputFile string, passPhrase string) error {
dir := "/run/runmqdevserver/tls"
keyFile := filepath.Join(dir, "key.kdb")
_, err = os.Stat(dir)
if err != nil {
if os.IsNotExist(err) {
// #nosec G301
err = os.MkdirAll(dir, 0770)
if err != nil {
return err
}
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(dir, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
} else {
return err
}
}
cms := keystore.NewCMSKeyStore(keyFile, passPhrase)
cms := NewCMSKeyStore(keyFile, passPhrase)
err = cms.Create()
err = cms.Create(log)
if err != nil {
return err
}
err = cms.CreateStash()
err = cms.CreateStash(log)
if err != nil {
return err
}
@@ -146,11 +120,11 @@ func configureTLS(qmName string, inputFile string, passPhrase string) error {
const mqsc string = "/etc/mqm/20-dev-tls.mqsc"
const mqscTemplate string = mqsc + ".tpl"
err = processTemplateFile(mqscTemplate, mqsc, map[string]string{
err = mqtemplate.ProcessTemplateFile(mqscTemplate, mqsc, map[string]string{
"SSLKeyR": filepath.Join(dir, "key"),
"CertificateLabel": newLabel,
"SSLCipherSpec": sslCipherSpec,
})
}, log)
if err != nil {
return err
}
@@ -162,3 +136,32 @@ func configureTLS(qmName string, inputFile string, passPhrase string) error {
return nil
}
func createDevTLSDir() error {
// TODO: Use a persisted file (on the volume) instead?
dir := "/run/runmqdevserver/tls"
_, err := os.Stat(dir)
if err != nil {
if os.IsNotExist(err) {
// #nosec G301
err = os.MkdirAll(dir, 0770)
if err != nil {
return err
}
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(dir, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
} else {
return err
}
}
return nil
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2018
© Copyright IBM Corporation 2017, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -60,3 +60,61 @@ func createVolume(path string) error {
}
return nil
}
func createWebConsoleTLSDirStructure() error {
// Create tls directory
dir := "/run/tls"
_, err := os.Stat(dir)
if err != nil {
if os.IsNotExist(err) {
err = os.MkdirAll(dir, 0770)
if err != nil {
return err
}
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(dir, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
} else {
return err
}
}
return nil
}
/* TODO: remove duplicated code */
func createDevTLSDir() error {
// TODO: Use a persisted file (on the volume) instead?
dir := "/run/runmqdevserver/tls"
_, err := os.Stat(dir)
if err != nil {
if os.IsNotExist(err) {
// #nosec G301
err = os.MkdirAll(dir, 0770)
if err != nil {
return err
}
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(dir, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
} else {
return err
}
}
return nil
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2018
© Copyright IBM Corporation 2017, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -138,6 +138,9 @@ func logDiagnostics() {
out, _, _ = command.Run("ls", "-l", "/mnt/mqm/data")
log.Debugf("/mnt/mqm/data:\n%s", out)
// #nosec G104
out, _, _ = command.Run("ls", "-l", "/etc/mqm")
log.Debugf("/etc/mqm:\n%s", out)
// #nosec G104
out, _, _ = command.Run("ls", "-l", "/var/mqm")
log.Debugf("/var/mqm:\n%s", out)
// #nosec G104

View File

@@ -104,6 +104,20 @@ func doMain() error {
return err
}
err = createWebConsoleTLSDirStructure()
if err != nil {
logTermination(err)
return err
}
if *devFlag == true {
err = createDevTLSDir()
if err != nil {
logTermination(err)
return err
}
}
// If init flag is set, exit now
if *initFlag {
return nil

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© 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.

View File

@@ -1,5 +1,3 @@
// +build mqdev
/*
© Copyright IBM Corporation 2018
@@ -22,18 +20,26 @@ import (
)
// postInit is run after /var/mqm is set up
// This version of postInit is only included as part of the MQ Advanced for Developers build
func postInit(name string) error {
disable := os.Getenv("MQ_DISABLE_WEB_CONSOLE")
if disable != "true" && disable != "1" {
// Configure Single-Sign-On for the web server (if enabled)
enableSSO := os.Getenv("MQ_ENABLE_SSO")
if enableSSO == "true" || enableSSO == "1" {
err := configureSSO()
if err != nil {
return err
}
}
// Configure the web server (if installed)
err := configureWebServer()
if err != nil {
return err
}
// Start the web server, in the background (if installed)
// WARNING: No error handling or health checking available for the web server,
// which is why it's limited to use with MQ Advanced for Developers only
// WARNING: No error handling or health checking available for the web server
go func() {
startWebServer()
}()

View File

@@ -1,22 +0,0 @@
// +build !mqdev
/*
© Copyright IBM Corporation 2018
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
func postInit(name string) error {
return nil
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© 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.

View File

@@ -34,6 +34,7 @@ func createDirStructure() error {
return err
}
log.Println("Created directory structure under /var/mqm")
return nil
}

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2018
© Copyright IBM Corporation 2017, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© 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.

View File

@@ -1,5 +1,3 @@
// +build mqdev
/*
© Copyright IBM Corporation 2018, 2019
@@ -25,9 +23,12 @@ import (
"os/user"
"path/filepath"
"strconv"
"strings"
"syscall"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/keystore"
"github.com/ibm-messaging/mq-container/internal/mqtemplate"
)
func startWebServer() error {
@@ -90,6 +91,82 @@ func CopyFile(src, dest string) error {
return err
}
func configureSSO() error {
// Ensure all required environment variables are set for SSO
requiredEnvVars := []string{
"MQ_WEB_ADMIN_USERS",
"MQ_OIDC_CLIENT_ID",
"MQ_OIDC_CLIENT_SECRET",
"MQ_OIDC_UNIQUE_USER_IDENTIFIER",
"MQ_OIDC_AUTHORIZATION_ENDPOINT",
"MQ_OIDC_TOKEN_ENDPOINT",
"MQ_OIDC_JWK_ENDPOINT",
"MQ_OIDC_ISSUER_IDENTIFIER",
"MQ_OIDC_CERTIFICATE",
}
for _, envVar := range requiredEnvVars {
if len(os.Getenv(envVar)) == 0 {
return fmt.Errorf("%v must be set when MQ_ENABLE_SSO=true", envVar)
}
}
// Check mqweb directory exists
const mqwebDir string = "/etc/mqm/web/installations/Installation1/servers/mqweb"
_, err := os.Stat(mqwebDir)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
// Process SSO template for generating file mqwebuser.xml
adminUsers := strings.Split(os.Getenv("MQ_WEB_ADMIN_USERS"), "\n")
err = mqtemplate.ProcessTemplateFile(mqwebDir+"/mqwebuser.xml.tpl", mqwebDir+"/mqwebuser.xml", map[string][]string{"AdminUser": adminUsers}, log)
if err != nil {
return err
}
// Configure SSO TLS
return configureSSO_TLS()
}
func configureSSO_TLS() error {
// Create tls directory
dir := "/run/tls"
mntdir := "/mnt/tls/"
// Setup key store & trust store
ks := keystore.NewJKSKeyStore(filepath.Join(dir, "key.jks"), "password")
ts := keystore.NewJKSKeyStore(filepath.Join(dir, "trust.jks"), "password")
log.Debug("Creating key store")
err := ks.Create(log)
if err != nil {
return err
}
log.Debug("Creating trust store")
err = ts.Create(log)
if err != nil {
return err
}
log.Debug("Generating PKCS12 file")
err = ks.GeneratePKCS12(filepath.Join(mntdir, "tls.key"), filepath.Join(mntdir, "tls.crt"), filepath.Join(dir, "tls.p12"), "default", "password")
if err != nil {
return err
}
log.Debug("Importing certificate into key store")
err = ks.Import(filepath.Join(dir, "tls.p12"), "password")
if err != nil {
return err
}
log.Debug("Adding OIDC certificate to trust store")
err = ts.Add(os.Getenv("MQ_OIDC_CERTIFICATE"), "OIDC")
return err
}
func configureWebServer() error {
_, err := os.Stat("/opt/mqm/bin/strmqweb")
if err != nil {
@@ -106,10 +183,6 @@ func configureWebServer() error {
}
return err
}
uid, gid, err := command.LookupMQM()
if err != nil {
return err
}
const prefix string = "/etc/mqm/web"
err = filepath.Walk(prefix, func(from string, info os.FileInfo, err error) error {
if err != nil {
@@ -145,10 +218,6 @@ func configureWebServer() error {
return err
}
}
err = os.Chown(to, uid, gid)
if err != nil {
return err
}
return nil
})
return err

View File

@@ -79,8 +79,6 @@ RUN chown -R mqm:mqm /etc/mqm/* \
&& chmod +x /usr/local/bin/runmq* \
&& install --directory --mode 0775 --owner mqm --group root /run/runmqdevserver
EXPOSE 9443
USER $MQM_UID
ENTRYPOINT ["runmqdevserver"]

View File

@@ -1,5 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<server>
<!-- ****************************************************************** -->
<!-- -->
<!-- IBM MQ security configuration for MQ Console and REST API. -->
<!-- -->
<!-- Name: mqwebuser.xml -->
<!-- -->
<!-- Description: Default webconsole configuration -->
<!-- -->
<!-- ****************************************************************** -->
<!-- <copyright -->
<!-- notice='lm-source-program' -->
<!-- pids='5724-H72' -->
<!-- years='2018,2019' -->
<!-- crc='0' > -->
<!-- -->
<!-- Licensed Materials - Property of IBM -->
<!-- -->
<!-- 5724-H72 -->
<!-- -->
<!-- (C) Copyright IBM Corp. 2018, 2019 All Rights Reserved. -->
<!-- -->
<!-- US Government Users Restricted Rights - Use, duplication or -->
<!-- disclosure restricted by GSA ADP Schedule Contract with -->
<!-- IBM Corp. -->
<!-- </copyright> -->
<featureManager>
<feature>appSecurity-2.0</feature>
<feature>basicAuthenticationMQ-1.0</feature>

View File

@@ -1,5 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<server>
<!-- ****************************************************************** -->
<!-- -->
<!-- IBM MQ security configuration for MQ Console and REST API. -->
<!-- -->
<!-- Name: mqwebuser.xml -->
<!-- -->
<!-- Description: Default webconsole configuration -->
<!-- -->
<!-- ****************************************************************** -->
<!-- <copyright -->
<!-- notice='lm-source-program' -->
<!-- pids='5724-H72' -->
<!-- years='2018,2019' -->
<!-- crc='0' > -->
<!-- -->
<!-- Licensed Materials - Property of IBM -->
<!-- -->
<!-- 5724-H72 -->
<!-- -->
<!-- (C) Copyright IBM Corp. 2018, 2019 All Rights Reserved. -->
<!-- -->
<!-- US Government Users Restricted Rights - Use, duplication or -->
<!-- disclosure restricted by GSA ADP Schedule Contract with -->
<!-- IBM Corp. -->
<!-- </copyright> -->
<keyStore id="MQWebKeyStore" location="/run/runmqdevserver/tls/key.jks" type="JKS" password="${env.MQ_TLS_PASSPHRASE}"/>
<keyStore id="MQWebTrustStore" location="/run/runmqdevserver/tls/trust.jks" type="JKS" password="${env.MQ_TLS_PASSPHRASE}"/>
<ssl id="thisSSLConfig" clientAuthenticationSupported="true" keyStoreRef="MQWebKeyStore" trustStoreRef="MQWebTrustStore" sslProtocol="TLSv1.2" serverKeyAlias="devcert"/>

View File

@@ -25,8 +25,8 @@ test -f /usr/bin/apt-get && UBUNTU=true || UBUNTU=false
# If MQ_PACKAGES isn't specifically set, then choose a valid set of defaults
if [ -z "$MQ_PACKAGES" ]; then
$UBUNTU && MQ_PACKAGES="ibmmq-server ibmmq-java ibmmq-jre ibmmq-gskit ibmmq-msg-.* ibmmq-samples ibmmq-ams"
$RHEL && MQ_PACKAGES="MQSeriesRuntime-*.rpm MQSeriesServer-*.rpm MQSeriesJava*.rpm MQSeriesJRE*.rpm MQSeriesGSKit*.rpm MQSeriesMsg*.rpm MQSeriesSamples*.rpm MQSeriesAMS-*.rpm"
$UBUNTU && MQ_PACKAGES="ibmmq-server ibmmq-java ibmmq-jre ibmmq-gskit ibmmq-msg-.* ibmmq-samples ibmmq-ams ibmmq-web"
$RHEL && MQ_PACKAGES="MQSeriesRuntime-*.rpm MQSeriesServer-*.rpm MQSeriesJava*.rpm MQSeriesJRE*.rpm MQSeriesGSKit*.rpm MQSeriesMsg*.rpm MQSeriesSamples*.rpm MQSeriesAMS-*.rpm MQSeriesWeb-*.rpm"
fi
if ($UBUNTU); then
@@ -65,7 +65,8 @@ if ($UBUNTU); then
procps \
sed \
tar \
util-linux
util-linux \
openssl
fi
# Install additional packages required by MQ, this install process and the runtime scripts
@@ -84,7 +85,8 @@ $RHEL && yum -y install \
procps-ng \
sed \
tar \
util-linux
util-linux \
openssl
# Download and extract the MQ installation files
DIR_EXTRACT=/tmp/mq

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2018
© Copyright IBM Corporation 2017, 2019
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© 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.
@@ -13,7 +13,9 @@ 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
// Package keystore contains code to create and update keystores
package keystore
import (
"bufio"
@@ -23,6 +25,7 @@ import (
"strings"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/logger"
)
// KeyStore describes information about a keystore file
@@ -54,7 +57,7 @@ func NewCMSKeyStore(filename, password string) *KeyStore {
}
// Create a key store, if it doesn't already exist
func (ks *KeyStore) Create() error {
func (ks *KeyStore) Create(log *logger.Logger) error {
_, err := os.Stat(ks.Filename)
if err == nil {
// Keystore already exists so we should refresh it by deleting it.
@@ -96,22 +99,11 @@ func (ks *KeyStore) Create() error {
if err != nil {
return fmt.Errorf("error running \"%v -keydb -create\": %v %s", ks.command, err, out)
}
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(ks.Filename, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
return nil
}
// CreateStash creates a key stash, if it doesn't already exist
func (ks *KeyStore) CreateStash() error {
func (ks *KeyStore) CreateStash(log *logger.Logger) error {
extension := filepath.Ext(ks.Filename)
stashFile := ks.Filename[0:len(ks.Filename)-len(extension)] + ".sth"
log.Debugf("TLS stash file: %v", stashFile)
@@ -125,15 +117,14 @@ func (ks *KeyStore) CreateStash() error {
}
return err
}
mqmUID, mqmGID, err := command.LookupMQM()
return nil
}
// GeneratePKCS12 generates a PKCS12 file
func (ks *KeyStore) GeneratePKCS12(keyFile, crtFile, pkcs12File, label, password string) error {
out, _, err := command.Run("openssl", "pkcs12", "-export", "-inkey", keyFile, "-in", crtFile, "-out", pkcs12File, "-name", label, "-passout", "pass:"+password)
if err != nil {
log.Error(err)
return err
}
err = os.Chown(stashFile, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
return fmt.Errorf("error running \"openssl pkcs12 -export\": %v %s", err, out)
}
return nil
}
@@ -147,6 +138,24 @@ func (ks *KeyStore) Import(inputFile, password string) error {
return nil
}
// CreateSelfSignedCertificate creates a self-signed certificate in the keystore
func (ks *KeyStore) CreateSelfSignedCertificate(label, dn string) error {
out, _, err := command.Run(ks.command, "-cert", "-create", "-db", ks.Filename, "-pw", ks.Password, "-label", label, "-dn", dn)
if err != nil {
return fmt.Errorf("error running \"%v -cert -create\": %v %s", ks.command, err, out)
}
return nil
}
// Add adds a CA certificate to the keystore
func (ks *KeyStore) Add(inputFile, label string) error {
out, _, err := command.Run(ks.command, "-cert", "-add", "-db", ks.Filename, "-type", ks.keyStoreType, "-pw", ks.Password, "-file", inputFile, "-label", label)
if err != nil {
return fmt.Errorf("error running \"%v -cert -add\": %v %s", ks.command, err, out)
}
return nil
}
// GetCertificateLabels returns the labels of all certificates in the key store
func (ks *KeyStore) GetCertificateLabels() ([]string, error) {
out, _, err := command.Run(ks.command, "-cert", "-list", "-type", ks.keyStoreType, "-db", ks.Filename, "-pw", ks.Password)

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© 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.

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2018
© 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.

View File

@@ -13,20 +13,21 @@ 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
// Package mqtemplate contains code to process template files
package mqtemplate
import (
"os"
"path"
"text/template"
"github.com/ibm-messaging/mq-container/internal/command"
"github.com/ibm-messaging/mq-container/internal/logger"
)
// processTemplateFile takes a Go templateFile, and processes it with the
// ProcessTemplateFile takes a Go templateFile, and processes it with the
// supplied data, writing to destFile
func processTemplateFile(templateFile, destFile string, data interface{}) error {
// Re-configure channel if app password not set
func ProcessTemplateFile(templateFile, destFile string, data interface{}, log *logger.Logger) error {
t, err := template.ParseFiles(templateFile)
if err != nil {
log.Error(err)
@@ -42,16 +43,6 @@ func processTemplateFile(templateFile, destFile string, data interface{}) error
log.Error(err)
return err
}
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(dir, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
} else {
return err
}
@@ -64,15 +55,5 @@ func processTemplateFile(templateFile, destFile string, data interface{}) error
log.Error(err)
return err
}
mqmUID, mqmGID, err := command.LookupMQM()
if err != nil {
log.Error(err)
return err
}
err = os.Chown(destFile, mqmUID, mqmGID)
if err != nil {
log.Error(err)
return err
}
return nil
}

View File

@@ -86,6 +86,7 @@ buildah run ${ctr_mq} -- microdnf ${microdnf_opts} install \
shadow-utils \
tar \
util-linux \
openssl \
which
# Install "sudo" if using MQ Advanced for Developers
@@ -121,6 +122,12 @@ buildah run --user root $ctr_mq -- chmod 0660 /run/termination-log
install --mode 0550 --owner root --group root ./mq-advanced-server-rhel/writePackages.sh ${mnt_mq}/usr/local/bin/writePackages
buildah run --user root $ctr_mq -- /usr/local/bin/writePackages
# Copy web XML files
cp -R web ${mnt_mq}/etc/mqm/web
# Copy web XML files
cp -R web ${mnt_mq}/etc/mqm/web
###############################################################################
# Final Buildah commands
###############################################################################
@@ -138,6 +145,7 @@ fi
buildah config \
--port 1414/tcp \
--port 9157/tcp \
--port 9443/tcp \
--os linux \
--label architecture=x86_64 \
--label io.openshift.tags="$OSTAG" \

View File

@@ -78,12 +78,7 @@ install --directory --mode 0775 --owner ${mqm_uid} --group 0 ${mnt_mq}/run/runmq
cp ./incubating/mqadvanced-server-dev/*.tpl ${mnt_mq}/etc/mqm/
# Copy web XML files for default developer configuration
mkdir --parents ${mnt_mq}/etc/mqm/web
cp --recursive ./incubating/mqadvanced-server-dev/web/* ${mnt_mq}/etc/mqm/web/
# Make "mqm" the owner of all the config files
chown --recursive ${mqm_uid}:${mqm_gid} ${mnt_mq}/etc/mqm/*
chmod --recursive 0750 ${mnt_mq}/etc/mqm/*
cp -R incubating/mqadvanced-server-dev/web/ ${mnt_mq}/etc/mqm/web
###############################################################################
# Final Buildah commands

View File

@@ -1,4 +1,4 @@
# © Copyright IBM Corporation 2017, 2018
# © Copyright IBM Corporation 2017, 2019
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
<!--
© Copyright IBM Corporation 2018
© 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.

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<server>
<featureManager>
<feature>appSecurity-2.0</feature>
</featureManager>
<enterpriseApplication id="com.ibm.mq.console">
<application-bnd>
<security-role name="MQWebAdmin">
<group name="MQWebUI" realm="defaultRealm"/>
</security-role>
</application-bnd>
</enterpriseApplication>
<enterpriseApplication id="com.ibm.mq.rest">
<application-bnd>
<security-role name="MQWebAdmin">
<group name="MQWebUI" realm="defaultRealm"/>
</security-role>
<security-role name="MQWebUser">
<group name="MQWebMessaging" realm="defaultRealm"/>
</security-role>
</application-bnd>
</enterpriseApplication>
<variable name="httpHost" value="*"/>
<include location="tls.xml"/>
</server>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<server>
<featureManager>
<feature>openidConnectClient-1.0</feature>
<feature>ssl-1.0</feature>
</featureManager>
<enterpriseApplication id="com.ibm.mq.console">
<application-bnd>
<security-role name="MQWebAdmin">
<group name="MQWebUI" realm="defaultRealm"/>
{{- range $index, $element := .AdminUser}}
<user name="admin{{$index}}" access-id="{{.}}"/>
{{- end}}
</security-role>
</application-bnd>
</enterpriseApplication>
<enterpriseApplication id="com.ibm.mq.rest">
<application-bnd>
<security-role name="MQWebAdmin">
<group name="MQWebUI" realm="defaultRealm"/>
</security-role>
<security-role name="MQWebUser">
<group name="MQWebMessaging" realm="defaultRealm"/>
</security-role>
</application-bnd>
</enterpriseApplication>
<openidConnectClient id="mqclient"
clientId="${env.MQ_OIDC_CLIENT_ID}"
clientSecret="${env.MQ_OIDC_CLIENT_SECRET}"
uniqueUserIdentifier="${env.MQ_OIDC_UNIQUE_USER_IDENTIFIER}"
authorizationEndpointUrl="${env.MQ_OIDC_AUTHORIZATION_ENDPOINT}"
tokenEndpointUrl="${env.MQ_OIDC_TOKEN_ENDPOINT}"
scope="openid profile email"
inboundPropagation="supported"
jwkEndpointUrl="${env.MQ_OIDC_JWK_ENDPOINT}"
signatureAlgorithm="RS256"
issuerIdentifier="${env.MQ_OIDC_ISSUER_IDENTIFIER}">
</openidConnectClient>
<variable name="httpHost" value="*"/>
<variable name="managementMode" value="externallyprovisioned"/>
<jndiEntry jndiName="xframeAllowedSourceList" value="${env.MQ_HOSTS}"/>
<keyStore id="MQWebKeyStore" location="/run/tls/key.jks" type="JKS" password="password"/>
<keyStore id="MQWebTrustStore" location="/run/tls/trust.jks" type="JKS" password="password"/>
<ssl id="thisSSLConfig" clientAuthenticationSupported="true" keyStoreRef="MQWebKeyStore" trustStoreRef="MQWebTrustStore" sslProtocol="TLSv1.2" serverKeyAlias="default"/>
<sslDefault sslRef="thisSSLConfig"/>
<httpDispatcher enableWelcomePage="false" appOrContextRootMissingMessage='&lt;script&gt;document.location.href="/ibmmq/console";&lt;/script&gt;' />
</server>