Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions network/stormshield-sns-firewall/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Deploy Stormshield SNS HA cluster on Public Cloud

This Terraform automate the deployment of a Stormshield SNS HA cluster on Public Cloud.

The manual steps to achieve this are described here:
https://help.ovhcloud.com/csm/en-public-cloud-network-stormshield-vrack?id=kb_article_view&sysparm_article=KB0065106

## Requirements

* A Public Cloud project
* An additional IP block
* A vRack
* A Stormshield SNS image for OpenStack
* At least one Stormshield license with the corresponding maj file
* A SSH key
* Terraform binary
* Openstack CLI

## Configuring the deployment

* Create an OpenStack user in your Public Cloud project (Users & Roles->Add user)
* Download your user openrc file
* Load the Openstack environment variable:
```source openrc.sh```
```export OS_REGION_NAME=<REGION>```

* Add your Public Cloud project to your vRack
* Add your IP block to your vRack
https://help.ovhcloud.com/csm/en-dedicated-servers-ip-block-vrack?id=kb_article_view&sysparm_article=KB0043342
* Upload Stormshield SNS image
```openstack image create --disk-format raw --container-format bare --file ./utm-SNS-EVA-4.8.11-openstack.qcow2 utm-SNS-EVA-4.8.11```

* Configure the following variables in terraform.tfvars:
- ovh_os_instance_region:
The region where you would like to deploy Stromshield SNS (example: SBG7).
This needs to be the same region than where you upload your SNS image.
- ovh_os_instance_password:
The password for the stormshield admin user
- ssh_public_key:
Your SSH public key
- admin_client_ip:
The public IP of the machine used to administrate stormshield.
You can use `curl ipinfo.io/ip` to get the public IP of your machine.
- ovh_os_instance_wan_ip:
A list of two public IP within your IP block that can be used by the two Stormshield instances.
Only the first one will be kept as VIP for your Stormshield HA cluster.
- ovh_os_instance_wan_mask:
The mask of your IP block.
- ovh_os_instance_wan_gw
The gateway for your IP block.
- ovh_os_instance_image_name
The name of your Stormshield image (example: utm-SNS-EVA-4.8.11).
- stormshield_serial_number
Two serial numbers for your Stormshield instances (example: ["VMSNSXXXXXXXXXX", "VMSNSYYYYYYYYYYY"]).
* Add your maj files (corresponding to your stormshield_serial_number list) to the stormshield-maj directory (exemple: vminit-<serial_number>.maj)

## Deploy Stormshield SNS HA cluster

terraform init
terraform plan
terraform apply

Browse: https://<first_public_ip>
Login: admin
Password: The value of the Terraform ovh_os_instance_password variable

**note:** The Stormshield SNS configuration can take a little bit of time, therefore wait a bit before trying to login.
65 changes: 65 additions & 0 deletions network/stormshield-sns-firewall/ovh_instance.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
resource "openstack_compute_servergroup_v2" "stormshield" {
name = "${var.ovh_os_instance_name}-stormshield"
region = var.ovh_os_instance_region
policies = ["anti-affinity"]
}

resource "openstack_compute_keypair_v2" "keypair" {
name = "${var.ovh_os_instance_name}-keypair"
public_key = var.ssh_public_key
}

resource "openstack_compute_instance_v2" "instance" {
count = 2

name = "${var.ovh_os_instance_name}-${count.index + 1}"
region = var.ovh_os_instance_region
image_name = var.ovh_os_instance_image_name
flavor_name = var.ovh_os_instance_flavor_name
key_pair = openstack_compute_keypair_v2.keypair.name

scheduler_hints {
group = openstack_compute_servergroup_v2.stormshield.id
}

connection {
type = "ssh"
user = "admin"
password = var.ovh_os_instance_password
host = var.ovh_os_instance_wan_ip[count.index]
}

provisioner "file" {
source = "./stormshield-maj/"
destination = "/tmp"
}

user_data = base64encode(templatefile("templates/stormshield-config.tpl",
{
SERIAL_NUMBER=var.stormshield_serial_number[count.index]
PASSWORD=var.ovh_os_instance_password
WAN_IP=var.ovh_os_instance_wan_ip[count.index]
WAN_MASK=var.ovh_os_instance_wan_mask
WAN_GW=var.ovh_os_instance_wan_gw
LAN_IP=cidrhost(openstack_networking_subnet_v2.private-subnet-workload.cidr, 1)
LAN_MASK=cidrnetmask(openstack_networking_subnet_v2.private-subnet-workload.cidr)
HA_IP=cidrhost(openstack_networking_subnet_v2.private-subnet-ha.cidr, count.index + 3)
HA_MASK=cidrnetmask(openstack_networking_subnet_v2.private-subnet-ha.cidr)
HA_ID=count.index + 1
HA_PRIMARY_IP=cidrhost(openstack_networking_subnet_v2.private-subnet-ha.cidr, count.index + 2)
ADMIN_CLIENT_IP=var.admin_client_ip
}
))

network {
name = openstack_networking_network_v2.private-net-ext.name
}

network {
name = openstack_networking_network_v2.private-net-workload.name
}

network {
name = openstack_networking_network_v2.private-net-ha.name
}
}
86 changes: 86 additions & 0 deletions network/stormshield-sns-firewall/ovh_private_network.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
resource "openstack_networking_network_v2" "private-net-ext" {
name = "${var.ovh_os_instance_name}-ext"
region = var.ovh_os_instance_region
admin_state_up = "true"
port_security_enabled = "false"
value_specs = {
"provider:network_type" = "vrack"
"provider:segmentation_id" = "0"
}
}

resource "openstack_networking_subnet_v2" "private-subnet-ext" {
name = "${var.ovh_os_instance_name}-ext"
network_id = openstack_networking_network_v2.private-net-ext.id
region = var.ovh_os_instance_region
cidr = "192.168.1.0/29"
enable_dhcp = true
allocation_pool {
start = "192.168.1.2"
end = "192.168.1.6"
}
no_gateway = false
}

data "openstack_networking_network_v2" "ext-net" {
name = "Ext-Net"
region = var.ovh_os_instance_region
}

resource "openstack_networking_router_v2" "router" {
name = "${var.ovh_os_instance_name}-router"
region = var.ovh_os_instance_region
admin_state_up = true
external_network_id = ""
}

resource "openstack_networking_router_interface_v2" "router-interface" {
region = var.ovh_os_instance_region
router_id = openstack_networking_router_v2.router.id
subnet_id = openstack_networking_subnet_v2.private-subnet-ext.id
}

resource "openstack_networking_network_v2" "private-net-workload" {
name = "${var.ovh_os_instance_name}-workload"
region = var.ovh_os_instance_region
admin_state_up = "true"
port_security_enabled = "false"
value_specs = {
"provider:network_type" = "vrack"
"provider:segmentation_id" = var.ovh_os_private_network_vlan_id
}
}

resource "openstack_networking_subnet_v2" "private-subnet-workload" {
name = "${var.ovh_os_instance_name}-workload"
network_id = openstack_networking_network_v2.private-net-workload.id
region = var.ovh_os_instance_region
cidr = "10.200.0.0/16"
enable_dhcp = true
allocation_pool {
start = "10.200.0.2"
end = "10.200.0.254"
}
dns_nameservers = ["213.186.33.99"]
no_gateway = false
}

resource "openstack_networking_network_v2" "private-net-ha" {
name = "${var.ovh_os_instance_name}-ha"
region = var.ovh_os_instance_region
admin_state_up = "true"
port_security_enabled = "false"
value_specs = {
"provider:network_type" = "vrack"
"provider:segmentation_id" = var.ovh_os_private_network_ha_vlan_id
}
}

resource "openstack_networking_subnet_v2" "private-subnet-ha" {
name = "${var.ovh_os_instance_name}-ha"
network_id = openstack_networking_network_v2.private-net-ha.id
region = var.ovh_os_instance_region
cidr = "192.168.2.0/29"
enable_dhcp = true
no_gateway = true
}
7 changes: 7 additions & 0 deletions network/stormshield-sns-firewall/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
terraform {
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
}
}
}
120 changes: 120 additions & 0 deletions network/stormshield-sns-firewall/templates/stormshield-config.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/bin/sh

SETCONF=/usr/Firewall/sbin/setconf
CF=/usr/Firewall/ConfigFiles
SBIN=/usr/Firewall/sbin
GLOBAL=/usr/Firewall/System/global

SERIAL_NUMBER="${SERIAL_NUMBER}"

PASSWORD="${PASSWORD}"

WAN_IP="${WAN_IP}"
WAN_MASK="${WAN_MASK}"
WAN_GW="${WAN_GW}"

LAN_IP="${LAN_IP}"
LAN_MASK="${LAN_MASK}"

HA_IP="${HA_IP}"
HA_MASK="${HA_MASK}"

ADMIN_CLIENT_IP="${ADMIN_CLIENT_IP}"

HA_ID="${HA_ID}"
HA_PRIMARY_IP="${HA_PRIMARY_IP}"

$SETCONF $CF/system Console State Serial
$SBIN/enconsole

# Configure password
$SBIN/fwpasswd -p $PASSWORD

$SETCONF $GLOBAL Options SystemName "STORMSHIELD"
$SETCONF $GLOBAL Options SystemNodeName "HA-"$HA_ID
$SBIN/enservice

#chsh -s /bin/sh admin

# Add default gateway and admin IP ACL
echo '[Host]' >> /usr/Firewall/ConfigFiles/object.new
echo Firewall_out_router=$WAN_GW >> /usr/Firewall/ConfigFiles/object.new
echo admin_client=$ADMIN_CLIENT_IP >> /usr/Firewall/ConfigFiles/object.new
sed -e '1,1d' /usr/Firewall/ConfigFiles/object >> /usr/Firewall/ConfigFiles/object.new
mv /usr/Firewall/ConfigFiles/object.new /usr/Firewall/ConfigFiles/object

# WAN interface configuration
sed -e '142,149d' /usr/Firewall/ConfigFiles/network > /usr/Firewall/ConfigFiles/network.new
echo '' >> /usr/Firewall/ConfigFiles/network.new
echo '[ethernet0]' >> /usr/Firewall/ConfigFiles/network.new
echo 'State=1' >> /usr/Firewall/ConfigFiles/network.new
echo 'Name=wan' >> /usr/Firewall/ConfigFiles/network.new
echo 'Color=800040' >> /usr/Firewall/ConfigFiles/network.new
echo 'Media=0' >> /usr/Firewall/ConfigFiles/network.new
echo 'EEE=0' >> /usr/Firewall/ConfigFiles/network.new
echo Address=$WAN_IP >> /usr/Firewall/ConfigFiles/network.new
echo Mask=$WAN_MASK >> /usr/Firewall/ConfigFiles/network.new
mv /usr/Firewall/ConfigFiles/network.new /usr/Firewall/ConfigFiles/network
$SBIN/ennetwork

# LAN and HA interfaces configuration
cat << EOCONFIG > /tmp/stormshield.cfg
CONFIG NETWORK INTERFACE ADDRESS UPDATE ifname=ethernet1 address=$LAN_IP mask=$LAN_MASK addrnb=0
CONFIG NETWORK INTERFACE ADDRESS UPDATE ifname=ethernet2 address=$HA_IP mask=$HA_MASK addrnb=0
CONFIG NETWORK INTERFACE ACTIVATE
CONFIG NETWORK INTERFACE RENAME ifname=ethernet1 name=lan
CONFIG NETWORK INTERFACE RENAME ifname=ethernet2 name=ha
CONFIG NETWORK INTERFACE ACTIVATE
EOCONFIG
$SBIN/nsrpc -f -c /tmp/stormshield.cfg -l /tmp/stormshield.output admin:[email protected]:1300

# Create default firewall rules
cat << EOFILTER > $CF/Filter/01
[Filter]
separator color="c0c0c0" comment="Remote Management" collapse="0"
pass from admin_client to firewall_all port firewall_srv|https # Admin from admin client IP
pass ipproto icmp type 8 code 0 proto none from admin_client to firewall_all # Allow Ping from admin client IP
pass from admin_client on wan to Firewall_wan port ssh # Allow SSH from admin client IP
separator color="c0c0c0" comment="HA policy" collapse="0"
pass from Network_ha on ha to Firewall_ha # Allow traffic between HA interfaces
separator color="c0c0c0" comment="Default policy" collapse="0"
block from any to any # Block all
EOFILTER
$SBIN/enfilter 01

# Enable SSH
$SETCONF $CF/system SSH State 1
$SETCONF $CF/system SSH Password 1
$SBIN/enservice

# HA configuration
if [ $HA_ID -eq 1 ]
then
cat << EOHA > /tmp/ha.cfg
CONFIG HA CREATE password=stormshield ifname=ha Unicast=1 secure=1
CONFIG HA ACTIVATE
EOHA

$SBIN/nsrpc -f -c /tmp/ha.cfg -l /tmp/ha.output admin:[email protected]:1300
else
cat << EOHA > /tmp/ha.cfg
CONFIG HA JOIN password=stormshield ip=$HA_PRIMARY_IP
CONFIG HA ACTIVATE
EOHA

(sleep 300 && $SBIN/nsrpc -f -c /tmp/ha.cfg -l /tmp/ha.output admin:[email protected]:1300 && sleep 60 && hasync)&
fi

# Configure licence
if [ $SERIAL_NUMBER ]
then
cat << EOUPDATEUPLOAD > /tmp/update-upload.cfg
SYSTEM UPDATE UPLOAD < /tmp/vminit-$SERIAL_NUMBER.maj
EOUPDATEUPLOAD

cat << EOUPDATEAPPLY > /tmp/update-activate.cfg
SYSTEM UPDATE ACTIVATE
EOUPDATEAPPLY

(while [ ! -f /tmp/vminit-$SERIAL_NUMBER.maj ]; do echo "Waiting for update file..." >> /tmp/update-upload.output && sleep 1; done && echo "Update file uploaded" >> /tmp/update-upload.output && sleep 10 && $SBIN/nsrpc -f -c /tmp/update-upload.cfg -l /tmp/update-upload.output admin:[email protected]:1300 && sed -i '' 's/VMSNSX00Z0000A0/'$SERIAL_NUMBER'/g' $CF/HA/hacluster && $SBIN/nsrpc -f -c /tmp/update-activate.cfg -l /tmp/update-activate.output admin:[email protected]:1300)&
fi
Loading