Use a gl-inlet router, HomeAssistant and your digital assistants to turn on/off a whole network VPN

I never had much use for a VPN until I cut the cord. Now that I have, I need to use a VPN so I can watch my blacked-out baseball games. For those that have the same issue, or want to use a VPN to get things like the UK version of Netflix, this might be for you.

VPN provider: I’m not pimping out any specific services. Let’s just say that my service rhymes with board and leave it at that.

The setup: I use a gl-inet router in front of my streaming device (AppleTV 4K) because most streaming devices don’t allow you to create VPN connections. You can do this either by using the LAN port, but this device streams so fast that I’ve had no problems connecting to the router’s SSID. The key point to this is that no matter which/how many devices are connected to the router, if the VPN is enabled on the router, then every client is behind the VPN.

I then uploaded my VPN information to the router, including a few endpoints. I use OpenVPN, but this also works with WireGurd. Once you have your VPN credentials on your router, you can use the router’s API to connect/disconnect from the VPN. Once you can manually connect/disconnect using a browser, using HA to automate the rest is easy.

Create two shell command objects. You will need to change the IP address to match your HA ip.

shell_command:
    gl_inet_set: "curl -X POST -H 'Content-Type: application/json' -H 'Authorization: {{ states.sensor.token.state }}' -d 'enableovpn={{vpn_state}}' -d 'ovpnclientid={{ovpn_clientid}}' -d 'force_client=1' http://172.16.68.47/cgi-bin/api/ovpn/client/set"    
    gl_inet_token: curl 172.16.68.47/cgi-bin/api/router/login -d "pwd=ROUTERPASSWORD" > mdata/token.json

Create a file Sensor to grab the router’s authentication token (you might also need to use allowlist_external_dirs to let HA access the token file).

- platform: file
  name: Token
  file_path: /config/mdata/token.json
  value_template: '{{ value_json.token }}'

Next, create automations to connect/disconnect to the VPN

  - alias: "VPN Connect"
    trigger:
      - platform: state
        entity_id: input_boolean.nord
        to: "on"
    condition:
      - condition: state
        entity_id: 'binary_sensor.allow_automation'
        state: 'on'
    action:
      - service: shell_command.gl_inet_token
      - delay:
          seconds: 4
      - service: shell_command.gl_inet_set
        data_template:
          ovpn_clientid: "ovpn1"
          vpn_state: "1"

  - alias: "VPN Disconnect"
    trigger:
      - platform: state
        entity_id: input_boolean.nord
        to: "off"
    condition:
      - condition: state
        entity_id: 'binary_sensor.allow_automation'
        state: 'on'
    action:
      - service: shell_command.gl_inet_token
      - delay:
          seconds: 4
      - service: shell_command.gl_inet_set
        data_template:
          ovpn_clientid: "ovpn1"
          vpn_state: "0"

Awesome project! I was wanting to do something like this because I have multiple locations that are running HA and would like to have them all centrally controlled by one HA. I already have Wireguard VPN installed.

Are there any details that I am missing or things I should look out for when connecting these?
On the flip side, since I already have Wireguard VPN running couldn’t I make one run in client mode instead of Host? Are there any guides on this?