Avatar Proxy and CDN Hot-Link Protection

My Discourse site is image-heavy. Due to the many images, I use a S3/CDN combination to store and serve images. Within the CDN, I use various measures to prevent image hijacking. One of the measures is to stop all direct access to pictures and only allow access from a defined hostname list.

Discourse works with this setup, except for Avatars. Avatars stop working when hotlinking protection is turned on.

The reason is Discourse uses a proxy setup for Avatars. The HTML uses a proxy link for avatars. The link structure is https://discourse.forum/user_avatar/discourse.forums/username/24/616_2.png.
Once the proxy is resolved, the browser requests direct access to the image file.

My CDN prevents direct access with a 403 when making this direct request. And all custom avatars become silhouettes.

What options do we have to remove the proxy?
Can we change the avatar to a standard image file structure?

Can’t you whitelist your Discourse IP address?

The direct access link call comes from the users IP address. The server resolves the info, but the local browser does the call.

I am not sure it works that way. Depending on your configuration, the proxy actually proxies or the CDN goes first. Can you elaborate on how this is set up?

I hate vague questions. What were you thinking when you asked for “this”?

Here are my current settings:

Discourse Setup:

  • Standard single container install
  • Setup as a subdomain: forums.domain.tld
  • Standard S3 setup for uploads
  • Uploads are saved on the S3

S3 Setup:

  • Digital Ocean S3 Bucket
  • Bucket turned on for external access
  • No other security layers or permissions

CDN Setup:

  • bunny CDN
  • Allowed referrers setup: domain.tld and *.domain.tld
  • The switch that killed Avatar access was to “Block Direct URL File Access”.

When turned on, all avatars received a 403 error. When turned off, avatars populate.

Non-Avatar Images:

  • URL in Discourse: https://cdn.domain.tld/optimized/3X/3/1/filename_#_size.jpeg

Avatar Images:

  • URL in Discourse: https://forums.domain.tld/user_avatar/forums.domain.tld/mazzini/48/776_2.png

A previous post, How are avatars stored and accessed?, indicates Discourse uses a proxy for avatars. Hence, the URL structure for avatars is not a standard image URL structure.

Within my system, avatars are either available from the S3 or the CDN. This indicates that some where/some how the avatar URL is converted to a CDN URL.

When this happens, the CDN considers the URL a direct access link and blocks access with a 403.

Hopefully, I answered the “this” question?

And I hate it when people respond like that when I am spending my time in helping them, so that makes it a draw :wink:.

Yes, and “proxy” means that the request passes through Discourse. The request is not made by the browser to the CDN but by Discourse.

Did you set up the CDN as a full site CDN or as the S3 CDN ? I suspect the latter. And in that case the request is made by Discourse to the CDN, without a referrer. But the CDN can still recognize that it is a legit request because the request is originating from the Discourse IP. Hence my advice to whitelist it.

Edit: you could check by turning off the protection for a short while and looking at the logs in Bunny, and see which IP they’re coming from.

I appreciate your help. After many decades of working in IT development and support, vague questions and responses create more work than necessary. Based on your experience, I think you would agree.

The CDN is only set up for the S3 bucket.

I did check the CDN logs for the Discourse IP related to the 403 errors before submitting the original topic. It was not in the log files.

Based on your comments, I went back and reanalyzed the logs. After reviewing the largest IP offenders, I found that the top couple are gateways for the hosting company.

The challenge is that I do not want to keep track of the Digital Ocean’s gateway IP addresses so my Discourse server can display images correctly.

Thank you for the assist.