| $Lang::tr{'enabled'} |
|
- $Lang::tr{'local subnet'}  |
-
-
- |
+ |
+ | $Lang::tr{'local ip address'}: |
+
+ |
$Lang::tr{'remote host/ip'}: $blob |
|
+
+
+ $Lang::tr{'local subnet'}  |
+
+
+ |
$Lang::tr{'remote subnet'} $blob |
-
+
|
@@ -2067,6 +2182,51 @@ END
print "";
&Header::closebox();
+ if ($cgiparams{'TYPE'} eq 'net') {
+ &Header::openbox('100%', 'left', $Lang::tr{'ipsec settings'});
+ print <
+
+
+ | $Lang::tr{'mode'}: |
+
+
+ |
+ |
+
+
+
+ | $Lang::tr{'interface mode'}: |
+
+
+ |
+
+ $Lang::tr{'ip address'}/$Lang::tr{'subnet mask'}: |
+
+
+ |
+
+
+
+ | $Lang::tr{'mtu'}: |
+
+
+ |
+ |
+
+
+
+EOF
+ &Header::closebox();
+ }
+
if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') {
&Header::openbox('100%', 'left', $Lang::tr{'authentication'});
print </dev/null`;
- # suggest a default name for this side
- if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") {
- if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
- my $ipaddr = ;
- close IPADDR;
- chomp ($ipaddr);
- $cgiparams{'VPN_IP'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0];
- if ($cgiparams{'VPN_IP'} eq '') {
- $cgiparams{'VPN_IP'} = $ipaddr;
- }
- }
- }
- # no IP found, use %defaultroute
- $cgiparams{'VPN_IP'} ='%defaultroute' if ($cgiparams{'VPN_IP'} eq '');
-
- $cgiparams{'VPN_DELAYED_START'} = 0 if (! defined ($cgiparams{'VPN_DELAYED_START'}));
$checked{'ENABLED'} = $cgiparams{'ENABLED'} eq 'on' ? "checked='checked'" : '';
&Header::showhttpheaders();
@@ -2782,35 +2934,21 @@ EOF
print <
-
-
-
END
;
@@ -3212,13 +3350,19 @@ sub make_algos($$$$$) {
return &array_unique(\@algos);
}
-sub make_subnets($) {
+sub make_subnets($$) {
+ my $direction = shift;
my $subnets = shift;
my @nets = split(/\|/, $subnets);
my @cidr_nets = ();
foreach my $net (@nets) {
my $cidr_net = &General::ipcidr($net);
+
+ # Skip 0.0.0.0/0 for remote because this renders the
+ # while system inaccessible
+ next if (($direction eq "right") && ($cidr_net eq "0.0.0.0/0"));
+
push(@cidr_nets, $cidr_net);
}
diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl
index 2f3ed41bc..cbb09ef59 100644
--- a/langs/de/cgi-bin/de.pl
+++ b/langs/de/cgi-bin/de.pl
@@ -2717,8 +2717,8 @@
'vpn start action add' => 'Auf Verbindungseingang warten',
'vpn start action route' => 'Bei Bedarf',
'vpn start action start' => 'Immer An',
-'vpn statistic n2n' => 'OpenVPN-Netz-zu-Netz-Statistik',
-'vpn statistic rw' => 'OpenVPN-Roadwarrior-Statistik',
+'vpn statistic n2n' => 'VPN: Netz-zu-Netz-Statistik',
+'vpn statistic rw' => 'VPN: Roadwarrior-Statistik',
'vpn subjectaltname' => 'Subjekt Alternativer Name',
'vpn wait' => 'WARTE',
'vpn watch' => 'Netz-zu-Netz VPN neu starten, wenn sich Remote-IP ändert (DynDNS).',
diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl
index 258176970..4f4b4d9c1 100644
--- a/langs/en/cgi-bin/en.pl
+++ b/langs/en/cgi-bin/en.pl
@@ -684,6 +684,7 @@
'cron server' => 'CRON Server',
'crypto error' => 'Cryptographic error',
'crypto warning' => 'Cryptographic warning',
+'cryptographic settings' => 'Cryptographic Settings',
'current' => 'Current',
'current aliases' => 'Current aliases',
'current class' => 'Current class',
@@ -725,6 +726,7 @@
'deep scan directories' => 'Scan recursive',
'def lease time' => 'Default Lease Time',
'default' => 'Default',
+'default IP address' => 'Default IP Address',
'default ip' => 'Default IP address',
'default lease time' => 'Default lease time (mins):',
'default networks' => 'Default networks',
@@ -1392,6 +1394,7 @@
'instant update' => 'Instant Update',
'integrity' => 'Integrity:',
'interface' => 'Interface',
+'interface mode' => 'Interface',
'interfaces' => 'Interfaces',
'internet' => 'INTERNET',
'intrusion detection' => 'Intrusion Detection',
@@ -1425,10 +1428,15 @@
'invalid input for hostname' => 'Invalid input for hostname.',
'invalid input for ike lifetime' => 'Invalid input for IKE lifetime',
'invalid input for inactivity timeout' => 'Invalid input for Inactivity Timeout',
+'invalid input for interface address' => 'Invalid input for interface address',
+'invalid input for interface mode' => 'Invalid input for interface mode',
+'invalid input for interface mtu' => 'Invalid input to interface MTU',
'invalid input for keepalive 1' => 'Invalid input for Keepalive ping',
'invalid input for keepalive 1:2' => 'Invalid input for Keepalive use at least a ratio of 1:2',
'invalid input for keepalive 2' => 'Invalid input for Keepalive ping-restart',
+'invalid input for local ip address' => 'Invalid input for local IP address',
'invalid input for max clients' => 'Invalid input for Max Clients',
+'invalid input for mode' => 'Invalid input for mode',
'invalid input for name' => 'Invalid input for user\'s full name or system hostname',
'invalid input for oink code' => 'Invalid input for Oink code',
'invalid input for organization' => 'Invalid input for organization',
@@ -1481,8 +1489,15 @@
'ipfires hostname' => 'IPFire\'s Hostname',
'ipinfo' => 'IP info',
'ipsec' => 'IPsec',
+'ipsec connection' => 'IPsec Connection',
+'ipsec interface mode gre' => 'GRE',
+'ipsec interface mode none' => '- None (Default) -',
+'ipsec interface mode vti' => 'VTI',
+'ipsec mode transport' => 'Transport',
+'ipsec mode tunnel' => 'Tunnel',
'ipsec network' => 'IPsec network',
'ipsec no connections' => 'No active IPsec connections',
+'ipsec settings' => 'IPsec Settings',
'iptable rules' => 'IPTable rules',
'iptmangles' => 'IPTable Mangles',
'iptnats' => 'IPTable Network Address Translation',
@@ -1518,6 +1533,7 @@
'load printer' => 'Load Printer',
'loaded modules' => 'Loaded modules:',
'local hard disk' => 'Hard disk',
+'local ip address' => 'Local IP Address',
'local master' => 'Local Master',
'local ntp server specified but not enabled' => 'Local NTP server specified but not enabled',
'local subnet' => 'Local subnet:',
@@ -1684,6 +1700,7 @@
'mpfire search' => 'MPFire Search',
'mpfire songs' => 'MPFire songlist',
'mpfire webradio' => 'MPFire Webradio',
+'mtu' => 'MTU',
'mtu QoS' => 'This does not change the global MTU, it only sets MTU for QoS.',
'my new share' => 'My new share',
'name' => 'Name',
@@ -2239,6 +2256,7 @@
'subject warn' => 'Warning - warnlevel reached',
'subnet' => 'Subnet',
'subnet is invalid' => 'Netmask is invalid',
+'subnet mask' => 'Subnet Mask',
'subscripted user rules' => 'Sourcefire VRT rules with subscription',
'successfully refreshed updates list' => 'Successfully refreshed updates list.',
'summaries kept' => 'Keep summaries for',
@@ -2371,6 +2389,7 @@
'trafficto' => 'To',
'transfer limits' => 'Transfer limits',
'transparent on' => 'Transparent on',
+'transport mode does not support vti' => 'VTI is not support in transport mode',
'tripwire' => 'Tripwire',
'tripwire cronjob' => 'tripwire cronjob',
'tripwire functions' => 'tripwire functions',
@@ -2762,8 +2781,8 @@
'vpn start action add' => 'Wait for connection initiation',
'vpn start action route' => 'On Demand',
'vpn start action start' => 'Always On',
-'vpn statistic n2n' => 'OpenVPN Net-to-Net Statistics',
-'vpn statistic rw' => 'OpenVPN Roadwarrior Statistics',
+'vpn statistic n2n' => 'VPN: Net-to-Net Statistics',
+'vpn statistic rw' => 'VPN: Roadwarrior Statistics',
'vpn subjectaltname' => 'Subject Alt Name',
'vpn wait' => 'WAITING',
'vpn watch' => 'Restart net-to-net vpn when remote peer IP changes (dyndns).',
diff --git a/langs/fr/cgi-bin/fr.pl b/langs/fr/cgi-bin/fr.pl
index b89254b59..3fa686994 100644
--- a/langs/fr/cgi-bin/fr.pl
+++ b/langs/fr/cgi-bin/fr.pl
@@ -2761,8 +2761,8 @@
'vpn start action add' => 'Attendre l\'initialisation de la connexion',
'vpn start action route' => 'A la demande',
'vpn start action start' => 'Toujours démarré',
-'vpn statistic n2n' => 'Stats OpenVPN (site-à-site)',
-'vpn statistic rw' => 'Stats OpenVPN (client nomade)',
+'vpn statistic n2n' => 'Stats VPN (site-à-site)',
+'vpn statistic rw' => 'Stats VPN (client nomade)',
'vpn subjectaltname' => 'Subject Alt Name',
'vpn wait' => 'ATTENTE',
'vpn watch' => 'Redémarrer le VPN site-à-site si l\'IP hôte distant change (dyndns).',
diff --git a/langs/tr/cgi-bin/tr.pl b/langs/tr/cgi-bin/tr.pl
index 53f0afc7a..114d0a297 100644
--- a/langs/tr/cgi-bin/tr.pl
+++ b/langs/tr/cgi-bin/tr.pl
@@ -2750,8 +2750,8 @@
'vpn start action' => 'Hareketi Başlat',
'vpn start action route' => 'İstek Üzerine',
'vpn start action start' => 'Her Zaman',
-'vpn statistic n2n' => 'Ağdan Ağa OpenVPN İstatistiği',
-'vpn statistic rw' => 'Roadwarrior OpenVPN İstatistiği',
+'vpn statistic n2n' => 'Ağdan Ağa VPN İstatistiği',
+'vpn statistic rw' => 'Roadwarrior VPN İstatistiği',
'vpn subjectaltname' => 'Alternatif konu adı',
'vpn watch' => 'Karşı eş IP değiştirdiğinde (dyndns) ağdan-ağa VPN bağlantısını yeniden başlat. Bu DPD ye yardımcı olur.',
'vpn weak' => 'Hafta',
diff --git a/lfs/configroot b/lfs/configroot
index 3cdd780fc..4e6751eee 100644
--- a/lfs/configroot
+++ b/lfs/configroot
@@ -111,7 +111,6 @@ $(TARGET) :
cp $(DIR_SRC)/config/fwhosts/customservices $(CONFIG_ROOT)/fwhosts/customservices.default
# Oneliner configfiles
echo "ENABLED=off" > $(CONFIG_ROOT)/vpn/settings
- echo "VPN_DELAYED_START=0" >>$(CONFIG_ROOT)/vpn/settings
echo "01" > $(CONFIG_ROOT)/certs/serial
echo "nameserver 1.2.3.4" > $(CONFIG_ROOT)/ppp/fake-resolv.conf
echo "DROPNEWNOTSYN=on" >> $(CONFIG_ROOT)/optionsfw/settings
diff --git a/lfs/stage2 b/lfs/stage2
index 7e8dfe316..4b8f0bc81 100644
--- a/lfs/stage2
+++ b/lfs/stage2
@@ -115,8 +115,8 @@ endif
/usr/lib/firewall/rules.pl
install -m 644 $(DIR_SRC)/config/firewall/firewall-lib.pl \
/usr/lib/firewall/firewall-lib.pl
- install -m 755 $(DIR_SRC)/config/firewall/ipsec-block \
- /usr/lib/firewall/ipsec-block
+ install -m 755 $(DIR_SRC)/config/firewall/ipsec-policy \
+ /usr/lib/firewall/ipsec-policy
# Nobody user
-mkdir -p /home/nobody
diff --git a/lfs/strongswan b/lfs/strongswan
index 99261ce93..4174f78fe 100644
--- a/lfs/strongswan
+++ b/lfs/strongswan
@@ -72,6 +72,7 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE)
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/strongswan-disable-ipv6.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/strongswan-ipfire.patch
+ cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/strongswan-ipfire-interfaces.patch
cd $(DIR_APP) && ./configure \
--prefix="/usr" \
diff --git a/src/initscripts/networking/red.up/50-ipsec b/src/initscripts/networking/red.up/50-ipsec
index 99abf4592..c5e043f21 100644
--- a/src/initscripts/networking/red.up/50-ipsec
+++ b/src/initscripts/networking/red.up/50-ipsec
@@ -1,7 +1,3 @@
#!/bin/bash
-eval $(/usr/local/bin/readhash /var/ipfire/vpn/settings)
-
-sleep $VPN_DELAYED_START && /usr/local/bin/ipsecctrl S &
-
-exit 0
+exec /usr/local/bin/ipsecctrl S
diff --git a/src/initscripts/system/firewall b/src/initscripts/system/firewall
index b9dd3485e..2739a6834 100644
--- a/src/initscripts/system/firewall
+++ b/src/initscripts/system/firewall
@@ -360,8 +360,8 @@ iptables_init() {
iptables -t nat -N REDNAT
iptables -t nat -A POSTROUTING -j REDNAT
- # Populate IPsec block chain
- /usr/lib/firewall/ipsec-block
+ # Populate IPsec chains
+ /usr/lib/firewall/ipsec-policy
# Apply OpenVPN firewall rules
/usr/local/bin/openvpnctrl --firewall-rules
diff --git a/src/initscripts/system/network b/src/initscripts/system/network
index b29ca2ca5..6e7120885 100644
--- a/src/initscripts/system/network
+++ b/src/initscripts/system/network
@@ -63,6 +63,9 @@ case "${DO}" in
fi
fi
+ # Create IPsec interfaces
+ /usr/local/bin/ipsec-interfaces
+
/etc/rc.d/init.d/static-routes start
;;
diff --git a/src/misc-progs/ipsecctrl.c b/src/misc-progs/ipsecctrl.c
index 9afc409ca..2a64775f0 100644
--- a/src/misc-progs/ipsecctrl.c
+++ b/src/misc-progs/ipsecctrl.c
@@ -52,42 +52,6 @@ static void ipsec_reload() {
safe_system("/usr/sbin/ipsec reload >/dev/null 2>&1");
}
-/*
- ACCEPT the ipsec protocol ah, esp & udp (for nat traversal) on the specified interface
-*/
-void open_physical (char *interface, int nat_traversal_port) {
- char str[STRING_SIZE];
-
- // IKE
- sprintf(str, "/sbin/iptables --wait -D IPSECINPUT -p udp -i %s --dport 500 -j ACCEPT >/dev/null 2>&1", interface);
- safe_system(str);
- sprintf(str, "/sbin/iptables --wait -A IPSECINPUT -p udp -i %s --dport 500 -j ACCEPT", interface);
- safe_system(str);
- sprintf(str, "/sbin/iptables --wait -D IPSECOUTPUT -p udp -o %s --dport 500 -j ACCEPT >/dev/null 2>&1", interface);
- safe_system(str);
- sprintf(str, "/sbin/iptables --wait -A IPSECOUTPUT -p udp -o %s --dport 500 -j ACCEPT", interface);
- safe_system(str);
-
- if (! nat_traversal_port)
- return;
-
- sprintf(str, "/sbin/iptables --wait -D IPSECINPUT -p udp -i %s --dport %i -j ACCEPT >/dev/null 2>&1", interface, nat_traversal_port);
- safe_system(str);
- sprintf(str, "/sbin/iptables --wait -A IPSECINPUT -p udp -i %s --dport %i -j ACCEPT", interface, nat_traversal_port);
- safe_system(str);
- sprintf(str, "/sbin/iptables --wait -D IPSECOUTPUT -p udp -o %s --dport %i -j ACCEPT >/dev/null 2>&1", interface, nat_traversal_port);
- safe_system(str);
- sprintf(str, "/sbin/iptables --wait -A IPSECOUTPUT -p udp -o %s --dport %i -j ACCEPT", interface, nat_traversal_port);
- safe_system(str);
-}
-
-void ipsec_norules() {
- /* clear input rules */
- safe_system("/sbin/iptables --wait -F IPSECINPUT");
- safe_system("/sbin/iptables --wait -F IPSECFORWARD");
- safe_system("/sbin/iptables --wait -F IPSECOUTPUT");
-}
-
/*
return values from the vpn config file or false if not 'on'
*/
@@ -152,15 +116,18 @@ void turn_connection_on(char *name, char *type) {
"/usr/sbin/ipsec down %s >/dev/null", name);
safe_system(command);
- // Reload the IPsec block chain
- safe_system("/usr/lib/firewall/ipsec-block >/dev/null");
+ // Reload the IPsec firewall policy
+ safe_system("/usr/lib/firewall/ipsec-policy >/dev/null");
+
+ // Create or destroy interfaces
+ safe_system("/usr/local/bin/ipsec-interfaces >/dev/null");
// Reload the configuration into the daemon (#10339).
ipsec_reload();
// Bring the connection up again.
snprintf(command, STRING_SIZE - 1,
- "/usr/sbin/ipsec up %s >/dev/null", name);
+ "/usr/sbin/ipsec stroke up-nb %s >/dev/null", name);
safe_system(command);
}
@@ -182,13 +149,14 @@ void turn_connection_off (char *name) {
// Reload, so the connection is dropped.
ipsec_reload();
- // Reload the IPsec block chain
- safe_system("/usr/lib/firewall/ipsec-block >/dev/null");
+ // Reload the IPsec firewall policy
+ safe_system("/usr/lib/firewall/ipsec-policy >/dev/null");
+
+ // Create or destroy interfaces
+ safe_system("/usr/local/bin/ipsec-interfaces >/dev/null");
}
int main(int argc, char *argv[]) {
- char configtype[STRING_SIZE];
- char redtype[STRING_SIZE] = "";
struct keyvalue *kv = NULL;
if (argc < 2) {
@@ -197,9 +165,8 @@ int main(int argc, char *argv[]) {
}
if (!(initsetuid()))
exit(1);
-
- FILE *file = NULL;
-
+
+ FILE *file = NULL;
if (strcmp(argv[1], "I") == 0) {
safe_system("/usr/sbin/ipsec status");
@@ -219,7 +186,8 @@ int main(int argc, char *argv[]) {
if (argc == 2) {
if (strcmp(argv[1], "D") == 0) {
safe_system("/usr/sbin/ipsec stop >/dev/null 2>&1");
- ipsec_norules();
+ safe_system("/usr/lib/firewall/ipsec-policy >/dev/null");
+ safe_system("/usr/local/bin/ipsec-interfaces >/dev/null");
exit(0);
}
}
@@ -241,82 +209,12 @@ int main(int argc, char *argv[]) {
exit(0);
}
- /* read interface settings */
- kv=initkeyvalues();
- if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings"))
- {
- fprintf(stderr, "Cannot read ethernet settings\n");
- exit(1);
- }
- if (!findkey(kv, "CONFIG_TYPE", configtype))
- {
- fprintf(stderr, "Cannot read CONFIG_TYPE\n");
- exit(1);
- }
- findkey(kv, "RED_TYPE", redtype);
-
-
- /* Loop through the config file to find physical interface that will accept IPSEC */
- int enable_red=0; // states 0: not used
- int enable_green=0; // 1: error condition
- int enable_orange=0; // 2: good
- int enable_blue=0;
- char if_red[STRING_SIZE] = "";
- char if_green[STRING_SIZE] = "";
- char if_orange[STRING_SIZE] = "";
- char if_blue[STRING_SIZE] = "";
char s[STRING_SIZE];
- // when RED is up, find interface name in special file
- FILE *ifacefile = NULL;
- if ((ifacefile = fopen(CONFIG_ROOT "/red/iface", "r"))) {
- if (fgets(if_red, STRING_SIZE, ifacefile)) {
- if (if_red[strlen(if_red) - 1] == '\n')
- if_red[strlen(if_red) - 1] = '\0';
- }
- fclose (ifacefile);
-
- if (VALID_DEVICE(if_red))
- enable_red++;
- }
-
- // Check if GREEN is enabled.
- findkey(kv, "GREEN_DEV", if_green);
- if (VALID_DEVICE(if_green))
- enable_green++;
-
- // Check if ORANGE is enabled.
- findkey(kv, "ORANGE_DEV", if_orange);
- if (VALID_DEVICE(if_orange))
- enable_orange++;
-
- // Check if BLUE is enabled.
- findkey(kv, "BLUE_DEV", if_blue);
- if (VALID_DEVICE(if_blue))
- enable_blue++;
-
- freekeyvalues(kv);
-
- // exit if nothing to do
- if ((enable_red+enable_green+enable_orange+enable_blue) == 0)
- exit(0);
-
- // open needed ports
- if (enable_red > 0)
- open_physical(if_red, 4500);
-
- if (enable_green > 0)
- open_physical(if_green, 4500);
-
- if (enable_orange > 0)
- open_physical(if_orange, 4500);
-
- if (enable_blue > 0)
- open_physical(if_blue, 4500);
-
- // start the system
+ // start the system
if ((argc == 2) && strcmp(argv[1], "S") == 0) {
- safe_system("/usr/lib/firewall/ipsec-block >/dev/null");
+ 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");
exit(0);
}
diff --git a/src/patches/strongswan-ipfire-interfaces.patch b/src/patches/strongswan-ipfire-interfaces.patch
new file mode 100644
index 000000000..5ec96a48a
--- /dev/null
+++ b/src/patches/strongswan-ipfire-interfaces.patch
@@ -0,0 +1,72 @@
+--- strongswan-5.7.0/src/_updown/_updown.in.bak 2019-02-06 18:19:25.723893992 +0000
++++ strongswan-5.7.0/src/_updown/_updown.in 2019-02-06 18:28:21.520560665 +0000
+@@ -130,6 +130,13 @@
+ # address family.
+ #
+
++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
++)
++
+ function ip_encode() {
+ local IFS=.
+
+@@ -319,6 +326,13 @@
+ fi
+ ;;
+ up-client:iptables)
++ # Read IPsec configuration
++ while IFS="," read -r "${VARS[@]}"; do
++ if [ "${PLUTO_CONNECTION}" = "${name}" ]; then
++ break
++ fi
++ done < /var/ipfire/vpn/config
++
+ # connection to client subnet, with (left/right)firewall=yes, coming up
+ # This is used only by the default updown script, not by your custom
+ # ones, so do not mess with it; see CAUTION comment up at top.
+@@ -383,23 +397,25 @@
+ "tunnel+ $PLUTO_PEER -- $PLUTO_ME"
+ fi
+
+- # Add source nat so also the gateway can access the other nets
+- eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
+- for _src in ${GREEN_ADDRESS} ${BLUE_ADDRESS} ${ORANGE_ADDRESS}; do
+- ip_in_subnet "${_src}" "${PLUTO_MY_CLIENT}"
+- if [ $? -eq 0 ]; then
+- src=${_src}
+- break
++ if [ -z "${interface_mode}" ]; then
++ # Add source nat so also the gateway can access the other nets
++ eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
++ for _src in ${GREEN_ADDRESS} ${BLUE_ADDRESS} ${ORANGE_ADDRESS}; do
++ ip_in_subnet "${_src}" "${PLUTO_MY_CLIENT}"
++ if [ $? -eq 0 ]; then
++ src=${_src}
++ break
++ fi
++ done
++
++ if [ -n "${src}" ]; then
++ iptables --wait -t nat -A IPSECNAT -o $PLUTO_INTERFACE -s $PLUTO_ME -d $PLUTO_PEER_CLIENT -j SNAT --to $src
++ logger -t $TAG -p $FAC_PRIO \
++ "snat+ $PLUTO_INTERFACE-$PLUTO_ME : $PLUTO_PEER_CLIENT - $src"
++ else
++ logger -t $TAG -p $FAC_PRIO \
++ "Cannot create NAT rule because no IP of the IPFire does match the subnet. $PLUTO_MY_CLIENT"
+ fi
+- done
+-
+- if [ -n "${src}" ]; then
+- iptables --wait -t nat -A IPSECNAT -o $PLUTO_INTERFACE -s $PLUTO_ME -d $PLUTO_PEER_CLIENT -j SNAT --to $src
+- logger -t $TAG -p $FAC_PRIO \
+- "snat+ $PLUTO_INTERFACE-$PLUTO_ME : $PLUTO_PEER_CLIENT - $src"
+- else
+- logger -t $TAG -p $FAC_PRIO \
+- "Cannot create NAT rule because no IP of the IPFire does match the subnet. $PLUTO_MY_CLIENT"
+ fi
+
+ # Flush routing cache
diff --git a/src/scripts/ipsec-interfaces b/src/scripts/ipsec-interfaces
new file mode 100644
index 000000000..0e43fccbc
--- /dev/null
+++ b/src/scripts/ipsec-interfaces
@@ -0,0 +1,172 @@
+#!/bin/bash
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# Copyright (C) 2015 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 . #
+# #
+###############################################################################
+
+shopt -s nullglob
+
+VPN_CONFIG="/var/ipfire/vpn/config"
+
+eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
+eval $(/usr/local/bin/readhash /var/ipfire/vpn/settings)
+
+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
+)
+
+log() {
+ logger -t ipsec "$@"
+}
+
+resolve_hostname() {
+ local hostname="${1}"
+
+ dig +short A "${hostname}" | tail -n1
+}
+
+main() {
+ # Register local variables
+ local "${VARS[@]}"
+ local action
+
+ local interfaces=()
+
+ # We are done when IPsec is not enabled
+ if [ "${ENABLED}" = "on" ]; then
+ while IFS="," read -r "${VARS[@]}"; do
+ # Check if the connection is enabled
+ [ "${status}" = "on" ] || continue
+
+ # Check if this a net-to-net connection
+ [ "${type}" = "net" ] || continue
+
+ # Determine the interface name
+ case "${interface_mode}" in
+ gre|vti)
+ local intf="${interface_mode}${id}"
+ ;;
+ *)
+ continue
+ ;;
+ esac
+
+ # Add the interface to the list of all interfaces
+ interfaces+=( "${intf}" )
+
+ # Compat for older connections
+ if [ "${local}" = "off" ]; then
+ if [ "${VPN_IP}" = "%defaultroute" ]; then
+ local=""
+ else
+ local="${VPN_IP}"
+ fi
+ fi
+
+ # Handle %defaultroute
+ if [ -z "${local}" ]; then
+ if [ -r "/var/ipfire/red/local-ipaddress" ]; then
+ local="$(/dev/null
+
+ # Create a new interface and bring it up
+ else
+ log "Creating interface ${intf}"
+ if ! ip link add name "${intf}" type "${interface_mode}" "${args[@]}"; then
+ log "Could not create interface ${intf}"
+ continue
+ fi
+ fi
+
+ # Add an IP address
+ ip addr flush dev "${intf}"
+ ip addr add "${interface_address}" dev "${intf}"
+
+ # Set MTU
+ ip link set dev "${intf}" mtu "${interface_mtu}"
+
+ # Bring up the interface
+ ip link set dev "${intf}" up
+ done < "${VPN_CONFIG}"
+ fi
+
+ # Delete all other interfaces
+ local intf
+ for intf in /sys/class/net/gre[0-9]* /sys/class/net/vti[0-9]*; do
+ intf="$(basename "${intf}")"
+
+ # Ignore a couple of interfaces that cannot be deleted
+ case "${intf}" in
+ gre0|gretap0)
+ continue
+ ;;
+ esac
+
+ # Check if interface is on the list
+ local i found="false"
+ for i in ${interfaces[@]}; do
+ if [ "${intf}" = "${i}" ]; then
+ found="true"
+ break
+ fi
+ done
+
+ # Nothing to do if interface was found
+ ${found} && continue
+
+ # Delete the interface
+ log "Deleting interface ${intf}"
+ ip link del "${intf}" &>/dev/null
+ done
+}
+
+main || exit $?