### Start Cloudflared Carrier Forwarder Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md This example demonstrates how to set up a WebSocket connection to the tunnel endpoint and start a carrier forwarder. It includes setting up logging, defining origin and host options, and handling shutdown signals. ```go package main import ( "log" "net" "os" "os/signal" "syscall" "github.com/rs/zerolog" "github.com/cloudflare/cloudflared/carrier" "github.com/cloudflare/cloudflared/websocket" ) func main() { logger := zerolog.New(os.Stderr).With().Timestamp().Logger() // Create WebSocket connection to tunnel endpoint wsConn, err := websocket.NewConnection("wss://tunnel.cloudflare.com") if err != nil { log.Fatal("failed to connect:", err) } defer wsConn.Close() // Setup proxy options := &carrier.StartOptions{ OriginURL: "https://localhost:8000", Host: "localhost", } // Setup shutdown channel shutdownC := make(chan struct{}) go func() { sigC := make(chan os.Signal, 1) signal.Notify(sigC, syscall.SIGINT, syscall.SIGTERM) <-sigC logger.Info().Msg("shutdown signal received") close(shutdownC) }() // Start forwarder logger.Info(). Str("listen", "127.0.0.1:8080"). Str("origin", options.OriginURL). Msg("starting proxy") err = carrier.StartForwarder(wsConn, "127.0.0.1:8080", shutdownC, options) if err != nil { logger.Error().Err(err).Msg("proxy error") } } ``` -------------------------------- ### Python Virtual Environment Setup Source: https://github.com/cloudflare/cloudflared/blob/master/component-tests/README.md Steps to create and activate a Python virtual environment and install dependencies from requirements.txt. ```bash python3 -m venv ./.venv source ./.venv/bin/activate python3 -m pip install -r requirements.txt ``` -------------------------------- ### Cloudflared Tunnel Info Command Example Source: https://github.com/cloudflare/cloudflared/blob/master/CHANGES.md Demonstrates how to get detailed information about cloudflared connectors to the Cloudflare Edge. It shows options for sorting and outputting in JSON format. ```bash cloudflared tunnel info --sort-by version --invert-sort --output json ``` -------------------------------- ### Logging Example Source: https://github.com/cloudflare/cloudflared/blob/master/AGENTS.md Shows how to use zerolog for structured logging with relevant context fields. ```go logger.Info(). Str("tunnelID", tunnel.ID). Int("connIndex", connIndex). Msg("Connection established") ``` -------------------------------- ### Full Connection Lifecycle Example Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/client-config.md Demonstrates the complete lifecycle of a connection using the client configuration, from creation to logging and protocol initialization. ```go func establishConnection(cfg *client.Config, edgeAddr string, attempt uint8) error { logger := zerolog.New(os.Stderr) // Step 1: Create snapshot snapshot := cfg.ConnectionOptionsSnapshot(nil, attempt) options := snapshot.ConnectionOptions() // Step 2: Log attempt event := logger.Info() snapshot.LogFields(event). Str("edge", edgeAddr). Int("attempt", attempt). Msg("attempting connection") // Step 3: Use options for connection // conn := protocol.Dial(edgeAddr, options) // Step 4: Log result logger.Info().Msg("connection established") return nil } ``` -------------------------------- ### Start Forwarder with WebSocket Connection Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Sets up a listening socket to forward connections through a tunnel. Requires a WebSocket connection, local address, shutdown channel, and start options. ```go options := &carrier.StartOptions{ OriginURL: "https://example.com", Host: "example.com", } shutdownC := make(chan struct{}) go func() { time.Sleep(5 * time.Minute) close(shutdownC) }() err := carrier.StartForwarder( wsConnection, "127.0.0.1:8080", shutdownC, options, ) if err != nil { log.Fatal("forwarding failed:", err) } ``` -------------------------------- ### Cloudflared Version Format Example Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/client-config.md Version should follow semantic versioning. Examples show different release scenarios. ```text YYYY.MINOR.PATCH Examples: - 2024.1.0 (2024 release, first minor version) - 2024.2.1 (2024 release, second minor with patch) - 2025.1.0 (2025 release) ``` -------------------------------- ### Install Gokeyless on Ubuntu (Jammy) Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Adds the Cloudflare APT repository and installs Gokeyless on Ubuntu 22.04 (Jammy Jellyfish). Ensure you have the necessary permissions to modify system repositories and install packages. ```bash echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/gokeyless jammy main' | sudo tee /etc/apt/sources.list.d/cloudflare.list sudo apt-get update && sudo apt-get install gokeyless ``` -------------------------------- ### Example Usage Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-ip-routes.md Demonstrates how to create and use an IpRouteFilter to list routes. ```APIDOC ## Example Usage ```go filter := cfapi.NewIPRouteFilter() filter.NotDeleted() filter.TunnelID(tunnelID) filter.MaxFetchSize(50) filter.Page(1) routes, err := client.ListRoutes(filter) ``` ``` -------------------------------- ### Install gokeyless on Ubuntu 22.04 (Jammy Jellyfish) Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs gokeyless on Ubuntu 22.04 (Jammy Jellyfish). Includes steps for GPG key and repository configuration. ```bash sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/gokeyless jammy main' | sudo tee /etc/apt/sources.list.d/cloudflare.list sudo apt-get update && sudo apt-get install gokeyless ``` -------------------------------- ### Good Error Handling Example Source: https://github.com/cloudflare/cloudflared/blob/master/AGENTS.md Illustrates proper error wrapping and context addition using fmt.Errorf. ```go // Good error handling patterns if err != nil { return fmt.Errorf("failed to process connection: %w", err) } ``` -------------------------------- ### Install gokeyless on Ubuntu 24.04 (Noble Numbat) Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs gokeyless on Ubuntu 24.04 (Noble Numbat). Sets up the Cloudflare GPG key and apt repository. ```bash sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/gokeyless noble main' | sudo tee /etc/apt/sources.list.d/cloudflare.list sudo apt-get update && sudo apt-get install gokeyless ``` -------------------------------- ### Install Gokeyless on Ubuntu (Focal) Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Adds the Cloudflare APT repository and installs Gokeyless on Ubuntu 20.04 (Focal Fossa). This involves fetching the GPG key and configuring the repository source. ```bash sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/gokeyless focal main' | sudo tee /etc/apt/sources.list.d/cloudflare.list sudo apt-get update && sudo apt-get install gokeyless ``` -------------------------------- ### Install gokeyless on Debian 12 (Bookworm) Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs gokeyless on Debian 12 (Bookworm). Includes steps to add the GPG key and repository. ```bash sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/gokeyless bookworm main' | sudo tee /etc/apt/sources.list.d/cloudflare.list sudo apt-get update && sudo apt-get install gokeyless ``` -------------------------------- ### Complete Cloudflare Virtual Network Workflow Example Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-virtual-networks.md Demonstrates a full lifecycle of a virtual network: creation, listing, updating, and deletion. Includes client initialization and error handling. ```go package main import ( "fmt" "log" "os" "github.com/google/uuid" "github.com/rs/zerolog" "github.com/cloudflare/cloudflared/cfapi" ) func main() { logger := zerolog.New(os.Stderr) client, err := cfapi.NewRESTClient( "https://api.cloudflare.com/client/v4", "account-id", "zone-id", "auth-token", "cloudflared/1.0", &logger, ) if err != nil { log.Fatal(err) } // Create virtual network newVnet := cfapi.NewVirtualNetwork{ Name: "prod-network", Comment: "Production environment", IsDefault: false, } vnet, err := client.CreateVirtualNetwork(newVnet) if err != nil { log.Fatal("failed to create vnet:", err) } fmt.Printf("Created vnet: %s\n", vnet.Name) // List all vnets filter := cfapi.NewVnetFilter() vnets, err := client.ListVirtualNetworks(filter) if err != nil { log.Fatal("failed to list vnets:", err) } fmt.Println("Virtual Networks:") for _, v := range vnets { fmt.Println(v.TableString()) } // Update vnet comment := "Updated production network" updates := cfapi.UpdateVirtualNetwork{ Comment: &comment, } err = client.UpdateVirtualNetwork(vnet.ID, updates) if err != nil { log.Fatal("failed to update vnet:", err) } // Delete vnet (if no routes) err = client.DeleteVirtualNetwork(vnet.ID, false) if err != nil { fmt.Printf("Cannot delete (routes exist): %v\n", err) // Force delete to remove routes too err = client.DeleteVirtualNetwork(vnet.ID, true) } if err != nil { log.Fatal("failed to delete vnet:", err) } } ``` -------------------------------- ### Good Function Example Source: https://github.com/cloudflare/cloudflared/blob/master/AGENTS.md Demonstrates a function with clear purpose and proper error handling. ```go // Good: Clear purpose, proper error handling func (c *Connection) HandleRequest(ctx context.Context, req *http.Request) error { if req == nil { return errors.New("request cannot be nil") } // Implementation... return nil } ``` -------------------------------- ### Install gokeyless on Debian 11 (Bullseye) Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs gokeyless on Debian 11 (Bullseye). Configures the apt repository with the Cloudflare GPG key. ```bash sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/gokeyless bullseye main' | sudo tee /etc/apt/sources.list.d/cloudflare.list sudo apt-get update && sudo apt-get install gokeyless ``` -------------------------------- ### Install Git Hooks Source: https://github.com/cloudflare/cloudflared/blob/master/README.md Installs pre-push git hooks to automatically run linting and tests before each push, ensuring code quality. ```bash make install-hooks ``` -------------------------------- ### Install cloudflared on RHEL Generic Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs cloudflared on RHEL Generic systems. Requires updating the repository configuration first. ```bash curl -fsSl https://pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo sudo yum update sudo yum install cloudflared ``` -------------------------------- ### Example: List Routes with Filter Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-ip-routes.md Demonstrates how to use the IpRouteFilter to specify criteria for listing routes. This example filters for non-deleted routes associated with a specific tunnel ID, sets a maximum fetch size, and specifies the page number. ```go filter := cfapi.NewIPRouteFilter() filter.NotDeleted() filter.TunnelID(tunnelID) filter.MaxFetchSize(50) filter.Page(1) routes, err := client.ListRoutes(filter) ``` -------------------------------- ### Install Gokeyless on RHEL 8 / CentOS 8 Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs Gokeyless on RHEL 8 or CentOS 8 using dnf. This command adds the EL8 RPM repository, compatible with glibc 2.28, and then installs the package. ```bash sudo dnf config-manager --add-repo https://pkg.cloudflare.com/gokeyless/rpm-el8/gokeyless.repo sudo dnf install gokeyless ``` -------------------------------- ### Start Client with WebSocket Connection Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Proxies stdin/stdout through a tunnel connection using a WebSocket connection. Configure with origin URL, host, and a stream for input/output. ```go options := &carrier.StartOptions{ OriginURL: "https://ssh.example.com", Host: "ssh.example.com", } stream := &carrier.StdinoutStream{} er := carrier.StartClient(wsConnection, stream, options) if err != nil { log.Fatal("client failed:", err) } ``` -------------------------------- ### Install Gokeyless on Amazon Linux 2 Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs Gokeyless on Amazon Linux 2 using the EL8 RPM repository, which is compatible with glibc 2.28. This involves adding the repository configuration and then installing the package via yum. ```bash curl -fsSl https://pkg.cloudflare.com/gokeyless/rpm-el8/gokeyless.repo | sudo tee /etc/yum.repos.d/gokeyless.repo sudo yum update sudo yum install gokeyless ``` -------------------------------- ### Testing Pattern Example Source: https://github.com/cloudflare/cloudflared/blob/master/AGENTS.md Demonstrates a test function using t.Parallel() and testify assertions. ```go func TestMetricsListenerCreation(t *testing.T) { t.Parallel() // Test implementation assert.Equal(t, expected, actual) require.NoError(t, err) } ``` -------------------------------- ### Install Gokeyless on Amazon Linux 2023 Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs Gokeyless on Amazon Linux 2023 by adding the appropriate RPM repository and then using yum to install the package. This repository is for systems with glibc 2.34+. ```bash curl -fsSl https://pkg.cloudflare.com/gokeyless/rpm/gokeyless.repo | sudo tee /etc/yum.repos.d/gokeyless.repo sudo yum update sudo yum install gokeyless ``` -------------------------------- ### Install gokeyless on Debian 13 (Trixie) Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs gokeyless on Debian 13 (Trixie). Adds the Cloudflare GPG key and repository configuration. ```bash sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/gokeyless trixie main' | sudo tee /etc/apt/sources.list.d/cloudflare.list sudo apt-get update && sudo apt-get install gokeyless ``` -------------------------------- ### Complete Cloudflare IP Routes Workflow Example Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-ip-routes.md Demonstrates a full workflow for managing Cloudflare IP routes, including adding a new route, listing all existing routes with a filter, and retrieving a route by IP address. Ensure you have the necessary authentication tokens and IDs configured. ```go package main import ( "fmt" "log" "net" "os" "github.com/google/uuid" "github.com/rs/zerolog" "github.com/cloudflare/cloudflared/cfapi" ) func main() { logger := zerolog.New(os.Stderr) client, err := cfapi.NewRESTClient( "https://api.cloudflare.com/client/v4", "account-id", "zone-id", "auth-token", "cloudflared/1.0", &logger, ) if err != nil { log.Fatal(err) } tunnelID := uuid.MustParse("550e8400-e29b-41d4-a716-446655440000") // Add a route _, network, _ := net.ParseCIDR("10.0.0.0/8") route, err := client.AddRoute(cfapi.NewRoute{ Network: *network, TunnelID: tunnelID, Comment: "Internal network", }) if err != nil { log.Fatal("failed to add route:", err) } fmt.Printf("Created route: %s\n", route.Network) // List all routes filter := cfapi.NewIPRouteFilter() filter.NotDeleted() routes, err := client.ListRoutes(filter) if err != nil { log.Fatal("failed to list routes:", err) } for _, r := range routes { fmt.Println(r.TableString()) } // Find route by IP ip := net.ParseIP("10.0.5.100") result, err := client.GetByIP(cfapi.GetRouteByIpParams{Ip: ip}) if err == nil && !result.IsZero() { fmt.Printf("IP %s uses tunnel %s\n", ip, result.TunnelName) } } ``` -------------------------------- ### StartOptions Struct Definition Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Defines the configuration options for starting a carrier connection. Use this to specify application information, origin URL, headers, host, TLS settings, and other connection-specific parameters. ```go type StartOptions struct { AppInfo *token.AppInfo OriginURL string Headers http.Header Host string TLSClientConfig *tls.Config AutoCloseInterstitial bool IsFedramp bool } ``` -------------------------------- ### Complete Cloudflared Configuration Example Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/configuration.md A comprehensive configuration example for cloudflared tunnels, including WARP routing, origin request settings, and ingress rules for various services. ```yaml # Tunnel identifier tunnel: my-production-tunnel # WARP routing configuration warp-routing: connectTimeout: 30s tcpKeepAlive: 30s maxActiveFlows: 100000 # Default settings applied to all rules originRequest: connectTimeout: 30s tlsTimeout: 10s tcpKeepAlive: 30s keepAliveConnections: 100 keepAliveTimeout: 5s http2Origin: false disableChunkedEncoding: false # HTTP ingress rules ingress: # Public API endpoint - hostname: api.example.com path: /v1/* service: https://internal-api.local:8443 originRequest: originServerName: api.internal.local caPool: /etc/ssl/certs/api-ca.crt matchSNItoHost: true # Admin dashboard (Access-protected) - hostname: admin.example.com service: http://localhost:3000 originRequest: access: required: true teamName: "myorg" audTag: ["admin.example.com"] # SSH via bastion host - hostname: ssh.example.com service: tcp://localhost:22 originRequest: bastionMode: true # Everything else - hostname: "*" service: http://localhost:8080 originRequest: ipRules: - prefix: 10.0.0.0/8 ports: [80, 443] allow: true - prefix: 0.0.0.0/0 allow: false ``` -------------------------------- ### Install Gokeyless on RHEL 9 / CentOS Stream 9 Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs Gokeyless on RHEL 9 or CentOS Stream 9 using dnf. This requires the `dnf-plugins-core` package for `config-manager` and uses the RPM repository suitable for glibc 2.34+. ```bash sudo dnf config-manager --add-repo https://pkg.cloudflare.com/gokeyless/rpm/gokeyless.repo sudo dnf install gokeyless ``` -------------------------------- ### Install cloudflared on CentOS 7 Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs cloudflared on CentOS 7. Requires installing yum-utils first to manage repositories. ```bash sudo yum install yum-utils sudo yum-config-manager --add-repo https://pkg.cloudflare.com/cloudflared.repo yum install cloudflared ``` -------------------------------- ### Go: Complete Cloudflared REST Client Example Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-rest-client.md This snippet demonstrates the full lifecycle of interacting with the Cloudflared REST Client API in Go. It covers client initialization, tunnel creation, and listing existing tunnels. Ensure you have set the CF_ACCOUNT_ID, CF_ZONE_ID, and CF_API_TOKEN environment variables. ```go package main import ( "fmt" "log" "os" "github.com/google/uuid" "github.com/rs/zerolog" "github.com/cloudflare/cloudflared/cfapi" ) func main() { // Setup logging logger := zerolog.New(os.Stderr).With().Timestamp().Logger() // Create client client, err := cfapi.NewRESTClient( "https://api.cloudflare.com/client/v4", os.Getenv("CF_ACCOUNT_ID"), os.Getenv("CF_ZONE_ID"), os.Getenv("CF_API_TOKEN"), "my-app/1.0", &logger, ) if err != nil { logger.Fatal().Err(err).Msg("failed to create client") } // Create tunnel secret := make([]byte, 32) if _, err := rand.Read(secret); err != nil { log.Fatal(err) } tunnel, err := client.CreateTunnel("my-tunnel", secret) if err != nil { logger.Error().Err(err).Msg("failed to create tunnel") return } fmt.Printf("Created tunnel: %s\n", tunnel.Name) fmt.Printf("Token: %s\n", tunnel.Token) // List tunnels filter := cfapi.NewTunnelFilter() filter.NoDeleted() tunnels, err := client.ListTunnels(filter) if err != nil { logger.Error().Err(err).Msg("failed to list tunnels") return } fmt.Printf("Total tunnels: %d\n", len(tunnels)) for _, t := range tunnels { fmt.Printf(" - %s (%s)\n", t.Name, t.ID) } } ``` -------------------------------- ### StartForwarder Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Sets up a listening socket and forwards connections through the tunnel. It takes a WebSocket connection, a local address to listen on, a shutdown channel, and optional start options. ```APIDOC ## StartForwarder ### Description Sets up a listening socket and forwards connections through the tunnel. ### Function Signature ```go func StartForwarder(conn Connection, address string, shutdownC <-chan struct{}, options *StartOptions) error ``` ### Parameters #### Path Parameters - **conn** (Connection) - Required - WebSocket connection handler - **address** (string) - Required - Local address to listen on (e.g., "127.0.0.1:8080") - **shutdownC** (<-chan struct{}) - Required - Channel to signal shutdown - **options** (*StartOptions) - Required - Proxy configuration ### Returns - `error`: Error if listener cannot be created or connection fails ### Errors - Network error if port already in use - Connection errors during forwarding ### Example ```go options := &carrier.StartOptions{ OriginURL: "https://example.com", Host: "example.com", } shutdownC := make(chan struct{}) go func() { time.Sleep(5 * time.Minute) close(shutdownC) }() err := carrier.StartForwarder( wsConnection, "127.0.0.1:8080", shutdownC, options, ) if err != nil { log.Fatal("forwarding failed:", err) } ``` ``` -------------------------------- ### Start HTTP/HTTPS Proxy with Carrier Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Starts an HTTP/HTTPS forwarder using a WebSocket connection. This is useful for proxying traffic to an internal service. ```go import ( "net" "time" "github.com/cloudflare/cloudflared/carrier" ) func startHTTPProxy() error { options := &carrier.StartOptions{ OriginURL: "https://internal.example.com", Host: "internal.example.com", } shutdownC := make(chan struct{}) return carrier.StartForwarder( wsConnection, "127.0.0.1:8080", shutdownC, options, ) } ``` -------------------------------- ### Start Protected Proxy with Cloudflare Access Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Sets up a forwarder that integrates with Cloudflare Access for authentication. It checks if Access is required and builds an authenticated request if necessary. ```go func startProtectedProxy(logger *zerolog.Logger) error { options := &carrier.StartOptions{ OriginURL: "https://api.example.com", Host: "api.example.com", AppInfo: &appInfo, AutoCloseInterstitial: true, } // Check if Access auth is required testResp, _ := http.Get(options.OriginURL) if carrier.IsAccessResponse(testResp) { // Build authenticated request req, err := carrier.BuildAccessRequest(options, logger) if err != nil { return err } // Token is in request headers, use for subsequent requests options.Headers = req.Header } return carrier.StartForwarder( wsConnection, "127.0.0.1:8080", make(chan struct{}), options, ) } ``` -------------------------------- ### Separate Rule Origins Example Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/configuration.md Demonstrates the best practice of using separate ingress rules for different hostnames, each pointing to a distinct service. Avoid using a single wildcard rule for all services. ```yaml # Good: Different services per hostname ingress: - hostname: api.example.com service: http://api:8080 - hostname: web.example.com service: http://web:3000 - hostname: admin.example.com service: http://admin:5000 # Avoid: Single service for all ingress: - hostname: "*" service: http://localhost:8080 ``` -------------------------------- ### TunnelConnection Interface Implementation Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/connection-credentials.md Example of implementing the TunnelConnection interface for managing tunnel connections. This includes connecting to the edge, handling errors, and reconnection logic. ```Go type MyConnection struct { credentials connection.Credentials } func (c *MyConnection) Serve(ctx context.Context) error { // Connect to edge // Handle errors and reconnection // Return when context cancelled or fatal error return nil } // Use connection conn := &MyConnection{ credentials: creds, } ctx := context.Background() if err := conn.Serve(ctx); err != nil { log.Fatal("connection error:", err) } ``` -------------------------------- ### Start RDP/VNC Tunnel with Carrier Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Initiates an RDP or VNC tunnel by serving traffic from a TCP listener. This allows remote desktop connections to be tunneled. ```go func startRDPTunnel(listenAddr string) error { options := &carrier.StartOptions{ OriginURL: "https://rdp.example.com", Host: "rdp.example.com", } listener, _ := net.Listen("tcp", listenAddr) defer listener.Close() shutdownC := make(chan struct{}) return carrier.Serve(wsConnection, listener, shutdownC, options) } ``` -------------------------------- ### Cloudflared Component Tests Configuration Source: https://github.com/cloudflare/cloudflared/blob/master/component-tests/README.md Example configuration YAML file for cloudflared component tests, specifying binary path, tunnel details, credentials, and ingress rules. ```yaml cloudflared_binary: "cloudflared" tunnel: "3d539f97-cd3a-4d8e-c33b-65e9099c7a8d" credentials_file: "/Users/tunnel/.cloudflared/3d539f97-cd3a-4d8e-c33b-65e9099c7a8d.json" origincert: "/Users/tunnel/.cloudflared/cert.pem" ingress: - hostname: named-tunnel-component-tests.example.com service: hello_world - service: http_status:404 ``` -------------------------------- ### Add Cloudflare GPG Key and Repository for Debian (Any) Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Adds the Cloudflare GPG key and configures the APT repository for cloudflared on Debian-based systems. Use this for general Debian installations. ```bash sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' | sudo tee /etc/apt/sources.list.d/cloudflared.list echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://next.pkg.cloudflare.com/cloudflared any main' | sudo tee /etc/apt/sources.list.d/cloudflared.list sudo apt-get update && sudo apt-get install cloudflared ``` -------------------------------- ### CIDR JSON Unmarshal Example Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-ip-routes.md Demonstrates how to unmarshal a JSON string into a CIDR type and print its string representation. This is useful for parsing CIDR values from API responses or configurations. ```go var cidr cfapi.CIDR json.Unmarshal([]byte(`"10.0.0.0/8"`), &cidr) fmt.Println(cidr.String()) // Output: 10.0.0.0/8 ``` -------------------------------- ### Configure IP Rules for Internal Services Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/configuration.md Illustrates configuring IP rules to restrict access to internal services. This example shows allowing a private network range and denying all others. ```yaml # Good: Restrict by IP originRequest: ipRules: - prefix: 10.0.0.0/8 allow: true - prefix: 0.0.0.0/0 allow: false # Avoid: Exposing internal services publicly ``` -------------------------------- ### Wrapped Error Examples Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/errors.md Examples of error messages that have been wrapped with additional context. ```text REST request failed: EOF Failed to create tunnel: tunnel with name already exists Error Parsing page 1: invalid character ``` -------------------------------- ### Install cloudflared on CentOS 8 Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Installs cloudflared on CentOS 8. Requires dnf config-manager for repository management. ```bash sudo dnf config-manager --add-repo https://pkg.cloudflare.com/cloudflared.repo sudo dnf install cloudflared ``` -------------------------------- ### StartClient Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Proxies stdin/stdout through a tunnel connection. It requires a WebSocket connection, an I/O stream, and proxy configuration options. ```APIDOC ## StartClient ### Description Proxies stdin/stdout through a tunnel connection. ### Function Signature ```go func StartClient(conn Connection, stream io.ReadWriter, options *StartOptions) error ``` ### Parameters #### Path Parameters - **conn** (Connection) - Required - WebSocket connection handler - **stream** (io.ReadWriter) - Required - Input/output stream (typically stdin/stdout) - **options** (*StartOptions) - Required - Proxy configuration ### Returns - `error`: Error if proxying fails ### Example - SSH through Tunnel ```go options := &carrier.StartOptions{ OriginURL: "https://ssh.example.com", Host: "ssh.example.com", } stream := &carrier.StdinoutStream{} err := carrier.StartClient(wsConnection, stream, options) if err != nil { log.Fatal("client failed:", err) } ``` ``` -------------------------------- ### Create Connection Options Snapshot Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/client-config.md Generate a snapshot of client configuration for a specific connection using `ConnectionOptionsSnapshot`. This method takes the origin IP and previous connection attempts as parameters. ```Go originIP := net.ParseIP("192.168.1.100") snapshot := cfg.ConnectionOptionsSnapshot(originIP, 0) // Use snapshot for connection options := snapshot.ConnectionOptions() ``` -------------------------------- ### Create and Query Routes in Virtual Network Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-virtual-networks.md Demonstrates how to create a new IP route associated with a specific virtual network and how to list routes filtered by a virtual network ID using the Cloudflare API. ```Go import ( "github.com/cloudflare/cloudflared/cmd/cloudflared/cli/cfapi" "github.com/cloudflare/cloudflared/cmd/cloudflared/cli/cfapi/internal/uuid" "net" ) // Create route in specific virtual network _, network, _ := net.ParseCIDR("10.0.0.0/8") tunnelID := uuid.MustParse("550e8400-e29b-41d4-a716-446655440000") vnetID := uuid.MustParse("660e8400-e29b-41d4-a716-446655440000") newRoute := cfapi.NewRoute{ Network: *network, TunnelID: tunnelID, VNetID: &vnetID, // Associate with virtual network Comment: "Production route", } route, err := client.AddRoute(newRoute) // Query routes by virtual network filter := cfapi.NewIPRouteFilter() filter.VNetID(vnetID) routes, err := client.ListRoutes(filter) ``` -------------------------------- ### Create New Client Configuration Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/client-config.md Use `NewConfig` to create a new client configuration object. Provide the version, architecture, and a feature selector. This function returns the configuration or an error if UUID generation fails. ```Go import ( "github.com/cloudflare/cloudflared/client" "github.com/cloudflare/cloudflared/features" ) func main() { selector := features.NewFeatureSelector() // or custom implementation cfg, err := client.NewConfig("2024.1.0", "amd64", selector) if err != nil { log.Fatal("failed to create config:", err) } fmt.Printf("Connector ID: %s\n", cfg.ConnectorID) fmt.Printf("Version: %s\n", cfg.Version) fmt.Printf("Architecture: %s\n", cfg.Arch) } ``` -------------------------------- ### Create and Configure Tunnel Filter Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-tunnel.md Demonstrates how to create a new TunnelFilter and apply various criteria to filter tunnel listings. Use this to specify search parameters like name prefix, deletion status, and pagination. ```go filter := cfapi.NewTunnelFilter() filter.ByNamePrefix("prod-") filter.NoDeleted() filter.MaxFetchSize(50) tunnels, err := client.ListTunnels(filter) ``` -------------------------------- ### TunnelConnection Interface Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/connection-credentials.md Defines the interface for tunnel connections to the Cloudflare edge. The Serve method starts the connection and handles errors. ```APIDOC ### Interface: TunnelConnection Interface for tunnel connections to the Cloudflare edge. ```go type TunnelConnection interface { Serve(ctx context.Context) error } ``` #### Method - **Serve**(ctx context.Context) error - Starts the connection and handles errors. Blocks until connection closes or context is cancelled. Returns error if connection fails. Handles reconnection logic internally. ``` -------------------------------- ### Convert Snapshot to Protocol Connection Options Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/client-config.md Convert a connection options snapshot into protocol-ready connection options using `ConnectionOptions`. This is useful for sending options to the edge. ```Go snapshot := cfg.ConnectionOptionsSnapshot(originIP, 0) options := snapshot.ConnectionOptions() // Send to edge protocol.SendConnectionOptions(options) ``` -------------------------------- ### Start SSH Tunnel with Carrier Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Establishes an SSH tunnel through a Cloudflare Access-protected endpoint. It uses stdin/stdout for the SSH client communication. ```go func startSSHTunnel() error { // Proxy SSH through Access-protected endpoint options := &carrier.StartOptions{ OriginURL: "https://ssh.example.com", Host: "ssh.example.com", AppInfo: &accessAppInfo, } // Use stdin/stdout for SSH client stream := &carrier.StdinoutStream{} return carrier.StartClient(wsConnection, stream, options) } ``` -------------------------------- ### BuildAccessRequest Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/carrier-websocket.md Creates an HTTP request with a Cloudflare Access token. It requires start options containing AppInfo and a logger, and returns the request and an error. ```APIDOC ## BuildAccessRequest ### Description Creates HTTP request with Cloudflare Access token. ### Function Signature ```go func BuildAccessRequest(options *StartOptions, log *zerolog.Logger) (*http.Request, error) ``` ### Parameters #### Path Parameters - **options** (*StartOptions) - Required - Connection options with AppInfo - **log** (*zerolog.Logger) - Required - Logger for errors ### Returns - `*http.Request`: HTTP GET request with Access token - `error`: Error if token fetch fails ### Behavior - Fetches token from Cloudflare Access provider - Follows redirects as needed - Adds token to request headers ### Example ```go options := &carrier.StartOptions{ OriginURL: "https://api.example.com", AppInfo: &appInfo, } req, err := carrier.BuildAccessRequest(options, logger) if err != nil { log.Fatal("failed to build access request:", err) } resp, err := http.DefaultClient.Do(req) ``` ``` -------------------------------- ### Get Tunnel Authentication Token Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-tunnel.md Retrieves the authentication token for a specific tunnel using its UUID. This token is required for the tunnel to authenticate with Cloudflare. ```go token, err := client.GetTunnelToken(tunnelID) if err != nil { log.Fatal("failed to get token:", err) } fmt.Println("Token:", token) ``` -------------------------------- ### Add Cloudflare Repository for Amazon Linux Source: https://github.com/cloudflare/cloudflared/blob/master/release/index.html Adds the Cloudflare repository configuration for cloudflared on Amazon Linux. This allows `yum` to install and update the package. ```bash curl -fsSl https://pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo sudo yum update ``` -------------------------------- ### Create and Reuse REST Client Instance Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-rest-client.md Instantiate the REST client once per application and reuse it for all subsequent API calls. Avoid creating a new client within loops. ```go // Good client, _ := cfapi.NewRESTClient(...) // Use client throughout app // Avoid for _, item := range items { client, _ := cfapi.NewRESTClient(...) // Creates new client each iteration } ``` -------------------------------- ### Create and Log Cloudflared Client Configuration Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/client-config.md This Go code snippet demonstrates how to create a new client configuration for cloudflared, including specifying the version, architecture, and feature selector. It then logs the generated client ID, version, and architecture. ```go package main import ( "fmt" "log" "net" "os" "runtime" "github.com/rs/zerolog" "github.com/cloudflare/cloudflared/client" "github.com/cloudflare/cloudflared/features" ) func main() { logger := zerolog.New(os.Stderr).With().Timestamp().Logger() // Create feature selector featureSelector := features.NewFeatureSelector() // Create client config cfg, err := client.NewConfig( "2024.1.0", // Version runtime.GOARCH, // Architecture (amd64, arm64, etc.) featureSelector, ) if err != nil { log.Fatal("failed to create config:", err) } logger.Info(). Str("connectorID", cfg.ConnectorID.String()). Str("version", cfg.Version). Str("arch", cfg.Arch). Msg("client configured") // Create connection snapshots originIPs := []string{ "192.168.1.100", "10.0.0.50", } for attempt, ip := range originIPs { originIP := net.ParseIP(ip) snapshot := cfg.ConnectionOptionsSnapshot(originIP, uint8(attempt)) options := snapshot.ConnectionOptions() // Log with snapshot info event := logger.Info() snapshot.LogFields(event). Str("origin", ip). Int("attempt", attempt). Msg("connection options created") _ = options // Use for protocol operations } } ``` -------------------------------- ### Create Credentials from API Response Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/connection-credentials.md Demonstrates how to create connection credentials by first creating a tunnel via the API, then retrieving its token, and finally constructing the Credentials struct. This pattern is common when dynamically provisioning tunnels. ```Go import ( "github.com/cloudflare/cloudflared/cfapi" "github.com/cloudflare/cloudflared/connection" ) func main() { client, _ := cfapi.NewRESTClient(...) // Create tunnel via API tunnel, err := client.CreateTunnel("my-tunnel", secret) if err != nil { log.Fatal(err) } // Get token token, err := client.GetTunnelToken(tunnel.ID) if err != nil { log.Fatal(err) } // Create credentials for connection creds := connection.Credentials{ AccountTag: accountID, TunnelSecret: secret, TunnelID: tunnel.ID, Endpoint: "https://tunnel.connect.cloudflare.com", } ``` -------------------------------- ### Create New IPRouteFilter Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-ip-routes.md Returns a new IpRouteFilter configured to list only CloudFlare Tunnel (cfd_tunnel) routes. Use this as a starting point for building more complex filters. ```go func NewIPRouteFilter() *IpRouteFilter ``` -------------------------------- ### Configure Origin-Specific Settings Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/configuration.md Illustrates configuring origin-specific settings, such as connect timeouts, for different hostnames. This allows for tailored performance based on origin characteristics. ```yaml # Good: Tuple-specific configuration ingress: - hostname: slow-api.example.com service: http://slow-origin:8080 originRequest: connectTimeout: 60s # Longer timeout for slow origin - hostname: fast-api.example.com service: http://fast-origin:8080 originRequest: connectTimeout: 10s # Shorter timeout # Avoid: One-size-fits-all settings ``` -------------------------------- ### Get Cloudflare Route by IP Address Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-ip-routes.md Use this to find which route handles a specific IP address. You can optionally specify a virtual network ID to query. ```go ip := net.ParseIP("10.0.5.100") result, err := client.GetByIP(cfapi.GetRouteByIpParams{ Ip: ip, VNetID: nil, // Query default virtual network }) if err != nil { log.Fatal("failed to get route by IP:", err) } if result.IsZero() { fmt.Println("No route found for IP") } else { fmt.Printf("IP %s is handled by tunnel %s\n", ip, result.TunnelName) } ``` -------------------------------- ### NewConfig Constructor Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/client-config.md Creates a new client configuration object with the specified version, architecture, and feature selector. ```APIDOC ## NewConfig Creates a new client configuration. ### Signature ```go func NewConfig(version string, arch string, featureSelector features.FeatureSelector) (*Config, error) ``` ### Parameters #### Path Parameters - **version** (string) - Required - Semantic version (e.g., "2024.1.0") - **arch** (string) - Required - Architecture string (amd64, arm64, etc.) - **featureSelector** (features.FeatureSelector) - Required - Feature flag selector for this client ### Returns - `*Config`: Client configuration with random ConnectorID - `error`: Error if UUID generation fails ### Errors - UUID generation errors (extremely rare) ### Example ```go import ( "github.com/cloudflare/cloudflared/client" "github.com/cloudflare/cloudflared/features" ) func main() { selector := features.NewFeatureSelector() // or custom implementation cfg, err := client.NewConfig("2024.1.0", "amd64", selector) if err != nil { log.Fatal("failed to create config:", err) } fmt.Printf("Connector ID: %s\n", cfg.ConnectorID) fmt.Printf("Version: %s\n", cfg.Version) fmt.Printf("Architecture: %s\n", cfg.Arch) } ``` ``` -------------------------------- ### Filter Virtual Networks by Name and Deleted Status Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/cfapi-virtual-networks.md Example of creating a filter and listing virtual networks. It filters by name and specifies whether to include deleted networks. ```go filter := cfapi.NewVnetFilter() filter.ByName("prod-vnet") filter.WithDeleted(false) vnets, err := client.ListVirtualNetworks(filter) ``` -------------------------------- ### Define ConnectionOptionsSnapshot Structure Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/client-config.md Captures a snapshot of client configuration at the time a connection is established. It includes protocol-level client information, origin IP, connection attempt count, and feature flags. ```go type ConnectionOptionsSnapshot struct { client pogs.ClientInfo originLocalIP net.IP numPreviousAttempts uint8 FeatureSnapshot features.FeatureSnapshot } ``` -------------------------------- ### TunnelConnection Interface Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/connection-credentials.md Defines the interface for tunnel connections to the Cloudflare edge. The Serve method starts the connection and handles errors, blocking until the connection closes or the context is cancelled. ```go type TunnelConnection interface { Serve(ctx context.Context) error } ``` -------------------------------- ### Convert TunnelToken to Credentials Struct Source: https://github.com/cloudflare/cloudflared/blob/master/_autodocs/api-reference/connection-credentials.md Converts a TunnelToken struct into a Credentials struct, which is used for establishing connections. This simplifies the process of using token data for connection setup. ```Go token := cfapi.TunnelToken{...} creds := token.Credentials() // Use credentials for connection conn := connection.NewConnection(creds) ```