Skip to content

Step-by-step guide showing how Cloudflare Tunnel integrates to have 2FA via Authelia in docker environment

License

Notifications You must be signed in to change notification settings

tamimology/cloudflare-authelia

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Cloudflare Tunnel Login Using Self-hosted Authelia

NOTE: WHEN WRITING THIS GUIDE, IT WAS BASED ON AUTHELIA v4.38.16 AND CLOUDFLARE TUNNEL v2024.9.1

Table of Contents

First, we start with Cloudflare platform

  1. Generating Hashed Secrets
  2. Setting Up Authentication Methods
  3. Adding Applications Rules and Policies
  4. Adding Firewall Rules

Second, we move to Authelia self-hosted

  1. Generating Secrets and OpenID Issuer Private Key
  2. Generating Random Alphanumeric String
  3. Editing Authelia Configuration File

Finally, we test our setup

  1. Testing The Integration Setup

Generating Hashed Secrets

This step will be used in a later step as the link where both Authelia and Cloudflare are integrated together.

In the terminal, execute the command docker run authelia/authelia:latest authelia crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986 and take note of the both the Random Password and Digest outputs.

hashed secret

Setting Up Authentication Methods

This step is where we add Authelia as a 2FA service into the Cloudflare platform.

On the same page, you are now, and on the left side, click on Settings, then choose Authentication

authentication

In the next window, under the Login methods, click Add new, and then Choose the OpenID Connect from the available options

new authentication

Now, this has to be filled in carefully, and remember each entry for later use.

  1. Fill in the name, i.e. "Authelia"

Considering the URL for Authelia as "auth.mydomain.com", then in each field that follows enter:

  1. cloudflare
  2. The Random Password generate in the previous step
  3. https://auth.mydomain.com/api/oidc/authorization
  4. https://auth.mydomain.com/api/oidc/token
  5. https://auth.mydomain.com/jwks.json
  6. Enable the Proof Key for Code Exchange (PKCE)
  7. Add new OIDC Claims, preferred_username and mail

Click on Save

openid connect

Before leaving the Cloudflare platform and moving to the Authelia part, take note of the Cloudflare team name, and have it saved somewhere safe for later use. To do that, click on Settings on the left side list, then choose Custom Pages. On the top right side, you will see the team name in the format myteam.cloudflareaccess.com. So, in this case, it will be only *myteam

cf team

Adding Applications Rules and Policies

This is where you define for each subdomain if Authelia is needed to be an intermediate gate between the Cloudflare Tunnel and the final URL requested

On the left side, click on Access, then choose Applications, then click on Add an application and choose the Self-hosted option.

add application

In the Configure app screen, give the application a name, i.e. "Portainer-CE". Choose a subdomain, i.e. "portainer", and choose your domain, which we agreed on to be mydomain.com. You can change the application logo if needed, or just keep the Default one. Click on Next on the top right.

In the Add policies screen, give this policy a name, i.e. "portainer_auth_policy". In the Action, select the "Allow", and duration make it "1 month". Then in Configure rules, set the Selector to "Login Methods", and the Value, choose the "OpenID Connect Authelia" option and click on Next on the top right.

In the Setup screen, leave everything as is, and click on Add application on the top right

application access

Adding Firewall Rules

What we need now is to allow specific countries to access the domain, and block all other countries to avoid external attacks.

In the Cloudfare dashboard, click on the Websites on the top left side, then choose the domain name that needs to have the firewall rules added to.

website_domain

From that screen, Security from the Home screen, then choose WAF. On the right side, click on Create rule.

waf

Follow the steps below:

  1. Enter the desired Rule Name
  2. Choose "Continent" from the Field list, Operator to be "equals", and then choose the first option in the Value list. Do this step for all items in the "Value" list by choosing the "Or" next to each rule line
  3. Choose the "Block" from action

waf_rule

By doing this, you have blocked all countries from accessing your domain.

Now, you need to unblock your country (or more than one if needed).

After you have added all continents as Block, check your desired country is in which continent, i.e. Cyprus, which is in Europe. You go to the Europe option you have added, and then click on And, then choose "Country" from the Field list, Operator to be "does not equals", and then choose "Cyprus" from the Value list.

Click on Deploy firewall rule at the bottom of the page

Your final result should look like below

final_waf

In case you have Home Assistant installed, and have the Google Home Devices integrated with it, you need to allow Google to bypass the firewall rule. In order to do that, with the North America rule, add an And rule, then choose "AS Num" from the Field list, Operator as "does not equal" and set the Value to "15169"
In case you have MariaDB installed, you need to allow it to bypass the firewall rule. In order to do that, with the North America rule, add an And rule, then choose "AS Num" from the Field list, Operator as "does not equal" and set the Value to "396982"

Generating Secrets and OpenID Issuer Private Key

What we need now is to generate an encrypted pair of RSA files to be used to encrypt Authelia public requests.

To do so, SSH into the host machine having the Authelia container installed on, and considering that: UID="1000", GID="100" , and PEM file output directory="/rsa"

Enter and execute the following command: docker run -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia:latest authelia crypto pair rsa generate --bits 4096 --directory /keys

2 .pem files will be generated in the current working folder as defined in the command executed

pem files

We are only in need of the private.pem file, keep it somewhere safe for later use.

Generating Random Alphanumeric String

This step is to generate an alphanumeric string to be used as a secret hash for Authelia when accessing it from Cloudflare

In the same SSH terminal, execute the following command tr -cd '[:alnum:]' < /dev/urandom | fold -w "64" | head -n 1 | tr -d '\n' ; echo

An output string will be shown on the terminal window, also copy that and keep it in a safe place for later use.

rsa

Editing Authelia Configuration File

Because Cloudflare has different settings to be configured, and are different compared to the one previously used with any reverse proxy, a new configuration.yml file should be created with the relevant parameters in it

In case an existing "configuration.yml" file is available in the Authelia folder, make a backup copy of that, or simply download the sample one from here and make sure to change all CAPITALISED parameters to match your setup

As a quick summary, just delete the "rules:" part under the "access_control:", and keep the rest untouched. Also make sure that you change all "URLs" from the previous one to Cloudflare's ones, i.e. from "DuckDNS"

Considering the team's name in Cloudflare is named as "myteam", then, we need to add the following at the end of the file:

identity_providers:
  oidc:
    hmac_secret: **PUT THE GENERATED RSA STRING FROM THE PREVIOUS STEP**
    jwks:
      - key_id: 'example'
        algorithm: 'RS256'
        use: 'sig'
        key: |
          -----BEGIN RSA PRIVATE KEY-----
          **HERE GOES WHATEVER IS IN THE _private.pem_ FILE**
          -----END RSA PRIVATE KEY-----
    lifespans.access_token: 1h
    lifespans.authorize_code: 1m
    lifespans.id_token: 1h
    lifespans.refresh_token: 90m
    enable_client_debug_messages: false
    enforce_pkce: public_clients_only
    cors:
      endpoints:
        - authorization
        - token
        - revocation
        - introspection
      allowed_origins:
        - "*"
      allowed_origins_from_client_redirect_uris: false

    clients:
      - client_id: cloudflare
        client_name: Cloudflare ZeroTrust
        client_secret: **PUT THE _Digest_ PASSPHRASE PREVIOUSLY GENERATED **
        public: false
        authorization_policy: two_factor
        pre_configured_consent_duration: '365d'
        redirect_uris:
          - https://**myteam**.cloudflareaccess.com/cdn-cgi/access/callback
        scopes:
          - openid
          - profile
          - email
        userinfo_signed_response_alg: none

Now, restart Authelia container and make sure that no errors are in the logs. If this is successful, it is time now to test the integration from Cloudflare.

In case there was an error, it is most probably due to the generated RSA encoding not matching.

level=error msg="Configuration: error occurred during unmarshalling configuration: decoding failed due to the following error(s):\n\nerror decoding 'identity_providers.oidc.jwks[0].key': could not decode to a schema.CryptographicKey: x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)"
level=fatal msg="Can't continue due to the errors loading the configuration" stack="github.com/authelia/authelia/v4/internal/commands/context.go:327 (*CmdCtx).ConfigValidateLogRunE\ngithub.com/authelia/authelia/v4/internal/commands/context.go:186 NewRootCmd.(*CmdCtx).ChainRunE.func1\ngithub.com/spf13/[email protected]/command.go:970                     (*Command).execute\ngithub.com/spf13/[email protected]/command.go:1117                    (*Command).ExecuteC\ngithub.com/spf13/[email protected]/command.go:1041                    (*Command).Execute\ngithub.com/authelia/authelia/v4/cmd/authelia/main.go:10          main\ninternal/runtime/atomic/types.go:194                             (*Uint32).Load\nruntime/asm_amd64.s:1700                                         goexit"

To resolve this, execute the following command in the same terminal window

openssl rsa -in private.pem -out key.pem -traditional

A new file will be generated named key.pem, copy the contents of this file into the above configuration and then run the container. All should be fine now

Testing The Integration Setup

This is the last step to make sure that nothing wrong is done during the setup, and Authelia is successfully integrated into Cloudflare as a 2FA platform

Now to make sure that, so far, everything is set up correctly, open the Cloudflare Zero Trust page. Click on Settings, then Authentication. Under the Login methods you will see the previously added "OpenID Connect Authelia" method. Click on Test beside it.

authentication test

If the below is seen, then Authelia is now a gateway for your Cloudflare's selected domains for 2FA authentication. Otherwise, re-check what have you missed from this guide, as it is 100% guaranteed if followed as is, the integration will be successful.

openid test

License

This document guide is licensed under the CC0 1.0 Universal license. The terms of the license are detailed in LICENSE

About

Step-by-step guide showing how Cloudflare Tunnel integrates to have 2FA via Authelia in docker environment

Resources

License

Stars

Watchers

Forks