Tutorial

Nuevas actualizaciones y mejoras para Macfleet.

Aviso importante

Los ejemplos de código y scripts proporcionados en estos tutoriales son solo para propósitos educativos. Macfleet no es responsable de ningún problema, daño o vulnerabilidad de seguridad que pueda surgir del uso, modificación o implementación de estos ejemplos. Siempre revisa y prueba el código en un entorno seguro antes de usarlo en sistemas de producción.

Browser Data Management and Privacy Compliance on macOS

Implement comprehensive browser data management and privacy compliance across your MacFleet devices. This tutorial covers multi-browser data clearing, privacy policy enforcement, data retention management, and automated compliance workflows for enterprise environments.

Understanding Browser Data Management

Browser data encompasses various types of user information:

  • Browsing history - Website visit records and timestamps
  • Cookies and local storage - Session data and user preferences
  • Cache files - Temporary web content and resources
  • Download history - File download records and metadata
  • Form data and passwords - Autofill information and credentials
  • Extensions and settings - Browser configuration and add-ons

Basic Browser History Clearing

Clear Google Chrome History

#!/bin/bash

# Clear Google Chrome browsing history
clear_chrome_history() {
    echo "=== Clearing Google Chrome History ==="
    
    # Get logged-in user
    local logged_user
    logged_user=$(stat -f%Su /dev/console 2>/dev/null)
    
    if [[ -z "$logged_user" || "$logged_user" == "root" ]]; then
        echo "❌ No active user session found"
        return 1
    fi
    
    echo "👤 Target user: $logged_user"
    
    # Chrome profile path
    local chrome_profile="/Users/$logged_user/Library/Application Support/Google/Chrome/Default"
    
    # Check if Chrome is installed and profile exists
    if [[ ! -d "$chrome_profile" ]]; then
        echo "⚠️  Chrome profile not found for user: $logged_user"
        return 1
    fi
    
    # Kill Chrome processes if running
    pkill -f "Google Chrome" 2>/dev/null
    sleep 2
    
    # Clear history file
    if sudo -u "$logged_user" rm -f "$chrome_profile/History" 2>/dev/null; then
        echo "✅ Chrome history cleared for user: $logged_user"
    else
        echo "❌ Failed to clear Chrome history"
        return 1
    fi
    
    return 0
}

# Execute function
clear_chrome_history

Clear Firefox History

#!/bin/bash

# Clear Firefox browsing history
clear_firefox_history() {
    echo "=== Clearing Firefox History ==="
    
    # Get logged-in user
    local logged_user
    logged_user=$(stat -f%Su /dev/console 2>/dev/null)
    
    if [[ -z "$logged_user" || "$logged_user" == "root" ]]; then
        echo "❌ No active user session found"
        return 1
    fi
    
    echo "👤 Target user: $logged_user"
    
    # Firefox profiles path
    local firefox_profiles="/Users/$logged_user/Library/Application Support/Firefox/Profiles"
    
    # Check if Firefox profiles exist
    if [[ ! -d "$firefox_profiles" ]]; then
        echo "⚠️  Firefox profiles not found for user: $logged_user"
        return 1
    fi
    
    # Kill Firefox processes if running
    pkill -f "firefox" 2>/dev/null
    sleep 2
    
    # Clear history from all Firefox profiles
    local profiles_cleared=0
    for profile_dir in "$firefox_profiles"/*; do
        if [[ -d "$profile_dir" ]]; then
            # Remove places.sqlite (contains history)
            if sudo -u "$logged_user" rm -f "$profile_dir/places.sqlite" 2>/dev/null; then
                profiles_cleared=$((profiles_cleared + 1))
                echo "✅ Cleared history for profile: $(basename "$profile_dir")"
            fi
        fi
    done
    
    if [[ $profiles_cleared -gt 0 ]]; then
        echo "✅ Firefox history cleared from $profiles_cleared profile(s)"
        return 0
    else
        echo "❌ Failed to clear Firefox history"
        return 1
    fi
}

# Execute function
clear_firefox_history

Enterprise Browser Data Management System

#!/bin/bash

# MacFleet Enterprise Browser Data Management System
# Comprehensive privacy compliance, data lifecycle management, and multi-browser support

# Configuration
LOG_FILE="/var/log/macfleet_browser_data.log"
CONFIG_DIR="/etc/macfleet/browser_management"
POLICIES_DIR="$CONFIG_DIR/policies"
REPORTS_DIR="$CONFIG_DIR/reports"
COMPLIANCE_DIR="$CONFIG_DIR/compliance"
BACKUP_DIR="/var/backups/browser_configs"

# Supported browsers and their data locations
declare -A BROWSER_PATHS=(
    ["chrome"]="/Library/Application Support/Google/Chrome"
    ["firefox"]="/Library/Application Support/Firefox"
    ["safari"]="/Library/Safari"
    ["edge"]="/Library/Application Support/Microsoft Edge"
    ["opera"]="/Library/Application Support/com.operasoftware.Opera"
    ["brave"]="/Library/Application Support/BraveSoftware/Brave-Browser"
    ["vivaldi"]="/Library/Application Support/Vivaldi"
)

# Browser data types and corresponding files
declare -A DATA_TYPES=(
    ["history"]="History,places.sqlite,History.db"
    ["cookies"]="Cookies,cookies.sqlite,Cookies.binarycookies"
    ["cache"]="Cache,cache2,WebKit/NetworkCache"
    ["downloads"]="Downloads,downloads.sqlite"
    ["passwords"]="Login Data,key4.db,logins.json"
    ["bookmarks"]="Bookmarks,bookmarks.sqlite,Bookmarks.plist"
    ["extensions"]="Extensions,extensions.sqlite,Extensions"
    ["settings"]="Preferences,prefs.js,com.apple.Safari.plist"
)

# Privacy policy templates
declare -A PRIVACY_POLICIES=(
    ["strict"]="clear_all_daily,no_persistent_cookies,history_retention_1day"
    ["moderate"]="clear_history_weekly,selective_cookies,history_retention_7days"
    ["lenient"]="clear_cache_monthly,allow_cookies,history_retention_30days"
    ["compliance"]="audit_all,encrypt_data,gdpr_compliance,history_retention_legal"
    ["education"]="clear_daily_schedule,safe_browsing,limited_downloads"
    ["healthcare"]="hipaa_compliant,no_data_retention,audit_all_access"
    ["finance"]="sox_compliant,encrypted_storage,detailed_audit"
)

# Compliance frameworks
declare -A COMPLIANCE_FRAMEWORKS=(
    ["gdpr"]="right_to_erasure,data_minimization,consent_required,audit_trails"
    ["hipaa"]="phi_protection,access_controls,audit_logs,encryption_required"
    ["sox"]="financial_data_protection,retention_policies,access_monitoring"
    ["coppa"]="child_privacy_protection,parental_consent,data_deletion"
    ["ccpa"]="california_privacy_rights,data_transparency,deletion_rights"
)

# Logging function
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Setup directories
setup_directories() {
    for dir in "$CONFIG_DIR" "$POLICIES_DIR" "$REPORTS_DIR" "$COMPLIANCE_DIR" "$BACKUP_DIR"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            log_action "Created directory: $dir"
        fi
    done
}

# Get all users with browser data
get_browser_users() {
    local users=()
    
    # Get all users with UID >= 500 (regular users)
    while IFS= read -r user; do
        local user_home
        user_home=$(dscl . read "/Users/$user" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
        
        if [[ -n "$user_home" && -d "$user_home" ]]; then
            # Check if user has any browser data
            for browser in "${!BROWSER_PATHS[@]}"; do
                local browser_path="$user_home${BROWSER_PATHS[$browser]}"
                if [[ -d "$browser_path" ]]; then
                    users+=("$user")
                    break
                fi
            done
        fi
    done < <(dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}')
    
    printf '%s\n' "${users[@]}"
}

# Detect installed browsers for a user
detect_user_browsers() {
    local username="$1"
    local user_home
    user_home=$(dscl . read "/Users/$username" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
    
    if [[ -z "$user_home" ]]; then
        return 1
    fi
    
    local installed_browsers=()
    
    for browser in "${!BROWSER_PATHS[@]}"; do
        local browser_path="$user_home${BROWSER_PATHS[$browser]}"
        if [[ -d "$browser_path" ]]; then
            installed_browsers+=("$browser")
        fi
    done
    
    printf '%s\n' "${installed_browsers[@]}"
}

# Clear specific browser data type
clear_browser_data() {
    local username="$1"
    local browser="$2"
    local data_type="$3"
    local backup="${4:-false}"
    
    log_action "Clearing $data_type from $browser for user: $username"
    
    local user_home
    user_home=$(dscl . read "/Users/$username" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
    
    if [[ -z "$user_home" ]]; then
        log_action "❌ User not found: $username"
        return 1
    fi
    
    local browser_path="$user_home${BROWSER_PATHS[$browser]}"
    
    if [[ ! -d "$browser_path" ]]; then
        log_action "⚠️  Browser $browser not found for user: $username"
        return 1
    fi
    
    # Kill browser processes
    case "$browser" in
        "chrome")
            pkill -f "Google Chrome" 2>/dev/null
            ;;
        "firefox")
            pkill -f "firefox" 2>/dev/null
            ;;
        "safari")
            pkill -f "Safari" 2>/dev/null
            ;;
        "edge")
            pkill -f "Microsoft Edge" 2>/dev/null
            ;;
        *)
            pkill -f "$browser" 2>/dev/null
            ;;
    esac
    
    sleep 2
    
    # Get data files for this type
    local data_files="${DATA_TYPES[$data_type]}"
    IFS=',' read -ra FILES <<< "$data_files"
    
    local cleared_count=0
    
    for file_pattern in "${FILES[@]}"; do
        # Find and process matching files
        while IFS= read -r -d '' file; do
            if [[ -f "$file" || -d "$file" ]]; then
                # Backup if requested
                if [[ "$backup" == "true" ]]; then
                    backup_browser_data "$username" "$browser" "$file"
                fi
                
                # Clear the data
                if sudo -u "$username" rm -rf "$file" 2>/dev/null; then
                    cleared_count=$((cleared_count + 1))
                    log_action "✅ Cleared: $file"
                else
                    log_action "❌ Failed to clear: $file"
                fi
            fi
        done < <(find "$browser_path" -name "$file_pattern" -print0 2>/dev/null)
    done
    
    log_action "Cleared $cleared_count data files for $data_type in $browser"
    return 0
}

# Comprehensive browser data audit
audit_browser_data() {
    log_action "Starting comprehensive browser data audit"
    
    local audit_report="$REPORTS_DIR/browser_audit_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$audit_report" << EOF
{
    "audit_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "os_version": "$(sw_vers -productVersion)",
        "generator": "MacFleet Browser Data Manager"
    },
    "user_browser_data": [
EOF

    local first=true
    local total_users=0
    local users_with_data=0
    
    # Audit each user
    for user in $(get_browser_users); do
        total_users=$((total_users + 1))
        users_with_data=$((users_with_data + 1))
        
        if [[ "$first" == true ]]; then
            first=false
        else
            echo "," >> "$audit_report"
        fi
        
        local user_home
        user_home=$(dscl . read "/Users/$user" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
        
        local user_browsers
        user_browsers=$(detect_user_browsers "$user")
        
        # Analyze data for each browser
        local browser_data="["
        local browser_first=true
        
        for browser in $user_browsers; do
            if [[ "$browser_first" == true ]]; then
                browser_first=false
            else
                browser_data+=","
            fi
            
            local data_analysis
            data_analysis=$(analyze_browser_data "$user" "$browser")
            
            browser_data+="{\"browser\": \"$browser\", \"data\": $data_analysis}"
        done
        
        browser_data+="]"
        
        cat >> "$audit_report" << EOF
        {
            "username": "$user",
            "user_home": "$user_home",
            "browsers": $browser_data,
            "last_login": "$(last -1 "$user" | head -1 | awk '{print $4, $5, $6, $7}' || echo 'Never')",
            "privacy_risk_score": $(calculate_privacy_risk "$user")
        }
EOF
        
        log_action "Audited user: $user"
    done
    
    cat >> "$audit_report" << EOF
    ],
    "summary": {
        "total_users": $total_users,
        "users_with_browser_data": $users_with_data,
        "supported_browsers": $(echo "${!BROWSER_PATHS[@]}" | tr ' ' '\n' | jq -R . | jq -s .),
        "data_types_monitored": $(echo "${!DATA_TYPES[@]}" | tr ' ' '\n' | jq -R . | jq -s .)
    }
}
EOF

    log_action "✅ Browser data audit completed: $audit_report"
    echo "$audit_report"
}

# Analyze browser data for a specific user and browser
analyze_browser_data() {
    local username="$1"
    local browser="$2"
    
    local user_home
    user_home=$(dscl . read "/Users/$username" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
    local browser_path="$user_home${BROWSER_PATHS[$browser]}"
    
    local data_summary="{"
    local type_first=true
    
    for data_type in "${!DATA_TYPES[@]}"; do
        if [[ "$type_first" == true ]]; then
            type_first=false
        else
            data_summary+=","
        fi
        
        local file_count=0
        local total_size=0
        
        local data_files="${DATA_TYPES[$data_type]}"
        IFS=',' read -ra FILES <<< "$data_files"
        
        for file_pattern in "${FILES[@]}"; do
            while IFS= read -r -d '' file; do
                if [[ -f "$file" ]]; then
                    file_count=$((file_count + 1))
                    local size
                    size=$(stat -f%z "$file" 2>/dev/null || echo 0)
                    total_size=$((total_size + size))
                elif [[ -d "$file" ]]; then
                    file_count=$((file_count + 1))
                    local size
                    size=$(du -sk "$file" 2>/dev/null | awk '{print $1*1024}' || echo 0)
                    total_size=$((total_size + size))
                fi
            done < <(find "$browser_path" -name "$file_pattern" -print0 2>/dev/null)
        done
        
        data_summary+="\"$data_type\": {\"file_count\": $file_count, \"total_size_bytes\": $total_size}"
    done
    
    data_summary+="}"
    echo "$data_summary"
}

# Calculate privacy risk score for a user
calculate_privacy_risk() {
    local username="$1"
    local risk_score=0
    
    # Analyze data retention and privacy risks
    local user_browsers
    user_browsers=$(detect_user_browsers "$username")
    
    for browser in $user_browsers; do
        local data_analysis
        data_analysis=$(analyze_browser_data "$username" "$browser")
        
        # Simple risk calculation based on data volume
        local history_size
        history_size=$(echo "$data_analysis" | jq -r '.history.total_size_bytes // 0')
        
        if [[ $history_size -gt 10485760 ]]; then  # > 10MB
            risk_score=$((risk_score + 3))
        elif [[ $history_size -gt 1048576 ]]; then  # > 1MB
            risk_score=$((risk_score + 2))
        elif [[ $history_size -gt 0 ]]; then
            risk_score=$((risk_score + 1))
        fi
    done
    
    # Cap at 10
    if [[ $risk_score -gt 10 ]]; then
        risk_score=10
    fi
    
    echo "$risk_score"
}

# Apply privacy policy to users
apply_privacy_policy() {
    local policy_name="$1"
    local target_users="$2"
    
    log_action "Applying privacy policy: $policy_name"
    
    local policy_config="${PRIVACY_POLICIES[$policy_name]}"
    if [[ -z "$policy_config" ]]; then
        log_action "❌ Unknown privacy policy: $policy_name"
        return 1
    fi
    
    # Get target users
    local users=()
    if [[ -n "$target_users" ]]; then
        IFS=',' read -ra users <<< "$target_users"
    else
        while IFS= read -r user; do
            users+=("$user")
        done < <(get_browser_users)
    fi
    
    # Parse policy configuration
    IFS=',' read -ra POLICY_RULES <<< "$policy_config"
    
    for user in "${users[@]}"; do
        log_action "Applying policy '$policy_name' to user: $user"
        
        for rule in "${POLICY_RULES[@]}"; do
            case "$rule" in
                "clear_all_daily")
                    schedule_daily_cleanup "$user" "all"
                    ;;
                "clear_history_weekly")
                    schedule_weekly_cleanup "$user" "history"
                    ;;
                "clear_cache_monthly")
                    schedule_monthly_cleanup "$user" "cache"
                    ;;
                "no_persistent_cookies")
                    clear_browser_data "$user" "all" "cookies"
                    ;;
                "audit_all")
                    enable_comprehensive_audit "$user"
                    ;;
                "gdpr_compliance")
                    configure_gdpr_compliance "$user"
                    ;;
                "hipaa_compliant")
                    configure_hipaa_compliance "$user"
                    ;;
            esac
        done
        
        log_action "✅ Policy applied to user: $user"
    done
    
    return 0
}

# Schedule automated cleanup
schedule_daily_cleanup() {
    local username="$1"
    local data_type="$2"
    
    log_action "Scheduling daily cleanup for user: $username, data: $data_type"
    
    # Create LaunchAgent for user
    local launch_agent_path="/Users/$username/Library/LaunchAgents/com.macfleet.browser-cleanup.plist"
    
    cat > "$launch_agent_path" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.macfleet.browser-cleanup</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/macfleet-browser-cleanup</string>
        <string>--user</string>
        <string>$username</string>
        <string>--data-type</string>
        <string>$data_type</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>2</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
    <key>RunAtLoad</key>
    <false/>
</dict>
</plist>
EOF
    
    chown "$username:staff" "$launch_agent_path"
    log_action "✅ Daily cleanup scheduled for user: $username"
}

# Generate compliance report
generate_compliance_report() {
    local framework="$1"
    
    log_action "Generating compliance report for framework: $framework"
    
    local compliance_report="$COMPLIANCE_DIR/compliance_${framework}_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$compliance_report" << EOF
{
    "compliance_metadata": {
        "timestamp": "$(date -Iseconds)",
        "framework": "$framework",
        "hostname": "$(hostname)",
        "generator": "MacFleet Browser Compliance Manager"
    },
    "compliance_assessment": {
        "framework_requirements": $(get_framework_requirements "$framework"),
        "current_status": $(assess_compliance_status "$framework"),
        "recommendations": $(generate_compliance_recommendations "$framework"),
        "risk_assessment": $(calculate_compliance_risk "$framework")
    },
    "user_compliance": [
EOF

    local first=true
    
    # Assess compliance for each user
    for user in $(get_browser_users); do
        if [[ "$first" == true ]]; then
            first=false
        else
            echo "," >> "$compliance_report"
        fi
        
        local user_compliance
        user_compliance=$(assess_user_compliance "$user" "$framework")
        
        cat >> "$compliance_report" << EOF
        {
            "username": "$user",
            "compliance_status": $user_compliance
        }
EOF
    done
    
    cat >> "$compliance_report" << EOF
    ]
}
EOF

    log_action "✅ Compliance report generated: $compliance_report"
    echo "$compliance_report"
}

# Get framework requirements
get_framework_requirements() {
    local framework="$1"
    
    case "$framework" in
        "gdpr")
            echo '{"data_minimization": true, "right_to_erasure": true, "consent_required": true, "audit_trails": true}'
            ;;
        "hipaa")
            echo '{"phi_protection": true, "access_controls": true, "audit_logs": true, "encryption_required": true}'
            ;;
        "sox")
            echo '{"financial_data_protection": true, "retention_policies": true, "access_monitoring": true}'
            ;;
        "coppa")
            echo '{"child_privacy_protection": true, "parental_consent": true, "data_deletion": true}'
            ;;
        *)
            echo '{"general_privacy": true, "basic_audit": true}'
            ;;
    esac
}

# Assess compliance status
assess_compliance_status() {
    local framework="$1"
    
    local compliance_score=0
    local total_checks=0
    
    # Check basic privacy controls
    total_checks=$((total_checks + 1))
    if [[ -f "$POLICIES_DIR/privacy_policy.conf" ]]; then
        compliance_score=$((compliance_score + 1))
    fi
    
    # Check audit logging
    total_checks=$((total_checks + 1))
    if [[ -f "$LOG_FILE" ]]; then
        compliance_score=$((compliance_score + 1))
    fi
    
    # Framework-specific checks
    case "$framework" in
        "gdpr")
            total_checks=$((total_checks + 2))
            # Check data retention policies
            if [[ -f "$POLICIES_DIR/data_retention.conf" ]]; then
                compliance_score=$((compliance_score + 1))
            fi
            # Check consent management
            if [[ -f "$POLICIES_DIR/consent_management.conf" ]]; then
                compliance_score=$((compliance_score + 1))
            fi
            ;;
        "hipaa")
            total_checks=$((total_checks + 1))
            # Check encryption
            if system_profiler SPStorageDataType | grep -q "Encrypted: Yes"; then
                compliance_score=$((compliance_score + 1))
            fi
            ;;
    esac
    
    local compliance_percentage
    compliance_percentage=$(awk "BEGIN {printf \"%.0f\", ($compliance_score/$total_checks)*100}")
    
    echo "{\"score\": $compliance_score, \"total_checks\": $total_checks, \"percentage\": $compliance_percentage, \"status\": \"$([ $compliance_percentage -ge 80 ] && echo 'compliant' || echo 'non_compliant')\"}"
}

# Assess user compliance
assess_user_compliance() {
    local username="$1"
    local framework="$2"
    
    local privacy_risk
    privacy_risk=$(calculate_privacy_risk "$username")
    
    local compliance_status="compliant"
    if [[ $privacy_risk -gt 7 ]]; then
        compliance_status="high_risk"
    elif [[ $privacy_risk -gt 4 ]]; then
        compliance_status="medium_risk"
    fi
    
    echo "{\"privacy_risk_score\": $privacy_risk, \"status\": \"$compliance_status\"}"
}

# Backup browser data before clearing
backup_browser_data() {
    local username="$1"
    local browser="$2"
    local data_path="$3"
    
    local timestamp
    timestamp=$(date '+%Y%m%d_%H%M%S')
    local backup_file="$BACKUP_DIR/browser_backup_${username}_${browser}_${timestamp}.tar.gz"
    
    if tar -czf "$backup_file" -C "$(dirname "$data_path")" "$(basename "$data_path")" 2>/dev/null; then
        log_action "✅ Browser data backed up: $backup_file"
        echo "$backup_file"
    else
        log_action "❌ Failed to backup browser data: $data_path"
        return 1
    fi
}

# Main execution function
main() {
    local action="${1:-audit}"
    local parameter="$2"
    local additional_param="$3"
    local extra_param="$4"
    
    log_action "=== MacFleet Browser Data Management Started ==="
    log_action "Action: $action"
    log_action "Parameter: ${parameter:-N/A}"
    
    setup_directories
    
    case "$action" in
        "clear")
            if [[ -z "$parameter" || -z "$additional_param" ]]; then
                echo "Usage: $0 clear <browser> <data_type> [username] [backup]"
                echo "Browsers: ${!BROWSER_PATHS[*]}"
                echo "Data types: ${!DATA_TYPES[*]}"
                exit 1
            fi
            local target_user="${extra_param:-$(stat -f%Su /dev/console 2>/dev/null)}"
            clear_browser_data "$target_user" "$parameter" "$additional_param" "${5:-false}"
            ;;
        "audit")
            audit_browser_data
            ;;
        "policy")
            if [[ -z "$parameter" ]]; then
                echo "Available privacy policies:"
                for policy in "${!PRIVACY_POLICIES[@]}"; do
                    echo "  - $policy: ${PRIVACY_POLICIES[$policy]}"
                done
                echo ""
                echo "Usage: $0 policy <policy_name> [target_users]"
                exit 1
            fi
            apply_privacy_policy "$parameter" "$additional_param"
            ;;
        "compliance")
            if [[ -z "$parameter" ]]; then
                echo "Available compliance frameworks:"
                for framework in "${!COMPLIANCE_FRAMEWORKS[@]}"; do
                    echo "  - $framework: ${COMPLIANCE_FRAMEWORKS[$framework]}"
                done
                echo ""
                echo "Usage: $0 compliance <framework>"
                exit 1
            fi
            generate_compliance_report "$parameter"
            ;;
        "detect")
            local target_user="${parameter:-$(stat -f%Su /dev/console 2>/dev/null)}"
            echo "Browsers detected for user '$target_user':"
            detect_user_browsers "$target_user"
            ;;
        *)
            echo "Usage: $0 {clear|audit|policy|compliance|detect}"
            echo "  clear       - Clear specific browser data"
            echo "  audit       - Generate comprehensive browser data audit"
            echo "  policy      - Apply privacy policy to users"
            echo "  compliance  - Generate compliance report"
            echo "  detect      - Detect installed browsers for user"
            exit 1
            ;;
    esac
    
    log_action "=== Browser data management completed ==="
}

# Execute main function
main "$@"

Advanced Browser Management Features

Multi-Browser Data Analysis

#!/bin/bash

# Comprehensive multi-browser data analysis
analyze_all_browsers() {
    echo "=== Multi-Browser Data Analysis ==="
    
    local analysis_report="$REPORTS_DIR/browser_analysis_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$analysis_report" << EOF
{
    "analysis_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)"
    },
    "browser_usage_analysis": {
EOF

    local browser_first=true
    
    # Analyze each supported browser
    for browser in "${!BROWSER_PATHS[@]}"; do
        if [[ "$browser_first" == true ]]; then
            browser_first=false
        else
            echo "," >> "$analysis_report"
        fi
        
        local users_with_browser=0
        local total_data_size=0
        
        # Count users and data size for this browser
        for user in $(get_browser_users); do
            local user_browsers
            user_browsers=$(detect_user_browsers "$user")
            
            if echo "$user_browsers" | grep -q "^$browser$"; then
                users_with_browser=$((users_with_browser + 1))
                
                local browser_data
                browser_data=$(analyze_browser_data "$user" "$browser")
                
                # Sum up data sizes
                for data_type in "${!DATA_TYPES[@]}"; do
                    local size
                    size=$(echo "$browser_data" | jq -r ".$data_type.total_size_bytes // 0")
                    total_data_size=$((total_data_size + size))
                done
            fi
        done
        
        cat >> "$analysis_report" << EOF
        "$browser": {
            "users_count": $users_with_browser,
            "total_data_size_bytes": $total_data_size,
            "average_data_per_user": $(( users_with_browser > 0 ? total_data_size / users_with_browser : 0 ))
        }
EOF
    done
    
    cat >> "$analysis_report" << EOF
    }
}
EOF

    echo "📊 Browser analysis completed: $analysis_report"
}

Automated Privacy Cleanup

#!/bin/bash

# Automated privacy cleanup based on data age and policy
automated_privacy_cleanup() {
    local retention_days="${1:-7}"
    local dry_run="${2:-false}"
    
    echo "=== Automated Privacy Cleanup ==="
    echo "Retention period: $retention_days days"
    echo "Dry run: $dry_run"
    
    local cleanup_report="$REPORTS_DIR/privacy_cleanup_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$cleanup_report" << EOF
{
    "cleanup_metadata": {
        "timestamp": "$(date -Iseconds)",
        "retention_days": $retention_days,
        "dry_run": $dry_run
    },
    "cleanup_results": [
EOF

    local first=true
    local total_cleaned=0
    
    # Process each user
    for user in $(get_browser_users); do
        local user_home
        user_home=$(dscl . read "/Users/$user" NFSHomeDirectory 2>/dev/null | awk '{print $2}')
        
        for browser in $(detect_user_browsers "$user"); do
            local browser_path="$user_home${BROWSER_PATHS[$browser]}"
            
            # Find old data files
            while IFS= read -r -d '' file; do
                local file_age_days
                file_age_days=$(( ($(date +%s) - $(stat -f%m "$file")) / 86400 ))
                
                if [[ $file_age_days -gt $retention_days ]]; then
                    if [[ "$first" == true ]]; then
                        first=false
                    else
                        echo "," >> "$cleanup_report"
                    fi
                    
                    cat >> "$cleanup_report" << EOF
        {
            "user": "$user",
            "browser": "$browser",
            "file": "$file",
            "age_days": $file_age_days,
            "action": "$([ "$dry_run" == "true" ] && echo "would_delete" || echo "deleted")"
        }
EOF
                    
                    if [[ "$dry_run" != "true" ]]; then
                        if sudo -u "$user" rm -rf "$file" 2>/dev/null; then
                            total_cleaned=$((total_cleaned + 1))
                        fi
                    fi
                fi
            done < <(find "$browser_path" -type f -print0 2>/dev/null)
        done
    done
    
    cat >> "$cleanup_report" << EOF
    ],
    "summary": {
        "total_files_processed": $total_cleaned
    }
}
EOF

    echo "🧹 Privacy cleanup completed: $cleanup_report"
}

Best Practices

🔒 Privacy and Security

  • Data minimization principles with automated cleanup policies
  • Consent management for data collection and processing
  • Encryption standards for sensitive browser data
  • Access controls with role-based data management permissions

📋 Compliance Management

  • Multi-framework support (GDPR, HIPAA, SOX, COPPA, CCPA)
  • Automated compliance assessment with regular auditing
  • Data retention policies aligned with legal requirements
  • Audit trails with comprehensive logging and reporting

🔧 Enterprise Operations

  • Fleet-wide deployment of privacy policies and data management
  • Scheduled cleanup operations with customizable retention periods
  • Backup and recovery capabilities for browser configurations
  • Integration support with existing security and compliance systems

🚀 User Experience

  • Non-disruptive operations with browser process management
  • Selective data clearing preserving important user preferences
  • Transparent reporting on data management activities
  • Flexible policy application based on user roles and requirements

Important Notes

  • Browser compatibility varies across different applications and versions
  • User data backup recommended before implementing aggressive cleanup policies
  • Performance impact minimal when operations are scheduled during off-hours
  • Legal compliance requirements vary by jurisdiction and industry
  • User notification may be required for certain data management activities
  • Regular policy review needed to adapt to changing privacy regulations

Tutorial

Nuevas actualizaciones y mejoras para Macfleet.

Configurando un Runner de GitHub Actions en un Mac Mini (Apple Silicon)

Runner de GitHub Actions

GitHub Actions es una plataforma poderosa de CI/CD que te permite automatizar tus flujos de trabajo de desarrollo de software. Aunque GitHub ofrece runners hospedados, los runners auto-hospedados proporcionan mayor control y personalización para tu configuración de CI/CD. Este tutorial te guía a través de la configuración y conexión de un runner auto-hospedado en un Mac mini para ejecutar pipelines de macOS.

Prerrequisitos

Antes de comenzar, asegúrate de tener:

  • Un Mac mini (regístrate en Macfleet)
  • Un repositorio de GitHub con derechos de administrador
  • Un gestor de paquetes instalado (preferiblemente Homebrew)
  • Git instalado en tu sistema

Paso 1: Crear una Cuenta de Usuario Dedicada

Primero, crea una cuenta de usuario dedicada para el runner de GitHub Actions:

# Crear la cuenta de usuario 'gh-runner'
sudo dscl . -create /Users/gh-runner
sudo dscl . -create /Users/gh-runner UserShell /bin/bash
sudo dscl . -create /Users/gh-runner RealName "GitHub runner"
sudo dscl . -create /Users/gh-runner UniqueID "1001"
sudo dscl . -create /Users/gh-runner PrimaryGroupID 20
sudo dscl . -create /Users/gh-runner NFSHomeDirectory /Users/gh-runner

# Establecer la contraseña para el usuario
sudo dscl . -passwd /Users/gh-runner tu_contraseña

# Agregar 'gh-runner' al grupo 'admin'
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Cambia a la nueva cuenta de usuario:

su gh-runner

Paso 2: Instalar Software Requerido

Instala Git y Rosetta 2 (si usas Apple Silicon):

# Instalar Git si no está ya instalado
brew install git

# Instalar Rosetta 2 para Macs Apple Silicon
softwareupdate --install-rosetta

Paso 3: Configurar el Runner de GitHub Actions

  1. Ve a tu repositorio de GitHub
  2. Navega a Configuración > Actions > Runners

Runner de GitHub Actions

  1. Haz clic en "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Selecciona macOS como imagen del runner y ARM64 como arquitectura
  3. Sigue los comandos proporcionados para descargar y configurar el runner

Runner de GitHub Actions

Crea un archivo .env en el directorio _work del runner:

# archivo _work/.env
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Ejecuta el script run.sh en tu directorio del runner para completar la configuración.
  2. Verifica que el runner esté activo y escuchando trabajos en la terminal y revisa la configuración del repositorio de GitHub para la asociación del runner y el estado Idle.

Runner de GitHub Actions

Paso 4: Configurar Sudoers (Opcional)

Si tus acciones requieren privilegios de root, configura el archivo sudoers:

sudo visudo

Agrega la siguiente línea:

gh-runner ALL=(ALL) NOPASSWD: ALL

Paso 5: Usar el Runner en Flujos de Trabajo

Configura tu flujo de trabajo de GitHub Actions para usar el runner auto-hospedado:

name: Flujo de trabajo de muestra

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: [self-hosted, macOS, ARM64]
    steps:
      - name: Instalar NodeJS
        run: brew install node

El runner está autenticado en tu repositorio y etiquetado con self-hosted, macOS, y ARM64. Úsalo en tus flujos de trabajo especificando estas etiquetas en el campo runs-on:

runs-on: [self-hosted, macOS, ARM64]

Mejores Prácticas

  • Mantén tu software del runner actualizado
  • Monitorea regularmente los logs del runner para problemas
  • Usa etiquetas específicas para diferentes tipos de runners
  • Implementa medidas de seguridad apropiadas
  • Considera usar múltiples runners para balanceo de carga

Solución de Problemas

Problemas comunes y soluciones:

  1. Runner no conectando:

    • Verifica conectividad de red
    • Verifica validez del token de GitHub
    • Asegúrate de permisos apropiados
  2. Fallas de construcción:

    • Verifica instalación de Xcode
    • Verifica dependencias requeridas
    • Revisa logs del flujo de trabajo
  3. Problemas de permisos:

    • Verifica permisos de usuario
    • Verifica configuración de sudoers
    • Revisa permisos del sistema de archivos

Conclusión

Ahora tienes un runner auto-hospedado de GitHub Actions configurado en tu Mac mini. Esta configuración te proporciona más control sobre tu entorno de CI/CD y te permite ejecutar flujos de trabajo específicos de macOS de manera eficiente.

Recuerda mantener regularmente tu runner y mantenerlo actualizado con los últimos parches de seguridad y versiones de software.

Aplicación Nativa

Aplicación nativa de Macfleet

Guía de Instalación de Macfleet

Macfleet es una solución poderosa de gestión de flota diseñada específicamente para entornos de Mac Mini alojados en la nube. Como proveedor de hosting en la nube de Mac Mini, puedes usar Macfleet para monitorear, gestionar y optimizar toda tu flota de instancias Mac virtualizadas.

Esta guía de instalación te llevará a través de la configuración del monitoreo de Macfleet en sistemas macOS, Windows y Linux para asegurar una supervisión integral de tu infraestructura en la nube.

🍎 macOS

  • Descarga el archivo .dmg para Mac aquí
  • Haz doble clic en el archivo .dmg descargado
  • Arrastra la aplicación Macfleet a la carpeta Aplicaciones
  • Expulsa el archivo .dmg
  • Abre Preferencias del Sistema > Seguridad y Privacidad
    • Pestaña Privacidad > Accesibilidad
    • Marca Macfleet para permitir el monitoreo
  • Inicia Macfleet desde Aplicaciones
  • El seguimiento comienza automáticamente

🪟 Windows

  • Descarga el archivo .exe para Windows aquí
  • Haz clic derecho en el archivo .exe > "Ejecutar como administrador"
  • Sigue el asistente de instalación
  • Acepta los términos y condiciones
  • Permite en Windows Defender si se solicita
  • Concede permisos de monitoreo de aplicaciones
  • Inicia Macfleet desde el Menú Inicio
  • La aplicación comienza el seguimiento automáticamente

🐧 Linux

  • Descarga el paquete .deb (Ubuntu/Debian) o .rpm (CentOS/RHEL) aquí
  • Instala usando tu gestor de paquetes
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Permite permisos de acceso X11 si se solicita
  • Agrega el usuario a los grupos apropiados si es necesario
  • Inicia Macfleet desde el menú de Aplicaciones
  • La aplicación comienza el seguimiento automáticamente

Nota: Después de la instalación en todos los sistemas, inicia sesión con tus credenciales de Macfleet para sincronizar datos con tu panel de control.