Claude 1
This commit is contained in:
18
sophos-xgs-ansible/roles/sophos_common/defaults/main.yml
Normal file
18
sophos-xgs-ansible/roles/sophos_common/defaults/main.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos Common Role - Default Variables
|
||||
# ============================================================================
|
||||
# These are default values that can be overridden in group_vars or host_vars.
|
||||
# ============================================================================
|
||||
|
||||
# API connection defaults
|
||||
sophos_mgmt_port: 4444
|
||||
sophos_validate_certs: false
|
||||
sophos_api_timeout: 30
|
||||
|
||||
# Retry settings
|
||||
sophos_api_retries: 3
|
||||
sophos_api_retry_delay: 5
|
||||
|
||||
# Security settings
|
||||
sophos_no_log_sensitive: true
|
||||
130
sophos-xgs-ansible/roles/sophos_common/tasks/main.yml
Normal file
130
sophos-xgs-ansible/roles/sophos_common/tasks/main.yml
Normal file
@@ -0,0 +1,130 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos Common Role - Main Tasks
|
||||
# ============================================================================
|
||||
# This role performs common setup tasks for all Sophos XGS firewalls:
|
||||
# - Validates required variables
|
||||
# - Tests API connectivity
|
||||
# - Authenticates to the firewall
|
||||
# - Gathers basic system facts
|
||||
#
|
||||
# This role should always run first before other configuration roles.
|
||||
# ============================================================================
|
||||
|
||||
- name: Validate required variables are defined
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- sophos_mgmt_host is defined
|
||||
- sophos_mgmt_host | length > 0
|
||||
- sophos_mgmt_port is defined
|
||||
- (sophos_api_key is defined) or (sophos_api_username is defined and sophos_api_password is defined)
|
||||
fail_msg: |
|
||||
Required variables are missing for {{ inventory_hostname }}.
|
||||
Please ensure the following are defined in host_vars:
|
||||
- sophos_mgmt_host (management IP or hostname)
|
||||
- sophos_mgmt_port (API port, default 4444)
|
||||
- Authentication: either sophos_api_key OR (sophos_api_username AND sophos_api_password)
|
||||
success_msg: "All required variables are defined for {{ inventory_hostname }}"
|
||||
tags: ['validation']
|
||||
|
||||
- name: Display firewall connection information
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "Connecting to Sophos XGS Firewall:"
|
||||
- " Hostname: {{ inventory_hostname }}"
|
||||
- " Management IP: {{ sophos_mgmt_host }}"
|
||||
- " API Port: {{ sophos_mgmt_port }}"
|
||||
- " Auth Method: {{ 'API Key' if sophos_api_key is defined else 'Username/Password' }}"
|
||||
- " Validate Certs: {{ sophos_validate_certs }}"
|
||||
tags: ['always']
|
||||
|
||||
# ============================================================================
|
||||
# Test API connectivity
|
||||
# ============================================================================
|
||||
|
||||
- name: Test HTTPS connectivity to Sophos XGS API
|
||||
ansible.builtin.wait_for:
|
||||
host: "{{ sophos_mgmt_host }}"
|
||||
port: "{{ sophos_mgmt_port }}"
|
||||
timeout: 10
|
||||
state: started
|
||||
delegate_to: localhost
|
||||
tags: ['validation', 'connectivity']
|
||||
|
||||
- name: Display connectivity success
|
||||
ansible.builtin.debug:
|
||||
msg: "Successfully connected to {{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}"
|
||||
tags: ['validation', 'connectivity']
|
||||
|
||||
# ============================================================================
|
||||
# Authenticate and gather system information
|
||||
# ============================================================================
|
||||
|
||||
- name: Authenticate to Sophos XGS firewall and retrieve system status
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController?reqxml=<Request><Login><Username>{{ sophos_api_username }}</Username><Password>{{ sophos_api_password }}</Password></Login><Get><System/></Get></Request>"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
return_content: true
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
register: sophos_system_info
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
retries: "{{ sophos_api_retries }}"
|
||||
delay: "{{ sophos_api_retry_delay }}"
|
||||
tags: ['authentication', 'facts']
|
||||
|
||||
- name: Parse system information from API response
|
||||
ansible.builtin.set_fact:
|
||||
sophos_facts:
|
||||
hostname: "{{ sophos_system_info.content | regex_search('<HostName>(.*?)</HostName>', '\\1') | first | default('unknown') }}"
|
||||
serial_number: "{{ sophos_system_info.content | regex_search('<SerialNumber>(.*?)</SerialNumber>', '\\1') | first | default('unknown') }}"
|
||||
firmware_version: "{{ sophos_system_info.content | regex_search('<FirmwareVersion>(.*?)</FirmwareVersion>', '\\1') | first | default('unknown') }}"
|
||||
device_model: "{{ sophos_system_info.content | regex_search('<ApplianceModel>(.*?)</ApplianceModel>', '\\1') | first | default('unknown') }}"
|
||||
uptime_days: "{{ sophos_system_info.content | regex_search('<Uptime>(.*?)</Uptime>', '\\1') | first | default('0') }}"
|
||||
tags: ['facts']
|
||||
|
||||
- name: Display Sophos XGS system information
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "======================================"
|
||||
- "Sophos XGS System Information"
|
||||
- "======================================"
|
||||
- "Hostname: {{ sophos_facts.hostname }}"
|
||||
- "Model: {{ sophos_facts.device_model }}"
|
||||
- "Serial Number: {{ sophos_facts.serial_number }}"
|
||||
- "Firmware Version: {{ sophos_facts.firmware_version }}"
|
||||
- "Uptime: {{ sophos_facts.uptime_days }} days"
|
||||
tags: ['facts']
|
||||
|
||||
# ============================================================================
|
||||
# Check firmware version compatibility (optional warning)
|
||||
# ============================================================================
|
||||
|
||||
- name: Check if firmware version is recent
|
||||
ansible.builtin.debug:
|
||||
msg: "WARNING: This automation was tested with firmware version 19.x and 20.x. Current version: {{ sophos_facts.firmware_version }}"
|
||||
when:
|
||||
- sophos_facts.firmware_version is defined
|
||||
- not sophos_facts.firmware_version is match('^(19|20)\.')
|
||||
tags: ['validation']
|
||||
|
||||
# ============================================================================
|
||||
# Store authentication token for subsequent API calls (if using token-based auth)
|
||||
# ============================================================================
|
||||
|
||||
- name: Store API authentication credentials for use in other roles
|
||||
ansible.builtin.set_fact:
|
||||
sophos_api_auth_header: "{{ sophos_api_key | default('') }}"
|
||||
sophos_api_credentials:
|
||||
username: "{{ sophos_api_username | default('') }}"
|
||||
password: "{{ sophos_api_password | default('') }}"
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['authentication']
|
||||
|
||||
- name: Common role tasks completed successfully
|
||||
ansible.builtin.debug:
|
||||
msg: "Sophos common role completed for {{ inventory_hostname }}"
|
||||
tags: ['always']
|
||||
30
sophos-xgs-ansible/roles/sophos_common/vars/main.yml
Normal file
30
sophos-xgs-ansible/roles/sophos_common/vars/main.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos Common Role - Internal Variables
|
||||
# ============================================================================
|
||||
# These variables are internal to the role and should not be overridden.
|
||||
# ============================================================================
|
||||
|
||||
# API endpoint paths (Sophos XGS XML API)
|
||||
sophos_api_base_path: "/webconsole/APIController"
|
||||
|
||||
# XML API request wrapper template
|
||||
sophos_api_request_template: |
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
{{ api_request_body }}
|
||||
</Request>
|
||||
|
||||
# Supported firmware versions (for validation)
|
||||
sophos_supported_firmware_versions:
|
||||
- "19.0"
|
||||
- "19.5"
|
||||
- "20.0"
|
||||
|
||||
# Default HTTP headers for API requests
|
||||
sophos_api_default_headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
Accept: "application/xml"
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
# Default device access settings
|
||||
sophos_default_device_access_enabled: true
|
||||
35
sophos-xgs-ansible/roles/sophos_device_access/tasks/main.yml
Normal file
35
sophos-xgs-ansible/roles/sophos_device_access/tasks/main.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos Device Access Role - Main Tasks
|
||||
# ============================================================================
|
||||
|
||||
- name: Display device access configuration overview
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "======================================"
|
||||
- "Configuring Device Access Policies"
|
||||
- "======================================"
|
||||
- "Firewall: {{ inventory_hostname }}"
|
||||
- "Policies: {{ sophos_common_device_access_policies | default([]) | length }}"
|
||||
tags: ['always']
|
||||
|
||||
- name: Configure device access policies
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'device_access_rule.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_common_device_access_policies | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.service }}"
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['device-access']
|
||||
|
||||
- name: Device access configuration completed
|
||||
ansible.builtin.debug:
|
||||
msg: "Device access policies configured successfully"
|
||||
tags: ['always']
|
||||
@@ -0,0 +1,24 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="update">
|
||||
<DeviceAccess>
|
||||
<Service>{{ item.service | upper }}</Service>
|
||||
<Status>{{ 'Enable' if item.enabled | default(true) else 'Disable' }}</Status>
|
||||
<AllowedZones>
|
||||
{% for zone in item.allowed_zones %}
|
||||
<Zone>{{ zone }}</Zone>
|
||||
{% endfor %}
|
||||
</AllowedZones>
|
||||
{% if item.allowed_networks is defined and item.allowed_networks | length > 0 %}
|
||||
<AllowedNetworks>
|
||||
{% for network in item.allowed_networks %}
|
||||
<Network>{{ network }}</Network>
|
||||
{% endfor %}
|
||||
</AllowedNetworks>
|
||||
{% endif %}
|
||||
</DeviceAccess>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
# Default firewall rule action
|
||||
sophos_default_rule_action: "deny"
|
||||
sophos_default_rule_log: true
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos Firewall Rules Role - Main Tasks
|
||||
# ============================================================================
|
||||
|
||||
- name: Display firewall rules configuration overview
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "======================================"
|
||||
- "Configuring Firewall Rules"
|
||||
- "======================================"
|
||||
- "Firewall: {{ inventory_hostname }}"
|
||||
- "Common Rules: {{ sophos_common_firewall_rules | default([]) | length }}"
|
||||
- "Custom Rules: {{ sophos_firewall_rules | default([]) | length }}"
|
||||
tags: ['always']
|
||||
|
||||
- name: Get current firewall rules from firewall
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController?reqxml=<Request><Login><Username>{{ sophos_api_username }}</Username><Password>{{ sophos_api_password }}</Password></Login><Get><FirewallRule/></Get></Request>"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
return_content: true
|
||||
status_code: [200]
|
||||
register: current_firewall_rules
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['rules']
|
||||
|
||||
- name: Parse current firewall rule names
|
||||
ansible.builtin.set_fact:
|
||||
existing_firewall_rules: "{{ current_firewall_rules.content | regex_findall('<Name>(.*?)</Name>') }}"
|
||||
tags: ['rules']
|
||||
|
||||
- name: Combine common and custom firewall rules
|
||||
ansible.builtin.set_fact:
|
||||
all_firewall_rules: "{{ sophos_common_firewall_rules | default([]) + sophos_firewall_rules | default([]) }}"
|
||||
tags: ['rules']
|
||||
|
||||
- name: Configure firewall rule {{ item.name }}
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'firewall_rule.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ all_firewall_rules }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
register: fw_rule_result
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
changed_when: "'successful' in fw_rule_result.content | lower"
|
||||
tags: ['rules']
|
||||
|
||||
- name: Firewall rules configuration completed
|
||||
ansible.builtin.debug:
|
||||
msg: "Configured {{ all_firewall_rules | length }} firewall rules successfully"
|
||||
tags: ['always']
|
||||
@@ -0,0 +1,43 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="{% if item.name in existing_firewall_rules %}update{% else %}add{% endif %}">
|
||||
<FirewallRule>
|
||||
<Name>{{ item.name }}</Name>
|
||||
<Description>{{ item.description | default('') }}</Description>
|
||||
<Status>{{ 'Enable' if item.enabled | default(true) else 'Disable' }}</Status>
|
||||
<Action>{{ item.action | upper }}</Action>
|
||||
<LogTraffic>{{ 'Enable' if item.log | default(false) else 'Disable' }}</LogTraffic>
|
||||
<SourceZones>
|
||||
{% for zone in item.source_zones %}
|
||||
<Zone>{{ zone }}</Zone>
|
||||
{% endfor %}
|
||||
</SourceZones>
|
||||
<DestinationZones>
|
||||
{% for zone in item.dest_zones %}
|
||||
<Zone>{{ zone }}</Zone>
|
||||
{% endfor %}
|
||||
</DestinationZones>
|
||||
<SourceNetworks>
|
||||
{% for network in item.source_networks %}
|
||||
<Network>{{ network }}</Network>
|
||||
{% endfor %}
|
||||
</SourceNetworks>
|
||||
<DestinationNetworks>
|
||||
{% for network in item.dest_networks %}
|
||||
<Network>{{ network }}</Network>
|
||||
{% endfor %}
|
||||
</DestinationNetworks>
|
||||
<Services>
|
||||
{% for service in item.services %}
|
||||
<Service>{{ service }}</Service>
|
||||
{% endfor %}
|
||||
</Services>
|
||||
{% if item.position is defined %}
|
||||
<Position>{{ item.position }}</Position>
|
||||
{% endif %}
|
||||
</FirewallRule>
|
||||
</Set>
|
||||
</Request>
|
||||
13
sophos-xgs-ansible/roles/sophos_network/defaults/main.yml
Normal file
13
sophos-xgs-ansible/roles/sophos_network/defaults/main.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos Network Role - Default Variables
|
||||
# ============================================================================
|
||||
|
||||
# Default MTU for interfaces
|
||||
sophos_default_mtu: 1500
|
||||
|
||||
# Default interface state
|
||||
sophos_default_interface_enabled: true
|
||||
|
||||
# Default DHCP lease time (seconds)
|
||||
sophos_default_dhcp_lease_time: 86400 # 24 hours
|
||||
52
sophos-xgs-ansible/roles/sophos_network/tasks/dhcp.yml
Normal file
52
sophos-xgs-ansible/roles/sophos_network/tasks/dhcp.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Configure DHCP Servers
|
||||
# ============================================================================
|
||||
|
||||
- name: Get current DHCP server configuration from firewall
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController?reqxml=<Request><Login><Username>{{ sophos_api_username }}</Username><Password>{{ sophos_api_password }}</Password></Login><Get><DHCPServer/></Get></Request>"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
return_content: true
|
||||
status_code: [200]
|
||||
register: current_dhcp_servers
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['dhcp']
|
||||
|
||||
- name: Parse current DHCP server names
|
||||
ansible.builtin.set_fact:
|
||||
existing_dhcp_servers: "{{ current_dhcp_servers.content | regex_findall('<Name>(.*?)</Name>') }}"
|
||||
tags: ['dhcp']
|
||||
|
||||
- name: Display existing DHCP servers
|
||||
ansible.builtin.debug:
|
||||
msg: "Found {{ existing_dhcp_servers | length }} existing DHCP servers: {{ existing_dhcp_servers | join(', ') }}"
|
||||
tags: ['dhcp']
|
||||
|
||||
# Loop through each DHCP server and configure it
|
||||
- name: Configure DHCP server {{ item.name }}
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'dhcp_server.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_dhcp_servers }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }} ({{ item.interface }})"
|
||||
register: dhcp_result
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
changed_when: "'successful' in dhcp_result.content | lower or '200' in dhcp_result.content"
|
||||
failed_when: "'error' in dhcp_result.content | lower"
|
||||
tags: ['dhcp']
|
||||
|
||||
- name: Display DHCP server configuration results
|
||||
ansible.builtin.debug:
|
||||
msg: "Configured {{ sophos_dhcp_servers | length }} DHCP servers successfully"
|
||||
tags: ['dhcp']
|
||||
43
sophos-xgs-ansible/roles/sophos_network/tasks/dns.yml
Normal file
43
sophos-xgs-ansible/roles/sophos_network/tasks/dns.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Configure DNS Settings
|
||||
# ============================================================================
|
||||
|
||||
- name: Get current DNS configuration from firewall
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController?reqxml=<Request><Login><Username>{{ sophos_api_username }}</Username><Password>{{ sophos_api_password }}</Password></Login><Get><DNS/></Get></Request>"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
return_content: true
|
||||
status_code: [200]
|
||||
register: current_dns_config
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['dns']
|
||||
|
||||
- name: Display current DNS forwarders
|
||||
ansible.builtin.debug:
|
||||
msg: "Current DNS configuration retrieved"
|
||||
tags: ['dns']
|
||||
|
||||
- name: Configure DNS settings
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'dns_config.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
register: dns_result
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
changed_when: "'successful' in dns_result.content | lower or '200' in dns_result.content"
|
||||
failed_when: "'error' in dns_result.content | lower"
|
||||
tags: ['dns']
|
||||
|
||||
- name: Display DNS configuration result
|
||||
ansible.builtin.debug:
|
||||
msg: "DNS configuration applied successfully"
|
||||
tags: ['dns']
|
||||
52
sophos-xgs-ansible/roles/sophos_network/tasks/interfaces.yml
Normal file
52
sophos-xgs-ansible/roles/sophos_network/tasks/interfaces.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Configure Physical Interfaces
|
||||
# ============================================================================
|
||||
|
||||
- name: Get current interface configuration from firewall
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController?reqxml=<Request><Login><Username>{{ sophos_api_username }}</Username><Password>{{ sophos_api_password }}</Password></Login><Get><Interface/></Get></Request>"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
return_content: true
|
||||
status_code: [200]
|
||||
register: current_interfaces
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['interfaces']
|
||||
|
||||
- name: Parse current interface names
|
||||
ansible.builtin.set_fact:
|
||||
existing_interfaces: "{{ current_interfaces.content | regex_findall('<Name>(.*?)</Name>') }}"
|
||||
tags: ['interfaces']
|
||||
|
||||
- name: Display existing interfaces
|
||||
ansible.builtin.debug:
|
||||
msg: "Found {{ existing_interfaces | length }} existing interfaces: {{ existing_interfaces | join(', ') }}"
|
||||
tags: ['interfaces']
|
||||
|
||||
# Loop through each interface and configure it
|
||||
- name: Configure physical interface {{ item.name }}
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'interface.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_interfaces }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }} ({{ item.zone }})"
|
||||
register: interface_result
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
changed_when: "'successful' in interface_result.content | lower or '200' in interface_result.content"
|
||||
failed_when: "'error' in interface_result.content | lower"
|
||||
tags: ['interfaces']
|
||||
|
||||
- name: Display interface configuration results
|
||||
ansible.builtin.debug:
|
||||
msg: "Configured {{ sophos_interfaces | length }} interfaces successfully"
|
||||
tags: ['interfaces']
|
||||
83
sophos-xgs-ansible/roles/sophos_network/tasks/main.yml
Normal file
83
sophos-xgs-ansible/roles/sophos_network/tasks/main.yml
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos Network Role - Main Tasks
|
||||
# ============================================================================
|
||||
# This role configures all network-related settings on Sophos XGS firewalls:
|
||||
# - Physical interfaces
|
||||
# - VLAN interfaces
|
||||
# - DHCP servers
|
||||
# - DNS configuration
|
||||
# - Static routes
|
||||
# ============================================================================
|
||||
|
||||
- name: Display network configuration overview
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "======================================"
|
||||
- "Configuring Network Settings"
|
||||
- "======================================"
|
||||
- "Firewall: {{ inventory_hostname }}"
|
||||
- "Interfaces: {{ sophos_interfaces | default([]) | length }}"
|
||||
- "VLANs: {{ sophos_vlans | default([]) | length }}"
|
||||
- "DHCP Servers: {{ sophos_dhcp_servers | default([]) | length }}"
|
||||
- "Static Routes: {{ sophos_static_routes | default([]) | length }}"
|
||||
tags: ['always']
|
||||
|
||||
# ============================================================================
|
||||
# Configure Physical Interfaces
|
||||
# ============================================================================
|
||||
|
||||
- name: Configure physical interfaces
|
||||
ansible.builtin.include_tasks: interfaces.yml
|
||||
when: sophos_interfaces is defined and sophos_interfaces | length > 0
|
||||
tags: ['interfaces']
|
||||
|
||||
# ============================================================================
|
||||
# Configure VLAN Interfaces
|
||||
# ============================================================================
|
||||
|
||||
- name: Configure VLAN interfaces
|
||||
ansible.builtin.include_tasks: vlans.yml
|
||||
when: sophos_vlans is defined and sophos_vlans | length > 0
|
||||
tags: ['vlans']
|
||||
|
||||
# ============================================================================
|
||||
# Configure DHCP Servers
|
||||
# ============================================================================
|
||||
|
||||
- name: Configure DHCP servers
|
||||
ansible.builtin.include_tasks: dhcp.yml
|
||||
when: sophos_dhcp_servers is defined and sophos_dhcp_servers | length > 0
|
||||
tags: ['dhcp']
|
||||
|
||||
# ============================================================================
|
||||
# Configure DNS Settings
|
||||
# ============================================================================
|
||||
|
||||
- name: Configure DNS settings
|
||||
ansible.builtin.include_tasks: dns.yml
|
||||
when: sophos_dns is defined
|
||||
tags: ['dns']
|
||||
|
||||
# ============================================================================
|
||||
# Configure Static Routes
|
||||
# ============================================================================
|
||||
|
||||
- name: Configure static routes
|
||||
ansible.builtin.include_tasks: routes.yml
|
||||
when: sophos_static_routes is defined and sophos_static_routes | length > 0
|
||||
tags: ['routes']
|
||||
|
||||
# ============================================================================
|
||||
# Summary
|
||||
# ============================================================================
|
||||
|
||||
- name: Network configuration completed
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "======================================"
|
||||
- "Network Configuration Complete"
|
||||
- "======================================"
|
||||
- "Firewall: {{ inventory_hostname }}"
|
||||
- "All network settings have been applied."
|
||||
tags: ['always']
|
||||
52
sophos-xgs-ansible/roles/sophos_network/tasks/routes.yml
Normal file
52
sophos-xgs-ansible/roles/sophos_network/tasks/routes.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Configure Static Routes
|
||||
# ============================================================================
|
||||
|
||||
- name: Get current static route configuration from firewall
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController?reqxml=<Request><Login><Username>{{ sophos_api_username }}</Username><Password>{{ sophos_api_password }}</Password></Login><Get><StaticRoute/></Get></Request>"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
return_content: true
|
||||
status_code: [200]
|
||||
register: current_routes
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['routes']
|
||||
|
||||
- name: Parse current route names
|
||||
ansible.builtin.set_fact:
|
||||
existing_routes: "{{ current_routes.content | regex_findall('<Name>(.*?)</Name>') }}"
|
||||
tags: ['routes']
|
||||
|
||||
- name: Display existing static routes
|
||||
ansible.builtin.debug:
|
||||
msg: "Found {{ existing_routes | length }} existing static routes: {{ existing_routes | join(', ') }}"
|
||||
tags: ['routes']
|
||||
|
||||
# Loop through each static route and configure it
|
||||
- name: Configure static route {{ item.name }}
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'static_route.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_static_routes }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }} ({{ item.destination }}/{{ item.netmask }} via {{ item.gateway }})"
|
||||
register: route_result
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
changed_when: "'successful' in route_result.content | lower or '200' in route_result.content"
|
||||
failed_when: "'error' in route_result.content | lower"
|
||||
tags: ['routes']
|
||||
|
||||
- name: Display static route configuration results
|
||||
ansible.builtin.debug:
|
||||
msg: "Configured {{ sophos_static_routes | length }} static routes successfully"
|
||||
tags: ['routes']
|
||||
52
sophos-xgs-ansible/roles/sophos_network/tasks/vlans.yml
Normal file
52
sophos-xgs-ansible/roles/sophos_network/tasks/vlans.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Configure VLAN Interfaces
|
||||
# ============================================================================
|
||||
|
||||
- name: Get current VLAN configuration from firewall
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController?reqxml=<Request><Login><Username>{{ sophos_api_username }}</Username><Password>{{ sophos_api_password }}</Password></Login><Get><VLANInterface/></Get></Request>"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
return_content: true
|
||||
status_code: [200]
|
||||
register: current_vlans
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['vlans']
|
||||
|
||||
- name: Parse current VLAN names
|
||||
ansible.builtin.set_fact:
|
||||
existing_vlans: "{{ current_vlans.content | regex_findall('<Name>(.*?)</Name>') }}"
|
||||
tags: ['vlans']
|
||||
|
||||
- name: Display existing VLANs
|
||||
ansible.builtin.debug:
|
||||
msg: "Found {{ existing_vlans | length }} existing VLANs: {{ existing_vlans | join(', ') }}"
|
||||
tags: ['vlans']
|
||||
|
||||
# Loop through each VLAN and configure it
|
||||
- name: Configure VLAN interface {{ item.name }}
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'vlan.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_vlans }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }} (VLAN {{ item.vlan_id }})"
|
||||
register: vlan_result
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
changed_when: "'successful' in vlan_result.content | lower or '200' in vlan_result.content"
|
||||
failed_when: "'error' in vlan_result.content | lower"
|
||||
tags: ['vlans']
|
||||
|
||||
- name: Display VLAN configuration results
|
||||
ansible.builtin.debug:
|
||||
msg: "Configured {{ sophos_vlans | length }} VLANs successfully"
|
||||
tags: ['vlans']
|
||||
@@ -0,0 +1,47 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="{% if item.name in existing_dhcp_servers %}update{% else %}add{% endif %}">
|
||||
<DHCPServer>
|
||||
<Name>{{ item.name }}</Name>
|
||||
<Interface>{{ item.interface }}</Interface>
|
||||
<Status>{{ 'Enable' if item.enabled | default(true) else 'Disable' }}</Status>
|
||||
<StartIPAddress>{{ item.start_ip }}</StartIPAddress>
|
||||
<EndIPAddress>{{ item.end_ip }}</EndIPAddress>
|
||||
<Netmask>{{ item.netmask }}</Netmask>
|
||||
<Gateway>{{ item.gateway }}</Gateway>
|
||||
<DNSServers>
|
||||
{% for dns in item.dns_servers %}
|
||||
<Server>{{ dns }}</Server>
|
||||
{% endfor %}
|
||||
</DNSServers>
|
||||
{% if item.domain is defined %}
|
||||
<DomainName>{{ item.domain }}</DomainName>
|
||||
{% endif %}
|
||||
<LeaseTime>{{ item.lease_time | default(86400) }}</LeaseTime>
|
||||
{% if item.reservations is defined and item.reservations | length > 0 %}
|
||||
<Reservations>
|
||||
{% for reservation in item.reservations %}
|
||||
<Reservation>
|
||||
<MACAddress>{{ reservation.mac_address }}</MACAddress>
|
||||
<IPAddress>{{ reservation.ip_address }}</IPAddress>
|
||||
<Hostname>{{ reservation.hostname | default('') }}</Hostname>
|
||||
</Reservation>
|
||||
{% endfor %}
|
||||
</Reservations>
|
||||
{% endif %}
|
||||
{% if item.dhcp_options is defined and item.dhcp_options | length > 0 %}
|
||||
<DHCPOptions>
|
||||
{% for option in item.dhcp_options %}
|
||||
<Option>
|
||||
<Code>{{ option.option }}</Code>
|
||||
<Value>{{ option.value }}</Value>
|
||||
</Option>
|
||||
{% endfor %}
|
||||
</DHCPOptions>
|
||||
{% endif %}
|
||||
</DHCPServer>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,19 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="update">
|
||||
<DNS>
|
||||
<Forwarders>
|
||||
{% for forwarder in sophos_dns.forwarders %}
|
||||
<Server>{{ forwarder }}</Server>
|
||||
{% endfor %}
|
||||
</Forwarders>
|
||||
{% if sophos_dns.domain is defined %}
|
||||
<DomainName>{{ sophos_dns.domain }}</DomainName>
|
||||
{% endif %}
|
||||
<DNSForwarder>{{ 'Enable' if sophos_dns.enable_dns_forwarder | default(true) else 'Disable' }}</DNSForwarder>
|
||||
</DNS>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,25 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="{% if item.name in existing_interfaces %}update{% else %}add{% endif %}">
|
||||
<Interface>
|
||||
<Name>{{ item.name }}</Name>
|
||||
<Description>{{ item.description | default('') }}</Description>
|
||||
<Zone>{{ item.zone }}</Zone>
|
||||
<Type>{{ item.type | default('physical') }}</Type>
|
||||
{% if item.mode == 'static' %}
|
||||
<IPAddress>{{ item.ip_address }}</IPAddress>
|
||||
<Netmask>{{ item.netmask }}</Netmask>
|
||||
{% if item.gateway is defined %}
|
||||
<Gateway>{{ item.gateway }}</Gateway>
|
||||
{% endif %}
|
||||
{% elif item.mode == 'dhcp' %}
|
||||
<DHCPMode>Enable</DHCPMode>
|
||||
{% endif %}
|
||||
<MTU>{{ item.mtu | default(sophos_default_mtu) }}</MTU>
|
||||
<Status>{{ 'Enable' if item.enabled | default(true) else 'Disable' }}</Status>
|
||||
</Interface>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,19 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="{% if item.name in existing_routes %}update{% else %}add{% endif %}">
|
||||
<StaticRoute>
|
||||
<Name>{{ item.name }}</Name>
|
||||
<Destination>{{ item.destination }}</Destination>
|
||||
<Netmask>{{ item.netmask }}</Netmask>
|
||||
<Gateway>{{ item.gateway }}</Gateway>
|
||||
{% if item.interface is defined %}
|
||||
<Interface>{{ item.interface }}</Interface>
|
||||
{% endif %}
|
||||
<Metric>{{ item.metric | default(10) }}</Metric>
|
||||
<Status>{{ 'Enable' if item.enabled | default(true) else 'Disable' }}</Status>
|
||||
</StaticRoute>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,18 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="{% if item.name in existing_vlans %}update{% else %}add{% endif %}">
|
||||
<VLANInterface>
|
||||
<Name>{{ item.name }}</Name>
|
||||
<Description>{{ item.description | default('') }}</Description>
|
||||
<VLANID>{{ item.vlan_id }}</VLANID>
|
||||
<ParentInterface>{{ item.parent_interface }}</ParentInterface>
|
||||
<Zone>{{ item.zone }}</Zone>
|
||||
<IPAddress>{{ item.ip_address }}</IPAddress>
|
||||
<Netmask>{{ item.netmask }}</Netmask>
|
||||
<Status>{{ 'Enable' if item.enabled | default(true) else 'Disable' }}</Status>
|
||||
</VLANInterface>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
# Default SNMP and logging settings
|
||||
sophos_default_snmp_enabled: false
|
||||
sophos_default_logging_enabled: true
|
||||
68
sophos-xgs-ansible/roles/sophos_snmp_logging/tasks/main.yml
Normal file
68
sophos-xgs-ansible/roles/sophos_snmp_logging/tasks/main.yml
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos SNMP and Logging Role - Main Tasks
|
||||
# ============================================================================
|
||||
|
||||
- name: Display SNMP and logging configuration overview
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "======================================"
|
||||
- "Configuring SNMP and Logging"
|
||||
- "======================================"
|
||||
- "Firewall: {{ inventory_hostname }}"
|
||||
- "SNMP Enabled: {{ sophos_snmp.enabled | default(false) }}"
|
||||
- "Syslog Servers: {{ sophos_logging.syslog_servers | default([]) | length }}"
|
||||
tags: ['always']
|
||||
|
||||
# Configure SNMP
|
||||
- name: Configure SNMP settings
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'snmp_config.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
when: sophos_snmp is defined
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['snmp']
|
||||
|
||||
# Configure Syslog
|
||||
- name: Configure syslog servers
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'syslog_server.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_logging.syslog_servers | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.host }}"
|
||||
when: sophos_logging is defined
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['logging', 'syslog']
|
||||
|
||||
# Configure NTP
|
||||
- name: Configure NTP settings
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'ntp_config.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
when: sophos_ntp is defined
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['ntp']
|
||||
|
||||
- name: SNMP and logging configuration completed
|
||||
ansible.builtin.debug:
|
||||
msg: "SNMP, logging, and NTP configured successfully"
|
||||
tags: ['always']
|
||||
@@ -0,0 +1,16 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="update">
|
||||
<NTP>
|
||||
<Servers>
|
||||
{% for server in sophos_ntp.servers %}
|
||||
<Server>{{ server }}</Server>
|
||||
{% endfor %}
|
||||
</Servers>
|
||||
<Timezone>{{ sophos_ntp.timezone | default('UTC') }}</Timezone>
|
||||
</NTP>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,35 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="update">
|
||||
<SNMP>
|
||||
<Status>{{ 'Enable' if sophos_snmp.enabled | default(false) else 'Disable' }}</Status>
|
||||
<Version>{{ sophos_snmp.version | default('v2c') }}</Version>
|
||||
{% if sophos_snmp.version | default('v2c') == 'v2c' %}
|
||||
<Community>{{ sophos_snmp.community }}</Community>
|
||||
{% endif %}
|
||||
<Location>{{ sophos_snmp.location | default('') }}</Location>
|
||||
<Contact>{{ sophos_snmp.contact | default('') }}</Contact>
|
||||
{% if sophos_snmp.allowed_networks is defined %}
|
||||
<AllowedNetworks>
|
||||
{% for network in sophos_snmp.allowed_networks %}
|
||||
<Network>{{ network }}</Network>
|
||||
{% endfor %}
|
||||
</AllowedNetworks>
|
||||
{% endif %}
|
||||
{% if sophos_snmp.trap_destinations is defined %}
|
||||
<TrapDestinations>
|
||||
{% for trap in sophos_snmp.trap_destinations %}
|
||||
<Destination>
|
||||
<Host>{{ trap.host }}</Host>
|
||||
<Port>{{ trap.port | default(162) }}</Port>
|
||||
<Community>{{ trap.community }}</Community>
|
||||
</Destination>
|
||||
{% endfor %}
|
||||
</TrapDestinations>
|
||||
{% endif %}
|
||||
</SNMP>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,15 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="add">
|
||||
<SyslogServer>
|
||||
<Host>{{ item.host }}</Host>
|
||||
<Port>{{ item.port | default(514) }}</Port>
|
||||
<Protocol>{{ item.protocol | default('udp') | upper }}</Protocol>
|
||||
<Facility>{{ item.facility | default('local0') }}</Facility>
|
||||
<Severity>{{ item.severity | default('informational') }}</Severity>
|
||||
</SyslogServer>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
# Default remote access VPN settings
|
||||
sophos_default_remote_vpn_port: 443
|
||||
sophos_default_remote_vpn_encryption: "aes256"
|
||||
sophos_default_remote_vpn_hash: "sha256"
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos Remote Access VPN Role - Main Tasks
|
||||
# ============================================================================
|
||||
|
||||
- name: Display remote access VPN configuration overview
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "======================================"
|
||||
- "Configuring Remote Access VPN"
|
||||
- "======================================"
|
||||
- "Firewall: {{ inventory_hostname }}"
|
||||
- "Type: {{ sophos_remote_access_vpn.type | default('Not configured') }}"
|
||||
tags: ['always']
|
||||
when: sophos_remote_access_vpn is defined
|
||||
|
||||
- name: Skip remote access VPN configuration (not defined)
|
||||
ansible.builtin.debug:
|
||||
msg: "No remote access VPN configuration defined for {{ inventory_hostname }}"
|
||||
when: sophos_remote_access_vpn is not defined
|
||||
tags: ['always']
|
||||
|
||||
- name: Configure remote access VPN
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'remote_access_vpn.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
register: remote_vpn_result
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
when: sophos_remote_access_vpn is defined
|
||||
changed_when: "'successful' in remote_vpn_result.content | lower"
|
||||
tags: ['vpn', 'remote-access']
|
||||
|
||||
- name: Remote access VPN configuration completed
|
||||
ansible.builtin.debug:
|
||||
msg: "Remote access VPN configured successfully"
|
||||
when: sophos_remote_access_vpn is defined
|
||||
tags: ['always']
|
||||
@@ -0,0 +1,63 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="update">
|
||||
<RemoteAccessVPN>
|
||||
<Name>{{ sophos_remote_access_vpn.name | default('Remote-Access-VPN') }}</Name>
|
||||
<Status>{{ 'Enable' if sophos_remote_access_vpn.enabled | default(true) else 'Disable' }}</Status>
|
||||
<Type>{{ sophos_remote_access_vpn.type | upper }}</Type>
|
||||
|
||||
<!-- Connection Settings -->
|
||||
<ListeningPort>{{ sophos_remote_access_vpn.listening_port | default(443) }}</ListeningPort>
|
||||
<ListeningInterface>{{ sophos_remote_access_vpn.listening_interface }}</ListeningInterface>
|
||||
|
||||
<!-- Authentication -->
|
||||
<AuthenticationMethod>{{ sophos_remote_access_vpn.authentication_method | default('local') }}</AuthenticationMethod>
|
||||
<UserGroups>
|
||||
{% for group in sophos_remote_access_vpn.user_groups %}
|
||||
<Group>{{ group }}</Group>
|
||||
{% endfor %}
|
||||
</UserGroups>
|
||||
|
||||
<!-- IP Address Pool -->
|
||||
<AddressPool>
|
||||
<Network>{{ sophos_remote_access_vpn.address_pool.network }}</Network>
|
||||
<Netmask>{{ sophos_remote_access_vpn.address_pool.netmask }}</Netmask>
|
||||
<StartIP>{{ sophos_remote_access_vpn.address_pool.start_ip }}</StartIP>
|
||||
<EndIP>{{ sophos_remote_access_vpn.address_pool.end_ip }}</EndIP>
|
||||
</AddressPool>
|
||||
|
||||
<!-- DNS Settings -->
|
||||
<DNSServers>
|
||||
{% for dns in sophos_remote_access_vpn.dns_servers %}
|
||||
<Server>{{ dns }}</Server>
|
||||
{% endfor %}
|
||||
</DNSServers>
|
||||
|
||||
<!-- Tunnel Mode -->
|
||||
<TunnelMode>{{ sophos_remote_access_vpn.tunnel_mode | default('split') }}</TunnelMode>
|
||||
{% if sophos_remote_access_vpn.tunnel_mode | default('split') == 'split' %}
|
||||
<TunnelNetworks>
|
||||
{% for network in sophos_remote_access_vpn.tunnel_networks | default([]) %}
|
||||
<Network>{{ network }}</Network>
|
||||
{% endfor %}
|
||||
</TunnelNetworks>
|
||||
{% endif %}
|
||||
|
||||
<!-- Encryption -->
|
||||
<Encryption>{{ sophos_remote_access_vpn.encryption | default('aes256') }}</Encryption>
|
||||
<Hash>{{ sophos_remote_access_vpn.hash | default('sha256') }}</Hash>
|
||||
|
||||
<!-- Timeouts -->
|
||||
<IdleTimeout>{{ sophos_remote_access_vpn.idle_timeout | default(1800) }}</IdleTimeout>
|
||||
<SessionTimeout>{{ sophos_remote_access_vpn.session_timeout | default(43200) }}</SessionTimeout>
|
||||
|
||||
<!-- Advanced Settings -->
|
||||
<MaxConnections>{{ sophos_remote_access_vpn.max_concurrent_connections | default(50) }}</MaxConnections>
|
||||
<Compression>{{ 'Enable' if sophos_remote_access_vpn.enable_compression | default(true) else 'Disable' }}</Compression>
|
||||
<BlockLANAccess>{{ 'Enable' if sophos_remote_access_vpn.block_lan_access | default(true) else 'Disable' }}</BlockLANAccess>
|
||||
</RemoteAccessVPN>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# Default VPN encryption settings
|
||||
sophos_default_ike_encryption: "aes256"
|
||||
sophos_default_ike_hash: "sha256"
|
||||
sophos_default_ike_dh_group: 14
|
||||
sophos_default_ike_lifetime: 28800
|
||||
|
||||
sophos_default_ipsec_encryption: "aes256"
|
||||
sophos_default_ipsec_hash: "sha256"
|
||||
sophos_default_ipsec_pfs_group: 14
|
||||
sophos_default_ipsec_lifetime: 3600
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos Site-to-Site VPN Role - Main Tasks
|
||||
# ============================================================================
|
||||
|
||||
- name: Display site-to-site VPN configuration overview
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "======================================"
|
||||
- "Configuring Site-to-Site VPN Tunnels"
|
||||
- "======================================"
|
||||
- "Firewall: {{ inventory_hostname }}"
|
||||
- "Tunnels: {{ sophos_site_to_site_vpns | default([]) | length }}"
|
||||
tags: ['always']
|
||||
when: sophos_site_to_site_vpns is defined
|
||||
|
||||
- name: Skip site-to-site VPN configuration (not defined)
|
||||
ansible.builtin.debug:
|
||||
msg: "No site-to-site VPN tunnels defined for {{ inventory_hostname }}"
|
||||
when: sophos_site_to_site_vpns is not defined or sophos_site_to_site_vpns | length == 0
|
||||
tags: ['always']
|
||||
|
||||
- name: Get current IPsec connections from firewall
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController?reqxml=<Request><Login><Username>{{ sophos_api_username }}</Username><Password>{{ sophos_api_password }}</Password></Login><Get><IPSecConnection/></Get></Request>"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
return_content: true
|
||||
status_code: [200]
|
||||
register: current_ipsec_connections
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
when: sophos_site_to_site_vpns is defined and sophos_site_to_site_vpns | length > 0
|
||||
tags: ['vpn', 'site-to-site']
|
||||
|
||||
- name: Parse current IPsec connection names
|
||||
ansible.builtin.set_fact:
|
||||
existing_ipsec_connections: "{{ current_ipsec_connections.content | regex_findall('<Name>(.*?)</Name>') }}"
|
||||
when: sophos_site_to_site_vpns is defined and sophos_site_to_site_vpns | length > 0
|
||||
tags: ['vpn', 'site-to-site']
|
||||
|
||||
- name: Configure site-to-site VPN tunnel {{ item.name }}
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'ipsec_connection.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_site_to_site_vpns }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }} ({{ item.local_gateway }} <-> {{ item.remote_gateway }})"
|
||||
register: vpn_result
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
when: sophos_site_to_site_vpns is defined and sophos_site_to_site_vpns | length > 0
|
||||
changed_when: "'successful' in vpn_result.content | lower"
|
||||
tags: ['vpn', 'site-to-site']
|
||||
|
||||
- name: Site-to-site VPN configuration completed
|
||||
ansible.builtin.debug:
|
||||
msg: "Configured {{ sophos_site_to_site_vpns | length }} site-to-site VPN tunnels successfully"
|
||||
when: sophos_site_to_site_vpns is defined and sophos_site_to_site_vpns | length > 0
|
||||
tags: ['always']
|
||||
@@ -0,0 +1,58 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="{% if item.name in existing_ipsec_connections | default([]) %}update{% else %}add{% endif %}">
|
||||
<IPSecConnection>
|
||||
<Name>{{ item.name }}</Name>
|
||||
<Description>{{ item.description | default('') }}</Description>
|
||||
<Status>{{ 'Enable' if item.enabled | default(true) else 'Disable' }}</Status>
|
||||
<ConnectionType>{{ item.connection_type | default('tunnel') }}</ConnectionType>
|
||||
|
||||
<!-- Local Settings -->
|
||||
<LocalGateway>{{ item.local_gateway }}</LocalGateway>
|
||||
<LocalID>{{ item.local_id | default(item.local_gateway) }}</LocalID>
|
||||
<LocalNetworks>
|
||||
{% for network in item.local_networks %}
|
||||
<Network>{{ network }}</Network>
|
||||
{% endfor %}
|
||||
</LocalNetworks>
|
||||
|
||||
<!-- Remote Settings -->
|
||||
<RemoteGateway>{{ item.remote_gateway }}</RemoteGateway>
|
||||
<RemoteID>{{ item.remote_id | default(item.remote_gateway) }}</RemoteID>
|
||||
<RemoteNetworks>
|
||||
{% for network in item.remote_networks %}
|
||||
<Network>{{ network }}</Network>
|
||||
{% endfor %}
|
||||
</RemoteNetworks>
|
||||
|
||||
<!-- Phase 1 (IKE) Settings -->
|
||||
<IKEVersion>{{ item.ike_version | default(2) }}</IKEVersion>
|
||||
<IKEEncryption>{{ item.ike_encryption | default(sophos_default_ike_encryption) }}</IKEEncryption>
|
||||
<IKEHash>{{ item.ike_hash | default(sophos_default_ike_hash) }}</IKEHash>
|
||||
<IKEDHGroup>{{ item.ike_dh_group | default(sophos_default_ike_dh_group) }}</IKEDHGroup>
|
||||
<IKELifetime>{{ item.ike_lifetime | default(sophos_default_ike_lifetime) }}</IKELifetime>
|
||||
|
||||
<!-- Authentication -->
|
||||
<AuthenticationMethod>{{ item.authentication_method | default('psk') }}</AuthenticationMethod>
|
||||
{% if item.authentication_method | default('psk') == 'psk' %}
|
||||
<PreSharedKey>{{ item.psk }}</PreSharedKey>
|
||||
{% endif %}
|
||||
|
||||
<!-- Phase 2 (IPsec) Settings -->
|
||||
<IPSecMode>{{ item.ipsec_mode | default('tunnel') }}</IPSecMode>
|
||||
<IPSecEncryption>{{ item.ipsec_encryption | default(sophos_default_ipsec_encryption) }}</IPSecEncryption>
|
||||
<IPSecHash>{{ item.ipsec_hash | default(sophos_default_ipsec_hash) }}</IPSecHash>
|
||||
<IPSecPFSGroup>{{ item.ipsec_pfs_group | default(sophos_default_ipsec_pfs_group) }}</IPSecPFSGroup>
|
||||
<IPSecLifetime>{{ item.ipsec_lifetime | default(sophos_default_ipsec_lifetime) }}</IPSecLifetime>
|
||||
|
||||
<!-- Advanced Settings -->
|
||||
<DPDEnabled>{{ 'Enable' if item.dpd_enabled | default(true) else 'Disable' }}</DPDEnabled>
|
||||
<DPDInterval>{{ item.dpd_interval | default(30) }}</DPDInterval>
|
||||
<DPDRetries>{{ item.dpd_retries | default(3) }}</DPDRetries>
|
||||
<NATTraversal>{{ 'Enable' if item.nat_traversal | default(true) else 'Disable' }}</NATTraversal>
|
||||
</IPSecConnection>
|
||||
</Set>
|
||||
</Request>
|
||||
4
sophos-xgs-ansible/roles/sophos_waf/defaults/main.yml
Normal file
4
sophos-xgs-ansible/roles/sophos_waf/defaults/main.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
# Default WAF settings
|
||||
sophos_default_waf_mode: "prevention"
|
||||
sophos_default_waf_session_timeout: 1800
|
||||
90
sophos-xgs-ansible/roles/sophos_waf/tasks/main.yml
Normal file
90
sophos-xgs-ansible/roles/sophos_waf/tasks/main.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Sophos WAF Role - Main Tasks
|
||||
# ============================================================================
|
||||
|
||||
- name: Display WAF configuration overview
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "======================================"
|
||||
- "Configuring Web Application Firewall"
|
||||
- "======================================"
|
||||
- "Firewall: {{ inventory_hostname }}"
|
||||
- "Backends: {{ sophos_waf_backends | default([]) | length }}"
|
||||
- "Policies: {{ sophos_waf_policies | default([]) | length }}"
|
||||
- "Virtual Hosts: {{ sophos_waf_virtual_hosts | default([]) | length }}"
|
||||
- "Exceptions: {{ sophos_waf_exceptions | default([]) | length }}"
|
||||
tags: ['always']
|
||||
|
||||
- name: Configure WAF backend servers
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'waf_backend.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_waf_backends | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
when: sophos_waf_backends is defined and sophos_waf_backends | length > 0
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['waf', 'backends']
|
||||
|
||||
- name: Configure WAF protection policies
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'waf_policy.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_waf_policies | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
when: sophos_waf_policies is defined and sophos_waf_policies | length > 0
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['waf', 'policies']
|
||||
|
||||
- name: Configure WAF virtual hosts
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'waf_policy.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_waf_virtual_hosts | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }} ({{ item.domain }})"
|
||||
when: sophos_waf_virtual_hosts is defined and sophos_waf_virtual_hosts | length > 0
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['waf', 'virtual-hosts']
|
||||
|
||||
- name: Configure WAF exceptions
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ sophos_mgmt_host }}:{{ sophos_mgmt_port }}/webconsole/APIController"
|
||||
method: POST
|
||||
validate_certs: "{{ sophos_validate_certs }}"
|
||||
headers:
|
||||
Content-Type: "application/x-www-form-urlencoded"
|
||||
body: "reqxml={{ lookup('template', 'waf_exception.json.j2') | urlencode }}"
|
||||
status_code: [200, 201]
|
||||
timeout: "{{ sophos_api_timeout }}"
|
||||
loop: "{{ sophos_waf_exceptions | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
when: sophos_waf_exceptions is defined and sophos_waf_exceptions | length > 0
|
||||
no_log: "{{ sophos_no_log_sensitive }}"
|
||||
tags: ['waf', 'exceptions']
|
||||
|
||||
- name: WAF configuration completed
|
||||
ansible.builtin.debug:
|
||||
msg: "Web Application Firewall configured successfully"
|
||||
tags: ['always']
|
||||
@@ -0,0 +1,15 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="add">
|
||||
<WebServer>
|
||||
<Name>{{ item.name }}</Name>
|
||||
<Host>{{ item.host }}</Host>
|
||||
<Port>{{ item.port }}</Port>
|
||||
<Protocol>{{ item.protocol | upper }}</Protocol>
|
||||
<HealthCheck>{{ 'Enable' if item.health_check | default(true) else 'Disable' }}</HealthCheck>
|
||||
</WebServer>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,24 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="add">
|
||||
<WebException>
|
||||
<Name>{{ item.name }}</Name>
|
||||
<VirtualHost>{{ item.virtual_host }}</VirtualHost>
|
||||
<Path>{{ item.path }}</Path>
|
||||
<SkipRules>
|
||||
{% for rule in item.skip_rules %}
|
||||
<Rule>{{ rule }}</Rule>
|
||||
{% endfor %}
|
||||
</SkipRules>
|
||||
<SourceNetworks>
|
||||
{% for network in item.source_networks %}
|
||||
<Network>{{ network }}</Network>
|
||||
{% endfor %}
|
||||
</SourceNetworks>
|
||||
<Comment>{{ item.comment | default('') }}</Comment>
|
||||
</WebException>
|
||||
</Set>
|
||||
</Request>
|
||||
@@ -0,0 +1,31 @@
|
||||
<Request>
|
||||
<Login>
|
||||
<Username>{{ sophos_api_username }}</Username>
|
||||
<Password>{{ sophos_api_password }}</Password>
|
||||
</Login>
|
||||
<Set operation="add">
|
||||
<WebPolicy>
|
||||
<Name>{{ item.name }}</Name>
|
||||
<Domain>{{ item.domain }}</Domain>
|
||||
<ListeningIP>{{ item.listening_ip }}</ListeningIP>
|
||||
<ListeningPort>{{ item.listening_port }}</ListeningPort>
|
||||
<Protocol>{{ item.protocol | upper }}</Protocol>
|
||||
{% if item.ssl_certificate is defined %}
|
||||
<SSLCertificate>{{ item.ssl_certificate }}</SSLCertificate>
|
||||
{% endif %}
|
||||
<BackendServers>
|
||||
{% for backend in item.backend_servers %}
|
||||
<Server>{{ backend }}</Server>
|
||||
{% endfor %}
|
||||
</BackendServers>
|
||||
<LoadBalancing>{{ item.load_balancing | default('round-robin') }}</LoadBalancing>
|
||||
<ProtectionPolicy>{{ item.protection_policy }}</ProtectionPolicy>
|
||||
<SessionTimeout>{{ item.session_timeout | default(1800) }}</SessionTimeout>
|
||||
<HSTS>{{ 'Enable' if item.enable_hsts | default(false) else 'Disable' }}</HSTS>
|
||||
<Compression>{{ 'Enable' if item.enable_compression | default(false) else 'Disable' }}</Compression>
|
||||
{% if item.websocket_support is defined %}
|
||||
<WebSocketSupport>{{ 'Enable' if item.websocket_support else 'Disable' }}</WebSocketSupport>
|
||||
{% endif %}
|
||||
</WebPolicy>
|
||||
</Set>
|
||||
</Request>
|
||||
Reference in New Issue
Block a user