Concrete CMS + Cloudflare: How to fix logging out problem
Tags: concretecms, cloudflare, symfony, concrete5
Published: 2023-05-19 07:05:26

You have a Concrete CMS website and using Cloudflare. When you enable DNS proxy of Cloudflare, your Concrete CMS website started to log out frequently and became uneditable.


## The reason why you get logged out

It's because Concrete CMS (Symfony framework) thinks you maybe compromised because your IP keeps changing.

Concrete CMS is built with Symfony framework. Symfony framework has security measurement to monitor user's session and IP address.

If user's IP address changes but the user session is the same, Symfony thinks that user session was hijacked and Symfony invalidates the session (log you out).

![Cloudflare in the middle of web server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/164ewcczpyk9dzjcn3r1.png)

Why?

When you enable Cloudflare's DNS proxy mode, your traffic start to go through Cloudflare servers, then reaches Concrete CMS server.

Now, your Concrete CMS server see Cloudflare's IP as user's IP address instead of your IP address.

Since Cloudflare has so many edge locations, you often access to different edges every time you access your site.

Which means that Concrete CMS sees the same user is accessed from different IP request after request.

## Symfony's trusted_proxy setting

But here is a good news. Symfony is already providing the solution.

You can set the range of Cloudflare's IP range.

Once you set the proxy address, the PHP application start to respect X-Forwarded-For header.

When the traffic go through Cloudflare, the Cloudflare embed the header called X-Forwarded-For which include the original user's IP address.

For more detail info you can read Symfony documentation: [How to Configure Symfony to Work behind a Load Balancer or a Reverse Proxy](https://symfony.com/doc/current/deployment/proxies.html)

I will skip why Symfony does it but it's very important security measurement.

## How to set-up Concrete CMS.

Anyway, where is Cloudflare's IPs?

Of course, Cloudflare provides its IP ranges at [their own IP page](https://www.cloudflare.com/ips/).

You set these IP ranges to Concrete CMS.

Concrete CMS of course has `Trusted Proxy` config.

It can set it up via dashboard or CLI add-on.
 

### Dashboard way

Here is the steps.

![Concrete CMS trusted proxy setting page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/witttfnqk1rorl711s9j.png)

- Disable Cloudflare DNS proxy for a moment
- Log-in to Concrete CMS as an admin
- Visit `System and Settings`
- Go to `Permission and Access` - `Trusted Proxy` page
- Enter the Cloudflare's IP range in the text box and save
- Enable Cloudflare DNS proxy and test if it works.
- Come back to visit [Cloudflare's IP Range page](https://www.cloudflare.com/ips/) and update the trusted proxies.


### Concrete CMS: Cloudflare Proxy add-on

The above trusted proxy way is a bit troublesome since you may need to check periodically. (Although Cloudflare seems to update IP range once every other year or less frequent.)

Good news is that Cloudflare offers simple text pages of IP ranges. ( [IPv4](https://www.cloudflare.com/ips-v4) & [IPv6](https://www.cloudflare.com/ips-v6) )

Then Concrete CMS has an add-on to update the IP range via those page, called Cloudflare Proxy add-on.

It is CLI based add-on.

- Visit the github page
    - [https://github.com/concretecms/cloudflare_proxy](https://github.com/concretecms/cloudflare_proxy)
- Download the zip file
- Rename the folder as `cloudflare_proxy`
- Run `composer install` in the cloudflare_proxy
- Upload or deploy the package folder to Concrete CMS's packages folder
- Install the package via dashboard or CLI
- Set-up cron to run the following command periodically.

### How to update the list

The command to run is

Concrete CMS v9

```
[path/to/]concrete/bin/concrete cf:ip:update
```

Concrete CMS v8

```
[path/to/]concrete/bin/concrete5 cf:ip:update
```

Then the package fetch the current IP range and update it.

If you would like to see the current IP list

### Find out the list

Concrete CMS v9

```
[path/to/]concrete/bin/concrete cf:ip:list
```

Concrete CMS v8

```
[path/to/]concrete/bin/concrete5 cf:ip:list
```

### Cron sample

The following is the crontab sample. It is to run at 1am everyday. It is different if you setup at `/etc/crontab` or systemd timer.

You may need to set php path in cron.

Concrete CMS V9 and later

```
0  1  *  *  * (user) [path/to/]concrete/bin/concrete cf:ip:update
```

Concrete CMS V8

```
0  1  *  *  * (user) [path/to/]concrete/bin/concrete5 cf:ip:update
```

Anyway, this should solve the troublesomeness.

## Conclusion

If you cannot figure out Cloudflare proxy add-on, juat set-it up at trusted proxy page via dashboard.

Cloudflare doesn't update the IP often, anywa.

If your Concrete CMS doesn't accept public user login, you just need to update when the user starts to complain that they started to get logged out. That's when you need to check Cloudflare IP page and update the trusted proxy IP. :p

By the way, this also applies to Concrete CMS environment with CloudFront and/or ELB. You will set-up IP range of those.