Labs are typically deployed in the isolated environments, such as company's internal network, cloud region or even a laptop. The lab nodes can happily talk to each other and, if needed, can reach Internet in the outbound direction.
But sometimes it is really needed to let your lab nodes be reachable over Internet securely and privately in the inbound direction. There are many use cases that warrant such publishing, some of the most common are:
- create a lab in your environment and share it with a customer/colleague on-demand
- make an interactive demo/training where nodes are shared with an audience for hands-on experience
- share a private lab with someone to collaborate or troubleshoot
- expose management interfaces (gNMI, NETCONF, SNMP) to test integration with collectors deployed outside of your lab environment
Check out the short video demonstrating the integration:
Containerlab made all of these use cases possible by integrating with mysocket.io service. Mysocket.io provides personal and secure tunnels for https/https/tls/tcp ports over global anycast1 network spanning US, Europe and Asia.
To make a certain port of a node available via mysocket.io tunnel provide a
publish container under the node/kind/default section of the topology:
name: demo topology: nodes: r1: kind: srl publish: # tcp port 22 will be published and accessible to anyone - tcp/22 # tcp port 57400 will be published for a specific user only - email@example.com # http service running over 10200 will be published # for any authenticated user within gmail domain - http/10200/gmail.com
Tunnels set up by mysocket.io are associated with a user who set them, thus users are required to register within the service. Luckily, the registration is a split second process carried out via a web portal. All it takes is an email and a password.
Acquiring a token#
To authenticate with mysocket.io service a user needs to acquire the token by logging into the service. A helper command
mysocketio login has been added to containerlab to help with that:
# Login with password entered from the prompt containerlab tools mysocketio login -e firstname.lastname@example.org Password: INFO Written mysocketio token to a file /root/containerlab/.mysocketio_token
The acquired token will be saved under
.mysocketio_token filename in the current working directory.
The token is valid for 5 hours, once the token expires, the already established tunnels will continue to work, but to establish new tunnels a new token must be provided.
Specify what to share#
To indicate which ports to publish a users needs to add the
publish section under the node/kind or default level of the topology definition file. In the example below, we are publishing SSH and gNMI services of
name: demo topology: nodes: r1: kind: srl publish: - tcp/22 # tcp port 22 will be exposed - tcp/57400 # tcp port 57400 will be exposed
publish section holds a list of
<type>/<port-number>[/<allowed-domains-and-email> strings, where
<type>must be one of the supported mysocket.io socket type2 - http/https/tls/tcp
<port>must be a single valid port value
<allowed-domains-and-email>an optional element restricting access to published ports for a list of users' emails or domains. Read more about in the Identity Aware tunnels section.
For a regular mysocketio account the maximum number of tunnels is limited to:
- tcp based tunnels: 5
- http based tunnels: 10
If >5 tcp tunnels are required users should launch a VM in a lab, expose it's SSH service and use this VM as a jumpbox.
Add mysocketio node#
Containerlab integrates with mysocket.io service by leveraging
mysocketctl application packaged in a container format. In order for the ports indicated in the
publish block to be published, a user needs to add a
mysocketio node to the topology. The complete topology file could look like this:
name: publish topology: nodes: r1: kind: srl image: ghcr.io/nokia/srlinux publish: - tcp/22 # tcp port 22 will be exposed grafana: kind: linux image: grafana/grafana:7.4.3 publish: - http/3000 # grafana' default http port will be published # adding mysocketio container which has mysocketctl client inside mysocketio: kind: mysocketio image: ghcr.io/hellt/mysocketctl:0.5.0 binds: - .mysocketio_token:/root/.mysocketio_token # bind mount API token
mysocketio node is a tiny linux container with mysocketctl client installed. Containerlab uses this node to create the sockets and start the tunnels as per
publish block instructions.
Pay specific attention to
binds section defined for mysocketio node. With this section we provide a path to the API token that we acquired before launching the lab. This token is used to authenticate with mysocketio API service.
Explore published ports#
When a user launches a lab with published ports it will be presented with a summary table after the lab deployment process finishes:
+---+-----------------------+--------------+---------------------------------+------------+-------+---------+----------------+----------------------+ | # | Name | Container ID | Image | Kind | Group | State | IPv4 Address | IPv6 Address | +---+-----------------------+--------------+---------------------------------+------------+-------+---------+----------------+----------------------+ | 1 | clab-sock-r1 | 9cefd6cdb239 | srlinux:20.6.3-145 | srl | | running | 172.20.20.2/24 | 2001:172:20:20::2/80 | | 2 | clab-sock-mysocketctl | 8f5385beb97e | ghcr.io/hellt/mysocketctl:0.5.0 | mysocketio | | running | 172.20.20.3/24 | 2001:172:20:20::3/80 | +---+-----------------------+--------------+---------------------------------+------------+-------+---------+----------------+----------------------+ Published ports: ┌──────────────────────────────────────┬──────────────────────────────────────┬─────────┬──────┬────────────┬────────────────────────┐ │ SOCKET ID │ DNS NAME │ PORT(S) │ TYPE │ CLOUD AUTH │ NAME │ ├──────────────────────────────────────┼──────────────────────────────────────┼─────────┼──────┼────────────┼────────────────────────┤ │ 444ed853-d3b6-448c-8f0a-6854b3578848 │ wild-water-9221.edge.mysocket.io │ 80, 443 │ http │ false │ clab-grafana-http-3000 │ │ 287e5962-29ac-4ca1-8e01-e0333d399070 │ falling-wave-5735.edge.mysocket.io │ 54506 │ tcp │ false │ clab-r1-tcp-22 │ └──────────────────────────────────────┴──────────────────────────────────────┴─────────┴──────┴────────────┴────────────────────────┘
To access the published port, users need to combine the DNS name and the Port to derive the full address. For the exposed SSH port, for example, the ssh client can use the following command to access remote SSH service:
ssh email@example.com -p 54506
When a lab with published ports start, containerlab first removes all previously established tunnels. This means that any manually set up tunnels for this account will get removed.
Identity aware tunnels#
In the previous examples the published ports were created in a way that makes them accessible to anyone on the Internet who knows the exact domain name and port of a respective tunnel. Although being convenient, this approach is not secure, since there is no control over who can access the ports you published.
If additional security is needed, containerlab users should define the published ports using Identity Awareness3 feature of mysocketio. With Identity aware sockets users are allowed to specify a list of email addresses or domains which will have access to a certain port.
Consider the following snippet:
topology: nodes: leaf1: publish: - firstname.lastname@example.org,email@example.com leaf2: publish: - tcp/22 grafana: publish: - http/3000/gmail.com,nokia.com,firstname.lastname@example.org
Within the same
publish block it is possible to provide a list of comma separated emails and/or domains which will be allowed to access the published port in question.
Authentication is carried out by OAuth via Google, GitHub, Facebook and Mysocket.io providers. When accessing a secured tunnel, a browser page is opened asking to authenticate:
Once authenticated via any of the available providers the sessions will establish.
ssh <ssh-username>@<mysocket-tunnel-address> \ -o 'ProxyCommand=mysocketctl client tls --host %h'
As with HTTP services, a browser page will appear asking to proceed with authentication. Upon successful authentication, the SSH session will establish.
Mysocketio uses SSH as a dataplane to build tunnels, thus it needs to be able to have external SSH access towards the
ssh.mysocket.io SSH server.
Chances are high that in your environment external SSH access might be blocked, preventing mysocket to setup tunnels. A possible solution for such environments would be to leverage the ability to tunnel SSH traffic via HTTP(S) proxies.
If your HTTP(S) proxy supports CONNECT method and is able to pass non-HTTP payloads, it is quite likely that mysocketio service will work.
To configure HTTP(S) proxy for mysocketio use the
mysocket-proxy parameter in the
extras section of the node definition:
mysocketio: kind: mysocketio image: ghcr.io/hellt/mysocketctl:0.5.0 binds: - .mysocketio_token:/root/.mysocketio_token extras: mysocket-proxy: http://192.168.0.1:8000
To check the health status of the established tunnels execute the following command to check the logs created on mysocketio container:
docker exec -it <mysocketio-node-name> /bin/sh -c "cat socket*"
This command will display all the logs for the published ports. If something is not right, you will see the errors in the log.