Claude 1
This commit is contained in:
465
sophos-xgs-ansible/README.md
Normal file
465
sophos-xgs-ansible/README.md
Normal file
@@ -0,0 +1,465 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user