Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabling TLS #101

Merged
merged 1 commit into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .github/workflows/test-chart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
- uses: actions/checkout@v2

- uses: azure/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
id: install

- name: Lint
Expand All @@ -34,4 +36,16 @@ jobs:
run: |
kubectl create namespace helm-test
helm install example-infinispan . -n helm-test --set deploy.replicas=2
kubectl wait --for=condition=Ready pods -lapp=infinispan-pod -n helm-test --timeout=300s
kubectl -n helm-test rollout status --watch --timeout=300s statefulset/example-infinispan
helm uninstall example-infinispan -n helm-test
kubectl delete namespace helm-test

- name: Testing TLS
run: |
kubectl create namespace helm-test
kubectl apply -f test/tls_secret.yaml -n helm-test
kubectl apply -f test/transport_tls_secret.yaml -n helm-test
helm install example-infinispan . -n helm-test -f values.yaml -f test/tls_values.snippet.yaml --set deploy.replicas=2
kubectl -n helm-test rollout status --watch --timeout=300s statefulset/example-infinispan
helm uninstall example-infinispan -n helm-test
kubectl delete namespace helm-test
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ All PRs that require modifications to the `README.md` or `values.schema.json` fi
The `brand.sh` script should then be executed using the upstream properties, i.e. `./brand.sh infinispan.conf`, and all
modified `*.tpl`, `*.md` and `*.json` files added to the commit.


# Creating a Release
1. Update `Chart.yaml`
- `.version` should be set to the version of the chart released
Expand Down
5 changes: 5 additions & 0 deletions README-tls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Quickstart: deploy a TLS cluster with HELM
rigazilla marked this conversation as resolved.
Show resolved Hide resolved

kubectl apply -f test/tls_secret.yaml<br>
kubectl apply -f test/transport_tls_secret.yaml<br>
helm install infinispan . -f values.yaml -f test/tls_values.snippet.yaml --set deploy.replicas=2
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@ Configure your Infinispan cluster by specifying values in the `deploy.*` section
| `deploy.monitoring.enabled` | Enable or disable `ServiceMonitor` functionality. | false | Users must have `monitoring-edit` role assigned by the admin to deploy the Helm chart with `ServiceMonitor` enabled. |
| `deploy.nameOverride` | Specifies a name for all Infinispan cluster resources. | Helm Chart release name | Configure a name for the created resources only if you need it to be different to the Helm Chart release name. |
| `deploy.securityContext` | Defines the securityContext settings used by the cluster's StatefulSet | `{}` | - |
| `deploy.ssl.endpointSecretName` | Specifies the name of the secret that contains certificate for endpoint encryption | `""` | - |
| `deploy.ssl.transportSecretName` | Specifies the name of the secret that contains certificate for transport encryption | `""` | - |
| `deploy.infinispan` | Infinispan Server configuration. | - | You should not change the default socket bindings or the security realm and endpoints named "metrics". Modifying these default properties can result in unexpected behavior and loss of service. |
2 changes: 2 additions & 0 deletions README.md.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@ Configure your {brandname} cluster by specifying values in the `deploy.*` sectio
| `deploy.monitoring.enabled` | Enable or disable `ServiceMonitor` functionality. | false | Users must have `monitoring-edit` role assigned by the admin to deploy the Helm chart with `ServiceMonitor` enabled. |
| `deploy.nameOverride` | Specifies a name for all {brandname} cluster resources. | Helm Chart release name | Configure a name for the created resources only if you need it to be different to the Helm Chart release name. |
| `deploy.securityContext` | Defines the securityContext settings used by the cluster's StatefulSet | `{}` | - |
| `deploy.ssl.endpointSecretName` | Specifies the name of the secret that contains certificate for endpoint encryption | `""` | - |
| `deploy.ssl.transportSecretName` | Specifies the name of the secret that contains certificate for transport encryption | `""` | - |
| `deploy.infinispan` | {brandname} Server configuration. | - | You should not change the default socket bindings or the security realm and endpoints named "metrics". Modifying these default properties can result in unexpected behavior and loss of service. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ifdef::context[:parent-context: {context}]
[id='encryption']
:context: network-access
= Configuring encryption
[role="_abstract"]
Configure encryption for your {brandname}.

include::{topics}/proc_enabling_encryption.adoc[leveloffset=+1]

// Restore the parent context.
ifdef::parent-context[:context: {parent-context}]
ifndef::parent-context[:!context:]
1 change: 1 addition & 0 deletions documentation/asciidoc/titles/stories.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include::{stories}/assembly_installing_helm_chart.adoc[leveloffset=+1]
include::{stories}/assembly_configuring_servers.adoc[leveloffset=+1]
include::{stories}/assembly_configuring_authentication.adoc[leveloffset=+1]
include::{stories}/assembly_configuring_encryption.adoc[leveloffset=+1]
include::{stories}/assembly_network_access.adoc[leveloffset=+1]
include::{stories}/assembly_connecting_clusters.adoc[leveloffset=+1]
5 changes: 0 additions & 5 deletions documentation/asciidoc/topics/proc_configuring_servers.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,3 @@ For example, you can create caches at startup with any {brandname} configuration
* Configure {brandname} Server endpoints with the `deploy.infinispan.server.endpoints` fields.
* Configure {brandname} Server network interfaces and ports with the `deploy.infinispan.server.interfaces` and `deploy.infinispan.server.socketBindings` fields.
* Configure {brandname} Server security mechanisms with the `deploy.infinispan.server.security` fields.
+
[NOTE]
====
The {brandname} chart does not currently support TLS/SSL security realms and encrypted client connections.
====
44 changes: 44 additions & 0 deletions documentation/asciidoc/topics/proc_enabling_encryption.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[id='enabling-encryption_{context}']
= Enabling TLS encryption

[role="_abstract"]
Encryption can be independently enabled for endpoint and cluster transport.

.Prerequisites
* A secret containing a certificate or a keystore. Endpoint and cluster should use
different secrets.

.Procedure

.Set the secret name in the deploy configuration

Provide the name of the secret containing the keystore.
ryanemerson marked this conversation as resolved.
Show resolved Hide resolved
[source,yaml,options="nowrap",subs=attributes+]
----
include::yaml/tls_secretname.yaml[]
----

.Enable cluster transport TLS

[source,yaml,options="nowrap",subs=attributes+]
----
include::yaml/transport_encryption.yaml[]
----
<1> Configures the transport stack to use the specified security-realm to provide cluster encryption.
<2> Configure the keystore path in the transport realm; secret is mounted at `/etc/encrypt/transport`.
<3> Configures the truststore with the same keystore, this allow the nodes to authenticate each other.
<4> Alias and password must be provided in case the secret contains a keystore.

.Enable endpoint TLS


[source,yaml,options="nowrap",subs=attributes+]
----
include::yaml/endpoint_encryption.yaml[]
----
<1> Configure the keystore path in the endpoint realm; secret is mounted at `/etc/encrypt/endpoint`.
<2> Alias and password must be provided in case the secret contains a keystore.

[role="_additional-resources"]
.Additional resources
* link:{security_docs}[{brandname} Security Guide]
12 changes: 12 additions & 0 deletions documentation/asciidoc/topics/yaml/endpoint_encryption.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
deploy:
infinispan:
server:
security:
securityRealms:
- name: default
serverIdentities:
ssl:
keystore:
path: "/etc/encrypt/endpoint/keystore.p12" #<1>
alias: "server" #<2>
password: "password" #<2>
4 changes: 4 additions & 0 deletions documentation/asciidoc/topics/yaml/tls_secretname.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
deploy:
ssl:
endpointSecretName: "tls-secret"
transportSecretName: "tls-transport-secret"
19 changes: 19 additions & 0 deletions documentation/asciidoc/topics/yaml/transport_encryption.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
deploy:
infinispan:
cacheContainer:
transport:
urn:infinispan:server:14.0:securityRealm: >
"cluster-transport" #<1>
server:
security:
securityRealms:
- name: cluster-transport
serverIdentities:
ssl:
keystore: #<2>
alias: "server"
path: "/etc/encrypt/endpoint/cert.p12"
password: "password"
truststore: #<3>
alias: "server" #<4>
path: "/etc/encrypt/endpoint/cert.p12" #<4>
18 changes: 17 additions & 1 deletion templates/helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,20 @@ Include for indentation
{{- if .env -}}
{{ .env | toYaml | nindent 0 }}
{{- end -}}
{{- end }}
{{- end }}

{{/*
Schema for default endpoint
*/}}

{{- define "infinispan-helm-charts.defaultEndpointSchema" -}}
{{- range .Values.deploy.infinispan.server.security.securityRealms }}
{{- if eq .name "default" }}
{{- if and .serverIdentities .serverIdentities.ssl -}}
HTTPS
{{- else -}}
HTTP
{{- end -}}
{{- end -}}
{{ end -}}
{{ end }}
24 changes: 21 additions & 3 deletions templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ spec:
httpGet:
path: rest/v2/cache-managers/default/health/status
port: 11222
scheme: HTTP
scheme: {{ include "infinispan-helm-charts.defaultEndpointSchema" . }}
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
Expand All @@ -104,7 +104,7 @@ spec:
httpGet:
path: rest/v2/cache-managers/default/health/status
port: 11222
scheme: HTTP
scheme: {{ include "infinispan-helm-charts.defaultEndpointSchema" . }}
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
Expand All @@ -114,7 +114,7 @@ spec:
httpGet:
path: rest/v2/cache-managers/default/health/status
port: 11222
scheme: HTTP
scheme: {{ include "infinispan-helm-charts.defaultEndpointSchema" . }}
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
Expand All @@ -137,13 +137,31 @@ spec:
name: data-volume
- mountPath: /etc/security
name: identities-volume
{{- if and .Values.deploy.ssl (ne .Values.deploy.ssl.transportSecretName "")}}
- mountPath: "/etc/encrypt/transport"
name: "transport-encrypt-volume"
{{- end }}
{{- if and .Values.deploy.ssl (ne .Values.deploy.ssl.endpointSecretName "")}}
- mountPath: "/etc/encrypt/endpoint"
name: "encrypt-volume"
{{- end }}
volumes:
- configMap:
name: {{ printf "%s-configuration" (include "infinispan-helm-charts.name" .) }}
name: config-volume
- name: identities-volume
secret:
secretName: {{ include "infinispan-helm-charts.secret" . }}
{{- if and .Values.deploy.ssl (ne .Values.deploy.ssl.transportSecretName "")}}
- name: "transport-encrypt-volume"
secret:
secretName: {{ .Values.deploy.ssl.transportSecretName }}
{{- end }}
{{- if and .Values.deploy.ssl (ne .Values.deploy.ssl.endpointSecretName "")}}
- name: "encrypt-volume"
secret:
secretName: {{ .Values.deploy.ssl.endpointSecretName }}
{{- end }}
{{- if .Values.deploy.container.storage.ephemeral }}
- name: data-volume
emptyDir: { }
Expand Down
115 changes: 115 additions & 0 deletions test/tls_secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: Opaque
stringData:
# Create a secret to encrypt traffic between endpoints and clients.
# The secret must contain either a keystore or a TLS certificate/key pair.
# Specify an alias for the keystore.
alias: server
# Specify a password for the keystore.
password: password
data:
# Add a base64 encoded PKCS12 keystore.
keystore.p12: "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\
CKUEybBaG1X/AgIIAA=="
# Add a TLS key.
tls.key: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZB\
QVNDQktjd2dnU2pBZ0VBQW9JQkFRREdyeU45T2pYL05wUTkKTDQ0MkVjQzhuY0IyT0JRbGpnL0x6\
WVhNZ1hOK2oxdlI1MUc4bHlsVlFuNytYd1RkZDZ4ZFhzMmtBTW5FdTVjSQpPR2N4N3FVTmZhWUtn\
a1dRVTFCZXpHSmRkT1g2bm9rVktGTUpvVHU2ZXJYbG0zbG5JZlJ2N3JVa09manhvdk0vCmpMei93\
MUpxbmZyZTVUcmZ1Q0hXdkdoekNocUhBWXpoN05BQ3p6cUlzQTY1eDdWSjRzM0o3Q05VTmI4TkZJ\
ZlcKY2J1VGRHaVVTWllQMzZqVms1N3Z5b09yYkpTRmxxMDRhRXNwb3hBc3h4b1B4dlNyZm4yTlNa\
VFZEZEx3YWVCRgo2YXYyamxKUVE5YTNhdnR2d2xoc3pEZ2k5d1ZBTGJYVDh6TzlGNUl6M3lBRFpO\
cEpmdFBJZExEOGdWdktaZThxCjBpK2cwcUVaQWdNQkFBRUNnZ0VBSE9kUnBHQVpodDByeDVMcGYx\
Z3B6OGFyUHdkOWR0RXAzeDR3L3NVK1JnVVkKK0hwTVc4RXAxQ3R1U2hjTW9DTk93ZTZPdi9NVlp6\
ZGJDMmtaS2h4cmlvRGk3Tmh5d2tJOGlPMzJ5VjIrTHkxdApCOVRyNzVTekdiZk1TbkRKd29VZ0NF\
Q1R2WWRwZmMyVTBZUHA0dE5KWkJWRGI3V3RVT3A2a2NDcStVRlpCcGFqClU1UWJhWUQxUTUveGdE\
TXVxZksyNWJteFdhYjBuTnBxRG41Zkx6cGhLMnNLcFNkOFg1SmhkNEJ0ZW1wZittWjUKYzYvMjRw\
UkI3dXNPQkFpQVluYjZzVFQ3RHhTeUw5Ym1hTkpGaG5iVFJSUEJCWnlTcVNoMnJqaG8rQUV6MjY4\
LwpMaHovUms1VnNac2N0Vjk0UnB1RzFlYlhCQW1EVUNtN0pDYkZzWmtWbVFLQmdRRDBCZUNoZ01s\
eS94dWdnSWZnCmE1TXl6MGxzRm1PSjJKZlluR0tMYUdiMWJuYTgrSWcrNXE3eE9qY1Y1bHNwMjZT\
N2JpVnVXRXlTbDgzdWE0cWcKUGQzQlRkVnBUS2pJazVlSmxaYXg5aWlWeUYwcFBralNhSTBVMExB\
RzdWbVJUNzY2K09naFh2T1JLZENCdll1cAp1K1N4MnZOK2x4S3pPeG82ZHU3dmpzSnBid0tCZ1FE\
UWI1VnJNOFNlSGZzdjN3Sy9vQ1BlYXVscHhDMDUvVnhVCnhIQnp2Smtla2xuTkFMcXJOUUl2NHl3\
VUs5dlBtcEx5M0JzcE9NcStKNDRDUXVtcm5YNXhLcTRBSTdXQnJOenAKVGQ1OGlGemg5dEt5bDRv\
NmZSdlFQUWNBWWZmL3dieUF6cFJhRkU5bFRiTmVnOUQ3aS9GT2hDWWxlK3RmaUhLTgpMa2N4NGhZ\
Sjl3S0JnUURhdFJIWmJrWWZUVW9EbG04eDB2akJCMHYxRmpQc2JqWGFMSCtlRnRxQWlwcmRUNXM5\
ClZSL2lrSnlpZ2kyZTNIOU9oYkFDc0IwaEhmR3lDS3pjWmRhRTFDKzhDcnNUMmtSdFNhY2dwVkZH\
dmFmUnVVTW4KWWhGZ1lKSUVBMkxOZkQyajhrYUs4a0UzRDlVVEUwRkR4V1Y1aXBYR0ZienE2c1Bk\
Tm85OEllVlkvUUtCZ0JFego5SEFab0xPd0k4Z3FyczVrQ0RIV1B4ZUVvbnJ6eDBnVHduZzY2NlJU\
VGVnV2xGR0hHWHdjVXNvRGFLdjB4UVlZClZvR0xkMmhFV1hza1RLYm1ZOFl4VUpVZ1hWMnJoN3dW\
dWpRckNRZDVXS0IyMDJqS1pKNUdPeXF6NjBVSGwyaEcKSklaZXdNTEtxL0EwRHU2RCtWR1NwSmRa\
Wis3Rmt6YkZ5QWg4OFhhM0FvR0FCN01OUjBQdHh6VkFPUWJ4Z21DZQoxUGJlN1BSNW9xOTN0YnZ3\
NGVnNXhrWW5maWhuemR6c1hsTTQ0Z1MyY2QvRXZnc3UwR2s4RzIwaWQ2bWJkRDZmCjg0TXNFdnYz\
ci9qVTliYllReFdhUXZhY0o5SzdUdUNndFhFbkJBWmc2Q0d6RVBvckhpcUlHbFcrTGtobUFHVWcK\
S2JkRERURUFIUlh0VGg5bjFUSU9YbEU9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"
# Add a TLS certificate.
tls.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURrekNDQW51Z0F3SUJBZ0lVZUtneEFpVTlw\
WW9jYkxQY0MvcTFIZ21OUUlFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1dURUxNQWtHQTFVRUJoTUNh\
WFF4Q3pBSkJnTlZCQWdNQW0xcE1Rc3dDUVlEVlFRSERBSnRhVEVUTUJFRwpBMVVFQ2d3S2FXNW1h\
VzVwYzNCaGJqRU1NQW9HQTFVRUN3d0RaVzVuTVEwd0N3WURWUVFEREFScGMzQnVNQjRYCkRURTVN\
RGt4TWpFeU1ERXlNVm9YRFRJNU1Ea3dPVEV5TURFeU1Wb3dXVEVMTUFrR0ExVUVCaE1DYVhReEN6\
QUoKQmdOVkJBZ01BbTFwTVFzd0NRWURWUVFIREFKdGFURVRNQkVHQTFVRUNnd0thVzVtYVc1cGMz\
QmhiakVNTUFvRwpBMVVFQ3d3RFpXNW5NUTB3Q3dZRFZRUUREQVJwYzNCdU1JSUJJakFOQmdrcWhr\
aUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQXhxOGpmVG8xL3phVVBTK09OaEhBdkozQWRq\
Z1VKWTRQeTgyRnpJRnpmbzliMGVkUnZKY3AKVlVKKy9sOEUzWGVzWFY3TnBBREp4THVYQ0Robk1l\
NmxEWDJtQ29KRmtGTlFYc3hpWFhUbCtwNkpGU2hUQ2FFNwp1bnExNVp0NVp5SDBiKzYxSkRuNDhh\
THpQNHk4LzhOU2FwMzYzdVU2MzdnaDFyeG9jd29haHdHTTRlelFBczg2CmlMQU91Y2UxU2VMTnll\
d2pWRFcvRFJTSDFuRzdrM1JvbEVtV0Q5K28xWk9lNzhxRHEyeVVoWmF0T0doTEthTVEKTE1jYUQ4\
YjBxMzU5alVtVTFRM1M4R25nUmVtcjlvNVNVRVBXdDJyN2I4SlliTXc0SXZjRlFDMjEwL016dlJl\
UwpNOThnQTJUYVNYN1R5SFN3L0lGYnltWHZLdEl2b05LaEdRSURBUUFCbzFNd1VUQWRCZ05WSFE0\
RUZnUVV3d3N3Ck0ycjY3MVZjR1R5L083WkllZXJnTUVBd0h3WURWUjBqQkJnd0ZvQVV3d3N3TTJy\
NjcxVmNHVHkvTzdaSWVlcmcKTUVBd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHOXcw\
QkFRc0ZBQU9DQVFFQWhvb3IxbWlPWFBnVQpmMDJQRG9yN1lXdlhCNTllcEpxTzlQVENlK0l4cmps\
VDROWEZHb1VoOTdQSFVBY3R5cnBScnM1UWRZNncxbWFyClY3UWdhSFZMaGtXWFRlb01vY1hYOERV\
UkZvRHJoS0wrcWhsUlBoNTZVdDRLVEdCS1UyK0p5UzNsVklQc3J4MnkKUXZFOHFYNWhOVDdFU2JM\
c3l6aHNoUXdSbjlQRXJ4b3NoeGhwUEkySnRIeFN6Y2U5V1VvMkd6TUlYd3VwMTJwTQpJTFZoWmF2\
d0xzd1RXbzBYemlaVVRNaWxkQys0U0gxZmRTb1M5aG9rdllZOEpJc1orT1RvYTFYRmY3LzkySytN\
CnZ3b29JK0FsTWQvNXpCNW9weVI1MjdlYVQyaE9vQ0s4d1IyL0VNNjh2OTdacHVVWG5ySkhzYity\
ZENIQVdVdXkKT05hUFJSUjNydz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
Loading
Loading