CLI Companion

  • Hugging Face CLI
    • login
    • whoami
    • repo create
    • upload
    • download
    • lfs-enable-largefiles
    • scan-cache
    • delete-cache
  • Hapi CLI
    • new
    • start
    • build
    • test
    • plugin create
    • route add
  • Cloudflared
    • tunnel
    • tunnel run
    • tunnel list
    • tunnel delete
    • access
    • access tcp
    • update

    The `cloudflared access tcp` command is used to proxy TCP traffic through Cloudflare Access to private services behind your Cloudflare Tunnel. This allows users to access internal TCP-based applications (like SSH, RDP, or databases) without exposing them directly to the internet, leveraging Cloudflare Access's authentication and authorization policies.

    Syntax

    bash
    cloudflared access tcp [--hostname <hostname>] [--url <url>] [--listen-address <address>] [--overwrite-host] [--destination-ip <ip>] [--destination-port <port>] [--force-vm] [--metrics-port <port>]

    Options

    * `--hostname <hostname>`: (Required) The hostname defined in your Cloudflare Access application for the TCP service. This is the public hostname users will connect to.

    * `--url <url>`: The URL of the TCP backend, typically in the format `tcp://<ip>:<port>`. This specifies where `cloudflared` should forward the traffic after successful authentication. If not provided, `--destination-ip` and `--destination-port` must be used.

    * `--listen-address <address>`: (Optional) The local address `cloudflared` will listen on for incoming TCP connections from the user. Default is `127.0.0.1:0` (a random available port on localhost).

    * `--overwrite-host`: (Optional) If set, `cloudflared` will overwrite the `Host` header sent to the backend with the value of `--hostname`. This is usually not relevant for pure TCP, but can be for HTTP-like services over TCP.

    * `--destination-ip <ip>`: (Optional) The IP address of the TCP backend. Used in conjunction with `--destination-port` if `--url` is not provided.

    * `--destination-port <port>`: (Optional) The port of the TCP backend. Used in conjunction with `--destination-ip` if `--url` is not provided.

    * `--force-vm`: (Optional) Forces `cloudflared` to operate as if it's running in a virtual machine environment (e.g., for specific networking configurations).

    * `--metrics-port <port>`: (Optional) Specifies a port for `cloudflared` to expose Prometheus-compatible metrics.

    Usage Examples

    #### 1. SSH into a private server

    Let's say you have an SSH server at `192.168.1.100` on port `22` and you've configured a Cloudflare Access TCP application for `ssh.yourcompany.com`.

    bash
    cloudflared access tcp --hostname ssh.yourcompany.com --url tcp://192.168.1.100:22 --listen-address 127.0.0.1:2222

    After running this command, `cloudflared` will listen on `127.0.0.1:2222`. You can then SSH to your private server through Cloudflare Access:

    bash
    ssh -p 2222 your_user@127.0.0.1

    `cloudflared` will intercept the SSH connection, handle the Cloudflare Access authentication flow (e.g., opening a browser for login), and then proxy the traffic to `192.168.1.100:22`.

    #### 2. Access a private PostgreSQL database

    Assume a PostgreSQL database is running at `192.168.1.50` on port `5432`, and your Access application hostname is `db.yourcompany.com`.

    bash
    cloudflared access tcp --hostname db.yourcompany.com --destination-ip 192.168.1.50 --destination-port 5432 --listen-address 127.0.0.1:5433

    Now, your database client can connect to `127.0.0.1:5433`:

    bash
    psql -h 127.0.0.1 -p 5433 -U your_db_user -d your_db

    #### 3. Using a random available port for listening

    If you omit `--listen-address`, `cloudflared` will pick a random available port on `127.0.0.1` and print it to the console.

    bash
    cloudflared access tcp --hostname ssh.yourcompany.com --url tcp://192.168.1.100:22

    Example output (port will vary):

    INFO[0000] Initializing metrics server on 127.0.0.1:39015
    INFO[0000] Starting proxy for ssh.yourcompany.com on 127.0.0.1:41397

    You would then connect using the reported port (e.g., `ssh -p 41397 your_user@127.0.0.1`).

    Explanation

    `cloudflared access tcp` acts as a local proxy. When you run the command, `cloudflared` starts a local TCP server on the specified (or random) listen address. When a client (like `ssh` or `psql`) attempts to connect to this local `cloudflared` port, `cloudflared` performs the following steps:

    1. **Authentication**: It initiates the Cloudflare Access authentication flow. This typically involves opening a browser window where you log in via your identity provider (e.g., Okta, Google, Azure AD).

    2. **Authorization**: Once authenticated, `cloudflared` verifies your session against the Access policy configured for the `--hostname` in Cloudflare.

    3. **Tunneling**: If authorized, `cloudflared` establishes a secure connection through your Cloudflare Tunnel to the backend service specified by `--url` or `--destination-ip`/`--destination-port`.

    4. **Traffic Proxying**: All subsequent TCP traffic from your client to the local `cloudflared` port is securely proxied to the private backend service.

    This method allows secure access to private TCP services without requiring a VPN, leveraging Cloudflare's global network and Access policies for zero-trust security.