Labels

Sunday, January 17, 2021

Edgerouter-12 setup for isolated Home-Assistant and IOT vlan

 Here is the cli firewall setup that I decided to use on my Edgerouter-12 (ER-12) to isolate the vlan for my home-assistant and IOT equipment.  This equipment is setup to work within my local network.  You still need a DHCP service defined on the ER-12, unless it comes from an external source.  The basics are:


  1. the HA-IOT are allowed to access the internet, they need this to connect to the Wyze servers
  2. the HA-IOT can access each other on the vlan
  3. the HA-IOT can be accessed by specific laptops located on different vlans
  4. the HA-IOT are not allowed to modify configuration on the Edgerouter-12 but can get their DNS and DHCP services from the ER-12
  5. the HA-IOT are not allowed to access any other vlan on the ER-12
  6. other specific vlans are allowed to access the home-assistant server at the 8123 port (not implemented yet)


First we need a Group of addresses for the RFC-1918 private addresses, control laptops, printer, and the HA-IOT vlan addresses:


set firewall group address-group RFC-1918_GROUP address 192.168.0.0/16
set firewall group address-group RFC-1918_GROUP address 172.16.0.0/12
set firewall group address-group RFC-1918_GROUP address 10.0.0.0/8
set firewall group address-group RFC-1918_GROUP description 'RFC-1918 Group'
set firewall group address-group CONTROL_LAPTOP address <control_laptop_1_IP>
set firewall group address-group CONTROL_LAPTOP address <control_laptop_2_IP>
set firewall group address-group CONTROL_LAPTOP description 'Laptop used for Admin on Network'
set firewall group address-group PRINTER address <printer_IP>
set firewall group address-group PRINTER description 'Printer IP on Network'
set firewall group network-group HA-IOT_GROUP description 'ip addresses in HA-IOT vlan'
set firewall group network-group HA-IOT_GROUP network <HA-IOT_vlan_address_range>/24


Next we need a vif off of switch0 for our vlan:


set interfaces switch switch0 vif <HA-IOT_vlan_tag> address <router_address_on_HA-IOT_vlan>/24
set interfaces switch switch0 vif <HA-IOT_vlan_tag> description HA-IOT
set interfaces switch switch0 vif <HA-IOT_vlan_tag> firewall in name HA-IOT_IN
set interfaces switch switch0 vif <HA-IOT_vlan_tag> firewall local name HA-IOT_LOCAL
set interfaces switch switch0 vif <HA-IOT_vlan_tag> firewall out name HA-IOT_OUT
set interfaces switch switch0 vif <HA-IOT_vlan_tag> ip enable-proxy-arp


The rules for traffic from our HA-IOT vlan to the ER-12 [HA-IOT_IN]:


set firewall name HA-IOT_IN default-action accept
set firewall name HA-IOT_IN description 'Guest In'
set firewall name HA-IOT_IN rule 10 action accept
set firewall name HA-IOT_IN rule 10 description 'accept established and related'
set firewall name HA-IOT_IN rule 10 log disable
set firewall name HA-IOT_IN rule 10 protocol all
set firewall name HA-IOT_IN rule 10 state established enable
set firewall name HA-IOT_IN rule 10 state invalid disable
set firewall name HA-IOT_IN rule 10 state new disable
set firewall name HA-IOT_IN rule 10 state related enable
set firewall name HA-IOT_IN rule 20 action reject
set firewall name HA-IOT_IN rule 20 description 'reject invalid packets'
set firewall name HA-IOT_IN rule 20 log disable
set firewall name HA-IOT_IN rule 20 protocol all
set firewall name HA-IOT_IN rule 20 state established disable
set firewall name HA-IOT_IN rule 20 state invalid enable
set firewall name HA-IOT_IN rule 20 state new disable
set firewall name HA-IOT_IN rule 20 state related disable
set firewall name HA-IOT_IN rule 30 action accept
set firewall name HA-IOT_IN rule 30 description 'allow printer'
set firewall name HA-IOT_IN rule 30 destination group address-group PRINTER
set firewall name HA-IOT_IN rule 30 log disable
set firewall name HA-IOT_IN rule 30 protocol all
set firewall name HA-IOT_IN rule 30 source group address-group CONTROL_LAPTOP
set firewall name HA-IOT_IN rule 40 action accept
set firewall name HA-IOT_IN rule 40 description 'accept HA-IOT traffic'
set firewall name HA-IOT_IN rule 40 destination group network-group HA-IOT_GROUP
set firewall name HA-IOT_IN rule 40 log disable
set firewall name HA-IOT_IN rule 40 protocol all
set firewall name HA-IOT_IN rule 50 action drop
set firewall name HA-IOT_IN rule 50 description 'Block RFC-1918 Traffic'
set firewall name HA-IOT_IN rule 50 destination group address-group RFC-1918_GROUP
set firewall name HA-IOT_IN rule 50 log disable
set firewall name HA-IOT_IN rule 50 protocol all


The rules for traffic from our HA-IOT vlan to the ER-12 itself (DNS, DHCP, other services) [HA-IOT_LOCAL]:


set firewall name HA-IOT_LOCAL default-action drop
set firewall name HA-IOT_LOCAL description 'Guest Local'
set firewall name HA-IOT_LOCAL rule 10 action accept
set firewall name HA-IOT_LOCAL rule 10 description 'accept established and related'
set firewall name HA-IOT_LOCAL rule 10 log disable
set firewall name HA-IOT_LOCAL rule 10 protocol all
set firewall name HA-IOT_LOCAL rule 10 state established enable
set firewall name HA-IOT_LOCAL rule 10 state invalid disable
set firewall name HA-IOT_LOCAL rule 10 state new disable
set firewall name HA-IOT_LOCAL rule 10 state related enable
set firewall name HA-IOT_LOCAL rule 20 action reject
set firewall name HA-IOT_LOCAL rule 20 description 'reject invalid packets'
set firewall name HA-IOT_LOCAL rule 20 log disable
set firewall name HA-IOT_LOCAL rule 20 protocol all
set firewall name HA-IOT_LOCAL rule 20 state established disable
set firewall name HA-IOT_LOCAL rule 20 state invalid enable
set firewall name HA-IOT_LOCAL rule 20 state new disable
set firewall name HA-IOT_LOCAL rule 20 state related disable
set firewall name HA-IOT_LOCAL rule 30 action accept
set firewall name HA-IOT_LOCAL rule 30 description 'Allow DHCP'
set firewall name HA-IOT_LOCAL rule 30 destination port 67
set firewall name HA-IOT_LOCAL rule 30 log disable
set firewall name HA-IOT_LOCAL rule 30 protocol udp
set firewall name HA-IOT_LOCAL rule 30 source port 68
set firewall name HA-IOT_LOCAL rule 40 action accept
set firewall name HA-IOT_LOCAL rule 40 description 'Allow DNS'
set firewall name HA-IOT_LOCAL rule 40 destination port 53
set firewall name HA-IOT_LOCAL rule 40 log disable
set firewall name HA-IOT_LOCAL rule 40 protocol tcp_udp


The rules for traffic from the ER-12 to our HA-IOT vlan [HA-IOT_OUT]:


set firewall name HA-IOT_OUT default-action accept
set firewall name HA-IOT_OUT description 'Guest Out'
set firewall name HA-IOT_OUT rule 10 action accept
set firewall name HA-IOT_OUT rule 10 description 'accept established and related'
set firewall name HA-IOT_OUT rule 10 log disable
set firewall name HA-IOT_OUT rule 10 protocol all
set firewall name HA-IOT_OUT rule 10 state established enable
set firewall name HA-IOT_OUT rule 10 state invalid disable
set firewall name HA-IOT_OUT rule 10 state new disable
set firewall name HA-IOT_OUT rule 10 state related enable
set firewall name HA-IOT_OUT rule 20 action reject
set firewall name HA-IOT_OUT rule 20 description 'reject invalid packets'
set firewall name HA-IOT_OUT rule 20 log disable
set firewall name HA-IOT_OUT rule 20 protocol all
set firewall name HA-IOT_OUT rule 20 state established disable
set firewall name HA-IOT_OUT rule 20 state invalid enable
set firewall name HA-IOT_OUT rule 20 state new disable
set firewall name HA-IOT_OUT rule 20 state related disable
set firewall name HA-IOT_OUT rule 40 action accept
set firewall name HA-IOT_OUT rule 40 description 'accept HA-IOT traffic'
set firewall name HA-IOT_OUT rule 40 log disable
set firewall name HA-IOT_OUT rule 40 protocol all
set firewall name HA-IOT_OUT rule 40 source group network-group HA-IOT_GROUP
set firewall name HA-IOT_OUT rule 50 action drop
set firewall name HA-IOT_OUT rule 50 description 'Drop Non-Guest Traffic'
set firewall name HA-IOT_OUT rule 50 log disable
set firewall name HA-IOT_OUT rule 50 protocol all
set firewall name HA-IOT_OUT rule 50 source group address-group RFC-1918_GROUP

Edgerouter-12 setup for completely isolated camera vlan

 Here is the cli firewall setup that I decided to use on my Edgerouter-12 (ER-12) to isolate the vlan for my cameras.  You still need a DHCP service defined on the ER-12, unless it comes from an external source.  The basics are:


  1. the cameras are allowed to access the internet, they need this to connect to the Wyze servers
  2. the cameras cannot access each other on the vlan
  3. the cameras are not allowed to modify configuration on the Edgerouter-12 but can get their DNS and DHCP services from the ER-12
  4. the cameras are not allowed to access any other vlan on the ER-12
  5. this ruleset is patterned after a normal Guest vlan with limited access


First we need a Group of addresses for the RFC-1918 private addresses:


set firewall group address-group RFC-1918_GROUP address 192.168.0.0/16
set firewall group address-group RFC-1918_GROUP address 172.16.0.0/12
set firewall group address-group RFC-1918_GROUP address 10.0.0.0/8
set firewall group address-group RFC-1918_GROUP description 'RFC-1918 Group'


Next we need a vif off of switch0 for our vlan:


set interfaces switch switch0 vif <camera_vlan_tag> address <router_address_on_camera_vlan>/24
set interfaces switch switch0 vif <camera_vlan_tag> description Cameras
set interfaces switch switch0 vif <camera_vlan_tag> firewall in name CAMERA_IN
set interfaces switch switch0 vif <camera_vlan_tag> firewall local name CAMERA_LOCAL
set interfaces switch switch0 vif <camera_vlan_tag> firewall out name CAMERA_OUT
set interfaces switch switch0 vif <camera_vlan_tag> ip enable-proxy-arp


The rules for traffic from our camera vlan to the ER-12 [CAMERA_IN]:


set firewall name CAMERA_IN default-action accept
set firewall name CAMERA_IN description 'Guest In'
set firewall name CAMERA_IN rule 10 action accept
set firewall name CAMERA_IN rule 10 description 'accept established and related'
set firewall name CAMERA_IN rule 10 log disable
set firewall name CAMERA_IN rule 10 protocol all
set firewall name CAMERA_IN rule 10 state established enable
set firewall name CAMERA_IN rule 10 state invalid disable
set firewall name CAMERA_IN rule 10 state new disable
set firewall name CAMERA_IN rule 10 state related enable
set firewall name CAMERA_IN rule 20 action reject
set firewall name CAMERA_IN rule 20 description 'reject invalid packets'
set firewall name CAMERA_IN rule 20 log disable
set firewall name CAMERA_IN rule 20 protocol all
set firewall name CAMERA_IN rule 20 state established disable
set firewall name CAMERA_IN rule 20 state invalid enable
set firewall name CAMERA_IN rule 20 state new disable
set firewall name CAMERA_IN rule 20 state related disable
set firewall name CAMERA_IN rule 30 action drop
set firewall name CAMERA_IN rule 30 description 'Block RFC-1918 Traffic'
set firewall name CAMERA_IN rule 30 destination group address-group RFC-1918_GROUP
set firewall name CAMERA_IN rule 30 log disable
set firewall name CAMERA_IN rule 30 protocol all


The rules for traffic from our camera vlan to the ER-12 itself (DNS, DHCP, other services) [CAMERA_LOCAL]:


set firewall name CAMERA_LOCAL default-action drop
set firewall name CAMERA_LOCAL description 'Guest Local'
set firewall name CAMERA_LOCAL rule 10 action accept
set firewall name CAMERA_LOCAL rule 10 description 'accept established and related'
set firewall name CAMERA_LOCAL rule 10 log disable
set firewall name CAMERA_LOCAL rule 10 protocol all
set firewall name CAMERA_LOCAL rule 10 state established enable
set firewall name CAMERA_LOCAL rule 10 state invalid disable
set firewall name CAMERA_LOCAL rule 10 state new disable
set firewall name CAMERA_LOCAL rule 10 state related enable
set firewall name CAMERA_LOCAL rule 20 action reject
set firewall name CAMERA_LOCAL rule 20 description 'reject invalid packets'
set firewall name CAMERA_LOCAL rule 20 log disable
set firewall name CAMERA_LOCAL rule 20 protocol all
set firewall name CAMERA_LOCAL rule 20 state established disable
set firewall name CAMERA_LOCAL rule 20 state invalid enable
set firewall name CAMERA_LOCAL rule 20 state new disable
set firewall name CAMERA_LOCAL rule 20 state related disable
set firewall name CAMERA_LOCAL rule 30 action accept
set firewall name CAMERA_LOCAL rule 30 description 'Allow DHCP'
set firewall name CAMERA_LOCAL rule 30 destination port 67
set firewall name CAMERA_LOCAL rule 30 log disable
set firewall name CAMERA_LOCAL rule 30 protocol udp
set firewall name CAMERA_LOCAL rule 30 source port 68
set firewall name CAMERA_LOCAL rule 40 action accept
set firewall name CAMERA_LOCAL rule 40 description 'Allow DNS'
set firewall name CAMERA_LOCAL rule 40 destination port 53
set firewall name CAMERA_LOCAL rule 40 log disable
set firewall name CAMERA_LOCAL rule 40 protocol tcp_udp


The rules for traffic from the ER-12 to our camera vlan [CAMERA_OUT]:


set firewall name CAMERA_OUT default-action accept
set firewall name CAMERA_OUT description 'Guest Out'
set firewall name CAMERA_OUT rule 10 action accept
set firewall name CAMERA_OUT rule 10 description 'accept established and related'
set firewall name CAMERA_OUT rule 10 log disable
set firewall name CAMERA_OUT rule 10 protocol all
set firewall name CAMERA_OUT rule 10 state established enable
set firewall name CAMERA_OUT rule 10 state invalid disable
set firewall name CAMERA_OUT rule 10 state new disable
set firewall name CAMERA_OUT rule 10 state related enable
set firewall name CAMERA_OUT rule 20 action reject
set firewall name CAMERA_OUT rule 20 description 'reject invalid packets'
set firewall name CAMERA_OUT rule 20 log disable
set firewall name CAMERA_OUT rule 20 protocol all
set firewall name CAMERA_OUT rule 20 state established disable
set firewall name CAMERA_OUT rule 20 state invalid enable
set firewall name CAMERA_OUT rule 20 state new disable
set firewall name CAMERA_OUT rule 20 state related disable
set firewall name CAMERA_OUT rule 30 action drop
set firewall name CAMERA_OUT rule 30 description 'Drop Non-Guest Traffic'
set firewall name CAMERA_OUT rule 30 log disable
set firewall name CAMERA_OUT rule 30 protocol all
set firewall name CAMERA_OUT rule 30 source group address-group RFC-1918_GROUP

Thursday, January 7, 2021

Thinking of making the IOT network self contained

 It occurred to me that at some time in the future, I might have problems with my network again.  But this time I will probably be more dependent on the elements of the network since I am highly dependent on the router providing DHCP IP addresses and the WAP providing the wifi connection for other elements that require support.  I now think it would be wise to be able to isolate my HA-IOT network from the other part of my network, and still be able to have it work if things happen.  Since I use an Atom based computer for the Home-assistant and MQTT base, I might be able to use that to provide both a WAP and a DHCP/DNS server for the network.  If I do that the wifi port can provide connection for the wifi components, the z-wave adapter for the z-wave components, and if the DHCP/DNS server extends to the HA-IOT vlan as it's control, I don't have to depend upon the router to give me those elements.  If I go on a trip, I can cut off everything else and still have the HA-IOT network working as it needs to be.  Since it is on an UPS, it won't be going down anytime soon.  I just have to figure out how to accomplish this on the Atom processor.

Update: over the weekend 1/9 - 10/2021, I modified the HA-IOT vlan to be completely isolated from other vlans, but at the same time able to communicate within the vlan itself.  It is also isolated from modifying the router or any other switch component in the network.  I am also thinking of changing the bandwidth to the internet to something that is below video capability.  My cameras are on a separate vlan which is isolated from everything due to their nature of using an external server.

Looking at alternatives for the IP Power Strip project

 I have recently discovered the whole Tasmota thing.  It occurred because I finally started setting up some Sonoff switches and Shelly pucks for use with my HA-IOT server.  When I finally pushed the first Tasmota load to a Sonoff switch and set it up as an extension cord.  When I went to Node Red and started controlling the switch, a lot of lights went on in my head.  

Up to this point I have been concentrating on the IP Power Strip as something being controlled by a Raspberry Pi.  Now, I don't need that.  I did however discover that China is going out of their way to prevent the Tasmota from being installed on their products, so OTA changes cannot occur.  They are interested in these products coming under their ecosystem and no other.  I discovered that with a Geeni smart power strip which I was unable to update from an OTA Tasmota push.  I have not at this point, looked into a physical connection with my development system.  I am pretty sure that the initial load onto this device will have had to be done by a physical connection.  I might have to unsolder something to do it.

This change has opened a whole different aspect to getting lights on and off.  I am anxious to get the Shelly pucks to work in my light switches.  As long as I have enough IP address space I should be good.





Tuesday, January 5, 2021

IP Power Strip #06 - Strikedown in a Docker Container

 It occurs to me that the optimal way to implement the strikedown function is to have it in a Docker container.  I was able to locate a Python project from GitHub that does describe a method for launching such a shutdown sequence in a process and alludes to a Docker Container implementation:

- https://pypi.org/project/systemctl-mqtt/

- https://github.com/fphammerle/systemctl-mqtt

- https://github.com/fphammerle/systemctl-mqtt/blob/master/docker-compose.yml

The docker-compose file is especially relevant since it implies a docker container can be built from scratch.  I also note that this implementation requires access to python3-dbus, python3-gi, and python3-paho-mqtt which I believe are all lower level routines.  I will have to implement this container to determine if it meets my needs.

Friday, October 23, 2020

IP Power Strip #05 - Some Operational Considerations for the IP Power Strip Project

 I have discovered that most of what you want to do with a scene in IOT is actually a binary sequence, it either is or isn't performing it's function.  Lights on / off, doors locked / unlocked, security alarmed / not-alarmed, etc.  You have some secondary effects like dimming values or changing a lights color but that is after you turn the light on, likewise with setting the temperature on a furnace.  So in essence it is a two message sequence.  Likewise, if you are shutting down a plug and a computer is connected to it, you would want to send a message to start the shutdown, followed by a timer of so many seconds before you issue the turn off plug message.  

As I have been using Node Red, I realize that it doesn't necessarily scale well, and you are re-deploying the Node Red thread multiple times as you are making changes on different tabs (unless you purposefully select just the new flows before deploy). And if you need to run tests on a separate vlan as you are doing development it breaks the stuff that you already have working. Also, by partitioning the problem up into smaller bits, your Node Red applications can continue to run while you are developing something else. By having the applications in smaller chunks it supports the CI/CD development pipeline.

What do you do if you want to add additional plugs to power your HomeLab network? I need to bring stuff up and down all the time. How do you do this in such a way that it is a minor bump if you add additional power strip plugs to control and additional ways to control them with? What if you need to drop in a dimming controller to be controlled by a new set of Node Red controls without disrupting Node Red flows that already do something that works? What do I do if I need the host that my Node Red flows are running on for something else? Can I simply move it to a different host? What if the host is not an ARM but it's an i386 based processor?

This experiment has everything to do with getting very familiar with Node Red as a prototyping tool. But I also wanted to be able to take down portions of my network (servers, switches, etc.) when I would shift attention to some of my other hobbies like woodworking/woodcarving. I wanted to be able to take on multiple types of smart plugs, some based on RPi hats, some based on wifi power strips, some based on z-wave devices. I wanted to be able to add onto, or subtract from what I was doing without having to continuously update one server worth of Node Red. Doing it in Docker containers has allowed me to move things around easily. I can see this generic control set (Master and multiple Slaves controlling multiple Interfaces to the hardware) being used for all kinds of things IOT wise. I also wanted to have control over what is powered up (including lights) from both home-assistant, NanoMotes and WallMotes and garage controllers without changing either a scene def in home-assistant or changing up my single Node Red instance.

That being said, let me use my experience in other systems to explain why this setup might need multiple instances of Node Red and why that makes sense. Think of those automations that are temporary, with two examples: a test and a temporary power setup.

Say I have an already running automation with Node Red in a Docker container. It is using an MQTT broker as the go between for all the “production” automations. In this case I would like to add some functionality to my “production” automation. If I have my MQTT broker running in a container, I can just spin up another instance on a different host (note different IP). I pull my definition for the automation from a Configuration Management server, like Git, modify the MQTT IP to point to my test MQTT broker and spin up the container (this could be automated with a script). If I require other containers for development I can also pull those, change the MQTT IP, and spin them up before making changes (this could also be part of the same script), I might even need some test driver NR containers as well. I can now make changes as necessary for the new function and test it until I am satisfied it is what I want. I push the definition back to Git. The containers I needed for development and test can now be taken down. I can now deploy the change, that involves taking down the “production” automation container, pulling the updated automation container, setting the MQTT IP for production, and spinning up the new container which now should take the place of the old one. By doing it this way, I have minimized the down time for the “production” automation.

In the case of the temporary power setup, in my experiment, I might need a new automation for part of a Halloween or Christmas display where it changes from year to year as to what lights are lit; or alternatively I might have to set up the lights for a party which I just found out about the night before. In my power experiment I have at the bottom layer, an InterfaceProxy that controls individual power strips, switches, lights or what have you. Each plug is given a name representative of what it is powering (and can be changed on the fly). Each plug also has a semaphore count that dictates whether the plug is turned off or not. The next level up is a Slave Function, which controls a grouping of plugs. Each plug might have more than one grouping assigned to it. The Slave takes care of one grouping of plugs which might go across multiple devices. The Slave knows it’s list of plugs when it is given a list of names. The Slave issues the turn off, turn on when it is commanded. A Master Function controls the whole thing at the top. You only spin up a Slave container when you have a new list of plugs to control. You only spin up an InterfaceProxy container when you have a new set of hardware “plugs” to control.

So for my Christmas lights example, you would bring out the smart power strips (probably Tasmota), spin up one or more InterfaceProxy containers, set the plug names, spin up one or more Slave containers, give the list of plugs to control for each from the Master container after the Slave announces itself, and you can then control your Christmas lights through the Master container. After Christmas the new containers are spun down, smart power strips and lights are put back in storage until next year. For the party example, just feed a list of the plug names that need to be controlled, and the Master container spins up a Slave container and the cycle repeats. The new Slave container goes down after the party.

So development of the MQTT messages that control all this will be paramount.

Monday, October 12, 2020

IP Power Strip #04 - the Strikedown Container

I had suspected that the fastest way to build this was to use node red, at least I know that shutdown and reboot are easily implemented.  The issue is Mac and Ubuntu computers.  I don't think that  I will need to consider PCs (except for the Atom HA-IOT Server which runs Ubuntu).  I got the initial sequence done in node red, however I have not set it up yet to do an actual shutdown/restart - still figuring out the MQTT messages to use.  I decided on the following messages

  • relay/strikedown along with relay/strikedown_answer
    • reboot: 0/1, name: IP1, ping: 0/1
    • if reboot is 0 then does a shutdown
    • if reboot is 1 then does a restart
    • if ping is 1 then starts ping message sequence (5 times with 2 sec in between)
    • note when ping is 1, upon restart the ping sequence will start up
  • relay/myping
    • name: IP1, ping: 0/1
    • if ping is 1 then starts ping message sequence (5 times with 2 sec in between)
    • if ping is 0 then stops ping
    • note when ping is 1, upon restart the ping sequence will start up
  • relay/ping
    • name: IP1

strikedown, the Docker container in node red, will always use port 1885 on each host.  That way, I will be able to get to the node red invocation to make changes.  For strikedown on Raspberry Pi, theer is a node red contrib library that does both functions.  For the one on Ubuntu servers it will have to be made specific to the server.  I am thinking of using Python since there is a Python function node in the contrib library.

The strikedown node red sequence is in two parts, the startup and the strikedown sequence.  The startup sequence is:


The strikedown node red sequence is:


Update: I have since discovered that the Shutdown and Restart Nodes in this sequence do not work under a Docker Container running on RPi.  So I will have to figure out how to accomplish the task in another way.