diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/conf_mode/vpn_ipsec.py | 11 | ||||
| -rwxr-xr-x | src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook | 58 | 
2 files changed, 23 insertions, 46 deletions
diff --git a/src/conf_mode/vpn_ipsec.py b/src/conf_mode/vpn_ipsec.py index 64d0f6d9d..ebfb21903 100755 --- a/src/conf_mode/vpn_ipsec.py +++ b/src/conf_mode/vpn_ipsec.py @@ -75,7 +75,7 @@ KEY_PATH    = f'{swanctl_dir}/private/'  CA_PATH     = f'{swanctl_dir}/x509ca/'  CRL_PATH    = f'{swanctl_dir}/x509crl/' -DHCP_HOOK_IFLIST = '/tmp/ipsec_dhcp_waiting' +DHCP_HOOK_IFLIST = '/tmp/ipsec_dhcp_interfaces'  def get_config(config=None):      if config: @@ -94,6 +94,7 @@ def get_config(config=None):                                   with_recursive_defaults=True,                                   with_pki=True) +    ipsec['dhcp_interfaces'] = set()      ipsec['dhcp_no_address'] = {}      ipsec['install_routes'] = 'no' if conf.exists(base + ["options", "disable-route-autoinstall"]) else default_install_routes      ipsec['interface_change'] = leaf_node_changed(conf, base + ['interface']) @@ -241,6 +242,8 @@ def verify(ipsec):                      if not os.path.exists(f'{dhcp_base}/dhclient_{dhcp_interface}.conf'):                          raise ConfigError(f"Invalid dhcp-interface on remote-access connection {name}") +                    ipsec['dhcp_interfaces'].add(dhcp_interface) +                      address = get_dhcp_address(dhcp_interface)                      count = 0                      while not address and count < dhcp_wait_attempts: @@ -410,6 +413,8 @@ def verify(ipsec):                  if not os.path.exists(f'{dhcp_base}/dhclient_{dhcp_interface}.conf'):                      raise ConfigError(f"Invalid dhcp-interface on site-to-site peer {peer}") +                ipsec['dhcp_interfaces'].add(dhcp_interface) +                  address = get_dhcp_address(dhcp_interface)                  count = 0                  while not address and count < dhcp_wait_attempts: @@ -527,9 +532,9 @@ def generate(ipsec):          render(charon_conf, 'ipsec/charon.j2', {'install_routes': default_install_routes})          return -    if ipsec['dhcp_no_address']: +    if ipsec['dhcp_interfaces']:          with open(DHCP_HOOK_IFLIST, 'w') as f: -            f.write(" ".join(ipsec['dhcp_no_address'].values())) +            f.write(" ".join(ipsec['dhcp_interfaces']))      elif os.path.exists(DHCP_HOOK_IFLIST):          os.unlink(DHCP_HOOK_IFLIST) diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook index 3f0c9cb7a..ebb100e8b 100755 --- a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook +++ b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook @@ -14,60 +14,32 @@  # You should have received a copy of the GNU General Public License  # along with this program.  If not, see <http://www.gnu.org/licenses/>. -DHCP_HOOK_IFLIST="/tmp/ipsec_dhcp_waiting" +DHCP_HOOK_IFLIST="/tmp/ipsec_dhcp_interfaces" -if [ -f $DHCP_HOOK_IFLIST ] && [ "$reason" == "BOUND" ]; then -    if grep -qw $interface $DHCP_HOOK_IFLIST; then -        sudo rm $DHCP_HOOK_IFLIST -        sudo /usr/libexec/vyos/conf_mode/vpn_ipsec.py -        exit 0 -    fi +if ! { [ -f $DHCP_HOOK_IFLIST ] && grep -qw $interface $DHCP_HOOK_IFLIST; }; then +    exit 0  fi +# Re-generate the config on the following events: +# - BOUND: always re-generate +# - RENEW: re-generate if the IP address changed +# - REBIND: re-generate if the IP address changed  if [ "$reason" == "RENEW" ] || [ "$reason" == "REBIND" ]; then      if [ "$old_ip_address" == "$new_ip_address" ]; then          exit 0      fi -else +elif [ "$reason" != "BOUND" ]; then      exit 0  fi -python3 - <<PYEND -import os -import re - -from vyos.utils.process import call -from vyos.utils.process import cmd -from vyos.utils.file import read_file -from vyos.utils.file import write_file - -SWANCTL_CONF="/etc/swanctl/swanctl.conf" +# Best effort wait for any active commit to finish +sudo python3 - <<PYEND +from vyos.utils.commit import wait_for_commit_lock  if __name__ == '__main__': -    interface = os.getenv('interface') -    new_ip = os.getenv('new_ip_address') -    old_ip = os.getenv('old_ip_address') - -    if os.path.exists(SWANCTL_CONF): -        conf_lines = read_file(SWANCTL_CONF).split("\n") -        found = False -        reset_conns = set() -        to_match = f'# dhcp:{interface}' - -        for i, line in enumerate(conf_lines): -            if line.find(to_match) > 0: -                conf_lines[i] = line.replace(old_ip, new_ip) -                found = True -                regex_match = re.search(r'#.* reset:([-_a-zA-Z0-9|@]+)', line) -                if regex_match: -                   connection_name = regex_match[1] -                   reset_conns.add(connection_name) - -        if found: -            write_file(SWANCTL_CONF, "\n".join(conf_lines)) -            for connection_name in reset_conns: -                call(f'sudo swanctl -t -i {connection_name}') -            call('sudo swanctl -q') - +    wait_for_commit_lock()      exit(0)  PYEND + +# Now re-generate the config +sudo /usr/libexec/vyos/conf_mode/vpn_ipsec.py  | 
