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 local TCP traffic through Cloudflare's network, allowing secure access to services protected by Cloudflare Access. This is particularly useful for accessing private services (like SSH, RDP, databases, or internal web applications) that are not exposed to the public internet but are connected to a Cloudflare Tunnel.

    Syntax

    bash
    cloudflared access tcp [--hostname <hostname>] [--url <local-address>] [--overwrite-dns] [--udp-proxy] [--loglevel <level>] [--config <path>] [flags]

    Purpose

    `cloudflared access tcp` creates a secure, authenticated tunnel from your local machine to a remote service via Cloudflare Access. When you connect to a specified local address (e.g., `localhost:2222`), `cloudflared` forwards that traffic through the Cloudflare network, authenticates you against your Cloudflare Access policy, and then routes the traffic to the actual private service.

    Options

    * `--hostname <hostname>` (required): The public hostname configured in Cloudflare Access that points to your private TCP service. This is the hostname the Zero Trust policy is applied to.

    * `--url <local-address>` (optional): The local address (IP:port or hostname:port) on which `cloudflared` will listen for incoming connections. If not specified, `cloudflared` will try to use a default or an available port. Common examples: `localhost:2222` for SSH, `127.0.0.1:3306` for MySQL.

    * `--overwrite-dns` (optional): If set, `cloudflared` will attempt to write entries to your local `/etc/hosts` file (or equivalent on Windows) to resolve the specified `--hostname` to `127.0.0.1`. This allows you to connect directly to the `--hostname` (e.g., `ssh user@my-ssh.example.com`) without specifying the local proxy port.

    * `--udp-proxy` (optional): Enables UDP proxying for the specified service. Useful for services that rely on UDP (e.g., DNS, some gaming services). Note that not all services are compatible, and UDP support through Cloudflare Access Tunnels might have specific limitations.

    * `--loglevel <level>` (optional): Sets the logging level. Options include `debug`, `info`, `warn`, `error`, `fatal`. Default is `info`.

    * `--config <path>` (optional): Specifies an alternative path to the `cloudflared` configuration file (e.g., `~/.cloudflared/config.yml`).

    Usage Examples

    #### 1. Accessing an SSH server

    Suppose you have an SSH server accessible via `ssh.example.com` through Cloudflare Access, and you want to access it locally on port `2222`.

    bash
    cloudflared access tcp --hostname ssh.example.com --url localhost:2222

    After running this, `cloudflared` will start listening on `localhost:2222`. You can then connect to your SSH server:

    bash
    ssh -p 2222 user@localhost

    `cloudflared` will open a browser window for authentication if needed, and then proxy the SSH connection.

    #### 2. Accessing a MySQL database

    If your MySQL database is exposed via Cloudflare Access on `db.example.com` and you want to connect to it through your local client on `127.0.0.1:3306`.

    bash
    cloudflared access tcp --hostname db.example.com --url 127.0.0.1:3306

    Then, use your MySQL client to connect:

    bash
    mysql -h 127.0.0.1 -P 3306 -u your_user -p

    #### 3. Accessing an internal web application (HTTP over TCP)

    For an internal web app on `internal-app.example.com` that you want to access locally via `localhost:8080`.

    bash
    bcloudflared access tcp --hostname internal-app.example.com --url localhost:8080

    Open your browser to `http://localhost:8080`.

    #### 4. Using `--overwrite-dns` for cleaner access

    To access `ssh.example.com` directly without specifying a local port, allowing `ssh user@ssh.example.com` to work:

    bash
    sudo cloudflared access tcp --hostname ssh.example.com --overwrite-dns

    (Note: `sudo` is required because `cloudflared` needs to modify `/etc/hosts`.)

    Now you can use:

    bash
    ssh user@ssh.example.com

    `cloudflared` will automatically intercept the DNS resolution for `ssh.example.com` and route it to itself, then through the tunnel.

    Explanation

    `cloudflared access tcp` leverages Cloudflare's Zero Trust platform to provide secure, identity-aware access to private resources. When you execute the command:

    1. **Local Listener:** `cloudflared` starts a local TCP server on the specified `--url` (or a default if not provided).

    2. **Authentication:** When a local connection is made (e.g., `ssh user@localhost:2222`), `cloudflared` initiates a connection to the Cloudflare network.

    3. **Browser-based Auth:** If an Access policy requires it, `cloudflared` will open your default browser to prompt you for authentication (e.g., SSO, 2FA). Once authenticated, it receives a short-lived Cloudflare Access JWT.

    4. **Secure Tunnel:** This JWT is used to establish a secure, encrypted connection to a Cloudflare Tunnel endpoint. The traffic is then forwarded to the actual private service that the `--hostname` points to (which is typically exposed via a `cloudflared` Tunnel running in your private network).

    5. **Policy Enforcement:** Cloudflare Access evaluates the policy associated with `--hostname`. If your identity passes the policy, access is granted. If not, the connection is denied.

    This method eliminates the need for VPNs, open inbound firewall ports, or exposing services directly to the public internet, enhancing security significantly.