466 lines
12 KiB
Markdown
466 lines
12 KiB
Markdown
# 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/<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`:
|
|
|
|
```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 <firewall-ip>`
|
|
2. Check firewall API port: `nc -zv <firewall-ip> 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
|