Creating the airgap by using Juniper vSRX
End of Marketing: As of 31 October 2025, new deployments of VMware Solutions offerings are no longer available for new customers. Existing customers can still use and expand their active VMware® workloads on IBM Cloud®. For more information, see End of Marketing for VMware on IBM Cloud.
The following steps are needed only when you are creating an isolated recovery environment and you are using the Juniper® vSRX to isolate the environment.
An Ansible® playbook is used to configure the Juniper vSRX to allow traffic to the Veeam® Linux® Hardened repository in the isolated recovery environment from the Veeam backup proxies in the production environment. After the cyberbackup is completed, the Ansible playbook is used to block the traffic, isolating the Veeam Linux Hardened repository from the production environment. The Ansible playbook is initiated by a cron job on the automation server.
The document also describes a second Ansible playbook that can be used to schedule the opening and closing of the airgap.
The playbook might be extended to trigger the Veeam backup job instead of running the backup job on a schedule controlled by the Veeam backup server. For more information about using the Veeam PowerShell module, see Start-VBRJob.
As an alternative, scripts can be used before and after the backup job that connects to the automation server and initiates the Ansible playbook. For more information, see Script settings and New-PSSession.
The New-PSSession module requires PowerShell 7. For more information, see Installing the MSI package.
Another option is to use the Posh-Junos® PowerShell module to interface with the vSRX directly from the Veeam backup server. For more information, see Scripting How-To: Windows® PowerShell.
Opening and closing the airgap
The document does not describe the configuration of the Juniper vSRX. You must create the required configuration. The playbook assumes that the vSRX configuration includes the following items:
- A user named
sa-ansible, with an SSH key.- Set system login user sa-ansible
uid 2002 - Set system login user sa-ansible
class super-user - Set system login user sa-ansible
authentication ssh-rsa <public_key>
- Set system login user sa-ansible
- NETCONF is enabled.
- Set system services netconf ssh port
830 - Set firewall filter PROTECT-IN term NETCONF from destination-address
<vSRX_private_ip>/32 - Set firewall filter PROTECT-IN term NETCONF from protocol TCP
- Set firewall filter PROTECT-IN term NETCONF from destination-port
830 - Set firewall filter PROTECT-IN term NETCONF then accept
- Set system services netconf ssh port
- The security zones are configured as follows.
IBM_CLOUD_PRIVATEonreth0(untrusted network)IBM_CLOUD_PUBLIConreth1(untrusted network)IRE_PRIVATEonreth2(trusted network)IRE_PUBLIConreth3(trusted network)
- Address book entries in an address book, called
CYBER, for the Veeam proxies and the Veeam Linux hardened repository.- Set security address-book
CYBERaddress PROXY_1<proxy_1_ip>/32 - Set security address-book
CYBERaddress PROXY_2<proxy_2_ip>/32 - Set security address-book
CYBERaddress LHBR_1<lhbr_ip>/32 - Set security address-book
CYBERaddress-set CYBER_PROD address PROXY_1 - Set security address-book
CYBERaddress-set CYBER_PROD address PROXY_2 - Set security address-book
CYBERaddress-set CYBER_IRE address LHBR_1 - Set security address-book
CYBERattach zoneIBM_CLOUD_PRIVATE - Set security address-book
CYBERattach zoneIRE_PRIVATE
- Set security address-book
- A custom application that defines the TCP ports
2500 - 3300, which is the default range of ports that are used as data transmission channels by Veeam.- Set applications - application VEEAM_DATA protocol TCP
- Set applications - application VEEAM_DATA destination-port 2500-3300
- A security policy is defined that denies traffic from the Veeam proxies to the Veeam Linux Hardened repositories.
- Set security policies from zone
IBM_CLOUD_PRIVATEto zoneIRE_PRIVATEpolicy AIRGAP match source-address CYBER_PROD - Set security policies from zone
IBM_CLOUD_PRIVATEto zoneIRE_PRIVATEpolicy AIRGAP match destination-address CYBER_IRE - Set security policies from zone
IBM_CLOUD_PRIVATEto zoneIRE_PRIVATEpolicy AIRGAP match application VEEAM_DATA - Set security policies from zone
IBM_CLOUD_PRIVATEto zoneIRE_PRIVATEpolicy AIRGAP then deny - Set security policies from zone
IBM_CLOUD_PRIVATEto zoneIRE_PRIVATEpolicy AIRGAP then log session-init - Set security policies from zone
IBM_CLOUD_PRIVATEto zoneIRE_PRIVATEpolicy AIRGAP then log session-close - Set security policies from zone
IBM_CLOUD_PRIVATEto zoneIRE_PRIVATEpolicy AIRGAP then count
- Set security policies from zone
The Ansible playbook uses the junipernetworks.junos.junos_config module, which enables the management of the configuration on devices that run Juniper JUNOS. This module requires the NETCONF system service to be enabled on the remote
device that is being managed. The module can be installed on the Ansible server by using the command ansible-galaxy collection install junipernetworks.junos.
The Ansible hosts file contains the following lines:
[vsrx]
gateway01 ansible_host=<vsrx_private_ip> ansible_user=sa-ansible ansible_connection=ansible.netcommon.netconf ansible_network_os=junipernetworks.junos.junos
[vsrx]needs to match the- hosts: vsrxentry in the airgap.yml file.<vsrx_private_ip>is the private IP address of the vSRX that is reachable from the automation server that runs Ansible.- The ansible user needs to match the user configured on the vSRX, for example
set system login user sa-ansible.
The Ansible playbook is run by using ansible-playbook airgap.yml --tag open or ansible-playbook airgap.yml --tag close.
-
The script connects to the vSRX through the private IP address over NETCONF as the user sa-ansible and an SSH key for that user.
-
The command
show security policies policy-name AIRGAPis used and the output displayed. -
If the
--tag closeoption is used, the commandset security policies from-zone IBM_CLOUD_PRIVATE to-zone IRE_PRIVATE policy AIRGAP then denyis run. -
If the
--tag openoption is used, the commandset security policies from-zone IBM_CLOUD_PRIVATE to-zone IRE_PRIVATE policy AIRGAP then permitis run. -
The command
show security policies policy-name AIRGAPis used again and the output displayed. -
The
ansible - airgap openedoransible - airgap closedcomment is used and can be seen when you use theshow system commiton the vSRX appliance.0 2022-04-22 10:48:40 UTC by sa-ansible via netconf ansible - airgap opened 1 2022-04-22 10:30:21 UTC by sa-ansible via netconf ansible - airgap closed
The Ansible playbook file airgap.yml contains the following lines:
- hosts: vsrx
connection: local
gather_facts: no
tasks:
- name: Get show security policies policy-name AIRGAP
junipernetworks.junos.junos_command:
commands:
- show security policies policy-name AIRGAP
register: airgap_policy
tags:
- open
- close
- name: Display AIRGAP security policy
debug:
var: airgap_policy.stdout_lines
tags:
- open
- close
- name: Close airgap
junipernetworks.junos.junos_config:
lines:
- set security policies from-zone IBM_CLOUD_PRIVATE to zone IRE_PRIVATE policy AIRGAP then deny
comment: ansible - airgap closed
tags: close
- name: Open airgap
junipernetworks.junos.junos_config:
lines:
- set security policies from-zone IBM_CLOUD_PRIVATE to zone IRE_PRIVATE policy AIRGAP then permit
comment: ansible - airgap opened
tags: open
- name: Get show security policies policy-name AIRGAP
junipernetworks.junos.junos_command:
commands:
- show security policies policy-name AIRGAP
register: airgap_policy
tags:
- open
- close
- name: Display AIRGAP security policy
debug:
var: airgap_policy.stdout_lines
tags:
- open
- close
Scheduling
The following file sched_airgap.yml uses cron on the automation server to open and close the airgap based on a schedule. The ansible-playbook sched_airgap.yml --tags set command configures the cron job while ansible-playbook sched_airgap.yml --tags cancel command deletes the cron job. You can verify by using the crontab -l command. Ansible output is captured in a log file /swlib/ansible/airgap.log. The following example opens the airgap at 01:00 and closes the airgap
at 05:00 each day.
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Create the airgap-open cron job
ansible.builtin.cron:
name: airgap-open
weekday: "*"
minute: "*"
hour: "1"
job: "ansible-playbook -i /swlib/ansible/hosts /swlib/ansible/airgap.yml --tags open >>/swlib/ansible/airgap.log"
tags: set
- name: Create the airgap-close cron job
ansible.builtin.cron:
name: airgap-close
weekday: "*"
minute: "*"
hour: "5"
job: "ansible-playbook -i /swlib/ansible/hosts /swlib/ansible/airgap.yml --tags close >>/swlib/ansible/airgap.log"
tags: set
- name: Delete the airgap-open cron job
ansible.builtin.cron:
name: airgap-open
state: absent
tags: cancel
- name: Delete the airgap-close cron job
ansible.builtin.cron:
name: airgap-close
state: absent
tags: cancel
If you are creating the cyber-recovery isolated recovery environment solution architecture, then see Production environment configuration for details.