# Sophos XGS Firewall Fleet Management with Ansible A production-ready Ansible project for automated configuration and management of Sophos XGS firewall fleets via API. ## Features - **Complete Network Configuration**: Interfaces, VLANs, DHCP, DNS, routing - **Firewall Rules Management**: Layer 3/4 rules with explicit ordering - **VPN Configuration**: Site-to-site IPsec and remote access SSL VPN - **Web Application Firewall**: Backend servers, policies, virtual hosts, and exceptions - **Device Access Control**: Management service restrictions per zone - **Monitoring & Logging**: SNMP, syslog, and NTP configuration - **Baseline Import**: Export WAF configuration from a baseline firewall to seed other devices - **Idempotent Operations**: Safe to run repeatedly without unwanted changes - **CI/CD Ready**: Designed for automation pipelines ## Project Structure ``` sophos-xgs-ansible/ ├── site.yml # Main playbook ├── baseline_import.yml # Import WAF config from baseline firewall ├── ansible.cfg # Ansible configuration ├── inventory/ │ ├── hosts.ini # Firewall inventory │ ├── group_vars/ # Group-level variables │ │ ├── all.yml │ │ ├── sophos_firewalls.yml │ │ └── baseline_web.yml # Baseline WAF config (auto-generated) │ └── host_vars/ # Per-firewall configuration │ ├── fw-baseline.yml │ ├── fw-branch1.yml │ └── fw-branch2.yml ├── roles/ # Configuration roles │ ├── sophos_common/ │ ├── sophos_network/ │ ├── sophos_firewall_rules/ │ ├── sophos_vpn_site_to_site/ │ ├── sophos_vpn_remote_access/ │ ├── sophos_waf/ │ ├── sophos_device_access/ │ └── sophos_snmp_logging/ └── collections/ └── requirements.yml # Required Ansible collections ``` ## Prerequisites ### Software Requirements - **Ansible**: Version 2.14 or higher - **Python**: Version 3.8 or higher - **Network Access**: HTTPS connectivity to Sophos XGS management interface (port 4444) ### Sophos XGS Requirements - **Firmware Version**: 19.x or 20.x (tested versions) - **API Access**: Enabled on the firewall - **Credentials**: Admin username/password or API key for each firewall ## Installation ### 1. Clone or Create Project Directory ```bash mkdir -p sophos-xgs-ansible cd sophos-xgs-ansible ``` ### 2. Install Required Ansible Collections ```bash ansible-galaxy collection install -r collections/requirements.yml ``` ### 3. Configure Inventory Edit `inventory/hosts.ini` to add your firewalls: ```ini [sophos_firewalls] fw-branch1 ansible_host=192.168.10.1 fw-branch2 ansible_host=192.168.20.1 [sophos_baseline] fw-baseline ansible_host=192.168.1.10 ``` ### 4. Configure Authentication For each firewall, create a host_vars file with credentials: ```yaml # inventory/host_vars/fw-branch1.yml sophos_mgmt_host: "192.168.10.1" sophos_api_username: "admin" sophos_api_password: "YourSecurePassword" # Use Ansible Vault in production ``` **IMPORTANT**: In production, encrypt sensitive variables with Ansible Vault: ```bash ansible-vault encrypt inventory/host_vars/fw-branch1.yml ``` ## Usage ### Basic Configuration Deployment Apply all configuration to all firewalls: ```bash ansible-playbook -i inventory/hosts.ini site.yml ``` ### Target Specific Firewalls Configure only one firewall: ```bash ansible-playbook -i inventory/hosts.ini site.yml --limit fw-branch1 ``` ### Apply Specific Configuration Areas Use tags to apply only certain configurations: ```bash # Configure only network settings ansible-playbook -i inventory/hosts.ini site.yml --tags network # Configure only firewall rules ansible-playbook -i inventory/hosts.ini site.yml --tags firewall # Configure only VPN settings ansible-playbook -i inventory/hosts.ini site.yml --tags vpn # Configure only WAF ansible-playbook -i inventory/hosts.ini site.yml --tags waf ``` ### Dry-Run Mode (Check Mode) Preview changes without applying them: ```bash ansible-playbook -i inventory/hosts.ini site.yml --check ``` ### Using Ansible Vault If you encrypted sensitive files: ```bash ansible-playbook -i inventory/hosts.ini site.yml --ask-vault-pass ``` Or use a vault password file: ```bash ansible-playbook -i inventory/hosts.ini site.yml --vault-password-file ~/.vault_pass ``` ## Baseline Import Workflow The baseline import feature allows you to export WAF configuration from an already-configured firewall and use it as the default for other firewalls. ### Step 1: Identify Baseline Firewall Ensure your baseline firewall is defined in `inventory/hosts.ini`: ```ini [sophos_baseline] fw-baseline ansible_host=192.168.1.10 ``` ### Step 2: Configure Baseline Firewall Create `inventory/host_vars/fw-baseline.yml` with connection details: ```yaml sophos_mgmt_host: "192.168.1.10" sophos_api_username: "admin" sophos_api_password: "BaselinePassword" ``` ### Step 3: Run Baseline Import Export WAF configuration from the baseline firewall: ```bash ansible-playbook -i inventory/hosts.ini baseline_import.yml ``` This will: - Connect to `fw-baseline` - Retrieve all WAF configuration (backends, policies, virtual hosts, exceptions) - Transform the data into structured YAML - Write the output to `inventory/group_vars/baseline_web.yml` ### Step 4: Review Generated Baseline Inspect the generated file: ```bash cat inventory/group_vars/baseline_web.yml ``` ### Step 5: Commit to Version Control ```bash git add inventory/group_vars/baseline_web.yml git commit -m "Import baseline WAF configuration from fw-baseline" git push ``` ### Step 6: Apply Baseline to Other Firewalls Run the main playbook to apply the baseline WAF configuration to all firewalls: ```bash ansible-playbook -i inventory/hosts.ini site.yml --tags waf ``` Individual firewalls can override or extend the baseline by defining their own `sophos_waf_*` variables in their host_vars files. ## Configuration Variables All configuration is data-driven through YAML variables. See `group_vars_schema.md` for complete documentation of all available variables. ### Variable Hierarchy Variables are loaded in this order (later overrides earlier): 1. `inventory/group_vars/all.yml` - Global defaults 2. `inventory/group_vars/sophos_firewalls.yml` - All Sophos firewalls 3. `inventory/group_vars/baseline_web.yml` - Baseline WAF config (auto-generated) 4. `inventory/host_vars/.yml` - Per-firewall overrides ### Key Variable Categories - **Network**: `sophos_interfaces`, `sophos_vlans`, `sophos_dhcp_servers`, `sophos_dns`, `sophos_static_routes` - **Firewall Rules**: `sophos_firewall_rules`, `sophos_common_firewall_rules` - **Site-to-Site VPN**: `sophos_site_to_site_vpns` - **Remote Access VPN**: `sophos_remote_access_vpn` - **WAF**: `sophos_waf_backends`, `sophos_waf_policies`, `sophos_waf_virtual_hosts`, `sophos_waf_exceptions` - **Device Access**: `sophos_common_device_access_policies` - **Monitoring**: `sophos_snmp`, `sophos_logging`, `sophos_ntp` ## Examples ### Example: Add a New VLAN Edit `inventory/host_vars/fw-branch1.yml`: ```yaml sophos_vlans: - name: "VLAN50-IoT" vlan_id: 50 parent_interface: "Port2" zone: "LAN" description: "IoT Devices" ip_address: "10.10.50.1" netmask: "255.255.255.0" enabled: true ``` Apply the change: ```bash ansible-playbook -i inventory/hosts.ini site.yml --limit fw-branch1 --tags vlans ``` ### Example: Add a Firewall Rule Edit `inventory/host_vars/fw-branch1.yml`: ```yaml sophos_firewall_rules: - name: "Allow-IoT-to-Internet" source_zones: ["LAN"] dest_zones: ["WAN"] source_networks: ["10.10.50.0/24"] dest_networks: ["any"] services: ["HTTP", "HTTPS"] action: "accept" log: true enabled: true description: "Allow IoT devices Internet access" ``` Apply the change: ```bash ansible-playbook -i inventory/hosts.ini site.yml --limit fw-branch1 --tags firewall ``` ### Example: Add a Site-to-Site VPN Edit `inventory/host_vars/fw-branch3.yml`: ```yaml sophos_site_to_site_vpns: - name: "Branch3-to-HQ" enabled: true local_gateway: "198.51.100.30" local_networks: ["10.30.0.0/16"] remote_gateway: "203.0.113.1" remote_networks: ["10.0.0.0/16"] psk: "YourPreSharedKey123" # Use Vault! description: "VPN tunnel to headquarters" ``` Apply the change: ```bash ansible-playbook -i inventory/hosts.ini site.yml --limit fw-branch3 --tags vpn ``` ## CI/CD Integration This project is designed for CI/CD pipelines. Example GitLab CI pipeline: ```yaml # .gitlab-ci.yml stages: - validate - plan - apply variables: ANSIBLE_FORCE_COLOR: "true" validate: stage: validate script: - ansible-lint site.yml - ansible-playbook site.yml --syntax-check plan: stage: plan script: - ansible-playbook -i inventory/hosts.ini site.yml --check --diff only: - merge_requests apply: stage: apply script: - ansible-playbook -i inventory/hosts.ini site.yml only: - main when: manual ``` ## Security Best Practices ### 1. Encrypt Sensitive Data Always use Ansible Vault for credentials: ```bash ansible-vault create inventory/host_vars/fw-branch1.yml ``` ### 2. Use Read-Only Accounts Where Possible For read-only operations (like gathering facts), consider using limited-privilege accounts. ### 3. Restrict API Access On each Sophos firewall: - Enable API access only from trusted management networks - Use strong, unique passwords - Consider using API keys instead of username/password ### 4. Version Control - Commit all configuration to Git - Use pull requests for changes - Require code review before merging - Never commit unencrypted passwords ### 5. Audit Logging All changes made via this automation are logged by Sophos XGS. Review logs regularly: ```bash ansible-playbook -i inventory/hosts.ini site.yml | tee deployment-$(date +%Y%m%d-%H%M%S).log ``` ## Troubleshooting ### Connection Issues **Problem**: Cannot connect to firewall **Solution**: 1. Verify network connectivity: `ping ` 2. Check firewall API port: `nc -zv 4444` 3. Verify credentials in host_vars 4. Check firewall device access rules (allow HTTPS from your management IP) ### Authentication Failures **Problem**: "401 Unauthorized" or "403 Forbidden" **Solution**: 1. Verify username/password in host_vars 2. Check if API access is enabled on the firewall 3. Verify the API user has sufficient privileges ### Idempotency Issues **Problem**: Playbook shows "changed" every run **Solution**: 1. Check role tasks for proper `changed_when` conditions 2. Verify API responses are being parsed correctly 3. Review templates for dynamic content (timestamps, etc.) ### Timeout Errors **Problem**: API calls timing out **Solution**: 1. Increase `sophos_api_timeout` in group_vars/all.yml 2. Check firewall CPU/memory usage 3. Reduce `sophos_serial_execution` to configure fewer firewalls simultaneously ### SSL Certificate Validation **Problem**: SSL certificate verification failures **Solution**: Set `sophos_validate_certs: false` in group_vars/all.yml (lab environments only). In production, import proper certificates. ## Support and Contributing ### Getting Help 1. Review `group_vars_schema.md` for variable documentation 2. Check role README files for role-specific details 3. Review playbook logs for detailed error messages ### Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Test thoroughly 5. Submit a pull request ## License This project is provided as-is for network automation purposes. ## Authors Network Automation Team --- **Version**: 1.0.0 **Last Updated**: 2025-12-09