Categories

Add and Remove traefik proxy to cloudspaces

You are here:
< All Topics

The API exposes 2 separate endpoints to add addProxy(cloudspaceId, config, proxyType, certificates) and remove proxy removeProxy(cloudspaceId) (edge router) to your cloudspace of choice. Currently, the API only supports traefik:2.3 at the time of this writing. A typical use case of this feature would be adding proxy, reverse proxy or a load balancer on the VMs under your cloudspace.
The API allows the user to enter specific traefik configuration as well as certificates to be used in case of https connections (optional). Below is a detailed walk-through of the parameters, options, restriction and caveats of adding a proxy to your cloudspace.

Parameters: addProxy(...)

Parameter: cloudspaceId

Id of the cloudspace.

Parameter: config

Here you pass a dictionary in the form: { "static": {...}, "provider": {...}} which define the static and dynamic configuration for traefik.

Parameter: proxyType

This parameter is currently restricted to be traefik:2.3 and this defines the logic in which the api will write and organize the configurations defined in config parameter.

Parameter: certificates (Optional)

Here you define certificates for your domains in the form:

{

 "<DOMAIN1>": {"crt": "-----BEGIN CERTIFICATE-----MIIDrDCCApSgAwIBAwIHBbBg+eFGSDANBgkqhkiG9w0BAQUFADBzMQswCQYDVQQG......-----END CERTIFICATE-----", "key": "-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDkYX/ebkmGpzLI...-----END PRIVATE KEY-----"}, 

 "<DOMAIN2>:  {"crt": "-----BEGIN CERTIFICATE-----NBgkqhkiG9w0BAQUFADBzMQswCQYDVQQGMIIDrDCCApSgAwIBAwIHBbBg+eFGSDA......-----END CERTIFICATE-----,  "key": "-----BEGIN PRIVATE KEY-----AASCBKgwggSkAgEAAoIBAQDkYX/ebkmGpzLMIIEvgIBADANBgkqhkiG9w0BAQEFI...-----END PRIVATE KEY-----"}

 }

Once you provide valid certificates, traefik will pick up on them and use them for tls.

Restrictions

As of the time of this writing, we impose certain restrictions on the static part of the config parameter. A typical static configuration must contain the following:

        "providers": {
            "file": {
                "filename": "/etc/traefik/provider.yaml"
            }
        }

If you need to specify your own certificates

Another restriction would be having the tls part exactly the following under providers part of the config parameter

            "tls": {
                "stores": {
                    "default": {
                        "defaultCertificate": {
                            "certFile": "<YOUR DOMAIN>.crt",
                            "keyFile": "<YOUR DOMAIN>.key",
                        }
                    }
                }
            }

NOTE the filenames for certFile and keyFile. So an example for certFile would be node1.example.com.crt

A typical complete configuration would look like the following
    "config": {
        "static": {
            "defaultEntryPoints": ["http"],
            "entryPoints": {
                "websecure": {"address": ":443"},
                "web": {"address": ":80"},
            },
            "providers": {"file": {"filename": "/etc/traefik/provider.yaml"}},
        },
        "provider": {
            "tls": {
                "stores": {
                    "default": {
                        "defaultCertificate": {
                            "certFile": "node1.example.com.crt",
                            "keyFile": "node1.example.com.key",
                        }
                    }
                }
            },
            "http": {
                "services": {
                    "node1.example.com": {
                        "loadBalancer": {
                            "servers": [{"url": "http://192.168.103.254:8080"}]
                        }
                    }
                },
                "routers": {
                    "http.node1.example.com": {
                        "service": "node1.example.com",
                        "rule": "Host(`node1.example.com`)",
                    },
                    "https.node1.example.com": {
                        "tls": {},
                        "service": "node1.example.com",
                        "rule": "Host(`node1.example.com`)",
                    },
                },
            },
        },
    }

If you need to use let's encrypt instead of your own certificates

In order to do this. You need to include an extra entry in the static part of the config parameter

    "certificatesResolvers": {
        "letsencrypt": {
            "acme": {
                "email": "<EMAIL>",
                "storage": "acme.json",
                "tlsChallenge": {}
            }
        }

You will also need to change the tls entry under your https router under routers to the following.

                "tls": {
                    "certResolver": "letsencrypt"
                }
A typical complete configuration would look like the following
    "config": {
        "static": {
            "certificatesResolvers": {
                "letsencrypt": {
                    "acme": {
                        "email": "<EMAIL>",
                        "storage": "acme.json",
                        "tlsChallenge": {}
                    }
                }
            },
            "defaultEntryPoints": ["http"],
            "entryPoints": {
                "web": {
                    "address": ":80"
                },
                "websecure": {
                    "address": ":443"
                }
            },
            "providers": {
                "file": {
                    "filename": "/etc/traefik/provider.yaml"
                }
            }
        },
        "provider": {
            "http": {
                "routers": {
                    "http.node1.example.com": {
                        "rule": "Host(`node1.example.com`)",
                        "service": "node1.example.com"
                    },
                    "https.node1.example.com": {
                        "rule": "Host(`node1.example.com`)",
                        "service": "node1.example.com",
                        "tls": {
                            "certResolver": "letsencrypt"
                        }
                    }
                },
                "services": {
                    "node1.example.com": {
                        "loadBalancer": {
                            "servers": [{
                                "url": "http://192.168.103.253:8080"
                            }]
                        }
                    }
                }
            }
        }
    }

Behavior

There are a couple of things worth mentioning about the behavior of this API endpoint.

  1. Every addProxy call will override existing proxy configurations
  2. In case you need multiple certificates. You can bundle them together, delimited by -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----

Parameters: removeProxy(...)

Parameter: cloudspaceId

Id of the cloudspace.

Behavior

This endpoint will completely remove the proxy configuration on a give cloudspace. Removed configurations cannot be restored and will have to be added once again via an addProxy call.

Example

TCP load balancer

In this example, we will spin up a TCP load balancer on a cloudspace. We will be using the minimum configuration to keep things simple, however you can try more advanced features for your load balancer by referring to traefik docs.

In order to see this in action, we will proxy ssh connections from cloudspace external IP on port 22 onto VMs port 22. Before you do the same you must have ssh access to your VMs and have copied your public key in known hosts so that we can skip entering a password later on.

Keep in mind that this example is just for demonstration purposes so we can see the TCP load balancer in action. We could have checked that the load balancer is working via several different ways.

Data for API call

{
    "cloudspaceId": <YOUR CLOUDSPACE ID>,
    "proxytype": "traefik:2.3",
    "config": {
        "static": {
            "entryPoints": {
                "ssh": {
                    "address": ":22"
                }
            },
            "providers": {
                "file": {
                    "filename": "/etc/traefik/provider.yaml"
                }
            }
        },
        "provider": {
            "tcp": {
                "services": {
                    "node1.example.com": {
                        "loadBalancer": {
                            "servers": [{
                                    "address": "192.168.103.253:22"
                                },
                                {
                                    "address": "192.168.103.254:22"
                                }
                            ]
                        }
                    }
                },
                "routers": {
                    "http.node1.example.com": {
                        "service": "node1.example.com",
                        "rule": "HostSNI(`*`)"
                    }
                }
            }
        }
    }
}

Sample response

After adding these proxy configs to your cloudspace. You can reproduce the following response by running the command. This will disable the expected warning about a Man-in-the-middle attack since ssh will see that the key of the machine has changed. This is expected of course since we are doing a reverse proxy from the ip in the command to 2 different ips.

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no user@<YOUR CLOUDSPACE ID> hostname

Responses

$> ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no user@172.17.1.110 hostname                         
vm1

$> ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no user@172.17.1.110 hostname
vm2
Table of Contents