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 michael.tremer@ipfire.org --- 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 http://www.gnu.org/licenses/. # +# # +############################################################################### + +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 $?
Charon has some verbose logging enabled by default. This clutters the logs a lot.
This patch disables debug logging but still lets charon log important messages like tunnels that are going up or down.
Signed-off-by: Michael Tremer michael.tremer@ipfire.org --- html/cgi-bin/vpnmain.cgi | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/html/cgi-bin/vpnmain.cgi b/html/cgi-bin/vpnmain.cgi index b3cd3e51e..d2bc70a27 100644 --- a/html/cgi-bin/vpnmain.cgi +++ b/html/cgi-bin/vpnmain.cgi @@ -266,6 +266,9 @@ sub writeipsecfiles { flock CONF, 2; flock SECRETS, 2; print CONF "version 2\n\n"; + print CONF "config setup\n"; + print CONF "\tcharondebug="dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"\n"; + print CONF "\n"; print CONF "conn %default\n"; print CONF "\tkeyingtries=%forever\n"; print CONF "\n";
May I suggest that we also move the IPSec logging into its own file? It seems to me that, even with verbosity reduced, having it in /var/log/messages makes it a pain to locate anything else in the kernel log.
Tom
On 02/05/2020 6:24 AM, Michael Tremer wrote:
Charon has some verbose logging enabled by default. This clutters the logs a lot.
This patch disables debug logging but still lets charon log important messages like tunnels that are going up or down.
Signed-off-by: Michael Tremer michael.tremer@ipfire.org
html/cgi-bin/vpnmain.cgi | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/html/cgi-bin/vpnmain.cgi b/html/cgi-bin/vpnmain.cgi index b3cd3e51e..d2bc70a27 100644 --- a/html/cgi-bin/vpnmain.cgi +++ b/html/cgi-bin/vpnmain.cgi @@ -266,6 +266,9 @@ sub writeipsecfiles { flock CONF, 2; flock SECRETS, 2; print CONF "version 2\n\n";
- print CONF "config setup\n";
- print CONF "\tcharondebug="dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"\n";
- print CONF "\n"; print CONF "conn %default\n"; print CONF "\tkeyingtries=%forever\n"; print CONF "\n";
Hi,
Are those logged messages really useful?
I know that there is a ticket open with this matter, but I am not sure if there is any value in the proposed changes.
https://bugzilla.ipfire.org/show_bug.cgi?id=11001
What are you getting from the logs that you won’t get right now?
I have to enable proper debugging every time I want to have a REALLY detailed look. Otherwise the amount of logs are very verbose and it is hard to find things.
Best, -Michael
On 5 Feb 2020, at 15:25, Tom Rymes trymes@rymes.com wrote:
May I suggest that we also move the IPSec logging into its own file? It seems to me that, even with verbosity reduced, having it in /var/log/messages makes it a pain to locate anything else in the kernel log.
Tom
On 02/05/2020 6:24 AM, Michael Tremer wrote:
Charon has some verbose logging enabled by default. This clutters the logs a lot. This patch disables debug logging but still lets charon log important messages like tunnels that are going up or down. Signed-off-by: Michael Tremer michael.tremer@ipfire.org
html/cgi-bin/vpnmain.cgi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/html/cgi-bin/vpnmain.cgi b/html/cgi-bin/vpnmain.cgi index b3cd3e51e..d2bc70a27 100644 --- a/html/cgi-bin/vpnmain.cgi +++ b/html/cgi-bin/vpnmain.cgi @@ -266,6 +266,9 @@ sub writeipsecfiles { flock CONF, 2; flock SECRETS, 2; print CONF "version 2\n\n";
- print CONF "config setup\n";
- print CONF "\tcharondebug="dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"\n";
- print CONF "\n"; print CONF "conn %default\n"; print CONF "\tkeyingtries=%forever\n"; print CONF "\n";
I have no issue with reducing the amount of verbosity of the current IPSec logging. It has been helpful in the past when troubleshooting a new tunnel, but it's not a major deal.
I was just hoping that whatever remaining messages are left after reducing the verbosity could be directed to /var/log/ipsec instead of /var/log/messages, as the IPSec messages can clutter up the kernel log, which can be annoying. We have 20+ tunnels on two different machines, so it can be quite extensive.
Tom
On 02/05/2020 11:55 AM, Michael Tremer wrote:
Hi,
Are those logged messages really useful?
I know that there is a ticket open with this matter, but I am not sure if there is any value in the proposed changes.
https://bugzilla.ipfire.org/show_bug.cgi?id=11001
What are you getting from the logs that you won’t get right now?
I have to enable proper debugging every time I want to have a REALLY detailed look. Otherwise the amount of logs are very verbose and it is hard to find things.
Best, -Michael
On 5 Feb 2020, at 15:25, Tom Rymes trymes@rymes.com wrote:
May I suggest that we also move the IPSec logging into its own file? It seems to me that, even with verbosity reduced, having it in /var/log/messages makes it a pain to locate anything else in the kernel log.
Tom
On 02/05/2020 6:24 AM, Michael Tremer wrote:
Charon has some verbose logging enabled by default. This clutters the logs a lot. This patch disables debug logging but still lets charon log important messages like tunnels that are going up or down. Signed-off-by: Michael Tremer michael.tremer@ipfire.org
html/cgi-bin/vpnmain.cgi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/html/cgi-bin/vpnmain.cgi b/html/cgi-bin/vpnmain.cgi index b3cd3e51e..d2bc70a27 100644 --- a/html/cgi-bin/vpnmain.cgi +++ b/html/cgi-bin/vpnmain.cgi @@ -266,6 +266,9 @@ sub writeipsecfiles { flock CONF, 2; flock SECRETS, 2; print CONF "version 2\n\n";
- print CONF "config setup\n";
- print CONF "\tcharondebug="dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"\n";
- print CONF "\n"; print CONF "conn %default\n"; print CONF "\tkeyingtries=%forever\n"; print CONF "\n";
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 michael.tremer@ipfire.org
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 http://www.gnu.org/licenses/. # +# # +###############################################################################
+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 $?
Hi,
On 5 Feb 2020, at 15:23, Tom Rymes trymes@rymes.com wrote:
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?
Thank you for looking at this. Good question.
For strongswan there will be no difference any more, but the script that checks the tunnels every 5 minutes will only try to bring up the “always on” tunnels.
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.
I think it is best to not offer these options any more. I suppose this only matters for users where one peer is behind NAT. Then you want to make sure that the tunnel is always up (but wouldn’t you normally always care about this?) or you would want the other side not to initiate a connection.
Best, -Michael
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 michael.tremer@ipfire.org
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";
} my $inactivity_timeout = $lconfighash{$key}[34];$start_action = "route";
@@ -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";
}
} # Fragmentationprint CONF "\tauto=$start_action\n";
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 http://www.gnu.org/licenses/. # +# # +###############################################################################
+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 $?
On 02/05/2020 11:53 AM, Michael Tremer wrote:
Hi,
On 5 Feb 2020, at 15:23, Tom Rymes trymes@rymes.com wrote:
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?
Thank you for looking at this. Good question.
For strongswan there will be no difference any more, but the script that checks the tunnels every 5 minutes will only try to bring up the “always on” tunnels.
OK, I see what you mean. May I suggest that we eliminate the distinction between "Always-On" and "On Demand" and just retain the time limit for inactivity? Tunnels set to have a limited time before being shut down to inactivity shouldn't be brought back up by the script and those that do not should be.
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.
I think it is best to not offer these options any more. I suppose this only matters for users where one peer is behind NAT. Then you want to make sure that the tunnel is always up (but wouldn’t you normally always care about this?) or you would want the other side not to initiate a connection.
Maybe you're saying the same thing I just said up above?
tom
Hi,
On 5 Feb 2020, at 17:19, Tom Rymes trymes@rymes.com wrote:
On 02/05/2020 11:53 AM, Michael Tremer wrote:
Hi,
On 5 Feb 2020, at 15:23, Tom Rymes trymes@rymes.com wrote:
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?
Thank you for looking at this. Good question. For strongswan there will be no difference any more, but the script that checks the tunnels every 5 minutes will only try to bring up the “always on” tunnels.
OK, I see what you mean. May I suggest that we eliminate the distinction between "Always-On" and "On Demand" and just retain the time limit for inactivity? Tunnels set to have a limited time before being shut down to inactivity shouldn't be brought back up by the script and those that do not should be.
That would still change one more thing. We would then decide to always keep all tunnels up. I am not sure if that has any disadvantages for anyone really. But we would definitely have to drop the timeout, too, because otherwise the tunnel will be brought down and the script will bring it back up again shortly after.
This has crossed my mind when I wrote the script today.
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.
I think it is best to not offer these options any more. I suppose this only matters for users where one peer is behind NAT. Then you want to make sure that the tunnel is always up (but wouldn’t you normally always care about this?) or you would want the other side not to initiate a connection.
Maybe you're saying the same thing I just said up above?
Yes :)
tom
On 02/05/2020 12:22 PM, Michael Tremer wrote:
Hi,
On 5 Feb 2020, at 17:19, Tom Rymes trymes@rymes.com wrote:
[snip]
OK, I see what you mean. May I suggest that we eliminate the distinction between "Always-On" and "On Demand" and just retain the time limit for inactivity? Tunnels set to have a limited time before being shut down to inactivity shouldn't be brought back up by the script and those that do not should be.
That would still change one more thing. We would then decide to always keep all tunnels up. I am not sure if that has any disadvantages for anyone really. But we would definitely have to drop the timeout, too, because otherwise the tunnel will be brought down and the script will bring it back up again shortly after.
Sorry for being unclear. There are currently eight options for "Inactivity Timeout", including "Unlimited". I would propose that the script you are adding should only bring back up tunnels whose Inactivity Timeout is set to "Unlimited". A tunnel with a timeout of one hour would time out, go down, and then the script should ignore it.
Does that make sense?
Tom
Hi,
On 5 Feb 2020, at 17:36, Tom Rymes trymes@rymes.com wrote:
On 02/05/2020 12:22 PM, Michael Tremer wrote:
Hi,
On 5 Feb 2020, at 17:19, Tom Rymes trymes@rymes.com wrote:
[snip]
OK, I see what you mean. May I suggest that we eliminate the distinction between "Always-On" and "On Demand" and just retain the time limit for inactivity? Tunnels set to have a limited time before being shut down to inactivity shouldn't be brought back up by the script and those that do not should be.
That would still change one more thing. We would then decide to always keep all tunnels up. I am not sure if that has any disadvantages for anyone really. But we would definitely have to drop the timeout, too, because otherwise the tunnel will be brought down and the script will bring it back up again shortly after.
Sorry for being unclear. There are currently eight options for "Inactivity Timeout", including "Unlimited". I would propose that the script you are adding should only bring back up tunnels whose Inactivity Timeout is set to "Unlimited". A tunnel with a timeout of one hour would time out, go down, and then the script should ignore it.
The inactivity timeout is only active when the connection is in “on demand” mode. The script ignores connections in that mode, so nothing will happen here.
Does that make sense?
Tom
On 02/06/2020 10:03 AM, Michael Tremer wrote:
Hi,
On 5 Feb 2020, at 17:36, Tom Rymes trymes@rymes.com wrote:
[snip]
Sorry for being unclear. There are currently eight options for "Inactivity Timeout", including "Unlimited". I would propose that the script you are adding should only bring back up tunnels whose Inactivity Timeout is set to "Unlimited". A tunnel with a timeout of one hour would time out, go down, and then the script should ignore it.
The inactivity timeout is only active when the connection is in “on demand” mode. The script ignores connections in that mode, so nothing will happen here.
Right, but I had proposed to combine "Always On" and "On Demand" into one, as they will effectively be the same after this proposed change. After this change, unless I am missing something, the only difference will be the "Inactivity Timeout".
If "On Demand" and "Always On" are combined into "Normal" (as opposed to "Wait for connection initiation"), then the script can use the Inactivty timeout to determine which tunnels to bring up. Come to think of it, shouldn't the script also bring up any "On-Demand" tunnels that are set to a timeout of "Unlimited"? I know that we run *all* of our tunnels as "On-Demand/Unlimited" because auto=route is so much more reliable.
It's not really a big deal either way, but if the only difference between "On Demand" and "Always On" after this proposed change is going to be the inactivity timeout, then I'd say merge the two into one and use the Inactivity Timeout of "Unlimited" to denote which tunnels should always be up. It's cleaner and less confusing.
My $0.02.
Tom