How To Setup Cloudflare Argo Tunnel On CentOS 7

Cloudflare Argo Tunnel allows you to expose your web server to the internet without having to open routes in your firewall or setup dedicated routes. This guide will outline how you can setup Cloudflare Argo Tunnel for private encrypted HTTP/2 connection to your origin web server or web application on CentOS 7 for Centmin Mod LEMP stack users.

The below instructions for setting up a Cloudflare Argo Tunnel connection to self hosted application/origin server are tailored to Centmin Mod LEMP stack users running CentOS 7 running CSF Firewall. The guide will be setting up Cloudflare Argo Tunnels using Named Tunnels and a Ingress Rule based configuration which allow you map traffic for multiple hostnames and services within a single Argo Tunnel.

What Is Cloudflare Argo Tunnel

Cloudflare Argo Tunnel is a private encrypted HTTP/2 connection between your web server and Cloudflare which makes it so that only traffic that routes through Cloudflare can reach your server or web application without needing a publicly routable IP address.

An example request follows these steps:

  • A visitor makes a request to tunnel.yourdomain.com.
  • The DNS lookup resolves to a Cloudflare network address.
  • The visitor connects to the closest Cloudflare edge PoP via Anycast.
  • Cloudflare routes the visitor through a special PoP-to-PoP route called Argo Smart Routing and connects them to a Cloudflare edge PoP that has an established persistent connection to the daemon (cloudflared) running on the visitor’s web server.
  • The request is routed to the cloudflared instance running on your server. The connection between cloudflared and the Cloudflare edge is a long-lived persistent HTTP2 connection encrypted with TLS. To keep the connection alive, cloudflared sends a heartbeat to the edge in the form of a ping frame over HTTP2. If the connection is dropped, the cloudflared client re-establishes the connection with Cloudflare. cloudflared connects to Cloudflare on port 7844. All packets between Cloudflare and the tunneled web server use stream multiplexing over HTTP2. In HTTP2, each request/response pair is called a Stream and given a unique Stream ID so that these streams can be “multiplexed” or sent asynchronously over the same connection.
  • The Argo Tunnel client forwards the request to your web service.

Cloudflare Argo Tunnel Connection

Contents

This guide will outline both manual (with cloudflared) and automated methods (via Cloudflare API with Cloudflare API Tokens) and is based on official Cloudflare documentation and Cloudflare Argo Tunnel FAQ documentation.

Sign Up For Cloudflare For Teams Free Subscription

The easiest way for your Cloudflare Account to get access to free Argo Tunnel feature is to sign up for Cloudflare For Teams free subscription which bundles Cloudflare Gateway, Cloudflare Access, Cloudflare Browser Isolation and Cloudflare Argo Tunnels together and is available as add-ons to your existing Cloudflare subscription. The official Cloudflare For Teams documentation is available here.

To sign up for the free Cloudflare For Teams subscription, go to the Cloudflare Team dashboard link at https://dash.teams.cloudflare.com/ and log into your Cloudflare Account and go through the Cloudflare For Teams onboarding process. You’d want to ensure your Cloudflare account’s billing details for credit card and billing address are updated if you choose a paid subscription instead of a free one.

Cloudflare Billing

Then go through the Cloudflare For Teams onboarding process

Cloudflare For Teams onboarding process

Cloudflare For Teams onboarding process

Cloudflare For Teams onboarding process

Cloudflare For Teams onboarding process

Once payment is processed, you’ll be greeted with the welcome page and can check your Account Billing section to check that your on the correct Cloudflare For Teams plan subscription.

Cloudflare For Teams onboarded

Cloudflare For Teams Billing page

CSF Firewall

This is a one time task. Place in /etc/csf/csf.allow allow file whitelisting for Cloudflare route1/2 hostname’s IP addresses to allow egress TCP traffic on destination port 7844 as per Cloudflare Argo Tunnel FAQ documentation.

First command backs up /etc/csf/csf.allow and then appends to csf.allow the CSF Firewall allow list to CF Argo Tunnel IPs for destination port 7844.

cp -a /etc/csf/csf.allow /etc/csf/csf.allow.backup.before-argo-tunnel
cat >> /etc/csf/csf.allow << EOF
tcp|out|d=7844|d=198.41.192.7
tcp|out|d=7844|d=198.41.192.47
tcp|out|d=7844|d=198.41.192.107
tcp|out|d=7844|d=198.41.192.167
tcp|out|d=7844|d=198.41.192.227
tcp|out|d=7844|d=198.41.200.193
tcp|out|d=7844|d=198.41.200.233
tcp|out|d=7844|d=198.41.200.13
tcp|out|d=7844|d=198.41.200.53
tcp|out|d=7844|d=198.41.200.113
EOF

restart CSF Firewall

csf -ra

Create Centmin Mod Nginx Vhost Sites

You can use Centmin Mod’s centmin.sh menu option 2, 22 or nv command line to create Nginx vhost sites if they haven’t already been created. Examples including enabling free Letsencrypt SSL certificate support during Nginx vhost site creation here.

touch /etc/centminmod/custom_config.inc
echo "LETSENCRYPT_DETECT='y'" >> /etc/centminmod/custom_config.inc

nv command line

nv

Usage: /usr/bin/nv [-d yourdomain.com] [-s y|n|yd|le|led|lelive|lelived] [-u ftpusername]

  -d  yourdomain.com or subdomain.yourdomain.com
  -s  ssl self-signed create = y or n or https only vhost = yd
  -s  le - letsencrypt test cert or led test cert with https default
  -s  lelive - letsencrypt live cert or lelived live cert with https default
  -u  your FTP username

  example:

  /usr/bin/nv -d yourdomain.com -s y -u ftpusername
  /usr/bin/nv -d yourdomain.com -s n -u ftpusername
  /usr/bin/nv -d yourdomain.com -s yd -u ftpusername
  /usr/bin/nv -d yourdomain.com -s le -u ftpusername
  /usr/bin/nv -d yourdomain.com -s led -u ftpusername
  /usr/bin/nv -d yourdomain.com -s lelive -u ftpusername
  /usr/bin/nv -d yourdomain.com -s lelived -u ftpusername

create self-signed SSL certificate with non-HTTPS + HTTPS vhosts

/usr/bin/nv -d tun.domain.com -s y -u ftpusername

create self-signed SSL certificate with HTTPS only vhosts

/usr/bin/nv -d tun.domain.com -s yd -u ftpusername

create free Letsencrypt SSL certificate with non-HTTPS + HTTPS vhosts

/usr/bin/nv -d tun.domain.com -s lelive -u ftpusername

create free Letsencrypt SSL certificate with HTTPS only vhosts

/usr/bin/nv -d tun.domain.com -s lelived -u ftpusername

Manual Argo Tunnel Setup with cloudflared

You can manually using cloudflared binary to setup an Argo Tunnel

Step 1. Install cloudflared Binary

curl -4s https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-amd64.tgz | tar xzC /usr/local/bin
cloudflared update

Authenticate cloudflared using your Cloudflare Account log as per https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/setup

cloudflared tunnel login

Verify cloudflared version installed

cloudflared --version
cloudflared version 2021.2.1 (built 2021-02-04-1528 UTC)

Step 2. Create Argo Tunnel

  • You can name your Argo Tunnels whatever you want, here we’ll use the intended hostname/subdomain as the name of the Argo Tunnel.
  • Pipe the tunnel create command output into a log file named $hostname-tunnel-create.log so can use the log file to find the tunnel id and credential file needed to install cloudflared as a service and assign them to variables.
  • You’ll need to have jq installed which is installed by default on Centmin Mod LEMP stacks. If not you can install it via yum -y install jq.
hostname=tun.domain.com
cloudflared tunnel create $hostname | tee $hostname-tunnel-create.log
tunnelid=$(cloudflared tunnel list -o json | jq -r --arg h $hostname '.[] | select(.name == $h) | .id')
credfile="/root/.cloudflared/${tunnelid}.json"

Step 3. Creating cloudflared YAML Config File

Create the cloudflared YAML config file at ~/.cloudflared/config.yml by populating the variables below. This configuration uses Cloudflare Named Tunnels and Ingress Rules.

hostname=tun.domain.com
localhost=https://localhost:443
metrics=localhost:5432
cftag='cmm=test'
cfpid='/var/run/cmm-test-argo.pid'
cfupdatettl='24h'

Make a copy of generated cert.pem file as /root/.cloudflared/cert-${hostname}.pem which will be used for origincert configuration value in tunnel’s YAML config file.

cp -a /root/.cloudflared/cert.pem /root/.cloudflared/cert-${hostname}.pem

Creating ~/.cloudflared/config.yml file with variables you assigned

cat > ~/.cloudflared/config.yml <<EOF
tunnel: $tunnelid
credentials-file: $credfile
origincert: /root/.cloudflared/cert-${hostname}.pem
protocol: http2
originRequest:
  connectTimeout: 30s

metrics: $metrics
#tag: $cftag
pidfile: $cfpid
autoupdate-freq: $cfupdatettl
loglevel: info
logfile: /var/log/cloudflared.log

ingress:
  - hostname: $hostname
    service: $localhost
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - service: http_status:404
EOF

The resulting ~/.cloudflared/config.yml file will contain

tunnel: your_tunnelid
credentials-file: /root/.cloudflared/your_tunnelid.json
origincert: /root/.cloudflared/cert-tun.domain.com.pem
protocol: http2
originRequest:
  connectTimeout: 30s

metrics: localhost:5432
#tag: cmm=test
pidfile: /var/run/cmm-test-argo.pid
autoupdate-freq: 24h
loglevel: info
logfile: /var/log/cloudflared.log

ingress:
  - hostname: tun.domain.com
    service: https://localhost:443
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - service: http_status:404

With Argo Tunnel Ingress rules, you can setup other Cloudflare domain zone sites within the same Cloudflare Account to go through this single Cloudflare Argo Tunnel by adding the additional domain/subdomains i.e. hostname.domain.com and host.example.com as CNAME DNS records pointing to the same tunnelid.cfargotunnel.com target. Then update ~/.cloudflared/config.yml config file to:

tunnel: your_tunnelid
credentials-file: /root/.cloudflared/your_tunnelid.json
origincert: /root/.cloudflared/cert-tun.domain.com.pem
protocol: http2
originRequest:
  connectTimeout: 30s

metrics: localhost:5432
#tag: cmm=blog
pidfile: /var/run/cmm-test-argo.pid
autoupdate-freq: 24h
loglevel: info
logfile: /var/log/cloudflared.log

ingress:
  - hostname: tun.domain.com
    service: https://localhost:443
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - hostname: hostname.domain.com
    service: https://localhost:443
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - hostname: host.example.com
    service: https://localhost:443
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - service: http_status:404

I commented out the tag: setting for now as manually running the cloudflared argo tunnel gives an error right now. Update: it seems the tag argument currently isn’t meant to do anything.

cloudflared tunnel --config ~/.cloudflared/config.yml run tun.domain.com
expected string slice found string for tag

Validate ingress rules

cloudflared tunnel ingress validate
Validating rules from /root/.cloudflared/config.yml
OK

Step 4. Create Cloudflare CNAME DNS Record To Route Argo Tunnel

As per documentation https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/routing-to-tunnel/dns, you can create the CNAME DNS record via command line. This will only work for the Cloudflare site zone that you authenticated the initial cloudflared login setup for in Step 1. Other Cloudflare site zones you intend to add to the Argo Tunnel will have to have their CNAME DNS records added either manually or via Cloudflare DNS API.

cloudflared tunnel route dns <UUID or NAME> www.app.com

In this case

cloudflared tunnel route dns tun.domain.com tun.domain.com

or using $tunnelid variable you populated in step 3 above.

cloudflared tunnel route dns $tunnelid tun.domain.com

This will then create the CNAME DNS record for tun.domain.com to point to tunnelid.cfargotunnel.com target if the CNAME doesn’t already exist. If the CNAME already exists, you’ll get an error and need to manually edit and update the existing CNAME DNS record.

Step 5. Install cloudflared Service on CentOS 7

Install cloudflared service, start it and ensure it starts on server reboots. Running service install command will create and configure systemd service file at /etc/systemd/system/cloudflared.service.

[Unit]
Description=Argo Tunnel
After=network.target

[Service]
TimeoutStartSec=0
Type=notify
ExecStart=/usr/local/bin/cloudflared --config /etc/cloudflared/config.yml --no-autoupdate tunnel run
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

You can check the cloudflared log file at /var/log/cloudflared.log.

cloudflared service install
service cloudflared start
chkconfig cloudflared on

Check status

systemctl status cloudflared.service

or

service cloudflared status

If you already had previously installed cloudflared service, you’ll get an error message:

cloudflared service install
Possible conflicting configuration in /root/.cloudflared/config.yml and /etc/cloudflared/config.yml. Either remove /etc/cloudflared/config.yml or run `cloudflared --config /etc/cloudflared/config.yml service install`

Then start and enable services to auto update the cloudflared binary.

systemctl start cloudflared-update.timer
systemctl enable cloudflared-update.timer
systemctl status cloudflared-update.timer

Automated Argo Tunnel Setup with Cloudflare API

Argo Tunnels can also be created via Cloudflare API. This below outlined steps could be scripted for automatic Cloudflare Argo Tunnel creation and setup.

Step 1. Create Cloudflare API Token with Argo Tunnel Write (Edit) Permission

Create a Cloudflare API Token with write permissions = Edit at the Cloudflare account level and DNS edit permissions at zone level.

Cloudflare Argo Tunnel API Token permissions

If you forget or lose your generated Cloudflare API Token, you can go to API Token listing page and in menu drop down (3 dots) link, select Roll to regenarate a new Cloudflare API Token.

Cloudflare API Token roll generate

Step 2. Create Argo Tunnel

Create Argo Tunnel via Cloudflare API with session variables populated where tunnelname is your desired Argo Tunnel hostname/subdomain.com and Cloudflare Account Id and Coudflare Zone ID are available on your Cloudflare site’s zone overview page right column and Cloudflare API Token is the one you generated from previous step. The Cloudflare API curl command output is saved to $tunnelname-tunnel-create.log log so we can get the Argo Tunnel’s tunnel id.

cfaccountid='your_cf_account_id'
cfapitoken='your_cf_api_token'
cfzoneid='your_cf_zone_id'
# tunnel name = hostname
tunnelname=tun.domain.com
tunnelsecret=$(openssl rand -hex 16 | base64)

curl -4sX POST "https://api.cloudflare.com/client/v4/accounts/$cfaccountid/tunnels" \
     -H "Authorization: Bearer $cfapitoken" \
     -H "Content-Type: application/json" \
     --data "{\"name\":\"$tunnelname\",\"tunnel_secret\":\"$tunnelsecret\"}" | jq | tee $tunnelname-tunnel-create.log

command output:

{
  "id": "34c4cadb-2edc-47ac-a682-xxxxxxxx",
  "created_at": "2021-02-08T17:41:25.125890Z",
  "deleted_at": null,
  "name": "tun.domain.com",
  "connections": []
}

Get tunnel id from $tunnelname-tunnel-create.log log

tunnelid=$(jq -r '.id' $tunnelname-tunnel-create.log)

Step 3. Create Argo Tunnel CNAME DNS Record

tunnelid=$(jq -r '.id' $tunnelname-tunnel-create.log)

curl -4sX POST "https://api.cloudflare.com/client/v4/zones/$cfzoneid/dns_records" \
     -H "Authorization: Bearer $cfapitoken" \
     -H "Content-Type: application/json" \
     --data "{\"type\":\"CNAME\",\"name\":\"$tunnelname\",\"content\":\"$tunnelid.cfargotunnel.com\",\"proxied\":true}" | jq | tee $tunnelname-tunnel-cname.log

command output:

{
  "result": {
    "id": "9b848b83cc6dfb46169cf8a9a9d9446b",
    "zone_id": "your_cf_zone_id",
    "zone_name": "domain.com",
    "name": "tun2.domain.com",
    "type": "CNAME",
    "content": "34c4cadb-2edc-47ac-a682-xxxxxxxx.cfargotunnel.com",
    "proxiable": true,
    "proxied": true,
    "ttl": 1,
    "locked": false,
    "meta": {
      "auto_added": false,
      "managed_by_apps": false,
      "managed_by_argo_tunnel": false,
      "source": "primary"
    },
    "created_on": "2021-02-08T18:04:17.990511Z",
    "modified_on": "2021-02-08T18:04:17.990511Z"
  },
  "success": true,
  "errors": [],
  "messages": []
}

This will then create the CNAME DNS record for tun2.domain.com to point to tunnelid.cfargotunnel.com target if the CNAME doesn’t already exist. If the CNAME already exists, you’ll get an error and need to manually edit and update the existing CNAME DNS record.

Step 4. Create Argo Tunnel Credentials JSON File

echo "{
  \"AccountTag\": \"$cfaccountid\",
  \"TunnelSecret\": \"$tunnelsecret\",
  \"TunnelID\": \"$tunnelid\",
  \"TunnelName\": \"$tunnelname\"
}" | jq -c | tee ~/.cloudflared/$tunnelid.json

contents of ~/.cloudflared/$tunnelid.json

cat ~/.cloudflared/$tunnelid.json | jq

{
  "AccountTag": "your_cf_account_id",
  "TunnelSecret": "ZTdkYTRlZmJjZDRmNDRlZjRiYzFjN2UxNGI0NzgyMTIK",
  "TunnelID": "34c4cadb-2edc-47ac-a682-xxxxxxxx",
  "TunnelName": "tun2.domain.com"
}

Step 5. Create Argo Tunnel YAML Config File

Create the cloudflared YAML config file at ~/.cloudflared/config.yml by populating the variables below. This configuration uses Cloudflare Named Tunnels and Ingress Rules.

hostname=tun2.domain.com
credfile="/root/.cloudflared/${tunnelid}.json"
localhost=https://localhost:443
metrics=localhost:5432
cftag='cmm=test'
cfpid='/var/run/cmm-test-argo.pid'
cfupdatettl='24h'

Make a copy of generated cert.pem file as /root/.cloudflared/cert-${hostname}.pem which will be used for origincert configuration value in tunnel’s YAML config file.

cp -a /root/.cloudflared/cert.pem /root/.cloudflared/cert-${hostname}.pem

Creating ~/.cloudflared/config.yml file with variables you assigned

cat > ~/.cloudflared/config.yml <<EOF
tunnel: $tunnelid
credentials-file: $credfile
origincert: /root/.cloudflared/cert-${hostname}.pem
protocol: http2
originRequest:
  connectTimeout: 30s

metrics: $metrics
#tag: $cftag
pidfile: $cfpid
autoupdate-freq: $cfupdatettl
loglevel: info
logfile: /var/log/cloudflared.log

ingress:
  - hostname: $hostname
    service: $localhost
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - service: http_status:404
EOF

The resulting ~/.cloudflared/config.yml file will contain

tunnel: your_tunnelid
credentials-file: /root/.cloudflared/your_tunnelid.json
origincert: /root/.cloudflared/cert-tun.domain.com.pem
protocol: http2
originRequest:
  connectTimeout: 30s

metrics: localhost:5432
#tag: cmm=test
pidfile: /var/run/cmm-test-argo.pid
autoupdate-freq: 24h
loglevel: info
logfile: /var/log/cloudflared.log

ingress:
  - hostname: tun2.domain.com
    service: https://localhost:443
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - service: http_status:404

With Argo Tunnel Ingress rules, you can setup other Cloudflare domain zone sites within the same Cloudflare Account to go through this single Cloudflare Argo Tunnel by adding the additional domain/subdomains i.e. hostname.domain.com and host.example.com as CNAME DNS records pointing to the same tunnelid.cfargotunnel.com target. Then update ~/.cloudflared/config.yml config file to:

tunnel: your_tunnelid
credentials-file: /root/.cloudflared/your_tunnelid.json
origincert: /root/.cloudflared/cert-tun2.domain.com.pem
protocol: http2
originRequest:
  connectTimeout: 30s

metrics: localhost:5432
#tag: cmm=blog
pidfile: /var/run/cmm-test-argo.pid
autoupdate-freq: 24h
loglevel: info
logfile: /var/log/cloudflared.log

ingress:
  - hostname: tun2.domain.com
    service: https://localhost:443
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - hostname: hostname.domain.com
    service: https://localhost:443
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - hostname: host.example.com
    service: https://localhost:443
    originRequest:
      connectTimeout: 10s
      noTLSVerify: true
  - service: http_status:404

I commented out the tag: setting for now as manually running the cloudflared argo tunnel gives an error right now. Update: it seems the tag argument currently isn’t meant to do anything.

cloudflared tunnel --config ~/.cloudflared/config.yml run tun.domain.com
expected string slice found string for tag

Validate ingress rules

cloudflared tunnel ingress validate
Validating rules from /root/.cloudflared/config.yml
OK

Step 6. Install cloudflared & CentOS 7 Service

If you have yet to install and authenticate cloudflared, you can do the one time task and install it via curl:

curl -4s https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-amd64.tgz | tar xzC /usr/local/bin
cloudflared update

Authenticate cloudflared using your Cloudflare Account log as per https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/setup

cloudflared tunnel login

Verify cloudflared version installed

cloudflared --version
cloudflared version 2021.2.1 (built 2021-02-04-1528 UTC)

Install cloudflared service, start it and ensure it starts on server reboots. Running service install command will create and configure systemd service file at /etc/systemd/system/cloudflared.service.

[Unit]
Description=Argo Tunnel
After=network.target

[Service]
TimeoutStartSec=0
Type=notify
ExecStart=/usr/local/bin/cloudflared --config /etc/cloudflared/config.yml --no-autoupdate tunnel run
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

You can check the cloudflared log file at /var/log/cloudflared.log.

cloudflared service install
service cloudflared start
chkconfig cloudflared on

Check status

systemctl status cloudflared.service

or

service cloudflared status

If you already had previously installed cloudflared service, you’ll get an error message:

cloudflared service install
Possible conflicting configuration in /root/.cloudflared/config.yml and /etc/cloudflared/config.yml. Either remove /etc/cloudflared/config.yml or run `cloudflared --config /etc/cloudflared/config.yml service install`

Then start and enable services to auto update the cloudflared binary.

systemctl start cloudflared-update.timer
systemctl enable cloudflared-update.timer
systemctl status cloudflared-update.timer

Listing Argo Tunnels Created

Above method used via cloudflared or Cloudflare API will not list the created Argo Tunnel in Cloudflare dashboard’s Traffic > Argo Tunnel section in web GUI.

To list your created Argo Tunnels use either command:

cloudflared tunnel list

or

cloudflared tunnel list -o json

Centmin Mod Nginx Access Logs

Argo Tunnel by default won’t pass on the visitor’s real IP address to Centmin Mod Nginx. Instead it will show up like

tail -1 /home/nginx/domains/tun.domain.com/log/access.log 
127.0.0.1 - - [07/Feb/2021:22:39:12 +0000] "GET /?test HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36 OPR/74.0.3911.75"

Centmin Mod Nginx config file at /usr/local/nginx/conf/nginx.conf has additional Nginx log format options which can log Argo Tunnel received visitor’s real IP addresses via $http_x_forwarded_for field.

Example for log format named cf_custom4

log_format cf_custom4 '$remote_addr - $remote_user [$time_local] $request '
              '"$status" $body_bytes_sent "$http_referer" '
              '"$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio" "$brotli_ratio"'
              ' "$connection" "$connection_requests" "$request_time" $http_cf_ray '
              '$ssl_protocol $ssl_cipher $http_content_length $http_content_encoding $request_length';

You can alter and create your own custom log formats too.

To enable this, you need to edit Nginx vhost config files include file /usr/local/nginx/conf/cloudflare.conf in /usr/local/nginx/conf/conf.d/tun.domain.com.ssl.conf and/or /usr/local/nginx/conf/conf.d/tun.domain.com.conf. This enables Cloudflare’s documented restoration of real visitor IP addresses.

# uncomment cloudflare.conf include if using cloudflare for
# server and/or vhost site
include /usr/local/nginx/conf/cloudflare.conf;

And also add a second access log line assigning the log format named cf_custom4

access_log /home/nginx/domains/tun.domain.com/log/cf-ssl-access.log cf_custom4;

to existing one so it looks like

access_log /home/nginx/domains/tun.domain.com/log/access.log combined buffer=256k flush=5m;
error_log /home/nginx/domains/tun.domain.com/log/error.log;
access_log /home/nginx/domains/tun.domain.com/log/cf-access.log cf_custom4;

Then restart Nginx

service nginx restart

Or via Centmin Mod command shortcut

ngxrestart

Visit Argo Tunnel site and then check the new access log and see the $http_x_forwarded_for field record the real visitor IP = 122.xxx.xxx.xxx

tail -1 /home/nginx/domains/tun.domain.com/log/cf-access.log

127.0.0.1 - - [07/Feb/2021:22:39:12 +0000] GET /?test HTTP/1.1 "200" 2112 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36 OPR/74.0.3911.75" "122.xxx.xxx.xxx" "3.14" "-" "54043" "3" "0.000" 61f323cc591c32a4-ORD TLSv1.3 TLS_AES_256_GCM_SHA384 - - 1303

Cloudflare Authenticated Origin Pull Incompatibility

Cloudflare Argo Tunnel is incompatible with Cloudflare Authenticated Origin Pull as they both do the same thing to prevent visitor access that bypasses Cloudflare proxy and tries HTTP access via the server’s real IP access – just done in different ways. So if you have manually enabled Cloudflare Authenticated Origin Pull certificate configuration in your Nginx vhost config file at /usr/local/nginx/conf/conf.d/yourdomain.com.conf and/or /usr/local/nginx/conf/conf.d/yourdomain.com.ssl.conf, you will need to disable them again by commenting out the relevant lines using a hash # in front of the 2nd and 3rd lines below and then restart Nginx service. By default Cloudflare Authenticated Origin Pull is disabled with a hash in front usually.

 # cloudflare authenticated origin pull cert community.centminmod.com/threads/13847/
 # ssl_client_certificate /usr/local/nginx/conf/ssl/cloudflare/yourdomain.com/origin.crt;
 # ssl_verify_client on;