I’m looking to automate/script my pfsense wireguard tunnels so that each wireguard tunnel only goes up if there are one or more clients connected to the subnet associated with that tunnel and goes down once all clients have disconnected. I was wondering if there is already a plugin that accomplishes this or can be adapted, otherwise what is best practice for running scripts on the pfsense box?

My initial thought was to have a cronjob monitor the various DHCP servers for each subnet, then initiate a script to connect the associated wireguard tunnel if it detects any active DHCP leases on that subnet.

I have multiple subnets on this box, each with it’s own wireguard gateway. I like the idea of only making the VPN connection if there is a client calling for it.

  • Possibly linux@lemmy.zip
    link
    fedilink
    English
    arrow-up
    2
    ·
    1 day ago

    In OpenWRT land this could be accomplished with a hook

    The question is, do you really need this. Wireguard is a fairly quite protocol and if you open ports on both sides you don’t even need keep alive packets. The connection will stay open but no data will be sent until someone uses it.

  • The thing with a cron job is that it would likely be every minute at best.
    If I connect at 20:25:01 and I have to wait 59 seconds for the next cron pass, it’ll probably be noticeable and annoying.

    I haven’t done pfsense in a while but it shouldn’t be too complicated.
    I think they still use ISC DHCP? If so, I vaguely remember you could use hooks or something event based instead of checking for leases every x time.
    Something like this in dhcpd.conf:

    on commit {
      execute("/path/to/wg-up.sh")
    

    Now… bringing it down is generally less “urgent” and a cron job that checks the number of leases would be fine. Being more instantaneous in bringing it up but taking your time to bring in down would be beneficial and introduce some sort of hysteresis so it flaps less.

    • brownmustardminionOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      edit-2
      21 hours ago

      To my frustration, I’ve tried both your method with ISC and a run_script hook with Kea, and pfsense just overwrites the custom configs. There’s a PR on their github but it’s been sitting there for months.

      • InEnduringGrowStrong@sh.itjust.works@sh.itjust.works
        link
        fedilink
        English
        arrow-up
        1
        ·
        edit-2
        19 hours ago

        Well that’s annoying.
        You could probably read the file where it writes the leases instead. Although that isn’t event based unless you do your own wrapper to check it every second instead of cronus minutes

    • brownmustardminionOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      2 days ago

      That’s a really good point. Thank you.

      ISC DHCP is still used though it may be phased out in a future update. I’m going to take your approach and see how it goes.

      • Also, if you’re using anything with a static IP, monitoring the DHCP obviously won’t work.
        If you got any of those, I’d recommend doing a static DHCP reservation, where the host is still using DHCP, but always gets the same IP.
        I’m not sure how these are handled in regards to the commits hook though.
        Maybe monitoring the ARP table can be useful to you depending on your use case, but then that’s back to a “polling” scenario instead of being event based.
        Actually you could have multiple triggers:

        • Event based hook from the DHCP
        • Polling the ARP table or even pinging a specific static host that isn’t DHCP compatible
        • microphone based detection: When someone in your household yells that it doesn’t work again, bring it up.

        Anyway, calling it from the hook or cronjob kinda becomes an “or” condition for bringing it up: Any one host brings it up, regardless of how you detect them.

        But then you likely still need an “and” condition when bringing it down: All conditions/hosts must be down for a period of time to bring it down.

        Also consider future troubleshooting. Maybe having some sort of toggle to force it up (and disable the wgdown scripts) if only for confirming an hypothesis during a future problem.

        Have fun