Configuration file
Locally-managed tunnels run as an instance of cloudflared on your machine. You can configure cloudflared properties by modifying command line parameters or by editing the tunnel configuration file.
The CLI provides a quick way to handle configurations if you are connecting a single service through cloudflared. The tunnel configuration file is useful if you are connecting multiple services and need to configure properties or exceptions for specific origins. In the configuration file, you can define top-level properties for your cloudflared instance as well as origin-specific properties. For a full list of configuration options, type cloudflared tunnel help in your terminal.
In the absence of a configuration file, cloudflared will proxy outbound traffic through port 8080.
If you are exposing a private network to end users running WARP, you need to add the warp-routing key and set it to true:
tunnel: <Tunnel-UUID>credentials-file: /path/<Tunnel-UUID>.jsonwarp-routing: enabled: trueIf you are exposing local services to the Internet, you can assign a public hostname to each service:
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551efcredentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json
ingress: - hostname: gitlab.widgetcorp.tech service: http://localhost:80 - hostname: gitlab-ssh.widgetcorp.tech service: ssh://localhost:22 - service: http_status:404Configuration files that contain ingress rules must always include a catch-all rule that concludes the file. In this example, cloudflared will respond with a 404 status code when the request does not match any of the previous hostnames.
When cloudflared receives an incoming request, it evaluates each ingress rule from top to bottom to find which rule matches the request. Rules can match either the hostname or path of an incoming request, or both. If a rule does not specify a hostname, all hostnames will be matched. If a rule does not specify a path, all paths will be matched.
The last ingress rule must be a catch-all rule that matches all traffic.
Here is an example configuration file that specifies several rules:
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551efcredentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json
ingress: # Rules map traffic from a hostname to a local service: - hostname: example.com service: https://localhost:8000 # Rules can match the request's path to a regular expression: - hostname: static.example.com path: \.(jpg|png|css|js)$ service: https://localhost:8001 # Rules can match the request's hostname to a wildcard character: - hostname: "*.example.com" service: https://localhost:8002 # An example of a catch-all rule: - service: https://localhost:8003You can use wildcards to match traffic to multiple subdomains. For example, if you set the hostname key to *.example.com, both alpha.example.com and beta.example.com will route traffic to your origin. cloudflared does not support wildcards in the middle of the hostname, such as test.*.example.com.
You can also enter regular expressions for the path key. For example, if hostname is static.example.com and path is \.(jpg|png|css|js)$, matching URLs could include https://static.example.com/data.js, http://static.example.com/images/photo.jpg, and so on. Cloudflare parses the path regex using the Go syntax package ↗.
In addition to HTTP, cloudflared supports protocols like SSH, RDP, arbitrary TCP services, and Unix sockets. You can also route traffic to the built-in Hello World test server or respond to traffic with an HTTP status.
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551efcredentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json
ingress: # Example of a request over TCP: - hostname: example.com service: tcp://localhost:8000 # Example of an HTTP request over a Unix socket: - hostname: staging.example.com service: unix:/home/production/echo.sock # Example of a request mapping to the Hello World test server: - hostname: test.example.com service: hello_world # Example of a rule responding to traffic with an HTTP status: - service: http_status:404| Service | Description | Example service value |
|---|---|---|
| HTTP/S | Incoming HTTP requests are proxied directly to your local service. | https://localhost:8000 |
| HTTP over Unix socket | Just like HTTP, but using a Unix socket instead. | unix:/home/production/echo.sock |
| HTTPS over Unix socket | Just like HTTPS, but using a Unix socket instead. | unix+tls:/home/production/echo.sock |
| TCP | TCP connections are proxied to your local service. | tcp://localhost:2222 |
| SSH | SSH connections are proxied to your local service. Learn more. | ssh://localhost:22 |
| RDP | RDP connections are proxied to your local service. Learn more. | rdp://localhost:3389 |
| kubectl bastion mode | cloudflared will act like a jumphost, allowing access to any local address. | bastion |
| Hello World | Test server for validating your Cloudflare Tunnel setup. | hello_world |
| HTTP status | Responds to all requests with the given HTTP status. | http_status:404 |
If you need to proxy traffic to multiple origins within one instance of cloudflared, you can define the way cloudflared sends requests to each service by specifying configuration options as part of your ingress rules.
In the following example, the top-level configuration connectTimeout: 30s sets a 30-second connection timeout for all services within that instance of cloudflared. The ingress rule for service: localhost:8002 then configures an exception to the top-level configuration by setting connectTimeout for that service at 10s. The 30-second connection timeout still applies to all other services.
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551efcredentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.jsonoriginRequest: # Top-level configuration connectTimeout: 30s
ingress: # The localhost:8000 service inherits all root-level configuration. # In other words, it will use a connectTimeout of 30 seconds. - hostname: example.com service: localhost:8000 - hostname: example2.com service: localhost:8001 # The localhost:8002 service overrides some root-level config. - service: localhost:8002 originRequest: connectTimeout: 10s disableChunkedEncoding: true # Some built-in services such as `http_status` do not use any configuration. # The service below will simply respond with HTTP 404. - service: http_status:404To validate the ingress rules in your configuration file, run:
cloudflared tunnel ingress validateThis will ensure that the set of ingress rules specified in your config file is valid.
To verify that cloudflared will proxy the right traffic to the right local service, use cloudflared tunnel ingress rule. This checks a URL against every rule, from first to last, and shows the first rule that matches. For example:
cloudflared tunnel ingress rule https://foo.example.comUsing rules from /usr/local/etc/cloudflared/config.ymlMatched rule #3 hostname: *.example.com service: https://localhost:8000When making changes to the configuration file for a given tunnel, we suggest relying on cloudflared replicas to propagate the new configuration with minimal downtime.
- Have a
cloudflaredinstance running with the original version of the configuration file. - Start a
cloudflaredreplica running with the updated version of the configuration file. - Wait for the replica to be fully running and usable.
- Stop the first instance of
cloudflared.
Your cloudflared will now be running with the updated version of your configuration file.
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Products
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark