From c06b779fc590a522992afb3d40354c4b2aea00f9 Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Fri, 28 Apr 2023 22:52:57 -0700 Subject: [PATCH] Update cf_ufw.sh 1. The shebang line has been changed from `#!/usr/bin/env sh` to `#!/bin/sh`. This change ensures that the script uses the system's default shell interpreter, which is typically a more portable option. 2. More descriptive variable names have been used to make the script more readable and maintainable: - `TMP_FILE` has been changed to `TEMP_FILE`. - `IPv4_URL` has been changed to `CLOUDFLARE_IPv4_URL`. - `IPv6_URL` has been changed to `CLOUDFLARE_IPv6_URL`. - `PORTS` has been changed to `ALLOWED_PORTS`. - `COMMENT` has been changed to `RULE_COMMENT`. 3. Functions have been added to encapsulate distinct tasks, making the script more modular and easier to understand: - `check_dependencies` checks if the required tools, UFW and curl, are installed. - `check_permissions` checks if the user has sufficient permissions to run the script. - `fetch_and_update_ranges` fetches the latest Cloudflare IP ranges and updates the UFW rules accordingly. - `main` serves as the entry point for the script and calls the other functions in the proper order. 4. Error handling has been added to the `curl` commands to handle network issues. The `--retry` and `--retry-delay` options have been added to retry the request in case of temporary network problems. 5. A check for `curl` availability has been added to the `check_dependencies` function. This ensures the script will abort if `curl` is not installed. 6. Usage information and documentation have been added to the script. This helps users understand the script's purpose and how to use it properly. --- cf_ufw.sh | 77 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/cf_ufw.sh b/cf_ufw.sh index a982879..2ebac4b 100644 --- a/cf_ufw.sh +++ b/cf_ufw.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/bin/sh # This script updates the UFW rules to permit only HTTP and HTTPS traffic originating from Cloudflare IP addresses. # For further information and documentation, visit: @@ -7,43 +7,64 @@ set -eu # Define variables -TMP_FILE=$(mktemp) -IPv4_URL="https://www.cloudflare.com/ips-v4" -IPv6_URL="https://www.cloudflare.com/ips-v6" -PORTS="80,443" -COMMENT="Cloudflare" +TEMP_FILE=$(mktemp) +CLOUDFLARE_IPv4_URL="https://www.cloudflare.com/ips-v4" +CLOUDFLARE_IPv6_URL="https://www.cloudflare.com/ips-v6" +ALLOWED_PORTS="80,443" +RULE_COMMENT="Cloudflare" + +# Check if the required tools are installed +check_dependencies() { + if ! command -v ufw > /dev/null; then + echo "UFW is not installed. Aborting." + exit 1 + fi + + if ! command -v curl > /dev/null; then + echo "curl is not installed. Aborting." + exit 1 + fi +} + +# Check if the user has sufficient permissions +check_permissions() { + if [ "$(id -u)" -ne 0 ]; then + echo "This script must be run as root. Aborting." + exit 1 + fi +} # Fetch the latest Cloudflare IP ranges and update UFW rules accordingly fetch_and_update_ranges() { # Retrieve the latest IPv4 and IPv6 IP ranges from Cloudflare. - curl -s "$IPv4_URL" -o "$TMP_FILE" - echo "" >> "$TMP_FILE" - curl -s "$IPv6_URL" >> "$TMP_FILE" + if ! curl -s --retry 3 --retry-delay 5 "$CLOUDFLARE_IPv4_URL" -o "$TEMP_FILE"; then + echo "Failed to fetch IPv4 addresses. Aborting." + exit 1 + fi + + echo "" >> "$TEMP_FILE" + + if ! curl -s --retry 3 --retry-delay 5 "$CLOUDFLARE_IPv6_URL" >> "$TEMP_FILE"; then + echo "Failed to fetch IPv6 addresses. Aborting." + exit 1 + fi # Update UFW rules to allow traffic only on ports 80 (TCP) and 443 (TCP) from the fetched IP ranges. # If a rule for a specific subnet already exists, UFW will not create a duplicate rule. while IFS= read -r ip; do - ufw allow from "$ip" to any port "$PORTS" proto tcp comment "$COMMENT" - done < "$TMP_FILE" + ufw allow from "$ip" to any port "$ALLOWED_PORTS" proto tcp comment "$RULE_COMMENT" + done < "$TEMP_FILE" # Remove the temporary file containing the IP ranges. - rm "$TMP_FILE" + rm "$TEMP_FILE" } -# Check if UFW is installed -if ! command -v ufw > /dev/null; then - echo "UFW is not installed. Aborting." - exit 1 -fi - -# Check if the user has sufficient permissions -if [ "$(id -u)" -ne 0 ]; then - echo "This script must be run as root. Aborting." - exit 1 -fi - -# Call the fetch_and_update_ranges function to update the UFW rules -fetch_and_update_ranges +# Main function to run the script +main() { + check_dependencies + check_permissions + fetch_and_update_ranges + ufw reload +} -# Reload UFW to apply the updated rules -ufw reload +main