12 KiB
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
mkdir -p sophos-xgs-ansible
cd sophos-xgs-ansible
2. Install Required Ansible Collections
ansible-galaxy collection install -r collections/requirements.yml
3. Configure Inventory
Edit inventory/hosts.ini to add your firewalls:
[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:
# 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:
ansible-vault encrypt inventory/host_vars/fw-branch1.yml
Usage
Basic Configuration Deployment
Apply all configuration to all firewalls:
ansible-playbook -i inventory/hosts.ini site.yml
Target Specific Firewalls
Configure only one firewall:
ansible-playbook -i inventory/hosts.ini site.yml --limit fw-branch1
Apply Specific Configuration Areas
Use tags to apply only certain configurations:
# 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:
ansible-playbook -i inventory/hosts.ini site.yml --check
Using Ansible Vault
If you encrypted sensitive files:
ansible-playbook -i inventory/hosts.ini site.yml --ask-vault-pass
Or use a vault password file:
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:
[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:
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:
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:
cat inventory/group_vars/baseline_web.yml
Step 5: Commit to Version Control
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:
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):
inventory/group_vars/all.yml- Global defaultsinventory/group_vars/sophos_firewalls.yml- All Sophos firewallsinventory/group_vars/baseline_web.yml- Baseline WAF config (auto-generated)inventory/host_vars/<hostname>.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:
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:
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:
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:
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:
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:
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:
# .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:
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:
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:
- Verify network connectivity:
ping <firewall-ip> - Check firewall API port:
nc -zv <firewall-ip> 4444 - Verify credentials in host_vars
- Check firewall device access rules (allow HTTPS from your management IP)
Authentication Failures
Problem: "401 Unauthorized" or "403 Forbidden"
Solution:
- Verify username/password in host_vars
- Check if API access is enabled on the firewall
- Verify the API user has sufficient privileges
Idempotency Issues
Problem: Playbook shows "changed" every run
Solution:
- Check role tasks for proper
changed_whenconditions - Verify API responses are being parsed correctly
- Review templates for dynamic content (timestamps, etc.)
Timeout Errors
Problem: API calls timing out
Solution:
- Increase
sophos_api_timeoutin group_vars/all.yml - Check firewall CPU/memory usage
- Reduce
sophos_serial_executionto 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
- Review
group_vars_schema.mdfor variable documentation - Check role README files for role-specific details
- Review playbook logs for detailed error messages
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- 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