Tuesday, 29 April 2025

Cisco Dual ISP Failover helper script

Is the internet's down?!?!

We all know how dependent daily life relies on internet connections and  how frustrations quickly mount when it fails. For years Cisco IOS versatility has offered various solutions to this problem via IP SLA and Track features to detect failures and reroute traffic via alternative interfaces.

While this solution works reliably, there are some draw backs, particularly where NAT is employed, due to stale translations mapped to failed interfaces. Inconveniently not all failures result in interfaces being down.

So what?

Stale NAT translation persisting after fail-over result in extended interruption, until they timeout. Non-DNS UDP translations time out after 5  minutes; DNS times out in 1 minute. TCP translations time out after 24  hours, unless a RST or FIN is seen on the stream, in which case it times  out in 1 minute.

The common solution

The common solution is the use Cisco IOS Embedded Event Manager (EEM) the automate the clear ip nat translation * command following a fail-over. This sledgehammer approach has drawbacks. Clearing all translations effectively resets all NAT sessions on all interfaces, not just the failed interface. Compounding the issue, is no TCP RST or FIN is sent when the translation is cleared, leading to packets being silently dropped, until the client times out and re-initiates the connection. 

Sadly IOS lacks a command to clear NAT translations per interface, but it does provide a command to clear individual translations... Not exactly useful when you have thousands of translations.

clear ip nat translation $protocol inside $inside_global_ip $inside_global_port $inside_local_ip $inside_local_port outside $outside_local_ip $outside_local_port $outside_global_ip $outside_global_port

Dual ISP config

Before we get into the specifics, I suggest familiarizing yourself  with the standard Dual ISP setup under Cisco IOS.  You'll find plenty of examples online, explaining how to configure a Cisco ISR with multiple ISP connections, employing route maps  and leveraging the IP SLA and Track features of IOS to detect failures and reroute traffic.

Once such example can be found here 


The challenge - Clearing NAT translations per interface.

One of the less known and used features of Cisco IOS is TCL scripting. The below script can be used to selectively clear ip NAT translation per interface, and triggered via EEM in the same manner.

Clearing only the NAT translations on failed interfaces will ensure the smoothest fail-over and avoid unnecessary interruptions, particularly where successive failures occur in close succession.

This method will only clear the translations of an interface that has failed SLA.

Part 1 - The TCL Script

Copy this script to bootflash: or another suitable location.

If you want to verify the operation of the script, you can manually invoke from the enable (#) prompt using; tclsh bootflash:clearnat.tcl <interface>

tclsh bootflash:clearnat.tcl dialer0

The script is basic.
  1. Parses the output of show ip interface to grab the IP
  2. Matching the interface provided in the argument it finds an IPv4 address it continues
  3. Parse the output of show ip nat translations
  4. For each translation, it checks for a match IP the interface
  5. If a match is found, it executes the command clear ip nat translation with the translation parameters.

#!/usr/bin/env tclsh

proc clear_nat_translations {interface} {
	set interface_details [exec "show ip interface $interface"]
    regexp {Internet address is ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)} $interface_details -> interface_ipv4
	
	if {[llength interface_ipv4] == 0} {
		puts ""
		puts "No IPv4 found for $interface"
		return
	}
	
	puts "Clearing NAT translations on $interface. IPv4: $interface_ipv4"
    
	set nat_entries [exec "show ip nat translations"]
    set nat_lines [split $nat_entries "\n"]
	
    foreach line $nat_lines {
        if {[regexp {([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)} $line inside_global_ip]} {
            if {$inside_global_ip == $interface_ipv4} {
				regexp {(tcp|udp)} $line protocol
				regexp {:(\d+)} [lindex $line 1] -> inside_global_port
                regexp {([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)} [lindex $line 2] inside_local_ip
				regexp {:(\d+)} [lindex $line 2] -> inside_local_port
				regexp {([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)} [lindex $line 3] outside_local_ip
				regexp {:(\d+)} [lindex $line 3] -> outside_local_port
                regexp {([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)} [lindex $line 4] outside_global_ip
				regexp {:(\d+)} [lindex $line 4] -> outside_global_port
				
                puts "clear ip nat translation $protocol inside $inside_global_ip $inside_global_port $inside_local_ip $inside_local_port outside $outside_local_ip $outside_local_port $outside_global_ip $outside_global_port"
				exec "clear ip nat translation $protocol inside $inside_global_ip $inside_global_port $inside_local_ip $inside_local_port outside $outside_local_ip $outside_local_port $outside_global_ip $outside_global_port"
            }
        }
    }
}

set argc [llength $argv]

if {$argc == 0} {

    puts ""
    puts "no command line argument passed"

    return
}

set target_interface [lindex $argv 0]
clear_nat_translations $target_interface


Download

Part 2- EEM Trigger


To trigger the script add the following EEM configuration.

event manager applet clear_nat_2 authorization bypass
 event track 5 state any maxrun 10
 action 1.0 syslog msg "Cellular Failover. Clearing NAT Translations"
 action 2.0 cli command "enable"
 action 3.0 cli command "tclsh bootflash:clearnat.tcl cell0/2/0"
 action 4.0 syslog msg "Cleared NAT Translations"
event manager applet clear_nat_1 authorization bypass
 event track 10 state any maxrun 10
 action 1.0 syslog msg "Dialer Failover. Clearing NAT Translations"
 action 2.0 cli command "enable"
 action 3.0 cli command "tclsh bootflash:clearnat.tcl dialer0"
 action 4.0 syslog msg "Cleared NAT Translations"


Hopefully you find this script useful. Please leave a comment if you find it useful, have issues or want to suggest improvements. 👍

Wednesday, 30 October 2024

Uninstall Google Workspace Sync for Microsoft Outlook (GWSMO)

Occasionally the GWSMO installer refuses to uninstall or reinstall. Thankfully a rare problem, but one that has persisted from the GASMO, then GSSMO through to GWSMO. This post will talk about how to manually uninstall Google Workspace Sync for Microsoft Outlook (hereafter referred to as GWSMO).

For one reason or another you have decided to uninstall GWSMO or attempted to reinstall to over come some issue.



Error: MAPI was unable to load the information service C:\Program Files (x86)\Google Apps Sync\gsync.dll

This is particular common where problems have persisted even after you've run through "Set up a Google Apps Sync user" and created a new Outlook profile for your Google Workspace email account.


Where the uninstall fails via add/remove programs, here's how to manually remove GWSMO components, to overcome errors that block reinstallation

  1. Ensure Outlook is not running
  2. Rename the folder C:\Program Files (x86)\Google\Google Apps Sync
    ie. Append '.old' to the folder name
  3. Rename the folder C:\Users\%username%\AppData\Local\Google\Google Apps Sync
    ie. Append '.old' to the folder name
  4. Rerun the installer and configure GWSMO.
  5. Upon completion can confirming all is operating as required, you can safely delete the renamed folders.

Thursday, 10 March 2022


ABC RSS Feeds
Australian Broadcasting Corporation
Where are they?

The ABC has decided to hide the legacy RSS feeds on their site.

Here are the main feeds that previous lived at http://www.abc.net.au/news/feeds/rss/

Sunday, 26 December 2021

Benexmart Irrigation Timer - Tasmota / ESPHome conversion

Finding a cost effective Tuya water timer that can be converted, has been a bit of a hit and miss.

Earlier this year I found this Water Timer. Price was about $60 AUD from AliExpress. The Timer itself uses the TYWE1S module and consists of a single button and relay to control the valve.

Manufacture: Benexmart
Model: FJSJKZQ-TY-W-XV-JS (PCB Markings)

I have been running the timer via the regular Tuya integration with Home Assistant, but had the odd event when it failed to turn off. 

The original vendor listing isn't active, but I found these links.

TuyaSmart Life Store

https://www.aliexpress.com/item/4001244982369.html
https://www.aliexpress.com/item/4001363870790.html





As with recent devices, this was shipped with the newer Tuya firmware that doesn't work with tuya-convert, and needs to be flashed directly via serial.


credit


Important note: Make sure your flasher is set to 3.3v

Opening

Opening the device takes a little patience. Case is glued. I started at the bottom (vents) and pried around, carefully breaking the glue. Once open you can access the 4 screws holding the front plate on. These have a small amount of silicon applied, but easily removed.


Tasmota config

There wasn't an existing Template for this device, but it was simple enough to create.

Device has LED (red), Button and relay. The Green led is linked to the valve state and not controllable independantly.

{"NAME":"FJSJKZQ","GPIO":[0,0,0,0,32,0,0,0,288,0,224,0,0,0],"FLAG":0,"BASE":18}


GPIO4 - Button - 1
GPIO12 - Led - 1
GPIO14 Relay - 1

Other Config

Console commands to configure auto off rule, in case of WiFi/MQTT interruption and (red) LED function.

Set red led to reflect WiFi/MQTT connection state (optional)

LedPower 1

Automatic turn off after 15 minutes (900 Seconds)

Rule1 ON power1#state=1 DO RuleTimer1 900 ENDON ON Rules#Timer=1 DO Power1 off ENDON
Rule1 1

ESPHome Config (Update Feb 24)

This is a sample ESPHome config. It features fail safe to turn off after 60 mins where wifi connection is lost. It leverages a Home Assistant calendar for flexible scheduling. 

esphome:
  name: watervalve
  friendly_name: WaterValve

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "<snip>"

ota:
  password: "<snip>"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  domain: .ha

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Watervalve Fallback Hotspot"
    password: "<snip>"

captive_portal:

web_server:
  port: 80
  auth:
    username: !secret web_server_admin_user
    password: !secret web_server_password

script:
  - id: valve_failsafe
    mode: restart    # Solenoid will be kept on for another 60 minutes since
                     # the latest time the script is executed
    then:
      - logger.log: "FAILSAFE set for 60 minutes"
      #- delay: 1 min
      - delay: 60 min
      - logger.log: "FAILSAFE TRIGGERED!!! Turning off valve"
      - switch.turn_off: water_valve

time:
  - platform: homeassistant
    id: homeassistant_time
    on_time_sync:
      then:
        - logger.log: "Synchronized system clock"

switch:
  - platform: gpio
    pin: GPIO14
    name: water_valve
    id: water_valve
    #restore_mode: always off   # default when power is turned on
    icon: mdi:pipe-valve
    # synchronise the LED with the relay
    on_turn_on:
      then:
        - logger.log: "Water Valve On"
        - output.turn_on: valve_led
        - script.execute: valve_failsafe  # Set timer for 60 minutes
    on_turn_off:
      then:
        - logger.log: "Water Valve Off"
        - output.turn_off: valve_led
        - script.stop: valve_failsafe  # Cancel Set timer for 60 minutes

  - platform: restart
    id: restart_controller

binary_sensor:
  - platform: gpio
    pin: GPIO4
    name: Button
    id: button
    device_class: window
    # when button is pressed, toggle the switch on/off
    on_press:
      then:
        - switch.toggle: water_valve

  - platform: status
    name: Controller status

  - platform: homeassistant
    name: "Irrigation - Rear garden"
    entity_id: calendar.irrigation_water_valve
    on_press:
      then:
        - switch.turn_on: water_valve
    on_release:
      then:
        - switch.turn_off: water_valve

output:
  - platform: gpio
    id: valve_led
    pin: GPIO12
    #restore_mode: always off   # default when power is turned on

sensor:
  - platform: wifi_signal
    name: Garden Controller WiFi Signal
    update_interval: 10s

  - platform: uptime
    name: Garden Controller Uptime




Friday, 12 November 2021

Mirabella Genio Power Plugs - Teardown / Open



This range of plugs can be sourced from Kmart or BigW for about $25-$30 AUD.

Mirabella Genio Wi-Fi Power Plug with Energy Monitoring (I002931) Kmart $25 Mirabella

Mirabella Genio Wi-Fi Double Power Plug with USB Ports (I002932) Kmart $29 Mirabella

New design

The new variety of Mirabella Genio Power Plugs lack screws and are now glued. With a bit of persistence, you can open these with a box cutter and small spatula or similar opening tool.

Mirabella are still using the TYWE2S is this design which is compatible with Tasmota.




Unfortunately these devices run the new Tuya firmware, which prevents using OTA tuya-convert to flash Tasmota or ESPHome.


WARNING - DISCLAIMER
Proceed at your own risk. This information is provided as a guide and you take full responsibility for any harm or damage that may result. Opening any mains powered device should only be done by a professional. I accept no responsibility for any malfunctioning devices as a result of this tutorial. This process will void warranty of the device. Proceed at your own risk.

Opening


Run the boxcutter around the outside, then use the spatula to carefully break the glue.

Once you have separated the sides, insert a the spatula just under the step a lift up. The corners can be a bit stubborn. Release both sides before trying to separate fully.

My favourite is the iSesamo from mymagmat.com, but you can find similar on ebay for half the price.



ISesamo - Ebay













Flashing

Only method available is serial. The TYWE2S IO can be accessed after unscrewing the PCB and separating the backplate. There is sufficient cable length to gain access.


Please see the other blog posts for flashing process.

Wednesday, 19 May 2021

We are sorry, but you do not have access to Please contact your organization administrator for access.

We are sorry, but you do not have access to <service Name>. Please contact  your organization administrator for access.

If you are a Google Workspace user and you see this message, it means your Google Workspace admin has turned off the a Google service for your account .

To resolve the issue, contact you Google Workspace admin or where you are the admin, please consult this article 

https://support.google.com/a/answer/182442?hl=en

Click a service name below for instructions (requires an administrator account).



Google Workspace


Additional Google Services


Google Workspace Marketplace Apps
Calendar
Google Chat
Cloud Search
Directory
Drive
Gmail
Currents
Groups for Business
Jamboard
Keep
Google Meet
Google Voice
Google Sites
Classic Sites
Tasks
Classic Hangouts
Vault

Blogger
Brand Accounts
Google Ads
Google Analytics
Google Cloud
Google Domains
Google Earth
Google Maps
Google My Maps
Google Payments
Google Photos
Google Play
Search and Assistant
Search Console
Web & App Activity
YouTube
Other...

Any Google Workspace Marketplace app



We are sorry, but you do not have access to google maps. Please contact your organization administrator for access.



We are sorry, but you do not have access to google maps. Please contact  your organization administrator for access.

We are sorry, but you do not have access to google maps.



If you are a Google Workspace user and you see this message, it means your Google Workspace admin has turned off the Google Maps service for your account.

Google recently made a change in Workspace admin:


"When the Google Maps service control is set to off, users are prevented from using Google Maps when signed into their Workspace account."


To resolve the issue, contact you Google Workspace admin or where you are the admin, please consult this article https://support.google.com/a/answer/6304830?hl=en