Skip to main content

TCP shares

TCP shares let you expose non-HTTP services (for example, SSH, databases, message brokers) over a secure TCP tunnel without opening inbound firewall ports.

They are ideal when your application speaks a raw TCP protocol and you want to enforce mutual TLS (mTLS) with client certificates.

Key concepts

  • Public TCP ingress: traffic enters via a Frontdoor-managed TCP endpoint and is tunneled to your private target.
  • Ingress port range: you choose an external TCP port in the range 2100–2199 to listen on for this share.
  • Target: the private TCP endpoint your service listens on (host:port). You may specify a URI form like tcp://host:port or host:port.
  • Client authentication (optional): restrict access with client certificates and subject filters.

Prerequisites

  • TCP shares must be enabled on the Frontdoor. If disabled, all requests will be rejected. Contact support to enable it.
  • An online Agent connected to the target Environment to route traffic.
  • If using client certificate authentication, create or upload the certificate first so you can reference its id. See Create a client certificate for more info.

Request fields specific to TCP

  • type: "tcp"
  • ingressPort (required): external port in 2100..2199 that clients connect to
  • target (required): your private service address, e.g., tcp://db.internal.local:5432
  • clientCertificateId (optional): the ID of a stored client certificate to require mTLS
  • allowedSubjects (optional): exact subject DNs permitted to connect
  • allowedCommonNamePrefixes (optional): allow-list by CN prefix
  • requiredOrganizationalUnit (optional): require a specific OU in the client cert subject
note
  • You may combine allowedSubjects, allowedCommonNamePrefixes, and requiredOrganizationalUnit. All specified constraints must pass for the client certificate to be accepted.
  • If clientCertificateId is omitted, the TCP share does not require a client certificate.

Example A: Intermediate CA with assurances (OU and/or CN prefix)

Each Frontdoor has a built-in intermediate CA that is used to sign client certificates. This example shows how to create a TCP share that requires a client certificate issued by the built-in intermediate CA and enforces assurances:

  1. Create a TCP share that trusts that intermediate and enforces assurances:

    curl -s -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
    "type": "tcp",
    "name": "svc-ssh",
    "envZId": "ijcrWb-ZOq",
    "ingressPort": 2142,
    "target": "tcp://ssh.internal.local:22",
    "requiredOrganizationalUnit": "engineering",
    "allowedCommonNamePrefixes": [ "svc-" ]
    }' \
    "https://gateway.production.netfoundry.io/frontdoor/$FRONTDOOR_ID/shares"

    Only client certificates issued by the intermediate AND matching OU=engineering AND with CN starting with svc- will be accepted.

  2. Connect using a leaf certificate issued by that intermediate:

    openssl s_client -connect your-tcp-endpoint.example.com:2142 \
    -cert client.crt -key client.key -quiet
tip

For best interoperability, include the full client chain in client.crt (leaf first, then any intermediates). The Frontdoor validates the presented chain up to the uploaded intermediate.

Example B: Pinned client certificate

Accept exactly one client certificate by pinning to a single Client Certificate. This is useful for highly restricted access.

  1. Create the TCP share and pin to the client certificate:

    curl -s -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
    "type": "tcp",
    "name": "db-admin",
    "envZId": "ijcrWb-ZOq",
    "ingressPort": 2155,
    "target": "tcp://db.internal.local:5432",
    "clientCertificateId": "fdkjasd74h"
    }' \
    "https://gateway.production.netfoundry.io/frontdoor/$FRONTDOOR_ID/shares"

    Only the certificate created in the Client Certificate Management section will be accepted.

  2. Connect with the pinned certificate:

    openssl s_client -connect your-tcp-endpoint.example.com:2155 \
    -cert client.crt -key client.key -quiet
note

Client certificate pinning uses the exact certificate. If you re-issue the certificate it will stop working.

Operational tips

  • Use narrow allow-lists (allowedSubjects or CN prefixes) to scope access.
  • Rotate client certificates periodically and update clientCertificateId as needed.