WPCloudDeploy / wp-cloud-deploy

WPCloudDeploy is a WordPress plugin that allows you to easily deploy and manage your own dedicated high-performance WordPress servers and sites at any cloud server provider.
https://wpclouddeploy.com
Other
91 stars 42 forks source link

Feature Request: Cloudflare Tunnel Support #80

Open batonac opened 1 year ago

batonac commented 1 year ago

Hey team, congrats on making it to 5.1!

Okay, this might be a bit "far out", but I've known this team to be ambitious, so here goes...

Cloudflare Tunnels are free. This allows a server to serve websites directly through Cloudflare without allowing any other ingress HTTP/HTTPS traffic. This translates to no direct external traffic to your machine that doesn't first pass through Cloudflare WAF (with the exception of SSH for WPCD, of course).

Additionally, this provides a secure way for the web the server to serve to Cloudflare using HTTP rather than HTTPS, avoiding the overhead of SSL, and the maintenance liability of certificate management and renewals. Cloudflare provides and manages public-facing certificates on your behalf, so no problems there.

Taken a step further, both the webserver and the Cloudflare Tunnel could be configured to connect to each other through a Unix socket, further eliminating overhead and latency caused by the TCP/IP stack.

By my estimations, this should be the most efficient way to run a web server behind Cloudflare, and should be a boon for both server performance and security.

I doubt that any other competing solutions are doing this, and probably wouldn't for some time (if ever). This could be a real differentiator for WPCD!

-- *Nginx, at least, can be configured to serve to a unix socket instead of a port with syntax like listen unix:/tmp/site-name.sock;. I'm not sure about OLS. *The syntax for connecting a Cloudflare Tunnel to a unix socket can be found here.

batonac commented 1 year ago

Oh, and in a Proxmox/OpenStack scenario, this should allow for servers using private IP addresses, eliminating the cost and hassle of provisioning public IP addresses for ever server, assuming that the WPCD site and servers are in the same private IP subnet and can communicate directly that way. This could mean even more security since all incoming external traffic could be blocked on the WPCD servers. 😯

elindydotcom commented 1 year ago

It's a cool idea but I don't think this is something that we can expect to be done anytime soon.

(Plus I shudder to think about the support level that would be required if this was added and a user didn't quite understand what pushing the button did or accidentally triggered it and they suddenly lost access to their servers.)

batonac commented 1 year ago

BTW, I have this working with a manual config under WPCD NGINX, following the instructions on the Cloudflare guide, with a bit of community guidance, and my own finagling:

  1. Install the correct package for Cloudflare: wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && dpkg -i cloudflared-linux-amd64.deb

  2. Enabling a tunnel (this would be the most difficult part to facilitate with WPCD, but doable):

    • mkdir /etc/cloudflared/
    • cloudflared tunnel login This command returns a link that needs to be followed for authorizing the connection to a particular site, which could presumably be passed back to the WPCD session for completing the activation.
    • cloudflared tunnel create <WPCD-Site>
    • cloudflared tunnel route dns <WPCD-Site> <Domain> --overwrite-dns This sets up a new cname mapping to <Tunnel-UUID>.cfargotunnel.com, which is how the DNS is configured within Cloudflare.

NOTE: Much of this step could be done manually with the Cloudflare Dashboard as well, but inclusion into WPCD would be swell.

  1. Enable the systemd service:

    • cloudflared service install
    • systemctl enable --now cloudflared
  2. Configure the following files (with sites-specific configs replaced with <> tags):

/etc/nginx/userconfigs/site/<WPCD-Site>-cloudflared.conf:

listen unix:/var/www/<WPCD-Site>.sock;

/etc/cloudflared/config.yml:

unix-socket: /var/www/<WPCD-Site>.sock
tunnel: <Tunnel-UUID>
credentials-file: /etc/cloudflared/<Tunnel-UUID>.json

Cloudflared complained about some systemctl parameters, so I setup /etc/sysctl.d/10-udp-recieve-buffer-size.conf:

net.core.rmem_max=2500000
net.core.wmem_max=2500000

From there, I could direct the site to the Tunnel ID in Cloudflare, set Cloudflare Encryption to "Flexible", and turn off HTTPS for the app in WPCD. WordPress didn't seem to like the HTTP to HTTPS handover though, and was leading to infinite redirect loops and mixed content until I added this directive to wp-config.php (props to the community forum):

if ( $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' )
{
    $_SERVER['HTTPS']       = 'on';
    $_SERVER['SERVER_PORT'] = 443;
}

To verify that everything was working correctly, I ran ufw deny 80 and ufw deny 443 on the server, and verified that the ports are blocked to incoming traffic. The site works and runs great on the frontend!

UPDATES:

11/21/2022: Nginx fails to restart if the .sock file already exists. I updated the .sock files location to /var/www/ (might be a better location...) and updated the Nginx service file to remove any existing .sock files before trying to restart: mkdir -p /etc/systemd/system/nginx.service.d/ echo $'[Service]\nExecStartPre=/bin/su -s /bin/sh -c "/bin/rm -f /var/www/*.sock"' > /etc/systemd/system/nginx.service.d/rm-sock.conf systemctl daemon-reload

elindydotcom commented 1 year ago

That is cool. Will have to try it out one of these days.

batonac commented 1 year ago

Here's an enhanced snippet for wp-config.php:

if ( $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' )
{
    $_SERVER['HTTPS']       = 'on';
    $_SERVER['SERVER_PORT'] = 443;
}
batonac commented 1 year ago

(Plus I shudder to think about the support level that would be required if this was added and a user didn't quite understand what pushing the button did or accidentally triggered it and they suddenly lost access to their servers.)

My suggestion would be to make it a two-step process where the user enables the tunnel through WPCD, and is then given the tunnel address that they can use for their site's DNS cname (and possibly add it as another copy-able line below the site's IP address). That way, the user needs to explicitly switch the site over if that's what they want to do.

If they really want to block port 80 and 443, that should be their own choice, as a completely separate step...

batonac commented 1 year ago

Another possible advantage of this that could impact all types of users, BTW, would be the ability to do quick/seamless server migrations and restorations, and possibly even fail-over, without needing to change the DNS (as long as the tunnel ID can follow the site between WPCD servers).

Just dreaming...