From 6c9d4161b3aadb516466e95d0ff45dc83229200c Mon Sep 17 00:00:00 2001 From: Paul Wright Date: Wed, 10 Jun 2026 16:26:47 +0100 Subject: [PATCH 1/9] Add comprehensive custom certificates documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add detailed custom certificates section to kube-yaml/site-linking.md - Explains default Skupper CA and certificate behavior - Documents custom server certificate setup - Provides kubectl/yq and manual methods for Link generation - Includes client certificate generation workflows - Add cross-reference in kube-cli/site-linking.md directing to YAML approach - Update overview/security.md with certificate trust explanation - Fix terminology: 'Issuer' → 'signing Certificate resource' - Fix certificate description: clarify CA hierarchy (not self-signed server cert) - Fix kubectl commands: remove incorrect .items[] path for named resources --- input/kube-cli/site-linking.md | 138 ++------------------ input/kube-yaml/site-linking.md | 216 ++++++++++++++++++++++++++++++-- input/overview/security.md | 22 +++- 3 files changed, 232 insertions(+), 144 deletions(-) diff --git a/input/kube-cli/site-linking.md b/input/kube-cli/site-linking.md index 1eec04a9..3dd14abe 100644 --- a/input/kube-cli/site-linking.md +++ b/input/kube-cli/site-linking.md @@ -1,8 +1,5 @@ # Linking sites on Kubernetes using the Skupper CLI - - -Create links between sites on Kubernetes by using the CLI. Using the Skupper command-line interface (CLI) allows you to create links between sites. The link direction is not significant, and is typically determined by ease of connectivity. For example, if east is behind a firewall, linking from east to west is the easiest option. @@ -11,7 +8,6 @@ Once sites are linked, services can be exposed and consumed across the applicati ## Linking sites using a token - A token provides a secure method to link sites. By default, a token can only be used once and must be used within 15 minutes to link sites. @@ -70,19 +66,11 @@ To link sites, you create a token on one site and redeem that token on the other skupper link status ``` You might need to issue the command multiple times before the link is ready: - ```bash - skupper link status ``` - Example output: - ```text + $ skupper link status NAME STATUS COST MESSAGE west-12f75bc8-5dda-4256-88f8-9df48150281a Pending 1 Not Operational - ``` - ```bash - skupper link status - ``` - Example output: - ```text + $ skupper link status NAME STATUS COST MESSAGE west-12f75bc8-5dda-4256-88f8-9df48150281a Ready 1 OK ``` @@ -92,7 +80,6 @@ There are many options to consider when linking sites using the CLI, see [CLI Re ## Linking sites using a `link` resource - An alternative approach to linking sites using tokens is to create a `link` resource YAML file using the CLI, and to apply that resource to another site. @@ -105,7 +92,7 @@ To link sites, you create a `link` resource YAML file on one site and apply that **Procedure** -1. On the site where you want to create a link, make sure link access is enabled: +1. On the site where you want to create a link , make sure link access is enabled: ```bash skupper site update --enable-link-access ``` @@ -114,12 +101,6 @@ To link sites, you create a `link` resource YAML file on one site and apply that skupper link generate > ``` where `` is the name of a YAML file that is saved on your local filesystem. - The `link` YAML file contains the following information: - * The name of the link - * The certificate used to authenticate the link - * Two host and port entries for the listening site are included for each link. - - If the listening site uses high availability mode, two link resources are created. 3. Apply the `link` resource YAML file on a different site to create a link: ```bash @@ -132,19 +113,11 @@ To link sites, you create a `link` resource YAML file on one site and apply that skupper link status ``` You might need to issue the command multiple times before the link is ready: - ```bash - skupper link status ``` - Example output: - ```text + $ skupper link status NAME STATUS COST MESSAGE west-12f75bc8-5dda-4256-88f8-9df48150281a Pending 1 Not Operational - ``` - ```bash - skupper link status - ``` - Example output: - ```text + $ skupper link status NAME STATUS COST MESSAGE west-12f75bc8-5dda-4256-88f8-9df48150281a Ready 1 OK ``` @@ -152,103 +125,12 @@ To link sites, you create a `link` resource YAML file on one site and apply that There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. - -## Linking sites through an HTTP proxy - - -If your network requires routing through an HTTP CONNECT proxy to reach remote sites, you can configure Skupper links to use a proxy. -This feature is only available when using `link` resources, not tokens. - -**Prerequisites** - -* Two sites -* At least one site with `enable-link-access` enabled. -* An HTTP CONNECT proxy accessible from the linking site -* Network connectivity from the proxy to the listening site's router endpoints -* The proxy must allow HTTP CONNECT requests to ports 55671 (inter-router) and 45671 (edge). For example, Squid requires: - ``` - acl skupper_ports port 55671 45671 - http_access allow CONNECT skupper_ports - ``` - -To link sites through a proxy, you create a Secret containing the proxy configuration, generate a `link` resource YAML file, reference the proxy Secret in the link settings, and apply that resource to create the link. - -**Procedure** - -1. On the listening site, make sure link access is enabled: - ```bash - skupper site update --enable-link-access - ``` +## Using custom certificates -2. On the listening site, create a `link` resource YAML file: - ```bash - skupper link generate > link.yaml - ``` +For information about linking sites using custom certificates instead of the default Skupper-generated certificates, see [Linking sites using custom certificates][custom-certs-yaml]. -3. Copy the generated `link.yaml` file to the linking site. - -4. On the linking site, create a Secret with the proxy configuration: - ```yaml - apiVersion: v1 - kind: Secret - metadata: - name: my-proxy-config - type: kubernetes.io/basic-auth - stringData: - host: proxy.example.com - port: "3128" - username: myuser - password: mypassword - ``` - - **📌 NOTE** - If your proxy does not require authentication, remove the username and password. - -5. On the linking site, edit the `link.yaml` file to add the proxy configuration in the settings section: - ```yaml - apiVersion: skupper.io/v2alpha1 - kind: Link - metadata: - name: link-to-remote-site - spec: - cost: 1 - endpoints: - - host: remote-site.example.com - name: inter-router - port: "55671" - - host: remote-site.example.com - name: edge - port: "45671" - tlsCredentials: link-to-remote-site - settings: - proxy-configuration: my-proxy-config - ``` - where `my-proxy-config` is the name of the Secret created in step 4. +**📌 NOTE** +The YAML approach is recommended for custom certificate workflows as it provides more control over certificate management and integration with existing PKI infrastructure. -6. On the linking site, apply the `link` resource YAML file to create the link: - ```bash - kubectl apply -f link.yaml - ``` +[custom-certs-yaml]: ../kube-yaml/site-linking.html#kube-link-custom-certs-yaml -7. Check the status of the link: - ```bash - skupper link status - ``` - You might need to issue the command multiple times before the link is ready. - - If the link remains in "Pending" or "Not Operational" status, check: - - * The proxy Secret exists and contains the correct host and port - * The proxy is accessible from the router pod - * Router logs for connection errors: `kubectl logs deployment/skupper-router` - - **📌 NOTE** - If you update the proxy Secret, you must trigger a reconciliation to apply the changes: - ```bash - kubectl annotate link reconcile=$(date +%s) --overwrite - ``` - -All inter-site traffic is protected by mutual TLS and routed through the HTTP CONNECT proxy tunnel. -You can now expose services on the application network. - -There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. diff --git a/input/kube-yaml/site-linking.md b/input/kube-yaml/site-linking.md index 504cb307..cf01e0f7 100644 --- a/input/kube-yaml/site-linking.md +++ b/input/kube-yaml/site-linking.md @@ -1,10 +1,5 @@ ---- -render_macros: false ---- - # Linking sites on Kubernetes using YAML - Once sites are linked, services can be exposed and consumed across the application network without the need to open ports or manage inter-site connectivity. @@ -17,10 +12,7 @@ The link direction is not significant, and is typically determined by ease of co -## Linking sites using `AccessGrant` and `AccessToken` resources - - -Use `AccessGrant` and `AccessToken` resources to create a link between two Kubernetes sites using YAML. +## Linking sites using `AccessGrant` and `AccessToken` resources **Prerequisites** @@ -71,10 +63,10 @@ A connecting site redeems this token for a `Link` resource to establish a link t 2. On the listening site, populate environment variables to allow token generation: - ```bash - URL="$(kubectl get accessgrant grant-west -o template --template '{{ .status.url }}')" - CODE="$(kubectl get accessgrant grant-west -o template --template '{{ .status.code }}')" - CA_RAW="$(kubectl get accessgrant grant-west -o template --template '{{ .status.ca }}')" + ```shell + URL="$(kubectl get accessgrant grant-west -o template --template '{{{ .status.url }}}')" + CODE="$(kubectl get accessgrant grant-west -o template --template '{{{ .status.code }}}')" + CA_RAW="$(kubectl get accessgrant grant-west -o template --template '{{{ .status.ca }}}')" ``` These environment variable settings support the next step of generating the token. @@ -122,3 +114,201 @@ A connecting site redeems this token for a `Link` resource to establish a link t NAME STATUS REMOTE SITE MESSAGE token-to-west Ready my-site OK ``` + + +## Linking sites using `Link` resources and custom certificates + +By default, the Skupper V2 controller generates internal Certificate Authorities (CAs) and self-signed certificates. +For example, it creates certificates to authenticate incoming Skupper links from external Skupper sites. + +The CA and server certificate used for this authentication are named `skupper-site-ca` (default signing `Certificate` resource for a Skupper Site) and `skupper-site-server`, respectively. + +The server certificate (`skupper-site-server`) issued by the self-signed CA `skupper-site-ca` is issued for the public hostname or IP address associated with the `skupper-router` service. This depends on the ingress method used, for example an OpenShift Route or a Kubernetes LoadBalancer Service. + +Although this behavior is automatic, you can override it by providing your own custom server certificate or even your own CA. + +**Prerequisites** + +* Two sites +* The listening site must have `link-access` enabled +* A server certificate and key for the listening site +* `jq` and `yq` installed if using the kubectl method to generate the `Link` resource +* `skupper` CLI installed if using the CLI method to generate the `Link` resource + +To link sites using custom certificates, you provide a custom server certificate on the listening site and create a `Link` resource on the connecting site that references matching client credentials. + +**Procedure** + +1. On the listening site, create a secret named `skupper-site-server`, for example: + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: skupper-site-server + data: + ca.crt: LS0tLS1C...redacted + tls.crt: LS0tLS1C...redacted + tls.key: LS0tLS1C...redacted + ``` + Apply the secret: + ```shell + kubectl apply -f skupper-site-server.yaml + ``` + + Make sure the certificate specified in `tls.crt` is valid for the hostname or IP address that will be referenced in your `Link` resource. In this example, consider the server certificate as being valid for the hostname: `skupper.public.host`. + +2. Determine the hostname or IP address for the listening site. + + In case your Skupper Site is already created, you can find the appropriate Hostname or IP by looking at the Endpoint element of a Site status: + ```shell + kubectl get site -o json | jq -r '.status.endpoints[0].host' + ``` + And you will see something like: + ``` + skupper.public.host + ``` + + **_Note:_** Make sure you specify the appropriate namespace when running the commands from this example. + + Again, if your Site has already been created, Skupper will recognize your custom secret. You can confirm this with the following command: + ```shell + kubectl get certificate skupper-site-server -o json | jq -r '.status.conditions[].message' + ``` + You should see a message like: + ``` + Secret exists but is not controlled by skupper + ``` + This confirms that Skupper has detected your certificate but is not managing it. + +3. On the listening site, create client credentials for the connecting site. + + Once your Skupper site is configured to use your custom server certificate, you can create a `Link` resource and an associated client `Secret`. If the `skupper-site-ca` signing `Certificate` resource has been provided, you can create a Certificate resource and Skupper will generate the client Secret to be used, but it is only possible if the signing `Certificate` resource has been provided, otherwise, you have to provide the client Secret yourself. + + If the listening site provides the `skupper-site-ca` issuer, create a `Certificate` resource so that Skupper generates a client secret named `skupper-link`: + ```yaml + apiVersion: skupper.io/v2alpha1 + kind: Certificate + metadata: + name: skupper-link + spec: + ca: skupper-site-ca + client: true + subject: skupper.public.host + ``` + Apply the resource: + ```shell + kubectl apply -f skupper-link-certificate.yaml + ``` + You should see an output like: + ``` + certificate.skupper.io/skupper-link created + ``` + Then a Secret named `skupper-link` should be created and it can be used to compose your link file. + + Save the generated secret to a local file for use in the next step: + ```shell + kubectl get secret skupper-link -o yaml | yq eval -o=yaml 'del(.metadata.namespace, .metadata.creationTimestamp, .metadata.resourceVersion, .metadata.uid, .metadata.managedFields)' - > client-secret.yaml + ``` + + If you are providing the client certificate yourself, create a secret named `skupper-link`, for example: + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: skupper-link + data: + ca.crt: LS0tLS1C...redacted + tls.crt: LS0tLS1C...redacted + tls.key: LS0tLS1C...redacted + ``` + Save this resource locally as `client-secret.yaml` if you want to combine it with a `Link` resource in a single file. + +4. On the listening site, create a `Link` resource YAML file. + + Now, regardless of whether Skupper generated your client certificate Secret or if you generated it yourself, to define a Skupper Link, that can be shared with remote sites allowing them to initiate a secure outgoing link to your site, you will need to write a YAML file that contains both documents: a `Link`, and a Client `Secret`. + + You can generate a Link using `kubectl` or manually (as long as retrieve the list of endpoints). Here are these two methods: + + **Option A: Using kubectl with jq and yq** + + The following command uses `kubectl`, `yq`, `jq` and `tee` to extract and compose the information needed to define a Link, storing the Link document into `skupper-link.yaml`: + ```shell + endpoints=$(kubectl get site -o json | jq -r '.status.endpoints') + cat << EOF | yq -y --argjson endpoints "${endpoints}" '.spec.endpoints = $endpoints' | tee skupper-link.yaml + apiVersion: skupper.io/v2alpha1 + kind: Link + metadata: + name: skupper-link + spec: + cost: 1 + tlsCredentials: skupper-link + EOF + ``` + Then you need to combine it in a YAML file that contains both the Link above and the client Secret. Suppose your client Secret is stored in a file named `client-secret.yaml`, you could run: + ```shell + echo "---" >> skupper-link.yaml + cat client-secret.yaml >> skupper-link.yaml + ``` + + **Option B: Manual generation** + + You can retrieve the list of endpoints from the Site definition, using: + ```shell + kubectl get site -o yaml | yq -y .status.endpoints + ``` + The command above uses both `kubectl` and `yq`. And the output should be something like: + ```yaml + - group: skupper-router + host: skupper.public.host + name: inter-router + port: '55671' + - group: skupper-router + host: skupper.public.host + name: edge + port: '45671' + ``` + + Then you can create your Link file with: + ```yaml + --- + apiVersion: skupper.io/v2alpha1 + kind: Link + metadata: + name: skupper-link + spec: + cost: 1 + tlsCredentials: skupper-link + endpoints: + - group: skupper-router + host: skupper.public.host # The hostname or IP specified in your custom certificate + name: inter-router + port: '55671' + - group: skupper-router + host: skupper.public.host # The same hostname or IP + name: edge + port: '45671' + --- + apiVersion: v1 + kind: Secret + metadata: + name: skupper-link + data: + ca.crt: LS0tLS1C...redacted # The trusted CA certificate + tls.crt: LS0tLS1C...redacted # The client certificate + tls.key: LS0tLS1C...redacted # The corresponding private key + ``` + +5. Securely transfer the `Link` resource YAML file to the context of the connecting site. + If you have both sites available from your terminal session, this step is not required. + + **📌 NOTE** + Access to this file provides access to the application network. + Protect it appropriately. + +6. On the connecting site, apply the YAML file and check status: + ```shell + kubectl apply -f skupper-link.yaml + kubectl get link + NAME STATUS REMOTE SITE MESSAGE + skupper-link Ready my-site OK + ``` diff --git a/input/overview/security.md b/input/overview/security.md index 81503c1d..737af5f2 100644 --- a/input/overview/security.md +++ b/input/overview/security.md @@ -1,8 +1,5 @@ # Skupper security - - -Skupper protects service-to-service communication with built-in mutual TLS security. Skupper securely connects your services with TLS authentication and encryption. See how Skupper enables you to deploy your application securely across Kubernetes clusters. @@ -24,3 +21,22 @@ Each router is uniquely identified by its own certificate. ![clusters-tls](../images/clusters-tls.svg) This means that the Skupper network is isolated from external access, preventing security risks such as lateral attacks, malware infestations, and data exfiltration. + +**Certificates and trust between sites** + +On Kubernetes, each site has its own certificate authority for inter-site communication. +By default, Skupper generates the certificates needed to identify the router and to authenticate incoming and outgoing links. + +When two sites are linked, each router verifies the certificate presented by the remote router and checks that it is signed by a trusted CA. +This mutual TLS exchange ensures that only sites with valid credentials can join the application network. + +If your environment requires certificates issued by your own PKI, you can replace the default server certificate that a site uses for incoming links and provide matching client credentials for connecting sites. +This allows you to keep Skupper's mutual TLS model while aligning certificate management with your organization's security requirements. + +**Service level TLS** + +Skupper always encrypts traffic between sites. +This protects traffic carried across the application network, even when workloads run in different clusters or clouds. + +This inter-site encryption is separate from any TLS configuration used by your application services. +If a backend service also requires TLS, you can configure listener and connector resources with appropriate credentials for the application side of the connection. From d929ea381bfccbee31fbb8516b52634c42a882a5 Mon Sep 17 00:00:00 2001 From: Paul Wright Date: Wed, 10 Jun 2026 16:58:19 +0100 Subject: [PATCH 2/9] fix rebase --- input/kube-cli/site-linking.md | 52 +++++++++++++++++++++------------ input/kube-yaml/site-linking.md | 18 ++++++++---- input/overview/security.md | 19 ------------ 3 files changed, 46 insertions(+), 43 deletions(-) diff --git a/input/kube-cli/site-linking.md b/input/kube-cli/site-linking.md index 3dd14abe..d4a36748 100644 --- a/input/kube-cli/site-linking.md +++ b/input/kube-cli/site-linking.md @@ -1,28 +1,41 @@ - -# Linking sites on Kubernetes using the Skupper CLI + +# Linking sites on local systems using the Skupper CLI + + +Use the Skupper CLI on local systems to create links between sites. Using the Skupper command-line interface (CLI) allows you to create links between sites. The link direction is not significant, and is typically determined by ease of connectivity. For example, if east is behind a firewall, linking from east to west is the easiest option. Once sites are linked, services can be exposed and consumed across the application network without the need to open ports or manage inter-site connectivity. - -## Linking sites using a token +A *local system* includes Docker, Podman or Linux system. + +In this release, the CLI does not support issuing tokens for local systems. +However, you can redeem tokens on a local system, and you can create and use 'link' resources. + + +## Linking to Kubernetes sites using a token + + +A token lets a local system site link securely to a Kubernetes site. A token provides a secure method to link sites. By default, a token can only be used once and must be used within 15 minutes to link sites. -This procedure describes how to issue a token from one site and redeem that token on another site to create a link. +This procedure describes how to issue a token from a Kubernetes site and redeem that token on a local system site to create a link. **Prerequisites** -* Two sites -* At least one site with `enable-link-access` enabled. +* A local system site and a Kubernetes site. +* A Kubernetes site with `enable-link-access` enabled. + +To link sites, you create a token on the Kubernetes site and redeem that token on the local system site to create the link. -To link sites, you create a token on one site and redeem that token on the other site to create the link. +There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. **Procedure** -1. On the site where you want to issue the token, make sure link access is enabled: +1. On the Kubernetes site where you want to issue the token, make sure link access is enabled: ```bash skupper site update --enable-link-access ``` @@ -55,7 +68,7 @@ To link sites, you create a token on one site and redeem that token on the other All inter-site traffic is protected by mutual TLS using a private, dedicated certificate authority (CA). A token is not a certificate, but is securely exchanged for a certificate during the linking process. -3. Redeem the token on a different site to create a link: +3. Redeem the token on a local system site to create a link: ```bash skupper token redeem ``` @@ -66,7 +79,7 @@ To link sites, you create a token on one site and redeem that token on the other skupper link status ``` You might need to issue the command multiple times before the link is ready: - ``` + ```text $ skupper link status NAME STATUS COST MESSAGE west-12f75bc8-5dda-4256-88f8-9df48150281a Pending 1 Not Operational @@ -76,10 +89,9 @@ To link sites, you create a token on one site and redeem that token on the other ``` You can now expose services on the application network. -There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. - - + ## Linking sites using a `link` resource + An alternative approach to linking sites using tokens is to create a `link` resource YAML file using the CLI, and to apply that resource to another site. @@ -90,11 +102,14 @@ An alternative approach to linking sites using tokens is to create a `link` reso To link sites, you create a `link` resource YAML file on one site and apply that resource on the other site to create the link. +There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. + **Procedure** 1. On the site where you want to create a link , make sure link access is enabled: ```bash skupper site update --enable-link-access + skupper site reload ``` 2. Create a `link` resource YAML file: ```bash @@ -104,7 +119,7 @@ To link sites, you create a `link` resource YAML file on one site and apply that 3. Apply the `link` resource YAML file on a different site to create a link: ```bash - kubectl apply -f + skupper system apply -f ``` where `` is the name of a YAML file that is saved on your local filesystem. @@ -113,17 +128,16 @@ To link sites, you create a `link` resource YAML file on one site and apply that skupper link status ``` You might need to issue the command multiple times before the link is ready: - ``` + ```text $ skupper link status NAME STATUS COST MESSAGE - west-12f75bc8-5dda-4256-88f8-9df48150281a Pending 1 Not Operational + west Pending 1 Not Operational $ skupper link status NAME STATUS COST MESSAGE - west-12f75bc8-5dda-4256-88f8-9df48150281a Ready 1 OK + west Ready 1 OK ``` You can now expose services on the application network. -There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. ## Using custom certificates diff --git a/input/kube-yaml/site-linking.md b/input/kube-yaml/site-linking.md index cf01e0f7..d80882b1 100644 --- a/input/kube-yaml/site-linking.md +++ b/input/kube-yaml/site-linking.md @@ -1,5 +1,10 @@ +--- +render_macros: false +--- + # Linking sites on Kubernetes using YAML + Once sites are linked, services can be exposed and consumed across the application network without the need to open ports or manage inter-site connectivity. @@ -12,7 +17,10 @@ The link direction is not significant, and is typically determined by ease of co -## Linking sites using `AccessGrant` and `AccessToken` resources +## Linking sites using `AccessGrant` and `AccessToken` resources + + +Use `AccessGrant` and `AccessToken` resources to create a link between two Kubernetes sites using YAML. **Prerequisites** @@ -63,10 +71,10 @@ A connecting site redeems this token for a `Link` resource to establish a link t 2. On the listening site, populate environment variables to allow token generation: - ```shell - URL="$(kubectl get accessgrant grant-west -o template --template '{{{ .status.url }}}')" - CODE="$(kubectl get accessgrant grant-west -o template --template '{{{ .status.code }}}')" - CA_RAW="$(kubectl get accessgrant grant-west -o template --template '{{{ .status.ca }}}')" + ```bash + URL="$(kubectl get accessgrant grant-west -o template --template '{{ .status.url }}')" + CODE="$(kubectl get accessgrant grant-west -o template --template '{{ .status.code }}')" + CA_RAW="$(kubectl get accessgrant grant-west -o template --template '{{ .status.ca }}')" ``` These environment variable settings support the next step of generating the token. diff --git a/input/overview/security.md b/input/overview/security.md index 737af5f2..530f0586 100644 --- a/input/overview/security.md +++ b/input/overview/security.md @@ -21,22 +21,3 @@ Each router is uniquely identified by its own certificate. ![clusters-tls](../images/clusters-tls.svg) This means that the Skupper network is isolated from external access, preventing security risks such as lateral attacks, malware infestations, and data exfiltration. - -**Certificates and trust between sites** - -On Kubernetes, each site has its own certificate authority for inter-site communication. -By default, Skupper generates the certificates needed to identify the router and to authenticate incoming and outgoing links. - -When two sites are linked, each router verifies the certificate presented by the remote router and checks that it is signed by a trusted CA. -This mutual TLS exchange ensures that only sites with valid credentials can join the application network. - -If your environment requires certificates issued by your own PKI, you can replace the default server certificate that a site uses for incoming links and provide matching client credentials for connecting sites. -This allows you to keep Skupper's mutual TLS model while aligning certificate management with your organization's security requirements. - -**Service level TLS** - -Skupper always encrypts traffic between sites. -This protects traffic carried across the application network, even when workloads run in different clusters or clouds. - -This inter-site encryption is separate from any TLS configuration used by your application services. -If a backend service also requires TLS, you can configure listener and connector resources with appropriate credentials for the application side of the connection. From 5af1f02a003924075b99d12ec2961a228f261213 Mon Sep 17 00:00:00 2001 From: Paul Wright Date: Wed, 10 Jun 2026 17:10:18 +0100 Subject: [PATCH 3/9] fix the fix --- input/kube-cli/site-linking.md | 179 +++++++++++++++++++++++++++------ 1 file changed, 147 insertions(+), 32 deletions(-) diff --git a/input/kube-cli/site-linking.md b/input/kube-cli/site-linking.md index d4a36748..114f998e 100644 --- a/input/kube-cli/site-linking.md +++ b/input/kube-cli/site-linking.md @@ -1,41 +1,32 @@ - -# Linking sites on local systems using the Skupper CLI + +# Linking sites on Kubernetes using the Skupper CLI -Use the Skupper CLI on local systems to create links between sites. +Create links between sites on Kubernetes by using the CLI. Using the Skupper command-line interface (CLI) allows you to create links between sites. The link direction is not significant, and is typically determined by ease of connectivity. For example, if east is behind a firewall, linking from east to west is the easiest option. Once sites are linked, services can be exposed and consumed across the application network without the need to open ports or manage inter-site connectivity. -A *local system* includes Docker, Podman or Linux system. - -In this release, the CLI does not support issuing tokens for local systems. -However, you can redeem tokens on a local system, and you can create and use 'link' resources. - - -## Linking to Kubernetes sites using a token + +## Linking sites using a token -A token lets a local system site link securely to a Kubernetes site. - A token provides a secure method to link sites. By default, a token can only be used once and must be used within 15 minutes to link sites. -This procedure describes how to issue a token from a Kubernetes site and redeem that token on a local system site to create a link. +This procedure describes how to issue a token from one site and redeem that token on another site to create a link. **Prerequisites** -* A local system site and a Kubernetes site. -* A Kubernetes site with `enable-link-access` enabled. - -To link sites, you create a token on the Kubernetes site and redeem that token on the local system site to create the link. +* Two sites +* At least one site with `enable-link-access` enabled. -There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. +To link sites, you create a token on one site and redeem that token on the other site to create the link. **Procedure** -1. On the Kubernetes site where you want to issue the token, make sure link access is enabled: +1. On the site where you want to issue the token, make sure link access is enabled: ```bash skupper site update --enable-link-access ``` @@ -68,7 +59,7 @@ There are many options to consider when linking sites using the CLI, see [CLI Re All inter-site traffic is protected by mutual TLS using a private, dedicated certificate authority (CA). A token is not a certificate, but is securely exchanged for a certificate during the linking process. -3. Redeem the token on a local system site to create a link: +3. Redeem the token on a different site to create a link: ```bash skupper token redeem ``` @@ -79,17 +70,27 @@ There are many options to consider when linking sites using the CLI, see [CLI Re skupper link status ``` You might need to issue the command multiple times before the link is ready: + ```bash + skupper link status + ``` + Example output: ```text - $ skupper link status NAME STATUS COST MESSAGE west-12f75bc8-5dda-4256-88f8-9df48150281a Pending 1 Not Operational - $ skupper link status + ``` + ```bash + skupper link status + ``` + Example output: + ```text NAME STATUS COST MESSAGE west-12f75bc8-5dda-4256-88f8-9df48150281a Ready 1 OK ``` You can now expose services on the application network. - +There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. + + ## Linking sites using a `link` resource @@ -102,24 +103,27 @@ An alternative approach to linking sites using tokens is to create a `link` reso To link sites, you create a `link` resource YAML file on one site and apply that resource on the other site to create the link. -There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. - **Procedure** -1. On the site where you want to create a link , make sure link access is enabled: +1. On the site where you want to create a link, make sure link access is enabled: ```bash skupper site update --enable-link-access - skupper site reload ``` 2. Create a `link` resource YAML file: ```bash skupper link generate > ``` where `` is the name of a YAML file that is saved on your local filesystem. + The `link` YAML file contains the following information: + * The name of the link + * The certificate used to authenticate the link + * Two host and port entries for the listening site are included for each link. + + If the listening site uses high availability mode, two link resources are created. 3. Apply the `link` resource YAML file on a different site to create a link: ```bash - skupper system apply -f + kubectl apply -f ``` where `` is the name of a YAML file that is saved on your local filesystem. @@ -128,16 +132,127 @@ There are many options to consider when linking sites using the CLI, see [CLI Re skupper link status ``` You might need to issue the command multiple times before the link is ready: + ```bash + skupper link status + ``` + Example output: ```text - $ skupper link status NAME STATUS COST MESSAGE - west Pending 1 Not Operational - $ skupper link status + west-12f75bc8-5dda-4256-88f8-9df48150281a Pending 1 Not Operational + ``` + ```bash + skupper link status + ``` + Example output: + ```text NAME STATUS COST MESSAGE - west Ready 1 OK + west-12f75bc8-5dda-4256-88f8-9df48150281a Ready 1 OK ``` You can now expose services on the application network. +There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. + + +## Linking sites through an HTTP proxy + + +If your network requires routing through an HTTP CONNECT proxy to reach remote sites, you can configure Skupper links to use a proxy. +This feature is only available when using `link` resources, not tokens. + +**Prerequisites** + +* Two sites +* At least one site with `enable-link-access` enabled. +* An HTTP CONNECT proxy accessible from the linking site +* Network connectivity from the proxy to the listening site's router endpoints +* The proxy must allow HTTP CONNECT requests to ports 55671 (inter-router) and 45671 (edge). For example, Squid requires: + ``` + acl skupper_ports port 55671 45671 + http_access allow CONNECT skupper_ports + ``` + +To link sites through a proxy, you create a Secret containing the proxy configuration, generate a `link` resource YAML file, reference the proxy Secret in the link settings, and apply that resource to create the link. + +**Procedure** + +1. On the listening site, make sure link access is enabled: + ```bash + skupper site update --enable-link-access + ``` + +2. On the listening site, create a `link` resource YAML file: + ```bash + skupper link generate > link.yaml + ``` + +3. Copy the generated `link.yaml` file to the linking site. + +4. On the linking site, create a Secret with the proxy configuration: + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: my-proxy-config + type: kubernetes.io/basic-auth + stringData: + host: proxy.example.com + port: "3128" + username: myuser + password: mypassword + ``` + + **📌 NOTE** + If your proxy does not require authentication, remove the username and password. + +5. On the linking site, edit the `link.yaml` file to add the proxy configuration in the settings section: + ```yaml + apiVersion: skupper.io/v2alpha1 + kind: Link + metadata: + name: link-to-remote-site + spec: + cost: 1 + endpoints: + - host: remote-site.example.com + name: inter-router + port: "55671" + - host: remote-site.example.com + name: edge + port: "45671" + tlsCredentials: link-to-remote-site + settings: + proxy-configuration: my-proxy-config + ``` + where `my-proxy-config` is the name of the Secret created in step 4. + +6. On the linking site, apply the `link` resource YAML file to create the link: + ```bash + kubectl apply -f link.yaml + ``` + +7. Check the status of the link: + ```bash + skupper link status + ``` + You might need to issue the command multiple times before the link is ready. + + If the link remains in "Pending" or "Not Operational" status, check: + + * The proxy Secret exists and contains the correct host and port + * The proxy is accessible from the router pod + * Router logs for connection errors: `kubectl logs deployment/skupper-router` + + **📌 NOTE** + If you update the proxy Secret, you must trigger a reconciliation to apply the changes: + ```bash + kubectl annotate link reconcile=$(date +%s) --overwrite + ``` + +All inter-site traffic is protected by mutual TLS and routed through the HTTP CONNECT proxy tunnel. +You can now expose services on the application network. + +There are many options to consider when linking sites using the CLI, see [CLI Reference][cli-ref], including *frequently used* options. + ## Using custom certificates From 10ff40577d9ddd50f9a87845cc00cc76d8213643 Mon Sep 17 00:00:00 2001 From: Paul Wright Date: Wed, 10 Jun 2026 17:11:16 +0100 Subject: [PATCH 4/9] tidy --- input/overview/security.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/input/overview/security.md b/input/overview/security.md index 530f0586..81503c1d 100644 --- a/input/overview/security.md +++ b/input/overview/security.md @@ -1,5 +1,8 @@ # Skupper security + + +Skupper protects service-to-service communication with built-in mutual TLS security. Skupper securely connects your services with TLS authentication and encryption. See how Skupper enables you to deploy your application securely across Kubernetes clusters. From 53e94e1d7fae90adb94c6839bf595f46e1b2b0a1 Mon Sep 17 00:00:00 2001 From: Paul Wright Date: Wed, 10 Jun 2026 18:14:12 +0100 Subject: [PATCH 5/9] update --- input/kube-yaml/site-linking.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/input/kube-yaml/site-linking.md b/input/kube-yaml/site-linking.md index d80882b1..da59fd3c 100644 --- a/input/kube-yaml/site-linking.md +++ b/input/kube-yaml/site-linking.md @@ -141,7 +141,6 @@ Although this behavior is automatic, you can override it by providing your own c * The listening site must have `link-access` enabled * A server certificate and key for the listening site * `jq` and `yq` installed if using the kubectl method to generate the `Link` resource -* `skupper` CLI installed if using the CLI method to generate the `Link` resource To link sites using custom certificates, you provide a custom server certificate on the listening site and create a `Link` resource on the connecting site that references matching client credentials. @@ -160,6 +159,7 @@ To link sites using custom certificates, you provide a custom server certificate ``` Apply the secret: ```shell + kubectl delete secret skupper-site-server # delete existing secret kubectl apply -f skupper-site-server.yaml ``` @@ -180,7 +180,7 @@ To link sites using custom certificates, you provide a custom server certificate Again, if your Site has already been created, Skupper will recognize your custom secret. You can confirm this with the following command: ```shell - kubectl get certificate skupper-site-server -o json | jq -r '.status.conditions[].message' + kubectl get certificate.skupper.io skupper-site-server -o json | jq -r '.status.conditions[].message' ``` You should see a message like: ``` From 4347ca236ad802a51af4769a9cb70e670c627f8b Mon Sep 17 00:00:00 2001 From: Paul Wright Date: Wed, 10 Jun 2026 18:19:24 +0100 Subject: [PATCH 6/9] update --- input/kube-cli/site-linking.md | 2 +- input/kube-yaml/site-linking.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/input/kube-cli/site-linking.md b/input/kube-cli/site-linking.md index 114f998e..ffb45bb4 100644 --- a/input/kube-cli/site-linking.md +++ b/input/kube-cli/site-linking.md @@ -259,7 +259,7 @@ There are many options to consider when linking sites using the CLI, see [CLI Re For information about linking sites using custom certificates instead of the default Skupper-generated certificates, see [Linking sites using custom certificates][custom-certs-yaml]. **📌 NOTE** -The YAML approach is recommended for custom certificate workflows as it provides more control over certificate management and integration with existing PKI infrastructure. +For custom certificate workflows YAML provides more control over certificate management and integration with existing PKI infrastructure, although you can still use the Skupper CLI to generate links for those workflows. [custom-certs-yaml]: ../kube-yaml/site-linking.html#kube-link-custom-certs-yaml diff --git a/input/kube-yaml/site-linking.md b/input/kube-yaml/site-linking.md index da59fd3c..7b461e07 100644 --- a/input/kube-yaml/site-linking.md +++ b/input/kube-yaml/site-linking.md @@ -190,9 +190,9 @@ To link sites using custom certificates, you provide a custom server certificate 3. On the listening site, create client credentials for the connecting site. - Once your Skupper site is configured to use your custom server certificate, you can create a `Link` resource and an associated client `Secret`. If the `skupper-site-ca` signing `Certificate` resource has been provided, you can create a Certificate resource and Skupper will generate the client Secret to be used, but it is only possible if the signing `Certificate` resource has been provided, otherwise, you have to provide the client Secret yourself. + Once your Skupper site is configured to use your custom server certificate, you can create a `Link` resource and an associated client `Secret`. Since Skupper always creates the `skupper-site-ca` signing `Certificate` resource on Kubernetes sites, you can use it to generate client credentials automatically. If you have replaced `skupper-site-ca` with a custom CA that Skupper cannot use for signing, you will need to provide the client `Secret` yourself. - If the listening site provides the `skupper-site-ca` issuer, create a `Certificate` resource so that Skupper generates a client secret named `skupper-link`: + To use the automatically created `skupper-site-ca` issuer, create a `Certificate` resource so that Skupper generates a client secret named `skupper-link`: ```yaml apiVersion: skupper.io/v2alpha1 kind: Certificate From 50edabf165abef44afcac7856cb3d0df1871d48c Mon Sep 17 00:00:00 2001 From: Paul Wright Date: Wed, 10 Jun 2026 18:21:37 +0100 Subject: [PATCH 7/9] update --- input/kube-yaml/site-linking.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/input/kube-yaml/site-linking.md b/input/kube-yaml/site-linking.md index 7b461e07..5e9dd93d 100644 --- a/input/kube-yaml/site-linking.md +++ b/input/kube-yaml/site-linking.md @@ -140,7 +140,7 @@ Although this behavior is automatic, you can override it by providing your own c * Two sites * The listening site must have `link-access` enabled * A server certificate and key for the listening site -* `jq` and `yq` installed if using the kubectl method to generate the `Link` resource +* `jq` and `yq` (mikefarah/yq, the Go-based implementation) installed if using the kubectl method to generate the `Link` resource To link sites using custom certificates, you provide a custom server certificate on the listening site and create a `Link` resource on the connecting site that references matching client credentials. @@ -239,18 +239,18 @@ To link sites using custom certificates, you provide a custom server certificate **Option A: Using kubectl with jq and yq** - The following command uses `kubectl`, `yq`, `jq` and `tee` to extract and compose the information needed to define a Link, storing the Link document into `skupper-link.yaml`: + The following command uses `kubectl`, `jq`, and `yq` to extract and compose the information needed to define a Link, storing the Link document into `skupper-link.yaml`: ```shell - endpoints=$(kubectl get site -o json | jq -r '.status.endpoints') - cat << EOF | yq -y --argjson endpoints "${endpoints}" '.spec.endpoints = $endpoints' | tee skupper-link.yaml - apiVersion: skupper.io/v2alpha1 - kind: Link - metadata: - name: skupper-link - spec: - cost: 1 - tlsCredentials: skupper-link - EOF + kubectl get site -o json | jq '{ + apiVersion: "skupper.io/v2alpha1", + kind: "Link", + metadata: {name: "skupper-link"}, + spec: { + cost: 1, + tlsCredentials: "skupper-link", + endpoints: .status.endpoints + } + }' | yq -P > skupper-link.yaml ``` Then you need to combine it in a YAML file that contains both the Link above and the client Secret. Suppose your client Secret is stored in a file named `client-secret.yaml`, you could run: ```shell @@ -262,7 +262,7 @@ To link sites using custom certificates, you provide a custom server certificate You can retrieve the list of endpoints from the Site definition, using: ```shell - kubectl get site -o yaml | yq -y .status.endpoints + kubectl get site -o yaml | yq '.status.endpoints' ``` The command above uses both `kubectl` and `yq`. And the output should be something like: ```yaml From c92066c7a09a82fa2a99dd27d7f071d1e33164b2 Mon Sep 17 00:00:00 2001 From: Paul Wright Date: Wed, 17 Jun 2026 15:57:35 +0100 Subject: [PATCH 8/9] update --- input/kube-yaml/site-linking.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/input/kube-yaml/site-linking.md b/input/kube-yaml/site-linking.md index 5e9dd93d..864d5b57 100644 --- a/input/kube-yaml/site-linking.md +++ b/input/kube-yaml/site-linking.md @@ -144,6 +144,8 @@ Although this behavior is automatic, you can override it by providing your own c To link sites using custom certificates, you provide a custom server certificate on the listening site and create a `Link` resource on the connecting site that references matching client credentials. +NOTE: In this procedure you delete and recreate your site to make sure the certificate configuration is applied. + **Procedure** 1. On the listening site, create a secret named `skupper-site-server`, for example: @@ -159,10 +161,12 @@ To link sites using custom certificates, you provide a custom server certificate ``` Apply the secret: ```shell - kubectl delete secret skupper-site-server # delete existing secret + kubectl delete site # delete the site kubectl apply -f skupper-site-server.yaml + kubectl apply -f site.yaml # recreate the site ``` - + NOTE: If you attempt to apply the secret on an existing site, the Skupper controller overwrites your changes. Make sure to create the secret before creating your site. + Make sure the certificate specified in `tls.crt` is valid for the hostname or IP address that will be referenced in your `Link` resource. In this example, consider the server certificate as being valid for the hostname: `skupper.public.host`. 2. Determine the hostname or IP address for the listening site. From 4c36aa58b6c051539c89a36bfa156e629e55d8e7 Mon Sep 17 00:00:00 2001 From: Paul Wright Date: Wed, 17 Jun 2026 16:55:30 +0100 Subject: [PATCH 9/9] update --- input/kube-cli/site-linking.md | 2 +- input/kube-yaml/custom-certs.md | 402 ++++++++++++++++++++++++++++++++ input/kube-yaml/index.md | 2 + input/kube-yaml/site-linking.md | 202 +--------------- mkdocs.yml | 1 + 5 files changed, 409 insertions(+), 200 deletions(-) create mode 100644 input/kube-yaml/custom-certs.md diff --git a/input/kube-cli/site-linking.md b/input/kube-cli/site-linking.md index ffb45bb4..7c763fdd 100644 --- a/input/kube-cli/site-linking.md +++ b/input/kube-cli/site-linking.md @@ -261,5 +261,5 @@ For information about linking sites using custom certificates instead of the def **📌 NOTE** For custom certificate workflows YAML provides more control over certificate management and integration with existing PKI infrastructure, although you can still use the Skupper CLI to generate links for those workflows. -[custom-certs-yaml]: ../kube-yaml/site-linking.html#kube-link-custom-certs-yaml +[custom-certs-yaml]: ../kube-yaml/custom-certs.md diff --git a/input/kube-yaml/custom-certs.md b/input/kube-yaml/custom-certs.md new file mode 100644 index 00000000..5ab676fe --- /dev/null +++ b/input/kube-yaml/custom-certs.md @@ -0,0 +1,402 @@ +--- +render_macros: false +--- + + +# Linking sites using custom certificates + + +By default, the Skupper controller generates internal Certificate Authorities (CAs) and self-signed certificates. +For example, it creates certificates to authenticate incoming Skupper links from external Skupper sites. + +The CA and server certificate used for this authentication are named `skupper-site-ca` (default signing `Certificate` resource for a Skupper Site) and `skupper-site-server`, respectively. + +Although this behavior is automatic, you can override it by providing your own custom server certificate or even your own CA. + +This document describes two approaches for using custom certificates: + +* **Using a custom `RouterAccess` and custom certificates** - Manually define the `RouterAccess` CR with your own certificate (`linkAccess` is not enabled) + +* **Using `Link` resources and custom certificates** - Override the default `skupper-site-server` certificate before `linkAccess` is enabled + + +**Key differences between approaches** + +| | `linkAccess` | `RouterAccess` | +|---|---|---| +| Who creates `RouterAccess` | Skupper controller (auto) | You (manually) | +| `generateTlsCredentials` | `true` | `false` | +| Secret name | Must be `skupper-site-server` | Any name you choose | +| Site delete/recreate needed | Yes, to prevent overwrite | No | +| Skupper overwrites your cert | Yes, unless pre-created | Never | + + + +## Linking sites using a custom `RouterAccess`, and custom certificates + + +By default, when you set `spec.linkAccess` on a `Site`, the Skupper controller automatically creates a `RouterAccess` named `skupper-router` with `generateTlsCredentials: true` and `tlsCredentials: skupper-site-server`. + +The alternative is to define the `RouterAccess` CR yourself with `generateTlsCredentials: false` and point `tlsCredentials` at a Secret you supply. When `generateTlsCredentials` is false, the `SecuredAccessManager` sets the downstream `SecuredAccess.spec.issuer` to `""`, and `checkCertificate` returns immediately without touching your Secret. + +**Prerequisites** + +* Two sites +* A server certificate and key for the listening site +* `jq` and `yq` (mikefarah/yq, the Go-based implementation) installed if using the kubectl method to generate the `Link` resource + +**Procedure** + +1. On the listening site, create a `Site` CR **without** `spec.linkAccess` (or with `spec.linkAccess: none`): + ```yaml + apiVersion: skupper.io/v2alpha1 + kind: Site + metadata: + name: my-site + spec: {} + ``` + Apply it: + ```shell + kubectl apply -f site.yaml + ``` + Because `spec.linkAccess` is not set, the controller will not auto-create any `RouterAccess`. + +2. On the listening site, create a Secret containing your custom server certificate. You can name it anything — this example uses `my-server-cert`: + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: my-server-cert + data: + ca.crt: LS0tLS1C...redacted + tls.crt: LS0tLS1C...redacted + tls.key: LS0tLS1C...redacted + ``` + Apply it: + ```shell + kubectl apply -f my-server-cert.yaml + ``` + Make sure the certificate in `tls.crt` is valid for the hostname or IP address that will be referenced in your `Link` resource. In this example, consider it valid for `skupper.public.host`. + +3. On the listening site, create a `RouterAccess` CR that references your Secret and sets `generateTlsCredentials: false`: + ```yaml + apiVersion: skupper.io/v2alpha1 + kind: RouterAccess + metadata: + name: my-router-access + spec: + generateTlsCredentials: false + tlsCredentials: my-server-cert + accessType: loadbalancer # or "route", "ingress", etc. + roles: + - name: inter-router + port: 55671 + - name: edge + port: 45671 + ``` + Apply it: + ```shell + kubectl apply -f my-router-access.yaml + ``` + Because `generateTlsCredentials: false`, Skupper will use your Secret as-is and will never overwrite it. + +4. Determine the hostname or IP address for the listening site. + + Check the `RouterAccess` status for the resolved endpoints: + ```shell + kubectl get routeraccess my-router-access -o json | jq -r '.status.endpoints[0].host' + ``` + You should see something like: + ``` + skupper.public.host + ``` + +5. On the listening site, create client credentials for the connecting site. + + Since Skupper still creates the `skupper-site-ca` signing `Certificate` resource, you can use it to generate a client secret automatically. Create a `Certificate` resource: + ```yaml + apiVersion: skupper.io/v2alpha1 + kind: Certificate + metadata: + name: skupper-link + spec: + ca: skupper-site-ca + client: true + subject: skupper.public.host + ``` + Apply it: + ```shell + kubectl apply -f skupper-link-certificate.yaml + ``` + Save the generated Secret for use in the next step: + ```shell + kubectl get secret skupper-link -o yaml | yq eval -o=yaml 'del(.metadata.namespace, .metadata.creationTimestamp, .metadata.resourceVersion, .metadata.uid, .metadata.managedFields)' - > client-secret.yaml + ``` + + If you are providing the client certificate yourself, create a Secret named `skupper-link` directly and save it as `client-secret.yaml`. + +6. On the listening site, create a `Link` resource YAML file. + + **Option A: Using kubectl with jq and yq** + ```shell + kubectl get routeraccess my-router-access -o json | jq '{ + apiVersion: "skupper.io/v2alpha1", + kind: "Link", + metadata: {name: "skupper-link"}, + spec: { + cost: 1, + tlsCredentials: "skupper-link", + endpoints: .status.endpoints + } + }' | yq -P > skupper-link.yaml + echo "---" >> skupper-link.yaml + cat client-secret.yaml >> skupper-link.yaml + ``` + + **Option B: Manual generation** + + Retrieve the endpoints: + ```shell + kubectl get routeraccess my-router-access -o yaml | yq '.status.endpoints' + ``` + Then compose the file manually: + ```yaml + --- + apiVersion: skupper.io/v2alpha1 + kind: Link + metadata: + name: skupper-link + spec: + cost: 1 + tlsCredentials: skupper-link + endpoints: + - group: skupper-router + host: skupper.public.host + name: inter-router + port: '55671' + - group: skupper-router + host: skupper.public.host + name: edge + port: '45671' + --- + apiVersion: v1 + kind: Secret + metadata: + name: skupper-link + data: + ca.crt: LS0tLS1C...redacted + tls.crt: LS0tLS1C...redacted + tls.key: LS0tLS1C...redacted + ``` + +7. Securely transfer the `Link` resource YAML file to the connecting site. + + **📌 NOTE** + Access to this file provides access to the application network. + Protect it appropriately. + +8. On the connecting site, apply the YAML file and check status: + ```shell + kubectl apply -f skupper-link.yaml + kubectl get link + NAME STATUS REMOTE SITE MESSAGE + skupper-link Ready my-site OK + ``` + + +## Linking sites using `Link` resources and custom certificates + + +The server certificate (`skupper-site-server`) issued by the self-signed CA `skupper-site-ca` is issued for the public hostname or IP address associated with the `skupper-router` service. This depends on the ingress method used, for example an OpenShift Route or a Kubernetes LoadBalancer Service. + +You can override this behavior by providing your own custom server certificate. + +**Prerequisites** + +* Two sites +* The listening site must have `link-access` enabled +* A server certificate and key for the listening site +* `jq` and `yq` (mikefarah/yq, the Go-based implementation) installed if using the kubectl method to generate the `Link` resource + +To link sites using custom certificates, you provide a custom server certificate on the listening site and create a `Link` resource on the connecting site that references matching client credentials. + +NOTE: In this procedure you delete and recreate your site to make sure the certificate configuration is applied. + +**Procedure** + +1. On the listening site, create a secret named `skupper-site-server`, for example: + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: skupper-site-server + data: + ca.crt: LS0tLS1C...redacted + tls.crt: LS0tLS1C...redacted + tls.key: LS0tLS1C...redacted + ``` + Apply the secret while deleting and recreating the site: + ```shell + kubectl delete site # delete the site + kubectl apply -f skupper-site-server.yaml + kubectl apply -f site.yaml # recreate the site + ``` + NOTE: If you attempt to apply the secret on an existing site, the Skupper controller overwrites your changes. Make sure to create the secret before creating your site. + + Make sure the certificate specified in `tls.crt` is valid for the hostname or IP address that will be referenced in your `Link` resource. In this example, consider the server certificate as being valid for the hostname: `skupper.public.host`. + +2. Determine the hostname or IP address for the listening site. + + In case your Skupper Site is already created, you can find the appropriate Hostname or IP by looking at the Endpoint element of a Site status: + ```shell + kubectl get site -o json | jq -r '.status.endpoints[0].host' + ``` + And you will see something like: + ``` + skupper.public.host + ``` + + **_Note:_** Make sure you specify the appropriate namespace when running the commands from this example. + + Again, if your Site has already been created, Skupper will recognize your custom secret. You can confirm this with the following command: + ```shell + kubectl get certificate.skupper.io skupper-site-server -o json | jq -r '.status.conditions[].message' + ``` + You should see a message like: + ``` + Secret exists but is not controlled by skupper + ``` + This confirms that Skupper has detected your certificate but is not managing it. + +3. On the listening site, create client credentials for the connecting site. + + Once your Skupper site is configured to use your custom server certificate, you can create a `Link` resource and an associated client `Secret`. Since Skupper always creates the `skupper-site-ca` signing `Certificate` resource on Kubernetes sites, you can use it to generate client credentials automatically. If you have replaced `skupper-site-ca` with a custom CA that Skupper cannot use for signing, you will need to provide the client `Secret` yourself. + + To use the automatically created `skupper-site-ca` issuer, create a `Certificate` resource so that Skupper generates a client secret named `skupper-link`: + ```yaml + apiVersion: skupper.io/v2alpha1 + kind: Certificate + metadata: + name: skupper-link + spec: + ca: skupper-site-ca + client: true + subject: skupper.public.host + ``` + Apply the resource: + ```shell + kubectl apply -f skupper-link-certificate.yaml + ``` + You should see an output like: + ``` + certificate.skupper.io/skupper-link created + ``` + Then a Secret named `skupper-link` should be created and it can be used to compose your link file. + + Save the generated secret to a local file for use in the next step: + ```shell + kubectl get secret skupper-link -o yaml | yq eval -o=yaml 'del(.metadata.namespace, .metadata.creationTimestamp, .metadata.resourceVersion, .metadata.uid, .metadata.managedFields)' - > client-secret.yaml + ``` + + If you are providing the client certificate yourself, create a secret named `skupper-link`, for example: + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: skupper-link + data: + ca.crt: LS0tLS1C...redacted + tls.crt: LS0tLS1C...redacted + tls.key: LS0tLS1C...redacted + ``` + Save this resource locally as `client-secret.yaml` if you want to combine it with a `Link` resource in a single file. + +4. On the listening site, create a `Link` resource YAML file. + + Now, regardless of whether Skupper generated your client certificate Secret or if you generated it yourself, to define a Skupper Link, that can be shared with remote sites allowing them to initiate a secure outgoing link to your site, you will need to write a YAML file that contains both documents: a `Link`, and a Client `Secret`. + + You can generate a Link using `kubectl` or manually (as long as retrieve the list of endpoints). Here are these two methods: + + **Option A: Using kubectl with jq and yq** + + The following command uses `kubectl`, `jq`, and `yq` to extract and compose the information needed to define a Link, storing the Link document into `skupper-link.yaml`: + ```shell + kubectl get site -o json | jq '{ + apiVersion: "skupper.io/v2alpha1", + kind: "Link", + metadata: {name: "skupper-link"}, + spec: { + cost: 1, + tlsCredentials: "skupper-link", + endpoints: .status.endpoints + } + }' | yq -P > skupper-link.yaml + ``` + Then you need to combine it in a YAML file that contains both the Link above and the client Secret. Suppose your client Secret is stored in a file named `client-secret.yaml`, you could run: + ```shell + echo "---" >> skupper-link.yaml + cat client-secret.yaml >> skupper-link.yaml + ``` + + **Option B: Manual generation** + + You can retrieve the list of endpoints from the Site definition, using: + ```shell + kubectl get site -o yaml | yq '.status.endpoints' + ``` + The command above uses both `kubectl` and `yq`. And the output should be something like: + ```yaml + - group: skupper-router + host: skupper.public.host + name: inter-router + port: '55671' + - group: skupper-router + host: skupper.public.host + name: edge + port: '45671' + ``` + + Then you can create your Link file with: + ```yaml + --- + apiVersion: skupper.io/v2alpha1 + kind: Link + metadata: + name: skupper-link + spec: + cost: 1 + tlsCredentials: skupper-link + endpoints: + - group: skupper-router + host: skupper.public.host # The hostname or IP specified in your custom certificate + name: inter-router + port: '55671' + - group: skupper-router + host: skupper.public.host # The same hostname or IP + name: edge + port: '45671' + --- + apiVersion: v1 + kind: Secret + metadata: + name: skupper-link + data: + ca.crt: LS0tLS1C...redacted # The trusted CA certificate + tls.crt: LS0tLS1C...redacted # The client certificate + tls.key: LS0tLS1C...redacted # The corresponding private key + ``` + +5. Securely transfer the `Link` resource YAML file to the context of the connecting site. + If you have both sites available from your terminal session, this step is not required. + + **📌 NOTE** + Access to this file provides access to the application network. + Protect it appropriately. + +6. On the connecting site, apply the YAML file and check status: + ```shell + kubectl apply -f skupper-link.yaml + kubectl get link + NAME STATUS REMOTE SITE MESSAGE + skupper-link Ready my-site OK + ``` diff --git a/input/kube-yaml/index.md b/input/kube-yaml/index.md index e39de691..811277a0 100644 --- a/input/kube-yaml/index.md +++ b/input/kube-yaml/index.md @@ -6,8 +6,10 @@ You can use YAML on Kubernetes after installing the Skupper controller to create * [Create sites][site-configuration] * [Link sites][site-linking] (requires that one site has link access enabled) +* [Link sites using custom certificates][custom-certs] * [Expose and consume services][service-exposure] [site-configuration]: ./site-configuration.html [site-linking]: ./site-linking.html +[custom-certs]: ./custom-certs.html [service-exposure]: ./service-exposure.html diff --git a/input/kube-yaml/site-linking.md b/input/kube-yaml/site-linking.md index 864d5b57..6f301f4f 100644 --- a/input/kube-yaml/site-linking.md +++ b/input/kube-yaml/site-linking.md @@ -123,204 +123,8 @@ A connecting site redeems this token for a `Link` resource to establish a link t token-to-west Ready my-site OK ``` - -## Linking sites using `Link` resources and custom certificates +## Using custom certificates -By default, the Skupper V2 controller generates internal Certificate Authorities (CAs) and self-signed certificates. -For example, it creates certificates to authenticate incoming Skupper links from external Skupper sites. +For information about linking sites using custom certificates instead of the default Skupper-generated certificates, see [Linking sites using custom certificates][custom-certs-yaml]. -The CA and server certificate used for this authentication are named `skupper-site-ca` (default signing `Certificate` resource for a Skupper Site) and `skupper-site-server`, respectively. - -The server certificate (`skupper-site-server`) issued by the self-signed CA `skupper-site-ca` is issued for the public hostname or IP address associated with the `skupper-router` service. This depends on the ingress method used, for example an OpenShift Route or a Kubernetes LoadBalancer Service. - -Although this behavior is automatic, you can override it by providing your own custom server certificate or even your own CA. - -**Prerequisites** - -* Two sites -* The listening site must have `link-access` enabled -* A server certificate and key for the listening site -* `jq` and `yq` (mikefarah/yq, the Go-based implementation) installed if using the kubectl method to generate the `Link` resource - -To link sites using custom certificates, you provide a custom server certificate on the listening site and create a `Link` resource on the connecting site that references matching client credentials. - -NOTE: In this procedure you delete and recreate your site to make sure the certificate configuration is applied. - -**Procedure** - -1. On the listening site, create a secret named `skupper-site-server`, for example: - ```yaml - apiVersion: v1 - kind: Secret - metadata: - name: skupper-site-server - data: - ca.crt: LS0tLS1C...redacted - tls.crt: LS0tLS1C...redacted - tls.key: LS0tLS1C...redacted - ``` - Apply the secret: - ```shell - kubectl delete site # delete the site - kubectl apply -f skupper-site-server.yaml - kubectl apply -f site.yaml # recreate the site - ``` - NOTE: If you attempt to apply the secret on an existing site, the Skupper controller overwrites your changes. Make sure to create the secret before creating your site. - - Make sure the certificate specified in `tls.crt` is valid for the hostname or IP address that will be referenced in your `Link` resource. In this example, consider the server certificate as being valid for the hostname: `skupper.public.host`. - -2. Determine the hostname or IP address for the listening site. - - In case your Skupper Site is already created, you can find the appropriate Hostname or IP by looking at the Endpoint element of a Site status: - ```shell - kubectl get site -o json | jq -r '.status.endpoints[0].host' - ``` - And you will see something like: - ``` - skupper.public.host - ``` - - **_Note:_** Make sure you specify the appropriate namespace when running the commands from this example. - - Again, if your Site has already been created, Skupper will recognize your custom secret. You can confirm this with the following command: - ```shell - kubectl get certificate.skupper.io skupper-site-server -o json | jq -r '.status.conditions[].message' - ``` - You should see a message like: - ``` - Secret exists but is not controlled by skupper - ``` - This confirms that Skupper has detected your certificate but is not managing it. - -3. On the listening site, create client credentials for the connecting site. - - Once your Skupper site is configured to use your custom server certificate, you can create a `Link` resource and an associated client `Secret`. Since Skupper always creates the `skupper-site-ca` signing `Certificate` resource on Kubernetes sites, you can use it to generate client credentials automatically. If you have replaced `skupper-site-ca` with a custom CA that Skupper cannot use for signing, you will need to provide the client `Secret` yourself. - - To use the automatically created `skupper-site-ca` issuer, create a `Certificate` resource so that Skupper generates a client secret named `skupper-link`: - ```yaml - apiVersion: skupper.io/v2alpha1 - kind: Certificate - metadata: - name: skupper-link - spec: - ca: skupper-site-ca - client: true - subject: skupper.public.host - ``` - Apply the resource: - ```shell - kubectl apply -f skupper-link-certificate.yaml - ``` - You should see an output like: - ``` - certificate.skupper.io/skupper-link created - ``` - Then a Secret named `skupper-link` should be created and it can be used to compose your link file. - - Save the generated secret to a local file for use in the next step: - ```shell - kubectl get secret skupper-link -o yaml | yq eval -o=yaml 'del(.metadata.namespace, .metadata.creationTimestamp, .metadata.resourceVersion, .metadata.uid, .metadata.managedFields)' - > client-secret.yaml - ``` - - If you are providing the client certificate yourself, create a secret named `skupper-link`, for example: - ```yaml - apiVersion: v1 - kind: Secret - metadata: - name: skupper-link - data: - ca.crt: LS0tLS1C...redacted - tls.crt: LS0tLS1C...redacted - tls.key: LS0tLS1C...redacted - ``` - Save this resource locally as `client-secret.yaml` if you want to combine it with a `Link` resource in a single file. - -4. On the listening site, create a `Link` resource YAML file. - - Now, regardless of whether Skupper generated your client certificate Secret or if you generated it yourself, to define a Skupper Link, that can be shared with remote sites allowing them to initiate a secure outgoing link to your site, you will need to write a YAML file that contains both documents: a `Link`, and a Client `Secret`. - - You can generate a Link using `kubectl` or manually (as long as retrieve the list of endpoints). Here are these two methods: - - **Option A: Using kubectl with jq and yq** - - The following command uses `kubectl`, `jq`, and `yq` to extract and compose the information needed to define a Link, storing the Link document into `skupper-link.yaml`: - ```shell - kubectl get site -o json | jq '{ - apiVersion: "skupper.io/v2alpha1", - kind: "Link", - metadata: {name: "skupper-link"}, - spec: { - cost: 1, - tlsCredentials: "skupper-link", - endpoints: .status.endpoints - } - }' | yq -P > skupper-link.yaml - ``` - Then you need to combine it in a YAML file that contains both the Link above and the client Secret. Suppose your client Secret is stored in a file named `client-secret.yaml`, you could run: - ```shell - echo "---" >> skupper-link.yaml - cat client-secret.yaml >> skupper-link.yaml - ``` - - **Option B: Manual generation** - - You can retrieve the list of endpoints from the Site definition, using: - ```shell - kubectl get site -o yaml | yq '.status.endpoints' - ``` - The command above uses both `kubectl` and `yq`. And the output should be something like: - ```yaml - - group: skupper-router - host: skupper.public.host - name: inter-router - port: '55671' - - group: skupper-router - host: skupper.public.host - name: edge - port: '45671' - ``` - - Then you can create your Link file with: - ```yaml - --- - apiVersion: skupper.io/v2alpha1 - kind: Link - metadata: - name: skupper-link - spec: - cost: 1 - tlsCredentials: skupper-link - endpoints: - - group: skupper-router - host: skupper.public.host # The hostname or IP specified in your custom certificate - name: inter-router - port: '55671' - - group: skupper-router - host: skupper.public.host # The same hostname or IP - name: edge - port: '45671' - --- - apiVersion: v1 - kind: Secret - metadata: - name: skupper-link - data: - ca.crt: LS0tLS1C...redacted # The trusted CA certificate - tls.crt: LS0tLS1C...redacted # The client certificate - tls.key: LS0tLS1C...redacted # The corresponding private key - ``` - -5. Securely transfer the `Link` resource YAML file to the context of the connecting site. - If you have both sites available from your terminal session, this step is not required. - - **📌 NOTE** - Access to this file provides access to the application network. - Protect it appropriately. - -6. On the connecting site, apply the YAML file and check status: - ```shell - kubectl apply -f skupper-link.yaml - kubectl get link - NAME STATUS REMOTE SITE MESSAGE - skupper-link Ready my-site OK - ``` +[custom-certs-yaml]: ../kube-yaml/custom-certs.md \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 9bc562d2..c300519b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -58,6 +58,7 @@ nav: - Overview: kube-yaml/index.md - Site Configuration: kube-yaml/site-configuration.md - Site Linking: kube-yaml/site-linking.md + - Custom Certificates: kube-yaml/custom-certs.md - Service Exposure: kube-yaml/service-exposure.md - System CLI: - Overview: system-cli/index.md