Cloudflare Worker solution with port knock-like functionality for time-limited access to public-facing services like an SSLVPN portal
1. Authenticate client requests for time-limited access to a protected service
2. Produce a real-time IP allow list for a security device like a firewall to consume
1. Clients run to authenticate against the Cloudflare Worker to receive time-limited access to the desired resource
- A firewall that supports external IP threat feeds (most do, including Cisco, Palo Alto, Fortinet)
- A Cloudflare account (https://www.cloudflare.com/)
- Don't have one? This solution can be deployed to even a free account!
NOTE: Naming within these instructions assume you are protecting an SSLVPN service. Adjust the names if desired.
- Log in to your Cloudflare dashboard, choose your account, select "Storage & Databases" and click "KV."
- Click "Create a namespace," enter "SSLUSERS" for the name, and click "Add."
- Click "Create a namespace," enter "SSLAUTHORIZED" for the name, and click "Add."
- Now click on "Overview" below the "Workers & Pages" menu option.
- Click "Create application"
- Click the "Create Worker" button
- Enter "vpn-auth" for the name and click "Deploy"
- IMPORTANT: Make note of the URL shown on the Congratulations page under, "Preview your worker."
- It will look something like https://vpn-auth.organization.workers.dev
- You will need this URL to set up the Canary webhook
- Click "Configure Worker"
- Click "Settings" above the summary section of the page
- Click the "Variables" menu option
- Under "Variables and Secrets" click "Add" and select "Secret" for the Type
- Enter "VPNAUTH" for the variable name and enter a pre-shared key of your choosing for the value (all authorized VPN users will need in order to authenticate to this service)
- Under "KV Namespace Bindings" click "Add binding"
- Enter "SSLUSERS" for the variable name and select "SSLUSERS" for the KV namespace
- Click "Save and deploy"
- Again, click "Add binding"
- Enter "SSLAUTHORIZED" for the variable name and select "SSLAUTHORIZED" for the KV namespace
- Click "Save and deploy"
- Click on the "Quick Edit" button at the top right area of the page
- Copy and paste the full contents of the vpn-knocking.js file into the editor window
- Click "Save and deploy."
- Click "Create application"
- Click the "Create Worker" button
- Enter "vpn-allowlist" for the name and click "Deploy"
- IMPORTANT: Make note of the URL shown on the Congratulations page under, "Preview your worker."
- It will look something like https://vpn-allowlist.organization.workers.dev
- You will need this URL for the security device (eg. firewall) or program that will be consuming this IP list
- Click "Configure Worker"
- Click "Settings" above the summary section of the page
- Click the "Variables" menu option
- Under "KV Namespace Bindings" click "Add binding"
- Enter "SSLAUTHORIZED" for the variable name and select "SSLAUTHORIZED" for the KV namespace
- Click "Save and deploy"
- Click on the "Quick Edit" button at the top right area of the page
- Copy and paste the full contents of the vpn-allowlist.js file into the editor window
- Edit the AllowedIPs string variable to include only IP addresses that should be permitted to retrieve the IP blocklist and click "Save and deploy."
- Log in to your security device
- Configure an external threat list
- Set the source to the allowlist worker (https://vpn-allowlist.organization.workers.dev in this example)
- No authentication is necessary, as the requests are filtered to only permitted IPs
- Set the fetch interval to 1 minute or 60 seconds
- Apply this IP list to your SSLVPN portal allow rule
- It is recommended to also add a static IP group or list that should always have access to the SSLVPN service
- Download SSLVPNAuth.ps1 to a Windows computer (Windows 10 1803 and later, as curl.exe is required)
- Right-click the downloaded file, click "Properties"
- Click "Unblock," then "OK"
- Run SSLVPNAuth.ps1, entering a valid username and pre-shared key, and base URI (https://vpn-auth.organization.workers.dev for this example) when prompted
- The PowerShell script will then complete a request and return the result
- If authentication was successful, the client IP address should be added to the allowlist within 2 minutes
- Attempt an SSLVPN connection to verify functionality
- Download SSLVPNAuth.sh to a MacOS computer
- In a terminal, navigate to the location of the SSLVPNAuth.sh script, then run:
chmod +x SSLVPNAuth.sh
- Run SSLVPNAuth.sh, entering a valid username and pre-shared key, and base URI (https://vpn-auth.organization.workers.dev for this example) when prompted
- The shell script will then complete a request and return the result
- If authentication was successful, the client IP address should be added to the allowlist within 2 minutes
- Attempt an SSLVPN connection to verify functionality
I have a user that entered the wrong authentication details when running the PowerShell script and now they are rate-limited and cannot attempt to authenticate for another 8 hours!
- IP addresses can be manually added to the SSLAUTHORIZED KV store within the Cloudflare dashboard under, "Storage & Databases"
- Be sure to remove this entry manually at the end of the day, as it is not automatically pruned in 8 hours
- This KV store can also be used to add persistent allowed IPs as desired -- Manual entires do not expire
- This solution assumes we are dealing with IPv4. To allow IPv6 client addresses, simply remove the "-4" immediately following the curl.exe command in each of the client scripts.
- Change the TTL values found on lines 44 and 68 in vpn-knocking.js