Class: Mt::Wall::DSL::DeviceBuilder
- Inherits:
-
Object
- Object
- Mt::Wall::DSL::DeviceBuilder
- Includes:
- PolicyScope
- Defined in:
- lib/mt/wall/dsl/device_builder.rb
Overview
Block context for the ‘device` verb. Configures the box’s OWN firewall (Layer B), decoupled from the abstract host/group/rule model (Layer A). The abstract grants are device-agnostic and compiled into this device’s forward chain by the Compiler — they are NOT declared here.
Verbs:
* policy <chain>, <action> — override the global chain default
* input / output / forward { } — open a ChainBuilder for that chain
(the box's own input/output rules and the forward baseline, e.g.
established/related/invalid handling)
* nat { } — open a NatBuilder (the box's
`/ip firewall nat` table; IPv4-only for v1)
* management src:, service:, port: — explicitly declare the mgmt
traffic the safe-chain must protect against lockout (else inferred
from the transport). REPEATABLE: each call adds another protected
path; the compiler emits the union of all of them.
device "edge-1", host: "10.0.0.1", transport: :rest_api do
policy :input, :drop
policy :forward, :drop
management src: "admin", service: "ssh" # optional; inferred if omitted
input do
allow_established
drop_invalid
accept protocol: :icmp
accept protocol: :tcp, dst_port: 22, src: "admin" # mgmt access
end
forward do
allow_established
drop_invalid
# global Layer-A grants are injected here, then the default policy
end
nat do
masquerade out_interface: "ether1-wan"
dst_nat protocol: :tcp, dst_port: 443, in_interface: "ether1-wan",
to_addresses: "10.0.0.5", to_ports: 8443
end
end
Instance Method Summary collapse
- #forward(&block) ⇒ void
-
#initialize(name, host:, transport: :rest_api, **options) ⇒ DeviceBuilder
constructor
A new instance of DeviceBuilder.
-
#input { ... } ⇒ void
Open a chain context; collected FilterRules are tagged with the chain.
-
#management(src: nil, service: nil, port: nil) ⇒ void
Explicitly declare the management traffic the safe-chain must keep open (INPUT chain only), so an apply can never lock the operator out.
-
#nat { ... } ⇒ void
Open a NatBuilder context; collected NatRules are stored on the device.
- #output(&block) ⇒ void
-
#record_policy(policy) ⇒ void
PolicyScope storage hook.
-
#to_device ⇒ Model::Device
Materialize the collected policies / filter rules / nat rules / management spec into a Model::Device.
Methods included from PolicyScope
Constructor Details
#initialize(name, host:, transport: :rest_api, **options) ⇒ DeviceBuilder
Returns a new instance of DeviceBuilder.
50 51 52 53 54 55 56 57 58 59 |
# File 'lib/mt/wall/dsl/device_builder.rb', line 50 def initialize(name, host:, transport: :rest_api, **) @name = name @host = host @transport = transport @options = @policies = [] @filter_rules = [] @nat_rules = [] @management = [] end |
Instance Method Details
#forward(&block) ⇒ void
This method returns an undefined value.
74 75 76 |
# File 'lib/mt/wall/dsl/device_builder.rb', line 74 def forward(&block) collect_chain(:forward, &block) end |
#input { ... } ⇒ void
This method returns an undefined value.
Open a chain context; collected FilterRules are tagged with the chain.
64 65 66 |
# File 'lib/mt/wall/dsl/device_builder.rb', line 64 def input(&block) collect_chain(:input, &block) end |
#management(src: nil, service: nil, port: nil) ⇒ void
This method returns an undefined value.
Explicitly declare the management traffic the safe-chain must keep open (INPUT chain only), so an apply can never lock the operator out. EXPLICIT is PRIMARY; ‘src` references a Layer-A host/group, `service` references a Service by name, `port` is a raw port. Stored on Model::Device#management.
REPEATABLE: each call ADDS one protected management path; the Compiler emits the UNION of all of them (so a device can protect, e.g., an SSH admin AND a REST/CI apply channel from different sources). A second call no longer overwrites the first.
This declaration becomes REQUIRED whenever the device locks its input chain (‘policy :input, :drop`): the Compiler FAILS FAST (ConfigurationError) if NO management path is declared. Transport inference is only a best-effort BACKSTOP (full mgmt service set —winbox 8291, ssh 22, api 8728, rest 80/443 — both families) used ONLY when no explicit management path exists, and is NEVER treated as the authoritative human mgmt source when the input chain is locked; the apply-connection source in particular is not authoritative.
management src: "admin", service: "ssh"
management src: "ci", port: 443 # adds a second path
114 115 116 117 118 119 120 121 |
# File 'lib/mt/wall/dsl/device_builder.rb', line 114 def management(src: nil, service: nil, port: nil) Validators.validate_name!(src, label: "management src") if src Validators.validate_name!(service, label: "management service") if service Validators.validate_ports!(port) unless port.nil? spec = { src: src, service: service, port: port }.compact @management << spec unless spec.empty? end |
#nat { ... } ⇒ void
This method returns an undefined value.
Open a NatBuilder context; collected NatRules are stored on the device.
81 82 83 84 85 |
# File 'lib/mt/wall/dsl/device_builder.rb', line 81 def nat(&block) builder = NatBuilder.new builder.instance_eval(&block) if block @nat_rules.concat(builder.rules) end |
#output(&block) ⇒ void
This method returns an undefined value.
69 70 71 |
# File 'lib/mt/wall/dsl/device_builder.rb', line 69 def output(&block) collect_chain(:output, &block) end |
#record_policy(policy) ⇒ void
This method returns an undefined value.
PolicyScope storage hook.
125 126 127 |
# File 'lib/mt/wall/dsl/device_builder.rb', line 125 def record_policy(policy) @policies << policy end |
#to_device ⇒ Model::Device
Materialize the collected policies / filter rules / nat rules / management spec into a Model::Device.
132 133 134 135 136 137 |
# File 'lib/mt/wall/dsl/device_builder.rb', line 132 def to_device Model::Device.new(name: Validators.validate_name!(@name, label: "device"), host: @host, transport: @transport, policies: @policies, filter_rules: @filter_rules, nat_rules: @nat_rules, management: @management, options: @options) end |