├── img ├── 1_lan.png ├── 2_dmz.png ├── 3_wan.png ├── 4_all.png └── 0_canvas.png ├── src └── Firewall rules.graffle ├── LICENSE └── README.md /img/1_lan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/didenko/er_poe_fw/HEAD/img/1_lan.png -------------------------------------------------------------------------------- /img/2_dmz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/didenko/er_poe_fw/HEAD/img/2_dmz.png -------------------------------------------------------------------------------- /img/3_wan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/didenko/er_poe_fw/HEAD/img/3_wan.png -------------------------------------------------------------------------------- /img/4_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/didenko/er_poe_fw/HEAD/img/4_all.png -------------------------------------------------------------------------------- /img/0_canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/didenko/er_poe_fw/HEAD/img/0_canvas.png -------------------------------------------------------------------------------- /src/Firewall rules.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/didenko/er_poe_fw/HEAD/src/Firewall rules.graffle -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Vlad Didenko 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the Vlad Didenko nor the names of other 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | `THIS IS A DRAFT. DO NOT USE for constructing a production firewall configuration.` 2 | 3 | EdgeMax firewall basic rules 4 | ============================ 5 | 6 | There are a few templates on the Internet for configuring firewall rules on Ubiquiti _EdgeRouter_ but no from-scratch guide which may be preferred for better understanding. Also, for visual people at least some imagery may be helpful. 7 | 8 | As usual, there are many way to skin a cat. Although there are good practices for configuring firewall rules, there is not a best one. Below is _a way_, to approach the task, without any claims of it's quality or fitness. 9 | 10 | While presenting configuration examples in this write-up, the configuration code is simplified to capture the concepts. In firewall riles `disabled` filters are not shown, unless relevant for understanding. Other lines not relevant in a paragraph context are omitted as well. Finally, empty bracket sequences are also dropped. 11 | 12 | 0. [Interfaces](#interfaces) 13 | 0. [Canvas](#canvas) 14 | 0. [Local network](#local-network) 15 | 0. [Perimeter network](#perimeter-network) 16 | 0. [Internet traffic](#internet-traffic) 17 | 0. [All together](#all-together) 18 | 19 | Interfaces 20 | ---------- 21 | 22 | This write-up walks through a SOHO firewall rules configuration reasoning. It assumes a SOHO setup on _EdgeRouter POE_ with three networks: _LAN_, _WAN_, and _DMZ_. The _LAN_ network is on the single Ethernet connection on `eth0` port of the router. The _WAN_ network is essentially an Ethernet link up to an ISP port via `eth1` port. There are not more than three devices on _DMZ_ in this example, so we will use the build-in switch for that purpose. The `eth2`, `eth3`, and `eth4` ports are assigned to `switch0` interface and all firewall rules then consider only `switch0` as _DMZ_ network interface. 23 | 24 | Here is the relevant extract from the configuration: 25 | 26 | ``` 27 | interfaces { 28 | ethernet eth0 { 29 | description LAN 30 | } 31 | ethernet eth1 { 32 | description WAN 33 | } 34 | ethernet eth2 35 | ethernet eth3 36 | ethernet eth4 37 | switch switch0 { 38 | description DMZ 39 | switch-port { 40 | interface eth2 41 | interface eth3 42 | interface eth4 43 | } 44 | } 45 | } 46 | ``` 47 | 48 | Canvas 49 | ------ 50 | 51 | First the configuration will be presented in visual form on a canvas, like this: 52 | 53 | ![Canvas](img/0_canvas.png) 54 | 55 | The main area is a four-sided field, where three sides dedicated to _LAN_, _DMZ_, and _WAN_ interfaces, as marked. The fourth, right, side does not correspond to an interface, but rather to the `local` traffic destination, designated for the router management. 56 | 57 | Each canvas side is divided in two parts, which correspond to `in` and `out` traffic directions. Traffic always flows from an `in` to an `out` on the canvas, including the imaginary `local` "`out`". If a line does not extend deep into canvas on an `in` side, it depicts traffic flowing "to any destination". Likewise if a line does not extend deep into canvas on an `out` side, it depicts traffic flowing "from any source". 58 | 59 | The type and handling of traffic is shown with colors and shapes of lines and badges in the legend below the canvas above. 60 | 61 | Local network 62 | ------------- 63 | 64 | The _LAN_ network is the most permissive for traffic flowing out of it, yet it also needs to have some safety guards for traffic coming from other directions. Valid incoming traffic (the `in` direction) is allowed to flow to any other destination, while only valid established connections' traffic is allowed to leave from the router into the _LAN_ network (the `out` direction). 65 | 66 | ![LAN](img/1_lan.png) 67 | 68 | The configuration excerpt demonstrates the _LAN_-related rule sets: 69 | 70 | ``` 71 | firewall { 72 | name LAN_IN { 73 | default-action drop 74 | description "incoming on LAN" 75 | rule 1 { 76 | action accept 77 | description "LAN all valid" 78 | state { 79 | established enable 80 | new enable 81 | related enable 82 | } 83 | } 84 | rule 2 { 85 | action drop 86 | description "LAN invalid" 87 | state { 88 | invalid enable 89 | } 90 | } 91 | } 92 | name LAN_OUT { 93 | default-action drop 94 | description "LAN outcoming" 95 | rule 1 { 96 | action accept 97 | description "LAN valid existing" 98 | state { 99 | established enable 100 | related enable 101 | } 102 | } 103 | rule 2 { 104 | action drop 105 | description "LAN new & invalid" 106 | state { 107 | invalid enable 108 | new enable 109 | } 110 | } 111 | } 112 | ... 113 | ``` 114 | 115 | You may notice the similar rule pattern in configuration examples below: first come rules which are percieved to match most common packets - mostly those are permissive rules. Then come other, less frequently matched rules. Finally, the rule set's `default-action` clause set to `drop` which discards all unrecognized traffic as a safety precaution. Note that it may not always be possible to order rules by a perceived frequency of matching, as rules may need another logical order for the rule set to make sense. 116 | 117 | In addition to configuring the rule sets we also need to bind them to interface configuration, like this: 118 | 119 | ``` 120 | ethernet eth0 { 121 | description LAN 122 | firewall { 123 | in { 124 | name LAN_IN 125 | } 126 | out { 127 | name LAN_OUT 128 | } 129 | } 130 | } 131 | ``` 132 | 133 | Perimeter network 134 | ----------------- 135 | 136 | The _DMZ_ side implements a [perimeter network](http://en.wikipedia.org/wiki/DMZ_%28computing%29). The intent is to allow limited controlled access to hosts in DMZ from public Internet (_WAN_ side), while restricting their access to _LOCAL_ and _LAN_ destinations. Here is the graphical representation of intended flows: 137 | 138 | ![DMZ](img/2_dmz.png) 139 | 140 | As pictured above, hosts from _DMZ_ should not reach the router itself (the `local` direction) with any traffic. They should be able to respond to all queries from _LAN_, so _DMZ_ `in` allows valid established traffic towards _LAN_. Host in DMZ should also have unrestricted access to public Internet, so there is an explicit rule accepting new connections from _DMZ_ to _WAN_. Here is the configuration excerpt: 141 | 142 | ``` 143 | name DMZ_IN { 144 | default-action drop 145 | description "incoming on DMZ" 146 | rule 1 { 147 | action accept 148 | description "DMZ valid established" 149 | state { 150 | established enable 151 | related enable 152 | } 153 | } 154 | rule 2 { 155 | action accept 156 | description "DMZ new to WAN" 157 | destination { 158 | group { 159 | address-group ADDRv4_eth1 160 | } 161 | } 162 | state { 163 | new enable 164 | } 165 | } 166 | rule 3 { 167 | action drop 168 | description "DMZ invalid" 169 | state { 170 | invalid enable 171 | } 172 | } 173 | } 174 | name DMZ_LOCAL { 175 | default-action drop 176 | description "DMZ to router" 177 | } 178 | ``` 179 | 180 | Note, that the `DMZ_LOCAL` rule set is empty - we want to dismiss all traffic on that path, so default `drop` action does the job. There are no rules to match, so all traffic fill fall through to the default action. 181 | 182 | As before, it is necessary to bind the rule sets to relevant interface - `switch0`: 183 | 184 | ``` 185 | switch switch0 { 186 | description DMZ 187 | firewall { 188 | in { 189 | name DMZ_IN 190 | } 191 | local { 192 | name DMZ_LOCAL 193 | } 194 | } 195 | switch-port { 196 | interface eth2 197 | interface eth3 198 | interface eth4 199 | } 200 | } 201 | ``` 202 | 203 | Internet traffic 204 | ---------------- 205 | 206 | There are two types of traffic from _WAN_ permitted to pass through the router: 207 | 208 | 0. Any valid communication over already established connections. Presumably most of the connection will be established on requests from _LAN_ and _DMZ_. 209 | 210 | 0. New connection requests to explicitly permitted _host:port_ combinations in DMZ. 211 | 212 | ![WAN](img/3_wan.png) 213 | 214 | When considering actual configuration this example does not provide an example of how to allow a new connection path to DMZ. Such configuration rule should go after the first rule in the `WAN_IN` rule set. Allowing connections from _WAN_ to _DMZ_ sides is a more complex topic and solutions vary depending on the type of application which traffic is being allowed. 215 | 216 | The example also omits throttling and other traffic limits to help with DDOS and similar traffic. 217 | 218 | ``` 219 | name WAN_IN { 220 | default-action drop 221 | description "incoming on WAN" 222 | rule 1 { 223 | action accept 224 | description "WAN valid established" 225 | state { 226 | established enable 227 | related enable 228 | } 229 | } 230 | 231 | /* Rules allowing WAN -> DMZ connections go here. */ 232 | 233 | rule 2 { 234 | action drop 235 | description "WAN new & invalid" 236 | state { 237 | invalid enable 238 | new enable 239 | } 240 | } 241 | } 242 | name WAN_LOCAL { 243 | default-action drop 244 | description "WAN to router" 245 | } 246 | ``` 247 | 248 | Here are the interface bindings: 249 | 250 | ``` 251 | ethernet eth1 { 252 | description WAN 253 | firewall { 254 | in { 255 | name WAN_IN 256 | } 257 | local { 258 | name WAN_LOCAL 259 | } 260 | } 261 | } 262 | ``` 263 | 264 | All together 265 | ============ 266 | 267 | Finally, here is the combined overall picture - and configuration. Hopefully it convinces the reader that is was worth to go over the configuration step-by-step: 268 | 269 | ![ALL](img/4_all.png) 270 | 271 | ``` 272 | firewall { 273 | name DMZ_IN { 274 | default-action drop 275 | description "incoming on DMZ" 276 | rule 1 { 277 | action accept 278 | description "DMZ valid established" 279 | state { 280 | established enable 281 | related enable 282 | } 283 | } 284 | rule 2 { 285 | action accept 286 | description "DMZ new to WAN" 287 | destination { 288 | group { 289 | address-group ADDRv4_eth1 290 | } 291 | } 292 | state { 293 | new enable 294 | } 295 | } 296 | rule 3 { 297 | action drop 298 | description "DMZ invalid" 299 | state { 300 | invalid enable 301 | } 302 | } 303 | } 304 | name DMZ_LOCAL { 305 | default-action drop 306 | description "DMZ to router" 307 | } 308 | name LAN_IN { 309 | default-action drop 310 | description "incoming on LAN" 311 | rule 1 { 312 | action accept 313 | description "LAN all valid" 314 | state { 315 | established enable 316 | new enable 317 | related enable 318 | } 319 | } 320 | rule 2 { 321 | action drop 322 | description "LAN invalid" 323 | state { 324 | invalid enable 325 | } 326 | } 327 | } 328 | name LAN_OUT { 329 | default-action drop 330 | description "LAN outcoming" 331 | rule 1 { 332 | action accept 333 | description "LAN valid existing" 334 | state { 335 | established enable 336 | related enable 337 | } 338 | } 339 | rule 2 { 340 | action drop 341 | description "LAN new & invalid" 342 | state { 343 | invalid enable 344 | new enable 345 | } 346 | } 347 | } 348 | name WAN_IN { 349 | default-action drop 350 | description "incoming on WAN" 351 | rule 1 { 352 | action accept 353 | description "WAN valid established" 354 | state { 355 | established enable 356 | related enable 357 | } 358 | } 359 | 360 | /* Rules allowing WAN -> DMZ connections go here. */ 361 | 362 | rule 2 { 363 | action drop 364 | description "WAN new & invalid" 365 | state { 366 | invalid enable 367 | new enable 368 | } 369 | } 370 | } 371 | name WAN_LOCAL { 372 | default-action drop 373 | description "WAN to router" 374 | } 375 | } 376 | interfaces { 377 | ethernet eth0 { 378 | description LAN 379 | firewall { 380 | in { 381 | name LAN_IN 382 | } 383 | out { 384 | name LAN_OUT 385 | } 386 | } 387 | } 388 | ethernet eth1 { 389 | description WAN 390 | firewall { 391 | in { 392 | name WAN_IN 393 | } 394 | local { 395 | name WAN_LOCAL 396 | } 397 | } 398 | } 399 | ethernet eth2 400 | ethernet eth3 401 | ethernet eth4 402 | switch switch0 { 403 | description DMZ 404 | firewall { 405 | in { 406 | name DMZ_IN 407 | } 408 | local { 409 | name DMZ_LOCAL 410 | } 411 | } 412 | switch-port { 413 | interface eth2 414 | interface eth3 415 | interface eth4 416 | } 417 | } 418 | } 419 | ``` 420 | ------- 421 | --------------------------------------------------------------------------------