Install Cloudflared on pfSense

Categories: cloudflare firewall

NOTE: Remember to create a backup before you proceed!
  1. Start by editing /usr/local/etc/pkg/repos/pfsense.repo and change the first line so it looks like this

    FreeBSD: {
      url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
      mirror_type: "srv",
      signature_type: "fingerprints",
      fingerprints: "/usr/share/keys/pkg",
      enabled: yes
    }

  2. Install Cloudflared

    pkg install cloudflared
    
    Output:
    
    [22.05-RELEASE]/root: pkg install cloudflared
    Updating FreeBSD repository catalogue...
    FreeBSD repository is up to date.
    Updating pfSense-core repository catalogue...
    pfSense-core repository is up to date.
    Updating pfSense repository catalogue...
    pfSense repository is up to date.
    All repositories are up to date.
    New version of pkg detected; it needs to be installed first.
    The following 1 package(s) will be affected (of 0 checked):
    
    Installed packages to be UPGRADED:
    	pkg: 1.17.5_2 -> 1.18.4 [FreeBSD]
    
    Number of packages to be upgraded: 1
    
    The process will require 15 MiB more space.
    7 MiB to be downloaded.
    
    Proceed with this action? [y/N]: y
    [1/1] Fetching pkg-1.18.4.pkg: 100%    7 MiB   7.7MB/s    00:01    
    Checking integrity... done (0 conflicting)
    [1/1] Upgrading pkg from 1.17.5_2 to 1.18.4...
    [1/1] Extracting pkg-1.18.4: 100%
    You may need to manually remove /usr/local/etc/pkg.conf if it is no longer needed.
    Updating FreeBSD repository catalogue...
    FreeBSD repository is up to date.
    Updating pfSense-core repository catalogue...
    pfSense-core repository is up to date.
    Updating pfSense repository catalogue...
    pfSense repository is up to date.
    All repositories are up to date.
    The following 22 package(s) will be affected (of 0 checked):
    
    New packages to be INSTALLED:
    	brotli: 1.0.9,1 [FreeBSD]
    	cloudflared: 2022.7.1_2 [FreeBSD]
    	fontconfig: 2.14.0,1 [FreeBSD]
    	freetype2: 2.12.1_2 [FreeBSD]
    	gdbm: 1.23 [FreeBSD]
    	giflib: 5.2.1 [FreeBSD]
    	gmp: 6.2.1 [FreeBSD]
    	graphite2: 1.3.14 [FreeBSD]
    	jbigkit: 2.1_1 [FreeBSD]
    	jpeg-turbo: 2.1.4 [FreeBSD]
    	libdeflate: 1.13 [FreeBSD]
    	libfontenc: 1.1.4 [FreeBSD]
    	libsodium: 1.0.18 [FreeBSD]
    	libunwind: 20211201_1 [FreeBSD]
    	libyaml: 0.2.5 [FreeBSD]
    	lua53: 5.3.6 [FreeBSD]
    	nettle: 3.8.1 [FreeBSD]
    	pixman: 0.40.0_1 [FreeBSD]
    	png: 1.6.37_1 [FreeBSD]
    	tcl86: 8.6.12 [FreeBSD]
    	tiff: 4.4.0 [FreeBSD]
    	zstd: 1.5.2_1 [FreeBSD]
    
    Number of packages to be installed: 22
    
    The process will require 71 MiB more space.
    16 MiB to be downloaded.
    
    Proceed with this action? [y/N]: y
    [1/22] Fetching freetype2-2.12.1_2.pkg: 100%    1 MiB   1.1MB/s    00:01    
    [2/22] Fetching nettle-3.8.1.pkg: 100%    1 MiB   1.4MB/s    00:01    
    [3/22] Fetching giflib-5.2.1.pkg: 100%  232 KiB 237.5kB/s    00:01    
    [4/22] Fetching graphite2-1.3.14.pkg: 100%  100 KiB 102.2kB/s    00:01    
    [5/22] Fetching gdbm-1.23.pkg: 100%  208 KiB 212.9kB/s    00:01    
    [6/22] Fetching libunwind-20211201_1.pkg: 100%  127 KiB 130.3kB/s    00:01    
    [7/22] Fetching zstd-1.5.2_1.pkg: 100%  587 KiB 601.3kB/s    00:01    
    [8/22] Fetching brotli-1.0.9,1.pkg: 100%  355 KiB 363.7kB/s    00:01    
    [9/22] Fetching fontconfig-2.14.0,1.pkg: 100%  455 KiB 465.7kB/s    00:01    
    [10/22] Fetching jbigkit-2.1_1.pkg: 100%   73 KiB  74.6kB/s    00:01    
    [11/22] Fetching tiff-4.4.0.pkg: 100%  854 KiB 874.4kB/s    00:01    
    [12/22] Fetching tcl86-8.6.12.pkg: 100%    2 MiB   2.5MB/s    00:01    
    [13/22] Fetching png-1.6.37_1.pkg: 100%  290 KiB 297.2kB/s    00:01    
    [14/22] Fetching jpeg-turbo-2.1.4.pkg: 100%  366 KiB 374.6kB/s    00:01    
    [15/22] Fetching libyaml-0.2.5.pkg: 100%   71 KiB  72.4kB/s    00:01    
    [16/22] Fetching libdeflate-1.13.pkg: 100%   74 KiB  75.7kB/s    00:01    
    [17/22] Fetching lua53-5.3.6.pkg: 100%  281 KiB 288.1kB/s    00:01    
    [18/22] Fetching cloudflared-2022.7.1_2.pkg: 100%    6 MiB   6.3MB/s    00:01    
    [19/22] Fetching libfontenc-1.1.4.pkg: 100%   19 KiB  19.9kB/s    00:01    
    [20/22] Fetching gmp-6.2.1.pkg: 100%  477 KiB 488.4kB/s    00:01    
    [21/22] Fetching pixman-0.40.0_1.pkg: 100%  324 KiB 331.6kB/s    00:01    
    [22/22] Fetching libsodium-1.0.18.pkg: 100%  263 KiB 268.9kB/s    00:01    
    Checking integrity... done (0 conflicting)
    [1/22] Installing brotli-1.0.9,1...
    [1/22] Extracting brotli-1.0.9,1: 100%
    [2/22] Installing png-1.6.37_1...
    [2/22] Extracting png-1.6.37_1: 100%
    [3/22] Installing freetype2-2.12.1_2...
    [3/22] Extracting freetype2-2.12.1_2: 100%
    [4/22] Installing zstd-1.5.2_1...
    [4/22] Extracting zstd-1.5.2_1: 100%
    [5/22] Installing jbigkit-2.1_1...
    [5/22] Extracting jbigkit-2.1_1: 100%
    [6/22] Installing jpeg-turbo-2.1.4...
    [6/22] Extracting jpeg-turbo-2.1.4: 100%
    [7/22] Installing libdeflate-1.13...
    [7/22] Extracting libdeflate-1.13: 100%
    [8/22] Installing gmp-6.2.1...
    [8/22] Extracting gmp-6.2.1: 100%
    [9/22] Installing nettle-3.8.1...
    [9/22] Extracting nettle-3.8.1: 100%
    [10/22] Installing giflib-5.2.1...
    [10/22] Extracting giflib-5.2.1: 100%
    [11/22] Installing graphite2-1.3.14...
    [11/22] Extracting graphite2-1.3.14: 100%
    [12/22] Installing gdbm-1.23...
    [12/22] Extracting gdbm-1.23: 100%
    [13/22] Installing libunwind-20211201_1...
    [13/22] Extracting libunwind-20211201_1: 100%
    [14/22] Installing fontconfig-2.14.0,1...
    [14/22] Extracting fontconfig-2.14.0,1: 100%
    [15/22] Installing tiff-4.4.0...
    [15/22] Extracting tiff-4.4.0: 100%
    [16/22] Installing tcl86-8.6.12...
    [16/22] Extracting tcl86-8.6.12: 100%
    [17/22] Installing libyaml-0.2.5...
    [17/22] Extracting libyaml-0.2.5: 100%
    [18/22] Installing lua53-5.3.6...
    [18/22] Extracting lua53-5.3.6: 100%
    [19/22] Installing cloudflared-2022.7.1_2...
    [19/22] Extracting cloudflared-2022.7.1_2: 100%
    [20/22] Installing libfontenc-1.1.4...
    [20/22] Extracting libfontenc-1.1.4: 100%
    [21/22] Installing pixman-0.40.0_1...
    [21/22] Extracting pixman-0.40.0_1: 100%
    [22/22] Installing libsodium-1.0.18...
    [22/22] Extracting libsodium-1.0.18: 100%
    Running fc-cache to build fontconfig cache...
    =====
    Message from freetype2-2.12.1_2:
    
    --
    The 2.7.x series now uses the new subpixel hinting mode (V40 port's option) as
    the default, emulating a modern version of ClearType. This change inevitably
    leads to different rendering results, and you might change port's options to
    adapt it to your taste (or use the new "FREETYPE_PROPERTIES" environment
    variable).
    
    The environment variable "FREETYPE_PROPERTIES" can be used to control the
    driver properties. Example:
    
    FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
    	cff:no-stem-darkening=1 \
    	autofitter:warping=1
    
    This allows to select, say, the subpixel hinting mode at runtime for a given
    application.
    
    If LONG_PCF_NAMES port's option was enabled, the PCF family names may include
    the foundry and information whether they contain wide characters. For example,
    "Sony Fixed" or "Misc Fixed Wide", instead of "Fixed". This can be disabled at
    run time with using pcf:no-long-family-names property, if needed. Example:
    
    FREETYPE_PROPERTIES=pcf:no-long-family-names=1
    
    How to recreate fontconfig cache with using such environment variable,
    if needed:
    # env FREETYPE_PROPERTIES=pcf:no-long-family-names=1 fc-cache -fsv
    
    The controllable properties are listed in the section "Controlling FreeType
    Modules" in the reference's table of contents
    (/usr/local/share/doc/freetype2/reference/index.html, if documentation was installed).

  3. Disable the FreeBSD repo again by setting enabled to no in /usr/local/etc/pkg/repos/pfsense.repo

    FreeBSD: {
      url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
      mirror_type: "srv",
      signature_type: "fingerprints",
      fingerprints: "/usr/share/keys/pkg",
      enabled: no
    }

  4. Revert some of the packages to the pfSense maintained version

    pkg upgrade
    
    Output:
    
    [22.05-RELEASE]/root: pkg update
    Updating pfSense-core repository catalogue...
    pfSense-core repository is up to date.
    Updating pfSense repository catalogue...
    pfSense repository is up to date.
    All repositories are up to date.
    [22.05-RELEASE]/root: pkg upgrade
    Updating pfSense-core repository catalogue...
    pfSense-core repository is up to date.
    Updating pfSense repository catalogue...
    pfSense repository is up to date.
    All repositories are up to date.
    Checking for upgrades (13 candidates): 100%
    Processing candidates (13 candidates): 100%
    The following 5 package(s) will be affected (of 0 checked):
    
    Installed packages to be REINSTALLED:
    	brotli-1.0.9,1 [pfSense] (options changed)
    	giflib-5.2.1 [pfSense] (options changed)
    	jbigkit-2.1_1 [pfSense] (options changed)
    	libsodium-1.0.18 [pfSense] (options changed)
    	lua53-5.3.6 [pfSense] (options changed)
    
    Number of packages to be reinstalled: 5
    
    The operation will free 1 MiB.
    899 KiB to be downloaded.
    
    Proceed with this action? [y/N]: y
    [1/5] Fetching lua53-5.3.6.pkg: 100%  196 KiB 200.4kB/s    00:01    
    [2/5] Fetching giflib-5.2.1.pkg: 100%   71 KiB  73.1kB/s    00:01    
    [3/5] Fetching brotli-1.0.9,1.pkg: 100%  352 KiB 360.7kB/s    00:01    
    [4/5] Fetching libsodium-1.0.18.pkg: 100%  215 KiB 220.1kB/s    00:01    
    [5/5] Fetching jbigkit-2.1_1.pkg: 100%   65 KiB  66.1kB/s    00:01    
    Checking integrity... done (0 conflicting)
    [1/5] Reinstalling lua53-5.3.6...
    [1/5] Extracting lua53-5.3.6: 100%
    [2/5] Reinstalling giflib-5.2.1...
    [2/5] Extracting giflib-5.2.1: 100%
    [3/5] Reinstalling brotli-1.0.9,1...
    [3/5] Extracting brotli-1.0.9,1: 100%
    [4/5] Reinstalling libsodium-1.0.18...
    [4/5] Extracting libsodium-1.0.18: 100%
    [5/5] Reinstalling jbigkit-2.1_1...
    [5/5] Extracting jbigkit-2.1_1: 100%

  5. cloudflared can be found in /usr/local/bin/cloudflared

  6. I won’t go into details about how you use cloudflared, but here’s the documentation https://developers.cloudflare.com/cloudflare-one/setup to get you started

  7. Cloudflared config.yaml file

    tunnel: <tunnel-id>
    credentials-file: /root/.cloudflared/<tunnel-id-file>.json
    warp-routing:
      enabled: true
    
    ingress:
      - hostname: pfsense.example.com
        service: https://localhost:443
        originRequest:                              # Only needed if protocol is https and the certificate hostname differs from the hostname in Cloudflare
          originServerName: "pfsense1.example.com"  #
      - hostname: pfsense-ssh.example.com   
        service: ssh://localhost:22
      - service: http_status:404

  8. Create a DNS record

    cloudflared tunnel route dns <tunnel id> pfsense.example.com

  9. Create a persistent startup service in /usr/local/etc/rc.d/ REMEMBER to use your tunnel id from above

    echo "
    #!/bin/sh
    
    # PROVIDE: cf
    # REQUIRE: cleanvar SERVERS
    
    # Options to configure cf(cloudflared) via /etc/rc.conf:
    #
    # cf_enable (bool)	Enable service on boot
    #				Default: NO
    #
    # cf_conf (str)	Config file to use
    #				Default: /usr/local/etc/cloudflared/config.yml
    #
    # cf_mode (str)	Mode to run cloudflared as (e.g. 'tunnel', 'tunnel run'
    #				or 'proxy-dns'). Should you use the default, a free
    #				tunnel is set up for you.
    #				Default: "tunnel"
    #
    # cf_origin_cert (str) path to origin certificate
    #       Default: "/etc/cloudflared/cert.pem"
    #
    # cf_tunnel_id (str) Your Cloudflared Tunnel ID
    #
    
    . /etc/rc.subr
    
    name="cf"
    rcvar="${name}_enable"
    
    : ${cf_enable:="YES"}
    : ${cf_conf:="/root/.cloudflared/config.yml"}
    : ${cf_origin_cert:="/root/.cloudflared/cert.pem"}
    : ${cf_mode:="tunnel run"}
    : ${cf_tunnel_id="<YOUR TUNNEL ID>"}
    
    logfile="/var/log/cloudflared.log"
    pidfile="/var/run/cloudflared.pid"
    procname="/usr/local/bin/cloudflared"
    
    command="/usr/sbin/daemon"
    command_args="-o ${logfile} -p ${pidfile} -f ${procname} --origincert ${cf_origin_cert} --config ${cf_conf} ${cf_mode} ${cf_tunnel_id}"
    
    stop_postcmd="killall cloudflared"
    
    load_rc_config $name
    run_rc_command "$1"
    " > /usr/local/etc/rc.d/cf.sh
    
    chmod +x /usr/local/etc/rc.d/cf.sh

  10. Install the cron package in pfSense and configure it to start the script on boot
    @reboot root /usr/local/etc/rc.d/cf.sh start