Last active
August 11, 2025 12:56
-
-
Save Sly777/949cd21d6b33f699e79e237d7fd82d72 to your computer and use it in GitHub Desktop.
Removing UFW Rules by domain-based check
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # UFW Domain Rules Remover - Centralized Domain Configuration | |
| # Removes domain-based UFW rules with configurable patterns | |
| # ============================================================================= | |
| # CONFIGURATION - UPDATE THIS SECTION TO ADD/REMOVE DOMAINS | |
| # ============================================================================= | |
| # Domain patterns to match in UFW rule comments | |
| # Add or remove patterns here - they will be used throughout the script | |
| DOMAIN_PATTERNS=( | |
| "GitHub" # Matches: GitHub HTTPS, GitHub API, GitHub Raw Content, etc. | |
| "Debian" # Matches: Debian Repo, Debian Security, Debian FTP, etc. | |
| "Cloudflare" # Matches: Cloudflare Tunnel, Cloudflare API, etc. | |
| "Pushover" # Matches: Pushover API | |
| "Crowdsec" # Matches: CrowdSec API & Hub | |
| ) | |
| # Build grep pattern from array (don't modify this) | |
| GREP_PATTERN=$(IFS='|'; echo "(${DOMAIN_PATTERNS[*]})") | |
| # ============================================================================= | |
| # SCRIPT VARIABLES - NO NEED TO MODIFY BELOW THIS LINE | |
| # ============================================================================= | |
| # Colors | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' | |
| # Global variables | |
| VERBOSE=false | |
| FORCE=false | |
| SCRIPT_NAME=$(basename "$0") | |
| print_color() { | |
| echo -e "${1}${2}${NC}" | |
| } | |
| # Show help information | |
| show_help() { | |
| echo "UFW Domain Rules Removal Script" | |
| echo "Removes domain-based UFW rules matching configured patterns" | |
| echo "" | |
| echo "Current domain patterns:" | |
| for pattern in "${DOMAIN_PATTERNS[@]}"; do | |
| echo " • $pattern" | |
| done | |
| echo "" | |
| echo "Usage: sudo $SCRIPT_NAME [OPTIONS]" | |
| echo "" | |
| echo "OPTIONS:" | |
| echo " -h, --help Show this help message" | |
| echo " -v, --verbose Show detailed output for all operations" | |
| echo " -f, --force Delete without interactive confirmation" | |
| echo " -d, --debug Show rules that would be deleted (dry run)" | |
| echo "" | |
| echo "Examples:" | |
| echo " sudo $SCRIPT_NAME # Interactive mode (default)" | |
| echo " sudo $SCRIPT_NAME --verbose # Show all deletion details" | |
| echo " sudo $SCRIPT_NAME --force # No confirmation prompts" | |
| echo " sudo $SCRIPT_NAME --force --verbose # Force with detailed output" | |
| echo " sudo $SCRIPT_NAME --debug # Preview what would be deleted" | |
| echo "" | |
| echo "Notes:" | |
| echo " • Creates automatic backup before deletion" | |
| echo " • Failed deletions are always shown" | |
| echo " • Successful deletions only shown with --verbose" | |
| echo " • Requires root privileges (use sudo)" | |
| echo "" | |
| echo "To add/remove domains: Edit DOMAIN_PATTERNS array at top of script" | |
| } | |
| # Parse command line arguments | |
| parse_arguments() { | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -h|--help) | |
| show_help | |
| exit 0 | |
| ;; | |
| -v|--verbose) | |
| VERBOSE=true | |
| shift | |
| ;; | |
| -f|--force) | |
| FORCE=true | |
| shift | |
| ;; | |
| -d|--debug) | |
| debug_mode | |
| exit 0 | |
| ;; | |
| *) | |
| print_color "$RED" "Unknown option: $1" | |
| echo "Use --help for usage information" | |
| exit 1 | |
| ;; | |
| esac | |
| done | |
| } | |
| # Debug mode - show what would be deleted | |
| debug_mode() { | |
| print_color "$BLUE" "=== DEBUG MODE - Preview Only ===" | |
| print_color "$YELLOW" "Looking for rules matching patterns: ${DOMAIN_PATTERNS[*]}" | |
| print_color "$YELLOW" "Grep pattern: $GREP_PATTERN" | |
| echo "" | |
| local domain_rules=$(ufw status numbered | grep -E "$GREP_PATTERN") | |
| if [[ -z "$domain_rules" ]]; then | |
| print_color "$GREEN" "No domain-based rules found." | |
| return | |
| fi | |
| print_color "$YELLOW" "Rules that would be deleted:" | |
| echo "$domain_rules" | |
| local rule_count=$(echo "$domain_rules" | wc -l) | |
| print_color "$BLUE" "\nTotal rules that would be deleted: $rule_count" | |
| print_color "$BLUE" "To actually delete these rules, run without --debug" | |
| } | |
| # Check if running as root | |
| check_root() { | |
| if [[ $EUID -ne 0 ]]; then | |
| print_color "$RED" "This script must be run as root" | |
| print_color "$YELLOW" "Usage: sudo $SCRIPT_NAME [OPTIONS]" | |
| print_color "$YELLOW" "Use --help for more information" | |
| exit 1 | |
| fi | |
| } | |
| # Create backup | |
| create_backup() { | |
| local backup_file="/tmp/ufw-backup-$(date +%Y%m%d-%H%M%S).txt" | |
| if [[ "$VERBOSE" == true ]]; then | |
| print_color "$BLUE" "Creating backup..." | |
| fi | |
| ufw status numbered > "$backup_file" | |
| print_color "$GREEN" "Backup saved: $backup_file" | |
| return 0 | |
| } | |
| # Show current rules and find domain rules | |
| show_and_find_rules() { | |
| if [[ "$VERBOSE" == true ]]; then | |
| print_color "$BLUE" "=== Current UFW Rules ===" | |
| ufw status numbered | |
| echo "" | |
| fi | |
| print_color "$BLUE" "=== Searching for Domain Rules ===" | |
| print_color "$YELLOW" "Patterns: ${DOMAIN_PATTERNS[*]}" | |
| echo "" | |
| local domain_rules=$(ufw status numbered | grep -E "$GREP_PATTERN") | |
| if [[ -z "$domain_rules" ]]; then | |
| print_color "$GREEN" "No domain-based rules found." | |
| return 1 | |
| fi | |
| print_color "$BLUE" "=== Domain Rules Found ===" | |
| echo "$domain_rules" | |
| return 0 | |
| } | |
| # Interactive confirmation | |
| get_confirmation() { | |
| if [[ "$FORCE" == true ]]; then | |
| print_color "$YELLOW" "Force mode: Skipping confirmation" | |
| return 0 | |
| fi | |
| print_color "$RED" "\n⚠️ WARNING: This will delete the domain rules shown above!" | |
| read -p "Continue? (yes/no): " confirm | |
| if [[ "$confirm" != "yes" ]]; then | |
| print_color "$GREEN" "Operation cancelled." | |
| exit 0 | |
| fi | |
| read -p "Type 'DELETE' to confirm: " final_confirm | |
| if [[ "$final_confirm" != "DELETE" ]]; then | |
| print_color "$GREEN" "Operation cancelled." | |
| exit 0 | |
| fi | |
| return 0 | |
| } | |
| # Perform the deletion | |
| perform_deletion() { | |
| print_color "$BLUE" "\n=== Starting Deletion ===" | |
| # Get the current UFW status and store it (to avoid multiple calls) | |
| local ufw_status=$(ufw status numbered) | |
| # Get rule numbers for domain rules (in reverse order) | |
| local rule_numbers=$(echo "$ufw_status" | grep -E "$GREP_PATTERN" | awk '{print $1}' | tr -d '[]' | sort -nr) | |
| if [[ -z "$rule_numbers" ]]; then | |
| print_color "$GREEN" "No rules to delete." | |
| return 0 | |
| fi | |
| local deleted_count=0 | |
| local failed_count=0 | |
| for rule_num in $rule_numbers; do | |
| if [[ "$rule_num" =~ ^[0-9]+$ ]]; then | |
| # Get rule text for logging | |
| local rule_text=$(ufw status numbered | grep "^$$rule_num$" || echo "Rule $rule_num") | |
| # Always show what we're about to delete in verbose mode | |
| if [[ "$VERBOSE" == true ]]; then | |
| print_color "$YELLOW" "Deleting rule #$rule_num..." | |
| print_color "$BLUE" " $rule_text" | |
| fi | |
| # Delete the rule | |
| if ufw --force delete "$rule_num" >/dev/null 2>&1; then | |
| if [[ "$VERBOSE" == true ]]; then | |
| print_color "$GREEN" " ✓ Deleted successfully" | |
| fi | |
| ((deleted_count++)) | |
| else | |
| # Always show failures, regardless of verbose mode | |
| print_color "$RED" "✗ Failed to delete rule #$rule_num" | |
| print_color "$RED" " $rule_text" | |
| ((failed_count++)) | |
| fi | |
| # Brief pause to let UFW update | |
| sleep 0.2 | |
| fi | |
| done | |
| # Summary | |
| print_color "$GREEN" "\n=== Deletion Complete ===" | |
| print_color "$GREEN" "Successfully deleted: $deleted_count rules" | |
| if [[ $failed_count -gt 0 ]]; then | |
| print_color "$RED" "Failed to delete: $failed_count rules" | |
| fi | |
| # Show updated rules if we deleted anything | |
| if [[ $deleted_count -gt 0 ]] && [[ "$VERBOSE" == true ]]; then | |
| print_color "$BLUE" "\n=== Updated UFW Rules ===" | |
| ufw status numbered | |
| fi | |
| return 0 | |
| } | |
| # Main function | |
| main() { | |
| # Parse arguments first | |
| parse_arguments "$@" | |
| # Check permissions | |
| check_root | |
| # Create backup | |
| create_backup | |
| # Show rules and check if any domain rules exist | |
| if ! show_and_find_rules; then | |
| exit 0 | |
| fi | |
| # Get confirmation (unless force mode) | |
| get_confirmation | |
| # Perform deletion | |
| perform_deletion | |
| print_color "$BLUE" "\nBackup location: /tmp/ufw-backup-*.txt" | |
| if [[ "$VERBOSE" != true ]]; then | |
| print_color "$YELLOW" "Tip: Use --verbose flag to see detailed deletion output" | |
| fi | |
| print_color "$YELLOW" "To modify domain patterns, edit DOMAIN_PATTERNS array in script" | |
| } | |
| # Run main function with all arguments | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment