Jump to content

HOW TO: Recommended Cloudflare Settings


pir8radio

Recommended Posts

vaise

I have now also got @HorsePDF's modified cloudflare/nginx split streaming working for my system also. 

His doco is very good and the only things I can offer to make it better are thus :

1 - put actual text that can be copied into the notes - so easier to see difference between letter 'eye' and 'elle' (see above someone else had)

2 - the nginX rewrite could just remove the /something from the uri like this :  rewrite ^/something(.*)$ $1 break;

3 - the nginx log for the streaming.acme.com initially threw me, as it was still showing GET /something/emby/videos/458295/xxxx - and I assumed the rewrite would remove the something in the log......  but it is actually working - I will know when i see the end of the month email from CF - will I have used 400+ GB on their network this time - I hope not - as this will further prove the config.

4 - I used the swag docker (which includes nginx), and this also includes the swag dashboard - the swag dashboard expects to fine the below three variables that are then passed to the proxypass - however I found I had to duplicate horsepdf's set $emby_url http://192.168.1.201:8096; and proxy_pass $emby_url; for some reason - I have no idea why this did not work with the below (see commented proxypass) :

    location ~* ^/something/emby/videos/(.*)$ {
        set $emby_url http://192.168.1.201:8096;
        rewrite ^/something(.*)$ $1 break;
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
#        The three lines below are searched by the swag dashboard to show an active instance but this parameter based proxy_pass did not work with redirect settings.
        set $upstream_app 192.168.1.201;
        set $upstream_port 8096;
        set $upstream_proto http;
        proxy_pass $emby_url;
#       proxy_pass $upstream_proto://$upstream_app:$upstream_port;
        proxy_set_header Connection $http_connection;   # websockets
        proxy_set_header Range $http_range;
        proxy_set_header If-Range $http_if_range;
    }

5 - The notes state this - if you visit https://streaming.acme.com:port/, then nothing is returned (where previously you could access Emby outside of Cloudflare and directly via your router) - nginx returns a 404 (or if you prefer, set it to return code 444 which drops the connection without explanation).

But if you follow the notes as written, this is not the case and while it wont go to emby, if does go to the default 'nginx is configured' screen.  I would like to know how @HorsePDF is configuring the location to both allow this rewrite and at the same time block the direct connection.  Horse mentions - In my Nginx service, I drop any request immediately that is not a request to stream an Emby video file (e.g. the login page or any other API/page) - I would like to see this section of the proxy.

6 - I do not have a 'local' emby proxy set for nginX like horsePDF does - that config means if horse's nginX goes down, then he cant access emby in the house.  My clients on my LAN go direct to the emby server so they are not dependent on nginX.  Horse therefore directs his CF rewrite url back to nginX - but mine is direct to the emby server.

7 - From the notes, it sounds like @HorsePDFis ONLY hosting emby on nginX in this way - whereas many selfhosters will also house other systems that are reverse proxied - hence there is only one port forwarded to nginx - and it is 443. 

8 - While testing, I have found that a movie played on 5G over my iphone will stop playing after some time - maybe 10-15 mins.  This will be tested by the remote users.

 

For further reference, I added my usual nginx hardening things to the streaming.acme.com proxy in my setup such as :

    # Only requests to our Host are allowed - VW
    if ($host !~ ^(streaming.acme.com)$ ) {
    return 444;
    }

    #COUNTRY GEO BLOCK - VW
    #Add this back once configured as it was stopping local access testing as the $lan-ip override was not taking place 
    if ($allowed_country = no) {
    return 444;
    }

    # Disable any unwanted HTTP methods - VW
    if ($request_method !~ ^(GET|HEAD|POST|DELETE)$ ) {
    return 444;
    }

    # Deny certain Referrers - VW
    if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) )
    {  
    # return 404;
    return 403;   
    }

    ###################
    # Block Bots - VW #
    ###################
    include /config/nginx/security/block-blockedbots.conf;
#    include /config/nginx/security/block-data_collectors.conf; # google TV cant work with this
    include /config/nginx/security/block-devtools.conf;
    include /config/nginx/security/block-monitoring.conf;    
    include /config/nginx/security/block-scanners.conf; 
    include /config/nginx/security/block-search.conf;
    include /config/nginx/security/block-social.conf; 

    ##############################################################################################################
    # Custom Headers - see securityheaders.com - Repeated here in case ssl.conf is eplaced in a swag update - VW #
    ##############################################################################################################
    add_header 'Referrer-Policy' 'origin-when-cross-origin';
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Content-Security-Policy "default-src 'none'; child-src 'self'; font-src 'self' data:; connect-src 'self' wss: ws: https://mb3admin.com https://github.com/MediaBrowser/; media-src 'self' blob: data: https://github.com/MediaBrowser/; manifest-src 'self'; base-uri 'none'; form-action 'self'; frame-ancestors 'self'; object-src 'none'; worker-src 'self' blob:; script-src 'self' https://www.gstatic.com; img-src data: https: http: ; style-src 'unsafe-inline' 'self' https://fonts.googleapis.com/css" always;
    add_header  X-Robots-Tag "noindex, nofollow, nosnippet, noarchive";

  • Like 1
Link to comment
Share on other sites

vaise

Further to the above, I answered my own question and for the streaming.acme.com block on nginx, I added the location to return a 444 - drop connection, if anything other than something/emby/videos is matched :

    location ~* ^/something/emby/videos/(.*)$ {
        set $emby_url http://192.168.1.201:8096;
        rewrite ^/something(.*)$ $1 break;
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
#        The three lines below are searches for the swag dashboard to show an active instance but proxy_pass did not work with redirect.
        set $upstream_app 192.168.1.201;
        set $upstream_port 8096;
        set $upstream_proto http;
        proxy_pass $emby_url;
#       proxy_pass $upstream_proto://$upstream_app:$upstream_port;
        proxy_set_header Connection $http_connection;   # websockets
        proxy_set_header Range $http_range;
        proxy_set_header If-Range $http_if_range;
    }    
    location / {
        return 444;
    }

 

Link to comment
Share on other sites

vaise

And further more, I still wanted my remote testing and alerting to work for this (done by freshping), so I modded this slightly to allow freshping checks to get through - and nothing else.

    location / {
        if ( $http_user_agent ~ 'FreshpingBot/1.0' ) {
        return 200;
        }
        return 444;
    } 

 

Link to comment
Share on other sites

vaise

And hopefully my final edits / reconfig, I have now done the following :

1 - remove the /something that horsepdf put in, and made it a simple proxy redirect with no need to rewite the url - I also change the proxy name (and dns etc) to be embyredirect.acme.com.  The server block now looks like this which is much simpler and follows the normal SWAG defaults.  It allows only freshping to connect and terminates any other connections :

location ~* ^/emby/videos/(.*)$ {

                include /config/nginx/proxy.conf;

                include /config/nginx/resolver.conf;

                set $upstream_app 192.168.1.201;

                set $upstream_port 8096;

                set $upstream_proto http;

                proxy_pass $upstream_proto://$upstream_app:$upstream_port;

                proxy_set_header Connection $http_connection;   # websockets

                proxy_set_header Range $http_range;

                proxy_set_header If-Range $http_if_range;

}              

 

location / {

                if ( $http_user_agent ~ 'FreshpingBot/1.0' ) {

                return 200;

                }

                return 444;

}

 

2 - To facilitate this, I change the cloudflare re-direct and removed the /something - as not really needed (horsepdf mentions something about using this to inject authorisation) :

image.png.5d8ddd873c98719aafa579768603cb59.png

 

3 - I re-did the doco on this which was initially a direct copy of @HorsePDFpost which I elaborated on - so all credit to him for coming up with this idea.

In summary, I look forward to the CF email next month and hopefully see the traffic no-where near the 400-600GB I was putting through there - specially at the moment with reports that CF sales staff have been told to approach and review all accounts.  

  • Like 1
Link to comment
Share on other sites

  • 1 month later...
Shidapu

I've been off from Emby forums for a couple of years now, but i have been reading up on this thread lately.

My CF account is still not TOS capped, and my bandwidth usage fluctuates between 250GB-1TB per month.

What has changed personally the last year or so, has been my migration from ovpn.com to Njal.la. Since Njalla changes IP every day, i have automated it to reflect the IP change automatically to CF with Marcs Updater..

See screenshot of my cloudflare dns setup.

I have no idea if that has enabled me to continue using CF, or if im just lucky.

1260-157-max.png

Link to comment
Share on other sites

vaise
4 hours ago, Shidapu said:

I've been off from Emby forums for a couple of years now, but i have been reading up on this thread lately.

My CF account is still not TOS capped, and my bandwidth usage fluctuates between 250GB-1TB per month.

What has changed personally the last year or so, has been my migration from ovpn.com to Njal.la. Since Njalla changes IP every day, i have automated it to reflect the IP change automatically to CF with Marcs Updater..

See screenshot of my cloudflare dns setup.

I have no idea if that has enabled me to continue using CF, or if im just lucky.

1260-157-max.png

 

Its strange isn't it.......  Many people online say they removed that TOS section and now is fine - others say by stopping the caching you are fine (however its all still going through the CF CDN so many others say you are not), I don't know who is right for sure.  I will be moving my domain hosting out fo CF in case I ever get blocked regardless.

My ISP for the last 18 months has a fixed IP - and never TOS blocked either in the tons of years since using CF.

I use CF for my domain hosting also - plus two other domains - that was one idea why I was safe - of the fact that my domain is in the lower alphabet and they start at the A;s and work down ?

Who knows.

Now I and not putting the streaming stuff though them any more - using a slightly modified and easier method that horsepdf above - but same idia.  I now see MB per day instead of many GB :

image.png.3b6c107068b3cc805249bed691b15a96.png

Link to comment
Share on other sites

Shidapu
16 hours ago, vaise said:

 

Its strange isn't it.......  Many people online say they removed that TOS section and now is fine - others say by stopping the caching you are fine (however its all still going through the CF CDN so many others say you are not), I don't know who is right for sure.  I will be moving my domain hosting out fo CF in case I ever get blocked regardless.

My ISP for the last 18 months has a fixed IP - and never TOS blocked either in the tons of years since using CF.

I use CF for my domain hosting also - plus two other domains - that was one idea why I was safe - of the fact that my domain is in the lower alphabet and they start at the A;s and work down ?

Who knows.

Now I and not putting the streaming stuff though them any more - using a slightly modified and easier method that horsepdf above - but same idia.  I now see MB per day instead of many GB :

image.png.3b6c107068b3cc805249bed691b15a96.png

Alright, good idea with regards to worst case scenario..

I have only 1 domain with cloudflare, but multiple subdomains in the higher 10s, who knows why we both not affected yet.. But I'll be sure to post here the day that changes..
I used to have a fixed IP, but not since ovpn.com sold out to the US.

 

Link to comment
Share on other sites

HorsePDF

I'm glad you were able to get something from my post @vaise

I can answer some of your questions too:

  • I think I had an error in my configuration, so browsing other locations that are not intended to be public would not drop the connection, you are right.
    • I believe if you have your video location rewrite for your media above a simple `return 444;` then you will see the right behavior, but I don't have time to check right now.
  • You're right that my local traffic goes through nginx - this is partly so that I have the same URL for everything. Nginx handles my SSL, so putting traffic through that means my devices will use nginx directly when I am at home, and connection has a valid SSL certificate (split DNS)
    • I don't worry about nginx going down because I use docker swarm and the same nginx container is deployed to multiple hosts, and when updating the config if the new container does not start then it will roll back so there is zero interruption to anyone watching.
  • I host many things on nginx, but I use some port redirecting so that I can keep a separation between external and internal traffic and do clever things like this setup. This lets me use the same hostname but different ports,
    • However all client devices always use 443, and it is Cloudflare or Cloudflare tunnels that will do some changes e.g. Client -> Cloudflare 443 -> Tunnel -> Nginx 12345 -> Emby 8096
    • Internally this looks like Client -> Nginx 443 -> Emby 8096

 

I think aside from that, you found some small errors in my work so thank you very much for that 🙏

I hope our work can help others who are not able to stream via Cloudflare.

 

One thing I am curious about is why you removed the additional random path that I use for the streaming endpoint. I put this here so that if there is a vulnerability in Emby, attackers will not find anything at the expected path. It is definitely not necessary, but I feel it adds an extra barrier for very little cost given you are already writing redirect rules.

Basically it is to avoid vulnerable endpoints being scanned like you see below from my CF dashboard. 

image.png.49244beb982c697f6f35a944d1e375b7.png

 

  • Like 1
Link to comment
Share on other sites

vaise

There you are @HorsePDF, was not sure if you dropped the cool post, then exited the building 😄

I understand the reasoning for your setup now.  Much more elaborateb thhan mine.  Nginx for me is external only.  Only have one and if I am away, yes chance of issue from the family of they are not dependent on another network and emby.

re the ‘something’ endpoint, I have a. complicated fw setup on cf as used it  forever.  My logs are very clean :

The first rule blocks any incorrect hosts (so only emby.mydomain.com gets through (some others too).  The same rule blocks all scanners.  

The second rule blocks all irl paths that are not allowed (the ones you list, plus many more after trawling my logs for ages) and I update this with any others found.

Then I have an allow (skip) rule that only allows known emby uri paths (see my post in beta section re this), plus my country, And my emby host only, (This also does same for my home assistant, photos etc)

Then finally a block all (cf don’t have such, but a rule that blocks anything without a uripath = blockallfomhere.

my nginx is hardened with a few things too but no direct attacks there work based on config there.

Of course, if a hack originated in Australia, using my exact home, and an allowed /emby/ path then they would get through……  not much I can do about that.  See my post where I pointed out a few insecure endpoints for all this testing.

 

Link to comment
Share on other sites

vaise

Just to elaborate on my FW rules here :

image.png.1f026aa14060be95b1796b9e0ccdad12.png

I basically check (as the free plan does not allow for api/remote access to FW logs) for the following :

If rule 2 has any entries, then it means something has got through on the real subdomain i.e emby.mydomain.com, then it will start blocking any bots/uri paths on that.  This is very rare.

Rule 3 and 4 are 'allow' rules - hardened where possible for only the hosts access (known server name, known country, known uri path's, known network AS number etc etc)

Rule 5 is the catch all - i.e this only sees two things really :

1 - Incorrect countries access (often an iphone/ipad/laptop emby app on holiday by a friend/family) but passed the other tests before

2 - Incorrect port sniffing attacks (they seem to go for 2052, 2053, 2086, 2095, 8880, 8080, 8443).  I believe on the paid CF plans you can ONLY allow 80 and 443 which would be good but I have read that on the free plan, this is not working.  If i could add that to the blocks up top, then nothing scary/unknown would make it to the catch all. 

 

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...