Name the parent network and count the VLAN tags #3
@@ -149,24 +149,53 @@ follows from it.
|
||||
|
||||
**Then, for both paths:**
|
||||
|
||||
1. `Get-Subnet -IPAddress <parent> -NewSubnetMask <NetworkMaskLength>` divides it. A
|
||||
`-NetworkMaskLength` not longer than the parent mask length throws.
|
||||
1. `Get-Subnet -IPAddress <parent> -NewSubnetMask <ParentNetworkSubnetMaskLength>` divides it
|
||||
(default `24`). This parameter applies on **both** paths - it describes how the parent is
|
||||
*divided*, not how the parent is *chosen*, so the mask length that an explicitly supplied parent
|
||||
carries has no bearing on it. Only `-ParentNetworkMaskLength` is bypassed on Path A. A value not
|
||||
longer than the parent mask length throws. `ValidateRange(16, 24)` caps it at `/24`; see §4.1.1.
|
||||
2. **Every** resulting network is included. The count is a consequence of the two mask lengths
|
||||
rather than a separate parameter that could disagree with them: `/20` into `/24` is 16 networks,
|
||||
`/21` is 8, `/19` is 32.
|
||||
3. **Network 0** is the untagged network: no VLAN tag, bound to the LAN adapter, becomes the
|
||||
OPNsense `lan` interface. It is flagged `IsUntaggedNetwork`.
|
||||
4. **Networks 1..n** each become a VLAN. **The VLAN tag is the third octet of the network address.**
|
||||
`10.42.96.0/20` yields `10.42.96.0/24` (untagged) and `10.42.97.0/24` (tag 97) through
|
||||
`10.42.111.0/24` (tag 111).
|
||||
4. **Networks 1..n** each become a VLAN. **The tag is counted**, starting at `-StartingVlanId`
|
||||
(default `2`) and advancing by `-VlanIdIncrement` (default `1`) per tagged network.
|
||||
`10.42.96.0/20` yields `10.42.96.0/24` (untagged) and `10.42.97.0/24` (tag 2) through
|
||||
`10.42.111.0/24` (tag 16).
|
||||
|
||||
A third octet is `0-255`, always within the valid 802.1Q range of `1-4094` except for `0` itself. A
|
||||
tag of `0` would require the network whose third octet is `0`, which is only ever the **first**
|
||||
network of a parent aligned on a third-octet boundary - and that network is the untagged one, which
|
||||
is never assigned a tag. So no generated tag is ever `0`, by construction rather than by rejecting
|
||||
candidates during selection.
|
||||
The highest tag is computed before the loop runs and a range that would exceed `4094` throws, naming
|
||||
the range it would have produced. The default of `2` leaves `1` unused because a switch commonly
|
||||
treats it as its own default VLAN.
|
||||
|
||||
### 4.1.1 Why the seed was replaced
|
||||
### 4.1.1 Why the tag is counted rather than derived
|
||||
|
||||
The tag was previously the third octet of the network address. That reads well while every network
|
||||
happens to occupy a whole third octet, and stops being possible the moment one does not: a network
|
||||
longer than `/24` owns only part of an octet, so several networks share one and are assigned the same
|
||||
tag. Duplicate tags on a single parent interface are not a valid VLAN configuration.
|
||||
|
||||
Measured against a `/20` parent while the tag was still derived:
|
||||
|
||||
| Subnet mask | Networks | Tags emitted | Distinct tags | Result |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `/22` | 4 | 3 | 3 | fine |
|
||||
| `/23` | 8 | 7 | 7 | fine |
|
||||
| `/24` | 16 | 15 | 15 | fine |
|
||||
| `/25` | 32 | 31 | 16 | 15 collisions |
|
||||
| `/26` | 64 | 63 | 16 | 16 collisions |
|
||||
|
||||
That constraint was briefly enforced by capping `-ParentNetworkSubnetMaskLength` at `/24`. Counting
|
||||
the tag instead removes the constraint at its source rather than fencing it off: the tag no longer
|
||||
has anything to do with the address, so it stays unique at any subnet mask length. The same `/25` and
|
||||
`/26` now produce 31 and 63 distinct tags, and the range reverted to `ValidateRange(16, 30)`.
|
||||
|
||||
What is given up is that a tag no longer tells you the address. What is gained is that the two are
|
||||
independent, so the subnet mask length, the starting tag and the increment can each be chosen on
|
||||
their own merits. `-VlanIdIncrement` also makes tag ranges expressible - a decade per purpose, say -
|
||||
which a derived tag could never have offered.
|
||||
|
||||
### 4.1.2 Why the seed was replaced
|
||||
|
||||
`-NetworkSeed` selected the `/20` by indexing `System.Random(seed).Next(0, N)` into the
|
||||
post-exclusion candidate list. It was repeatable but effectively unusable, for two reasons:
|
||||
@@ -791,7 +820,10 @@ Hyper-V itself, the toolkit modules, and anything the operator created by hand a
|
||||
| `GenerateRootPassword` | `Switch` | off | Generate a random 16 character password instead |
|
||||
| `BaseNetwork` | `String` | `10.0.0.0/8` | `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16` |
|
||||
| `ParentNetwork` | `String` | _(random)_ | CIDR. Taken verbatim; ignores `ParentNetworkMaskLength` |
|
||||
| `ParentNetworkMaskLength` | `Int` | `20` | `8-28`. Sets the network count. Ignored when `ParentNetwork` is supplied |
|
||||
| `ParentNetworkMaskLength` | `Int` | `20` | `8-28`. Ignored when `ParentNetwork` is supplied |
|
||||
| `ParentNetworkSubnetMaskLength` | `Int` | `24` | `16-30`. Size of each network inside the parent. Always applies, on both paths |
|
||||
| `StartingVlanId` | `Int` | `2` | `1-4094`. Tag of the first tagged network |
|
||||
| `VlanIdIncrement` | `Int` | `1` | `1-4093`. Step between consecutive tags |
|
||||
| `NamePrefix` | `String` | `LAB` | |
|
||||
| `NetworkRoleList` | `String[]` | see §4.3 | |
|
||||
| `Release` | `String` | `Latest` | e.g. `26.1.6` |
|
||||
@@ -882,7 +914,10 @@ The following were executed against the current implementation rather than assum
|
||||
| Check | Result |
|
||||
| --- | --- |
|
||||
| All scripts parse (`System.Management.Automation.Language.Parser`) | Pass |
|
||||
| `New-OPNSenseNetworkPlan` on `10.0.0.0/8` with exclusions and a fixed seed | `/20` selected, `/24`s split, VLAN tags equal the third octet, zones paired |
|
||||
| `New-OPNSenseNetworkPlan` on `10.0.0.0/8` with exclusions | `/20` resolved, `/24`s split, zones paired |
|
||||
| Counted VLAN tags | Defaults produce `2-16`; `-VlanIdIncrement 10` produces `2,12,22,…`; `-StartingVlanId 100 -VlanIdIncrement 5` produces `100,105,110,…` |
|
||||
| Tag distinctness at every subnet mask length | `/25` yields 31 distinct tags across 32 networks and `/26` yields 63 across 64, both of which collided under the derived scheme |
|
||||
| VLAN ceiling guard | A range ending past `4094` throws and names the range; `-StartingVlanId 4080` with 15 networks is accepted and ends exactly at `4094` |
|
||||
| `New-OPNSenseConfigurationDocument` + `Save-OPNSenseConfigurationDocument` | Valid document, UTF-8 without BOM, matches the OPNsense element shapes |
|
||||
| Generated rule set on a 16 network plan | 28 rules and 8 aliases, in the sequence order defined in §5.3 |
|
||||
| Sequence 40 in the generated document | Bound to `wan`, `RFC1918` → `RFC1918`, direction `in`, `enabled=1`, `disablereplyto=1`. Every other rule `enabled=1` and `disablereplyto=0`, so no rule regressed. `blockpriv=0` confirmed on the same interface |
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
1. The "Indented.Net.IP" and "Indented.Net.Dns" powershell modules are saved into the toolkit module directory.
|
||||
2. The Hyper-V platform and its powershell management module are detected and installed. When a restart is required, the script exits with exit code 3010 and performs no further action.
|
||||
3. The lab network plan is generated. A parent network is resolved out of the specified private base network and divided into individual networks. The first network is the untagged network and every remaining network becomes a virtual local area network whose tag is the third octet of its own network address.
|
||||
3. The lab network plan is generated. A parent network is resolved out of the specified private base network and divided into individual networks. The first network is the untagged network and every remaining network becomes a virtual local area network whose tag is counted from a starting tag and advanced by an increment.
|
||||
4. The OPNsense installation media is acquired. A disc image that is already present within the content directory is always preferred.
|
||||
5. The OPNsense configuration document is generated and written to the content directory.
|
||||
6. The configuration document is placed onto a secondary virtual hard disk at "\conf\config.xml" so that the OPNsense installer can import it.
|
||||
@@ -38,10 +38,27 @@
|
||||
.PARAMETER ParentNetworkMaskLength
|
||||
The mask length of the parent network that is selected out of the base network.
|
||||
|
||||
This value determines how many networks the deployment contains, because the parent network is divided into as many networks as fit within it. A parent of "/20" divided into the default "/24" networks is sixteen networks, a "/21" is eight, and a "/19" is thirty two.
|
||||
Together with the subnet mask length, this value determines how many networks the deployment contains, because the parent network is divided into as many networks as fit within it. A parent of "/20" divided into the default "/24" networks is sixteen networks, a "/21" is eight, and a "/19" is thirty two.
|
||||
|
||||
This value is ignored when a parent network is specified, because the supplied value carries its own mask length.
|
||||
|
||||
.PARAMETER ParentNetworkSubnetMaskLength
|
||||
The mask length of each individual network that the parent network is subnetted into.
|
||||
|
||||
This value always applies. It describes how the parent network is divided rather than how the parent network is chosen, so it is honoured whether the parent network was selected at random or was specified, and the mask length that a specified parent network carries has no bearing upon it. A parent network of "/20" divided by a subnet mask length of "/22" is four networks whether that "/20" was chosen by this script or supplied by the operator.
|
||||
|
||||
This value must be longer than the mask length of the parent network, because a parent network cannot be divided into networks that are the same size as itself or larger.
|
||||
|
||||
.PARAMETER StartingVlanId
|
||||
The virtual local area network tag that is assigned to the first tagged network. Each subsequent tagged network is assigned the previous tag plus the increment.
|
||||
|
||||
The default of 2 leaves the tag of 1 unused, because a switch commonly treats it as its own default network and assigning it here invites a collision that is awkward to diagnose.
|
||||
|
||||
.PARAMETER VlanIdIncrement
|
||||
The amount that the virtual local area network tag is advanced by for each tagged network after the first.
|
||||
|
||||
The default of 1 numbers the tagged networks consecutively, so a sixteen network deployment carries the tags 2 through 16. A larger increment leaves gaps, which is useful when a tag is meant to carry meaning of its own, such as reserving a decade to each purpose.
|
||||
|
||||
.PARAMETER NamePrefix
|
||||
An optional prefix that every generated interface and virtual local area network name begins with. No prefix is applied by default, so a name is simply the virtual local area network identifier followed by the role, such as "129_Management".
|
||||
|
||||
@@ -248,6 +265,21 @@
|
||||
[Alias('PNML')]
|
||||
[System.Int32]$ParentNetworkMaskLength,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[ValidateRange(16, 30)]
|
||||
[Alias('PNSML')]
|
||||
[System.Int32]$ParentNetworkSubnetMaskLength,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[ValidateRange(1, 4094)]
|
||||
[Alias('SVID')]
|
||||
[System.Int32]$StartingVlanId,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[ValidateRange(1, 4093)]
|
||||
[Alias('VIDI')]
|
||||
[System.Int32]$VlanIdIncrement,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[ValidatePattern('^[A-Za-z0-9]{1,16}$')]
|
||||
@@ -516,6 +548,21 @@ Switch (Test-ProcessElevationStatus)
|
||||
[System.Int32]$ParentNetworkMaskLength = 20
|
||||
}
|
||||
|
||||
{($ParentNetworkSubnetMaskLength -le 0)}
|
||||
{
|
||||
[System.Int32]$ParentNetworkSubnetMaskLength = 24
|
||||
}
|
||||
|
||||
{($StartingVlanId -le 0)}
|
||||
{
|
||||
[System.Int32]$StartingVlanId = 2
|
||||
}
|
||||
|
||||
{($VlanIdIncrement -le 0)}
|
||||
{
|
||||
[System.Int32]$VlanIdIncrement = 1
|
||||
}
|
||||
|
||||
{([System.String]::IsNullOrEmpty($Release) -eq $True) -or ([System.String]::IsNullOrWhiteSpace($Release) -eq $True)}
|
||||
{
|
||||
[System.String]$Release = 'Latest'
|
||||
@@ -768,6 +815,9 @@ Switch (Test-ProcessElevationStatus)
|
||||
$NewOPNSenseNetworkPlanParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
||||
$NewOPNSenseNetworkPlanParameters.BaseNetwork = $BaseNetwork
|
||||
$NewOPNSenseNetworkPlanParameters.ParentNetworkMaskLength = $ParentNetworkMaskLength
|
||||
$NewOPNSenseNetworkPlanParameters.ParentNetworkSubnetMaskLength = $ParentNetworkSubnetMaskLength
|
||||
$NewOPNSenseNetworkPlanParameters.StartingVlanId = $StartingVlanId
|
||||
$NewOPNSenseNetworkPlanParameters.VlanIdIncrement = $VlanIdIncrement
|
||||
$NewOPNSenseNetworkPlanParameters.ExclusionNetworkList = $NetworkExclusionList.ToArray()
|
||||
$NewOPNSenseNetworkPlanParameters.Verbose = $False
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ flowchart TD
|
||||
H -- No --> H1["Report reason and exit 3010 - restart required"]
|
||||
H -- Yes --> I["Get-HostUpstreamDNSConfiguration"]
|
||||
F -- Yes --> I
|
||||
I --> J["New-OPNSenseNetworkPlan - resolve parent network, VLAN tag equals third octet"]
|
||||
I --> J["New-OPNSenseNetworkPlan - resolve parent network, count the VLAN tags"]
|
||||
J --> K["New-RandomPassword and New-OPNSensePasswordHash"]
|
||||
K --> L["New-OPNSenseConfigurationDocument - interfaces, VLANs, Kea, Unbound, aliases, rules"]
|
||||
L --> M["Save-OPNSenseConfigurationDocument - UTF-8 without BOM"]
|
||||
@@ -75,9 +75,8 @@ flowchart TD
|
||||
|
||||
### Addressing
|
||||
|
||||
A **parent network** is divided into `/24` networks. **The VLAN tag of each network is the third
|
||||
octet of its own network address**, which keeps the addressing and the tagging aligned. The first
|
||||
network is the untagged one that the appliance uses as its `lan` interface.
|
||||
A **parent network** is divided into `/24` networks. The first is the untagged one that the appliance
|
||||
uses as its `lan` interface; each of the rest gets a **VLAN tag counted from 2 upwards**.
|
||||
|
||||
You get the parent network one of two ways:
|
||||
|
||||
@@ -97,30 +96,57 @@ Copy that line and you have a repeatable build. Nothing to look up or calculate.
|
||||
`192.168.0.0/16`) and only bounds the random pick - an explicit `-ParentNetwork` is not required to
|
||||
sit inside it.
|
||||
|
||||
**`-ParentNetworkMaskLength` sets how many networks you get**, since the parent is divided into as
|
||||
many `/24`s as fit:
|
||||
**Two mask lengths decide how many networks you get.** The parent is divided into as many subnets as
|
||||
fit inside it:
|
||||
|
||||
| Parent | Networks |
|
||||
| --- | --- |
|
||||
| `/22` | 4 |
|
||||
| `/21` | 8 |
|
||||
| `/20` (default) | 16 |
|
||||
| `/19` | 32 |
|
||||
| | Parameter | Default | What it is |
|
||||
| --- | --- | --- | --- |
|
||||
| Parent | `-ParentNetworkMaskLength` | `20` | How big the whole lab range is |
|
||||
| Subnet | `-ParentNetworkSubnetMaskLength` | `24` | How big each network inside it is |
|
||||
|
||||
An explicit `-ParentNetwork` carries its own mask length, so this is ignored when you pass one.
|
||||
Values beyond the 16 named roles fall back to `Network_Zone_NN`.
|
||||
| Parent | Subnet | Networks |
|
||||
| --- | --- | --- |
|
||||
| `/20` | `/24` (default) | 16 |
|
||||
| `/20` | `/23` | 8 |
|
||||
| `/20` | `/22` | 4 |
|
||||
| `/19` | `/24` | 32 |
|
||||
| `/21` | `/24` | 8 |
|
||||
|
||||
`-ParentNetworkSubnetMaskLength` **always applies.** It describes how the parent is *divided*, not
|
||||
how the parent is *chosen*, so it works the same whether you passed `-ParentNetwork` or let the
|
||||
script pick one. Only `-ParentNetworkMaskLength` is ignored when you pass an explicit
|
||||
`-ParentNetwork`, because that value carries its own mask length.
|
||||
|
||||
The only rule is that the subnet mask length has to be longer than the parent mask length. Networks
|
||||
beyond the 16 named roles fall back to `Network_Zone_NN`.
|
||||
|
||||
### VLAN tags
|
||||
|
||||
Tags are **counted**, not derived from the addressing:
|
||||
|
||||
| Parameter | Default | What it does |
|
||||
| --- | --- | --- |
|
||||
| `-StartingVlanId` | `2` | Tag of the first tagged network |
|
||||
| `-VlanIdIncrement` | `1` | How much each subsequent tag advances by |
|
||||
|
||||
The default of `2` leaves tag `1` alone, since switches commonly use it as their own default VLAN
|
||||
and colliding with that is awkward to diagnose. A larger increment leaves gaps, which is handy if you
|
||||
want tags to carry meaning - `-VlanIdIncrement 10` gives you `2, 12, 22, 32 …`.
|
||||
|
||||
Counting rather than deriving means the tags stay distinct no matter how the parent is divided, so
|
||||
any subnet mask length works. The plan refuses up front if the range would run past `4094`.
|
||||
|
||||
| Interface | VLAN | Network | Gateway | DHCP pool | Name |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `wan` | untagged | DHCP from upstream | - | - | `WAN` |
|
||||
| `lan` | untagged | `10.218.176.0/24` | `10.218.176.1` | `.2` - `.254` | `LAN` |
|
||||
| `opt1` | 177 | `10.218.177.0/24` | `10.218.177.1` | `.2` - `.254` | `177_Management` |
|
||||
| `opt2` | 178 | `10.218.178.0/24` | `10.218.178.1` | `.2` - `.254` | `178_Infrastructure` |
|
||||
| `opt3` | 179 | `10.218.179.0/24` | `10.218.179.1` | `.2` - `.254` | `179_DMZ` |
|
||||
| `opt4` | 180 | `10.218.180.0/24` | `10.218.180.1` | `.2` - `.254` | `180_VPN` |
|
||||
| `opt5` | 181 | `10.218.181.0/24` | `10.218.181.1` | `.2` - `.254` | `181_Guest` |
|
||||
| `opt6` - `opt10` | 182 - 186 | ... | ... | ... | `182_Servers_Zone_001` through `186_Servers_Zone_005` |
|
||||
| `opt11` - `opt15` | 187 - 191 | ... | ... | ... | `187_Clients_Zone_001` through `191_Clients_Zone_005` |
|
||||
| `opt1` | 2 | `10.218.177.0/24` | `10.218.177.1` | `.2` - `.254` | `2_Management` |
|
||||
| `opt2` | 3 | `10.218.178.0/24` | `10.218.178.1` | `.2` - `.254` | `3_Infrastructure` |
|
||||
| `opt3` | 4 | `10.218.179.0/24` | `10.218.179.1` | `.2` - `.254` | `4_DMZ` |
|
||||
| `opt4` | 5 | `10.218.180.0/24` | `10.218.180.1` | `.2` - `.254` | `5_VPN` |
|
||||
| `opt5` | 6 | `10.218.181.0/24` | `10.218.181.1` | `.2` - `.254` | `6_Guest` |
|
||||
| `opt6` - `opt10` | 7 - 11 | ... | ... | ... | `7_Servers_Zone_001` through `11_Servers_Zone_005` |
|
||||
| `opt11` - `opt15` | 12 - 16 | ... | ... | ... | `12_Clients_Zone_001` through `16_Clients_Zone_005` |
|
||||
|
||||
The DHCP pool of each network spans **every usable address it contains** - 253 of them in a `/24`.
|
||||
Only the network address, the broadcast address, and the address of the firewall itself are
|
||||
|
||||
@@ -12,7 +12,7 @@ Function New-OPNSenseConfigurationDocument
|
||||
|
||||
- System identity, name resolution, console, and administrative credentials.
|
||||
- The wide area network interface, the parent local area network interface, and one optional interface per planned virtual local area network.
|
||||
- The virtual local area network device for each planned network, tagged with the third octet of its own network address.
|
||||
- The virtual local area network device for each planned network, carrying the tag that the network plan assigned to it.
|
||||
- A Kea dynamic host configuration protocol scope per network, including the preboot execution environment options.
|
||||
- The Unbound resolver.
|
||||
- A small set of firewall aliases that the rules are written against.
|
||||
|
||||
@@ -9,7 +9,7 @@ Function New-OPNSenseNetworkPlan
|
||||
A parent network is selected out of the specified private base network, and that parent network is then divided into the individual networks that are assigned to the virtual firewall.
|
||||
|
||||
The first resulting network is the untagged network. It is bound directly to the network adapter of the virtual firewall.
|
||||
Every remaining network is assigned a virtual local area network identifier that is calculated from the third octet of its own network address, which keeps the addressing and the tagging aligned and predictable.
|
||||
Every remaining network is assigned a virtual local area network identifier, counted from a starting identifier and advanced by an increment, so the identifiers are consecutive and predictable regardless of how the parent network was divided.
|
||||
|
||||
The dynamic address pool of each network spans every usable address that it contains. Only the network address, the broadcast address, and the address of the firewall itself are excluded, so the pool is expressed as either one or two ranges depending upon where the firewall sits within the network.
|
||||
|
||||
@@ -24,12 +24,26 @@ Function New-OPNSenseNetworkPlan
|
||||
When this parameter is specified, the value is taken as given. It is aligned to its own mask length if it is not already aligned, and it is not required to avoid the exclusion networks, because naming a parent network explicitly is treated as a deliberate choice rather than a suggestion. An overlap is reported as a warning.
|
||||
|
||||
.PARAMETER ParentNetworkMaskLength
|
||||
The mask length of the parent network that is selected out of the base network. This value determines how many networks the plan contains, because the parent network is divided into as many networks of the individual network mask length as fit within it.
|
||||
The mask length of the parent network that is selected out of the base network. Together with the subnet mask length, this value determines how many networks the plan contains, because the parent network is divided into as many networks of the subnet mask length as fit within it.
|
||||
|
||||
This value is ignored when a parent network is specified, because the supplied value carries its own mask length.
|
||||
|
||||
.PARAMETER NetworkMaskLength
|
||||
The mask length of each individual network that the parent network is divided into.
|
||||
.PARAMETER ParentNetworkSubnetMaskLength
|
||||
The mask length of each individual network that the parent network is subnetted into.
|
||||
|
||||
This value always applies. It describes how the parent network is divided rather than how the parent network is chosen, so it is honoured whether the parent network was selected at random or was specified, and the mask length that a specified parent network carries has no bearing upon it.
|
||||
|
||||
This value must be longer than the mask length of the parent network, because a parent network cannot be divided into networks that are the same size as itself or larger.
|
||||
|
||||
.PARAMETER StartingVlanId
|
||||
The virtual local area network identifier that is assigned to the first tagged network. Each subsequent tagged network is assigned the previous identifier plus the increment.
|
||||
|
||||
The default of 2 leaves the identifier of 1 unused, because a switch commonly treats it as its own default network and assigning it here invites a collision that is awkward to diagnose.
|
||||
|
||||
.PARAMETER VlanIdIncrement
|
||||
The amount that the virtual local area network identifier is advanced by for each tagged network after the first.
|
||||
|
||||
The default of 1 numbers the tagged networks consecutively. A larger increment leaves gaps, which is useful when an identifier is meant to carry meaning of its own, such as reserving a decade to each purpose.
|
||||
|
||||
.PARAMETER NamePrefix
|
||||
An optional prefix that every generated name begins with. No prefix is applied by default, so a name is simply the virtual local area network identifier followed by the role, such as "10_Servers_Zone_01".
|
||||
@@ -106,8 +120,18 @@ Function New-OPNSenseNetworkPlan
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[ValidateRange(16, 30)]
|
||||
[Alias('NML')]
|
||||
[System.Int32]$NetworkMaskLength,
|
||||
[Alias('PNSML')]
|
||||
[System.Int32]$ParentNetworkSubnetMaskLength,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[ValidateRange(1, 4094)]
|
||||
[Alias('SVID')]
|
||||
[System.Int32]$StartingVlanId,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[ValidateRange(1, 4093)]
|
||||
[Alias('VIDI')]
|
||||
[System.Int32]$VlanIdIncrement,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
@@ -170,9 +194,19 @@ Function New-OPNSenseNetworkPlan
|
||||
[System.Int32]$ParentNetworkMaskLength = 20
|
||||
}
|
||||
|
||||
{($NetworkMaskLength -le 0)}
|
||||
{($ParentNetworkSubnetMaskLength -le 0)}
|
||||
{
|
||||
[System.Int32]$NetworkMaskLength = 24
|
||||
[System.Int32]$ParentNetworkSubnetMaskLength = 24
|
||||
}
|
||||
|
||||
{($StartingVlanId -le 0)}
|
||||
{
|
||||
[System.Int32]$StartingVlanId = 2
|
||||
}
|
||||
|
||||
{($VlanIdIncrement -le 0)}
|
||||
{
|
||||
[System.Int32]$VlanIdIncrement = 1
|
||||
}
|
||||
|
||||
{([System.String]::IsNullOrEmpty($NamePrefix) -eq $True) -or ([System.String]::IsNullOrWhiteSpace($NamePrefix) -eq $True)}
|
||||
@@ -417,32 +451,59 @@ Function New-OPNSenseNetworkPlan
|
||||
# separate parameter that could disagree with them, so a /20 parent divided into /24 networks is sixteen networks and choosing a different
|
||||
# parent mask length is how the count is changed.
|
||||
|
||||
Switch ($NetworkMaskLength -le $ParentNetworkMaskLength)
|
||||
Switch ($ParentNetworkSubnetMaskLength -le $ParentNetworkMaskLength)
|
||||
{
|
||||
{($_ -eq $True)}
|
||||
{
|
||||
Throw "The individual network mask length of /$($NetworkMaskLength) is not longer than the parent network mask length of /$($ParentNetworkMaskLength), so the parent network cannot be divided."
|
||||
Throw "The individual network mask length of /$($ParentNetworkSubnetMaskLength) is not longer than the parent network mask length of /$($ParentNetworkMaskLength), so the parent network cannot be divided."
|
||||
}
|
||||
}
|
||||
|
||||
$DividedNetworkList = Get-Subnet -IPAddress ($OutputObjectProperties.ParentNetwork) -NewSubnetMask ($NetworkMaskLength) -ErrorAction Stop
|
||||
$DividedNetworkList = Get-Subnet -IPAddress ($OutputObjectProperties.ParentNetwork) -NewSubnetMask ($ParentNetworkSubnetMaskLength) -ErrorAction Stop
|
||||
|
||||
$DividedNetworkListCount = ($DividedNetworkList | Measure-Object).Count
|
||||
|
||||
$WriteLogMessage.Invoke(0, @("The parent network `"$($OutputObjectProperties.ParentNetwork)`" divides into $($DividedNetworkListCount) /$($NetworkMaskLength) network(s), all of which will be included within the plan."))
|
||||
$WriteLogMessage.Invoke(0, @("The parent network `"$($OutputObjectProperties.ParentNetwork)`" divides into $($DividedNetworkListCount) /$($ParentNetworkSubnetMaskLength) network(s), all of which will be included within the plan."))
|
||||
|
||||
#region Determine the range of virtual local area network identifier(s) that will be assigned
|
||||
# The identifiers are counted rather than derived from the addressing. A derived identifier reads well while every network happens to
|
||||
# occupy a whole octet, and stops being possible the moment one does not, because two networks that share an octet would be assigned
|
||||
# the same identifier. Counting them is independent of how the parent network is divided, so any subnet mask length is usable.
|
||||
#
|
||||
# Only the tagged networks consume an identifier, and the untagged network is the first of them, so the count is one fewer than the
|
||||
# number of networks.
|
||||
|
||||
[System.Int32]$TaggedNetworkCount = $DividedNetworkListCount - 1
|
||||
|
||||
Switch ($TaggedNetworkCount -gt 0)
|
||||
{
|
||||
{($_ -eq $True)}
|
||||
{
|
||||
[System.Int32]$HighestVlanId = $StartingVlanId + (($TaggedNetworkCount - 1) * $VlanIdIncrement)
|
||||
|
||||
Switch ($HighestVlanId -gt 4094)
|
||||
{
|
||||
{($_ -eq $True)}
|
||||
{
|
||||
Throw "The $($TaggedNetworkCount) tagged network(s) would be assigned identifiers from $($StartingVlanId) through $($HighestVlanId) in steps of $($VlanIdIncrement), and $($HighestVlanId) is beyond the highest valid identifier of 4094. Reduce the starting identifier, the increment, or the number of networks."
|
||||
}
|
||||
}
|
||||
|
||||
$WriteLogMessage.Invoke(0, @("The $($TaggedNetworkCount) tagged network(s) will be assigned the identifiers $($StartingVlanId) through $($HighestVlanId) in steps of $($VlanIdIncrement)."))
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
[System.Int32]$OptionalInterfaceCounter = 1
|
||||
|
||||
[System.Int32]$VlanId = $StartingVlanId
|
||||
|
||||
For ($DividedNetworkListIndex = 0; $DividedNetworkListIndex -lt $DividedNetworkListCount; $DividedNetworkListIndex++)
|
||||
{
|
||||
$DividedNetwork = $DividedNetworkList[$DividedNetworkListIndex]
|
||||
|
||||
[System.Boolean]$IsUntaggedNetwork = ($DividedNetworkListIndex -eq 0)
|
||||
|
||||
[System.String[]]$NetworkAddressOctetList = "$($DividedNetwork.NetworkAddress)" -isplit '\.'
|
||||
|
||||
[System.Int32]$VlanId = [System.Int32]$NetworkAddressOctetList[2]
|
||||
|
||||
$NetworkObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
||||
$NetworkObjectProperties.Index = $DividedNetworkListIndex
|
||||
$NetworkObjectProperties.IsUntaggedNetwork = $IsUntaggedNetwork
|
||||
@@ -628,6 +689,8 @@ Function New-OPNSenseNetworkPlan
|
||||
|
||||
$OutputObjectProperties.VlanIdList.Add($VlanId)
|
||||
|
||||
[System.Int32]$VlanId = $VlanId + $VlanIdIncrement
|
||||
|
||||
$OptionalInterfaceCounter++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ Every stage of the deployment detects the current state before it acts, so the s
|
||||
|
||||
1. The "Indented.Net.IP" and "Indented.Net.Dns" powershell modules are saved into the toolkit module directory.
|
||||
2. The Hyper-V platform and its powershell management module are detected and installed. When a restart is required, the script exits with exit code 3010 and performs no further action.
|
||||
3. The lab network plan is generated. A parent network is resolved out of the specified private base network and divided into individual networks. The first network is the untagged network and every remaining network becomes a virtual local area network whose tag is the third octet of its own network address.
|
||||
3. The lab network plan is generated. A parent network is resolved out of the specified private base network and divided into individual networks. The first network is the untagged network and every remaining network becomes a virtual local area network whose tag is counted from a starting tag and advanced by an increment.
|
||||
4. The OPNsense installation media is acquired. A disc image that is already present within the content directory is always preferred.
|
||||
5. The OPNsense configuration document is generated and written to the content directory.
|
||||
6. The configuration document is placed onto a secondary virtual hard disk at "\conf\config.xml" so that the OPNsense installer can import it.
|
||||
@@ -26,7 +26,10 @@ Every stage of the deployment detects the current state before it acts, so the s
|
||||
| `DomainName` | `String` | No | DN | The domain name of the appliance. |
|
||||
| `BaseNetwork` | `String` | No | BN | The private base network that a parent network is selected out of. One of the three ranges that RFC 1918 reserves for private use. |
|
||||
| `ParentNetwork` | `String` | No | PN | The parent network to divide into the individual networks, expressed in classless inter-domain routing notation, such as "10.130.240.0/20". When this parameter is not specified, a parent network is selected at random out of the base network, avoiding every network that this host is already attached to. The deployment summary reports the value that was selected, and supplying it back through this parameter reproduces the same plan exactly. When this parameter is specified, the value is taken as given rather than selected. It is aligned to its own mask length if it is not already aligned, and it is not required to sit within the base network or to avoid the networks that this host is attached to, because naming a parent network explicitly is a deliberate choice. Anything unusual about it is reported as a warning. |
|
||||
| `ParentNetworkMaskLength` | `Int32` | No | PNML | The mask length of the parent network that is selected out of the base network. This value determines how many networks the deployment contains, because the parent network is divided into as many networks as fit within it. A parent of "/20" divided into the default "/24" networks is sixteen networks, a "/21" is eight, and a "/19" is thirty two. This value is ignored when a parent network is specified, because the supplied value carries its own mask length. |
|
||||
| `ParentNetworkMaskLength` | `Int32` | No | PNML | The mask length of the parent network that is selected out of the base network. Together with the subnet mask length, this value determines how many networks the deployment contains, because the parent network is divided into as many networks as fit within it. A parent of "/20" divided into the default "/24" networks is sixteen networks, a "/21" is eight, and a "/19" is thirty two. This value is ignored when a parent network is specified, because the supplied value carries its own mask length. |
|
||||
| `ParentNetworkSubnetMaskLength` | `Int32` | No | PNSML | The mask length of each individual network that the parent network is subnetted into. This value always applies. It describes how the parent network is divided rather than how the parent network is chosen, so it is honoured whether the parent network was selected at random or was specified, and the mask length that a specified parent network carries has no bearing upon it. A parent network of "/20" divided by a subnet mask length of "/22" is four networks whether that "/20" was chosen by this script or supplied by the operator. This value must be longer than the mask length of the parent network, because a parent network cannot be divided into networks that are the same size as itself or larger. |
|
||||
| `StartingVlanId` | `Int32` | No | SVID | The virtual local area network tag that is assigned to the first tagged network. Each subsequent tagged network is assigned the previous tag plus the increment. The default of 2 leaves the tag of 1 unused, because a switch commonly treats it as its own default network and assigning it here invites a collision that is awkward to diagnose. |
|
||||
| `VlanIdIncrement` | `Int32` | No | VIDI | The amount that the virtual local area network tag is advanced by for each tagged network after the first. The default of 1 numbers the tagged networks consecutively, so a sixteen network deployment carries the tags 2 through 16. A larger increment leaves gaps, which is useful when a tag is meant to carry meaning of its own, such as reserving a decade to each purpose. |
|
||||
| `NamePrefix` | `String` | No | NP | An optional prefix that every generated interface and virtual local area network name begins with. No prefix is applied by default, so a name is simply the virtual local area network identifier followed by the role, such as "129_Management". |
|
||||
| `NetworkRoleList` | `String[]` | No | NRL | The role names that are assigned to each network, in order. |
|
||||
| `Release` | `String` | No | R | The OPNsense release to deploy, such as "26.1.6". Specify "Latest" to resolve the most recent release that the mirror publishes. |
|
||||
|
||||
@@ -12,7 +12,7 @@ The following sections are populated.
|
||||
|
||||
- System identity, name resolution, console, and administrative credentials.
|
||||
- The wide area network interface, the parent local area network interface, and one optional interface per planned virtual local area network.
|
||||
- The virtual local area network device for each planned network, tagged with the third octet of its own network address.
|
||||
- The virtual local area network device for each planned network, carrying the tag that the network plan assigned to it.
|
||||
- A Kea dynamic host configuration protocol scope per network, including the preboot execution environment options.
|
||||
- The Unbound resolver.
|
||||
- A small set of firewall aliases that the rules are written against.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
A parent network is selected out of the specified private base network, and that parent network is then divided into the individual networks that are assigned to the virtual firewall.
|
||||
|
||||
The first resulting network is the untagged network. It is bound directly to the network adapter of the virtual firewall.
|
||||
Every remaining network is assigned a virtual local area network identifier that is calculated from the third octet of its own network address, which keeps the addressing and the tagging aligned and predictable.
|
||||
Every remaining network is assigned a virtual local area network identifier, counted from a starting identifier and advanced by an increment, so the identifiers are consecutive and predictable regardless of how the parent network was divided.
|
||||
|
||||
The dynamic address pool of each network spans every usable address that it contains. Only the network address, the broadcast address, and the address of the firewall itself are excluded, so the pool is expressed as either one or two ranges depending upon where the firewall sits within the network.
|
||||
|
||||
@@ -19,8 +19,10 @@ The dynamic address pool of each network spans every usable address that it cont
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `BaseNetwork` | `String` | No | BN | The private base network to select a parent network out of. One of the three ranges that RFC 1918 reserves for private use. |
|
||||
| `ParentNetwork` | `String` | No | PN | The parent network to divide into the individual networks, expressed in classless inter-domain routing notation. When this parameter is not specified, a parent network is selected at random out of the base network. The selected value is reported, and supplying it back through this parameter reproduces the same plan exactly. When this parameter is specified, the value is taken as given. It is aligned to its own mask length if it is not already aligned, and it is not required to avoid the exclusion networks, because naming a parent network explicitly is treated as a deliberate choice rather than a suggestion. An overlap is reported as a warning. |
|
||||
| `ParentNetworkMaskLength` | `Int32` | No | PNML | The mask length of the parent network that is selected out of the base network. This value determines how many networks the plan contains, because the parent network is divided into as many networks of the individual network mask length as fit within it. This value is ignored when a parent network is specified, because the supplied value carries its own mask length. |
|
||||
| `NetworkMaskLength` | `Int32` | No | NML | The mask length of each individual network that the parent network is divided into. |
|
||||
| `ParentNetworkMaskLength` | `Int32` | No | PNML | The mask length of the parent network that is selected out of the base network. Together with the subnet mask length, this value determines how many networks the plan contains, because the parent network is divided into as many networks of the subnet mask length as fit within it. This value is ignored when a parent network is specified, because the supplied value carries its own mask length. |
|
||||
| `ParentNetworkSubnetMaskLength` | `Int32` | No | PNSML | The mask length of each individual network that the parent network is subnetted into. This value always applies. It describes how the parent network is divided rather than how the parent network is chosen, so it is honoured whether the parent network was selected at random or was specified, and the mask length that a specified parent network carries has no bearing upon it. This value must be longer than the mask length of the parent network, because a parent network cannot be divided into networks that are the same size as itself or larger. |
|
||||
| `StartingVlanId` | `Int32` | No | SVID | The virtual local area network identifier that is assigned to the first tagged network. Each subsequent tagged network is assigned the previous identifier plus the increment. The default of 2 leaves the identifier of 1 unused, because a switch commonly treats it as its own default network and assigning it here invites a collision that is awkward to diagnose. |
|
||||
| `VlanIdIncrement` | `Int32` | No | VIDI | The amount that the virtual local area network identifier is advanced by for each tagged network after the first. The default of 1 numbers the tagged networks consecutively. A larger increment leaves gaps, which is useful when an identifier is meant to carry meaning of its own, such as reserving a decade to each purpose. |
|
||||
| `NamePrefix` | `String` | No | NP | An optional prefix that every generated name begins with. No prefix is applied by default, so a name is simply the virtual local area network identifier followed by the role, such as "10_Servers_Zone_01". |
|
||||
| `NetworkRoleList` | `String[]` | No | NRL | The role names that are assigned to each network, in order. The first entry is always applied to the untagged network. A role of the form "Servers_Zone_<Index>" or "Clients_Zone_<Index>" is recognised as a zone, which allows the firewall rule generator to grant a client zone access to the server zone that carries the same index. A role that begins with "Management" is recognised as the management network, which is granted access to every other network. |
|
||||
| `ExclusionNetworkList` | `String[]` | No | ENL | One or more networks, expressed in classless inter-domain routing notation, that a randomly selected parent network must not overlap. These are not applied to a parent network that is specified explicitly. |
|
||||
|
||||
@@ -105,8 +105,11 @@ LAN (hn0) -> 10.44.32.1/24
|
||||
43_Clients_Zone_001 … 47_Clients_Zone_005
|
||||
```
|
||||
|
||||
The VLAN tag matches the third octet on every one of them, which is the whole point of the
|
||||
addressing scheme.
|
||||
The VLAN tag matches the third octet on every one of them. **This walkthrough was captured while the
|
||||
tag was derived from the address**, which is no longer how it works - tags are now counted from
|
||||
`-StartingVlanId` (default `2`) in steps of `-VlanIdIncrement` (default `1`), so the same deployment
|
||||
today would name these interfaces `2_Management` through `16_Clients_Zone_005`. The frames are left
|
||||
as they were captured rather than restaged; everything else in them still holds.
|
||||
|
||||

|
||||
|
||||
|
||||
Reference in New Issue
Block a user