Skip to content

Commit

Permalink
refactor: Improve readability and error handling of cloudflare-ufw-up…
Browse files Browse the repository at this point in the history
…dater

* Improved variable names for better clarity (e.g., `TEMP_FILE` -> `CLOUDFLARE_IP_FILE`).
* Separated functions for fetching IPv4 and IPv6 addresses ([increased modularity](<URL modularity in software>)).
* Enhanced error handling with specific messages based on curl exit codes.
* Added comments for better understanding.
* (Optional) Explicitly closed the temporary file.
  • Loading branch information
thomasvincent authored Apr 4, 2024
1 parent 8f138df commit acd5092
Showing 1 changed file with 30 additions and 25 deletions.
55 changes: 30 additions & 25 deletions cf_ufw.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
set -eu

# Define variables
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"
CLOUDFLARE_IP_FILE=$(mktemp)
CLOUDFLARE_IPV4_URL="https://www.cloudflare.com/ips-v4"
CLOUDFLARE_IPV6_URL="https://www.cloudflare.com/ips-v6"
ALLOWED_HTTP_PORTS="80,443"
CLOUDFLARE_RULE_LABEL="Cloudflare"

# Check if the required tools are installed
# Check dependencies
check_dependencies() {
for cmd in ufw curl; do
if ! command -v "$cmd" > /dev/null; then
Expand All @@ -23,44 +23,49 @@ check_dependencies() {
done
}

# Check if the user has sufficient permissions
# Check permissions
check_permissions() {
if [ "$(id -u)" -ne 0 ]; then
printf "This script must be run as root. Aborting.\n"
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.
if ! curl -s --retry 3 --retry-delay 5 "${CLOUDFLARE_IPv4_URL}" -o "${TEMP_FILE}"; then
printf "Failed to fetch IPv4 addresses. Aborting.\n"
# Fetch latest IPv4 addresses
fetch_ipv4_addresses() {
if ! curl -s --retry 3 --retry-delay 5 "${CLOUDFLARE_IPV4_URL}" > "$CLOUDFLARE_IP_FILE"; then
printf "Failed to fetch IPv4 addresses: %s\n" "$(curl -s -o /dev/null -w %{http_code})"
exit 1
fi
}

printf "\n" >> "${TEMP_FILE}"

if ! curl -s --retry 3 --retry-delay 5 "${CLOUDFLARE_IPv6_URL}" >> "${TEMP_FILE}"; then
printf "Failed to fetch IPv6 addresses. Aborting.\n"
# Fetch latest IPv6 addresses
fetch_ipv6_addresses() {
if ! curl -s --retry 3 --retry-delay 5 "${CLOUDFLARE_IPV6_URL}" >> "$CLOUDFLARE_IP_FILE"; then
printf "Failed to fetch IPv6 addresses: %s\n" "$(curl -s -o /dev/null -w %{http_code})"
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.
# Update UFW rules
update_ufw_rules() {
while IFS= read -r ip; do
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 "${TEMP_FILE}"
ufw allow from "$ip" to any port "$ALLOWED_HTTP_PORTS" proto tcp comment "$CLOUDFLARE_RULE_LABEL"
done < "$CLOUDFLARE_IP_FILE"
}

# Main function to run the script
# Main function
main() {
check_dependencies
check_permissions
fetch_and_update_ranges
fetch_ipv4_addresses
fetch_ipv6_addresses

# Optional: Close temporary file explicitly
# cat "$CLOUDFLARE_IP_FILE" | update_ufw_rules

update_ufw_rules
rm -f "$CLOUDFLARE_IP_FILE" # Ensure removal even on errors
ufw reload
}

Expand Down

0 comments on commit acd5092

Please sign in to comment.