I probably misunderstood something here, but if we're setting all tunnels to auto=route, what's the difference between On-Demand and Always-On? Also, this should be a nice improvement for reliability, as lots of folks don't know that choosing "Always-On" means "auto=start", which is far less reliable. Tom On 02/05/2020 6:24 AM, Michael Tremer wrote: > With an IPFire box behind NAT it is difficult to keep an IPsec > VPN up all of the time. On-demand mode does not work when one > side cannot initiate the connection. > > This patch adds a script which will check every 5 minutes or > when RED comes up if all VPNs are up and launch those which > are not. > > This should ensure that we are constantly attempting to > establish the connection. > > Additionally this patch changes that "always-on" VPNs will > be "routed" like "on-demand" connections. When we see traffic, > we will now automatically try to bring up the tunnel. > > Signed-off-by: Michael Tremer > --- > config/cron/crontab | 3 ++ > config/rootfiles/common/aarch64/stage2 | 1 + > config/rootfiles/common/stage2 | 1 + > config/rootfiles/common/x86_64/stage2 | 1 + > html/cgi-bin/vpnmain.cgi | 10 ++++-- > src/misc-progs/ipsecctrl.c | 1 + > src/scripts/ipsec-always-on | 65 ++++++++++++++++++++++++++++++++++ > 7 files changed, 79 insertions(+), 3 deletions(-) > create mode 100644 src/scripts/ipsec-always-on > > diff --git a/config/cron/crontab b/config/cron/crontab > index 56801394e..46cbe6ece 100644 > --- a/config/cron/crontab > +++ b/config/cron/crontab > @@ -30,6 +30,9 @@ HOME=/ > # Update dynamic DNS records every five minutes. > */5 * * * * [ -f "/var/ipfire/red/active" ] && /usr/bin/ddns update-all > > +# Make sure VPNs are up > +*/5 * * * * /usr/local/bin/ipsec-always-on > + > # Logwatch > 05 0 * * * /usr/local/bin/logwatch > /var/log/logwatch/`date -I -d yesterday`; \ > LOGWATCH_KEEP=$(sed -ne 's/^LOGWATCH_KEEP=\([0-9]\+\)$/\1/p' /var/ipfire/logging/settings); \ > diff --git a/config/rootfiles/common/aarch64/stage2 b/config/rootfiles/common/aarch64/stage2 > index f4169a44e..eda34f743 100644 > --- a/config/rootfiles/common/aarch64/stage2 > +++ b/config/rootfiles/common/aarch64/stage2 > @@ -95,6 +95,7 @@ usr/local/bin/convert-dns-settings > usr/local/bin/convert-ovpn > usr/local/bin/filesystem-cleanup > usr/local/bin/hddshutdown > +usr/local/bin/ipsec-always-on > usr/local/bin/ipsec-interfaces > usr/local/bin/makegraphs > usr/local/bin/qosd > diff --git a/config/rootfiles/common/stage2 b/config/rootfiles/common/stage2 > index fca540431..cc0e1dea5 100644 > --- a/config/rootfiles/common/stage2 > +++ b/config/rootfiles/common/stage2 > @@ -94,6 +94,7 @@ usr/local/bin/convert-dns-settings > usr/local/bin/convert-ovpn > usr/local/bin/filesystem-cleanup > usr/local/bin/hddshutdown > +usr/local/bin/ipsec-always-on > usr/local/bin/ipsec-interfaces > usr/local/bin/makegraphs > usr/local/bin/qosd > diff --git a/config/rootfiles/common/x86_64/stage2 b/config/rootfiles/common/x86_64/stage2 > index cc67837e5..28a99ceec 100644 > --- a/config/rootfiles/common/x86_64/stage2 > +++ b/config/rootfiles/common/x86_64/stage2 > @@ -96,6 +96,7 @@ usr/local/bin/convert-dns-settings > usr/local/bin/convert-ovpn > usr/local/bin/filesystem-cleanup > usr/local/bin/hddshutdown > +usr/local/bin/ipsec-always-on > usr/local/bin/ipsec-interfaces > usr/local/bin/makegraphs > usr/local/bin/qosd > diff --git a/html/cgi-bin/vpnmain.cgi b/html/cgi-bin/vpnmain.cgi > index 43cdc5aa0..b3cd3e51e 100644 > --- a/html/cgi-bin/vpnmain.cgi > +++ b/html/cgi-bin/vpnmain.cgi > @@ -453,7 +453,7 @@ sub writeipsecfiles { > > my $start_action = $lconfighash{$key}[33]; > if (!$start_action) { > - $start_action = "start"; > + $start_action = "route"; > } > > my $inactivity_timeout = $lconfighash{$key}[34]; > @@ -466,13 +466,17 @@ sub writeipsecfiles { > print CONF "\tauto=add\n"; > print CONF "\trightsourceip=$lvpnsettings{'RW_NET'}\n"; > } else { > - print CONF "\tauto=$start_action\n"; > - > # If in on-demand mode, we terminate the tunnel > # after 15 min of no traffic > if ($start_action eq 'route' && $inactivity_timeout > 0) { > print CONF "\tinactivity=$inactivity_timeout\n"; > } > + > + # Always route connections so that we have the triggers > + if ($start_action eq "start") { > + $start_action = "route"; > + } > + print CONF "\tauto=$start_action\n"; > } > > # Fragmentation > diff --git a/src/misc-progs/ipsecctrl.c b/src/misc-progs/ipsecctrl.c > index 2a64775f0..54e3b3410 100644 > --- a/src/misc-progs/ipsecctrl.c > +++ b/src/misc-progs/ipsecctrl.c > @@ -216,6 +216,7 @@ int main(int argc, char *argv[]) { > safe_system("/usr/lib/firewall/ipsec-policy >/dev/null"); > safe_system("/usr/local/bin/ipsec-interfaces >/dev/null"); > safe_system("/usr/sbin/ipsec restart >/dev/null"); > + safe_system("/usr/local/bin/ipsec-always-on >/dev/null"); > exit(0); > } > > diff --git a/src/scripts/ipsec-always-on b/src/scripts/ipsec-always-on > new file mode 100644 > index 000000000..34cae169d > --- /dev/null > +++ b/src/scripts/ipsec-always-on > @@ -0,0 +1,65 @@ > +#!/bin/bash > +############################################################################### > +# # > +# IPFire.org - A linux based firewall # > +# Copyright (C) 2020 IPFire Team # > +# # > +# This program is free software: you can redistribute it and/or modify # > +# it under the terms of the GNU General Public License as published by # > +# the Free Software Foundation, either version 3 of the License, or # > +# (at your option) any later version. # > +# # > +# This program is distributed in the hope that it will be useful, # > +# but WITHOUT ANY WARRANTY; without even the implied warranty of # > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # > +# GNU General Public License for more details. # > +# # > +# You should have received a copy of the GNU General Public License # > +# along with this program. If not, see . # > +# # > +############################################################################### > + > +VPN_CONFIG="/var/ipfire/vpn/config" > + > +VARS=( > + id status name lefthost type ctype psk local local_id leftsubnets > + remote_id remote rightsubnets x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 > + x13 x14 x15 x16 x17 x18 x19 proto x20 x21 x22 > + route x23 mode interface_mode interface_address interface_mtu rest > +) > + > +# Load IPsec configuration > +eval $(/usr/local/bin/readhash /var/ipfire/vpn/settings) > + > +log() { > + logger -t ipsec "$@" > +} > + > +main() { > + # Do nothing if IPsec is disabled > + if [ "${ENABLED}" != "on" ]; then > + return 0 > + fi > + > + # Do nothing if we are not online > + if [ ! -e "/var/ipfire/red/active" ]; then > + return 0 > + fi > + > + local "${VARS[@]}" > + while IFS="," read -r "${VARS[@]}"; do > + # Skip disabled connections > + [ "${status}" = "on" ] || continue > + > + # Skip all connections that are not in always-on mode > + [ "${route}" = "start" ] || continue > + > + # If the connection is not up, try bringing it up > + if ! ipsec status "${name}" | grep -q "INSTALLED"; then > + log "Trying to start ${name}..." > + ipsec stroke up-nb "${name}" &>/dev/null > + fi > + done < "${VPN_CONFIG}" > +} > + > +main "$@" || exit $? >