Mistake on this page? Email us

Tunneling with Izuma Direct Connect Client

Izuma Direct Connect Client acts as a local TCP server that accepts local TCP connections and establishes corresponding websocket connections to the Izuma Edge tunneling service through a TCP connection on the Izuma cloud.

direct-connect-client-overview

This diagram shows Izuma Direct Connect Client has a local TCP server ready to accept any TCP-based connection locally. Izuma Direct Connect Client establishes the websocket connection to the exposed websocket API on Izuma Device Management's cloud per TCP-based connection and proxies the bytes back and forth between the local TCP connections and cloud websocket connections.

Using Izuma Direct Connect Client

  1. Deploy a TCP-based native or containerized service to the gateway:

  2. Install Go.

  3. Clone the proxy client on your local machine:

    git clone https://github.com/PelionIoT/pelion-direct-connect-client
    
  4. Build the client by running:

    $ go build
    
  5. Launch pelion-direct-connect-client locally by providing parameters listen-uri, cloud-uri and api-key:

    $ ./pelion-direct-connect-client -listen-uri=<LOCAL_ADDRESS> -cloud-uri=<CLOUD_URI> -api-key=<API_KEY>
    

    Note: If you are using a JWT token, you must also pass the application-id.

    For example:

    ./pelion-direct-connect-client -listen-uri=127.0.0.1:3131 -cloud-uri=wss://api.us-east-1.mbedcloud.com/v3/devices/017b7fddb124724840c1c7b800000000/services/127.0.0.1:80/connection -api-key=ak_***
    

    This redirects all local traffic from port :3131 to the remote edge gateway 017b7fddb124724840c1c7b800000000 and the service listening on port :80.

  6. If the service is TCP based, you can quickly verify the connection by opening a browser and pointing to the address with the above listen-uri.

Note: The browser is one of the example local clients, and the choice of local client depends on the native or container service deployed on the gateway.

Configuration of parameters

Parameter Type Description Example
listen-uri string Local address that Izuma Direct Connect Client is listening on. (Please note this is not related to the container service that is listening to the device.) localhost:8181
cloud-uri string The exposed websocket API on the Izuma Device Management cloud that is ready for connections from Izuma Direct Connect Client. Check the last step for how to use this API. wss://{PDM_CLOUD_API_ADDRESS}/v3/devices/{DEVICE_ID}/services/127.0.0.1:80/connection
api-key string Access key generated from the Izuma Device Management Portal. ak_*********
application-id string The application ID to which the verification key is attached (applies only if a JWT key is used). *********
ping-duration number Ping duration in seconds. 0 disables pings to the tunnel (default 5). 5

Websocket API

For details about the exposed websocket API, please see the Swagger documentation.

Application access management with JWT keys

JSON Web Token (JWT) keys are one of two types of keys you can use to manage an application's access to Izuma Device Management. Similarly, you can use a JWT key to manage a cloud application's access with Izuma Edge. Creation of the JWT is up to the client, but a public certificate that signed the JWT needs to be uploaded into Izuma Device Management.

As with Izuma Device Management, the steps to manage access to your application using JWT keys in Izuma Edge are:

  1. Create an application.
  2. Create a verification key.
  3. Upload the verification key.
  4. Create the JWT key.
  5. Deploy the JWT key.

An example flow is provided below.

Example flow

  1. Create a private key-public key certificate pair:

    $ openssl req -newkey rsa:2048 -nodes -keyout private.key -x509 -days 365 -out public.crt

  2. Upload the public certificate to the Izuma Device Management verification keys API with an administrator application access key created from Izuma Device Management. If you are using the API directly, you can do:

    curl -0 -v -X POST https://api.us-east-1.mbedcloud.com/v3/applications/{application-id}/verification-keys \
    -H 'Authorization: Bearer ak_2MD...' \
    -H 'content-type: application/json' \
    --data-binary @- << EOF
    {
        "name": "JWT-test",
        "certificate": "-----BEGIN CERTIFICATE-----
        ...
        -----END CERTIFICATE-----"
    }
    EOF
    
  3. Create a JWT in RSA SHA-256 format using either jwt.io or jsonwebtokencli tool.

    1. Sign it with the private key and certificate.

      The supported signing algorithms are:

      • RS256.
      • RS384.
      • RS512.
      • ES256.
      • ES384.
      • ES512.
    2. Make sure the exp expiration claim exists and is valid. Include any other optional claims.

    An example generated using jsonwebtokencli:

    jwt --encode --algorithm 'RS256' --private-key-file './private.key' '{"exp":1640947429, "pelion.edge.tunnel.device_id":"017b7fddb124724840c1c7b800000000", "pelion.edge.tunnel.port":80}'
    
  4. Provide the parameter application-id with the ID of the application you created earlier, and use the JWT token as parameter to api_key:

    ./pelion-direct-connect-client -application-id=<APP_ID> -listen-uri=<LOCAL_ADDRESS> -cloud-uri=<CLOUD_URI> -api-key=<API_KEY>
    
  5. If using the API directly, access /v3/devices/{id}/services/{address}/connection with a header "X-Application-ID" corresponding to the same {application-id} (where the verification keys are created), and set Authorization header with value Bearer {JWT}. Using JWT as a bearer token without this header causes the client not to be authenticated. {id} is the device ID or gateway ID, and {address} is the tunnel_ip:tunnel_port format.

JWT claims

Required claim

  • exp: JWT expiration date in number of seconds since Epoch format.

Optional claims

The JWT key can specify one or all of the claims below to restrict access to the application:

  • pelion.edge.tunnel.device_id: The only device ID that can be used to open the tunnel, if specified.
  • pelion.edge.tunnel.ip: The only IP that can connect over the tunnel, if specified.
  • pelion.edge.tunnel.port: The only port that can connect over the tunnel, if specified.