IPsec: Fix routing

Message ID 1519917338-3303-1-git-send-email-jonatan.schlag@ipfire.org
State Accepted
Commit 048afd0747a14e4188d9617741962bfb38773f5b
Headers
Series IPsec: Fix routing |

Commit Message

Jonatan Schlag March 2, 2018, 2:15 a.m. UTC
  Based on the examples found in strongswan
we need to specific the source IP for our routes through an IPsec VPN.
If we have no source IP (a router can route packages
which do not belong to the network assigned to our zones) we set no routes,
but clients can still use the tunnel.

For IPsec VPNs in tunnel mode we
also need the device which has the ${PLUTO_ME} IP address asigned.

The source IP  is determined ip_get_assigned_addresses_from_net()
the device is determined by the  device_get_by_ip_address() function.

For tunnel mode see:
https://www.strongswan.org/testing/testresults/ipv6-stroke/net2net-ip4-in-ip6-ikev2/moon.ip.route

Fixes: #11629

Signed-off-by: Jonatan Schlag <jonatan.schlag@ipfire.org>
---
 src/helpers/ipsec-updown | 46 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 7 deletions(-)
  

Comments

Michael Tremer March 2, 2018, 8:06 a.m. UTC | #1
Hello,

thanks for sending in this patch.

I consider this slightly messy since the solution to the problem is not a very
good one. But we don't have anything better either. So I hope we will be able at
some time to come back to this and improve it a little bit.

-Michael

On Thu, 2018-03-01 at 15:15 +0000, Jonatan Schlag wrote:
> Based on the examples found in strongswan
> we need to specific the source IP for our routes through an IPsec VPN.
> If we have no source IP (a router can route packages
> which do not belong to the network assigned to our zones) we set no routes,
> but clients can still use the tunnel.
> 
> For IPsec VPNs in tunnel mode we
> also need the device which has the ${PLUTO_ME} IP address asigned.
> 
> The source IP  is determined ip_get_assigned_addresses_from_net()
> the device is determined by the  device_get_by_ip_address() function.
> 
> For tunnel mode see:
> https://www.strongswan.org/testing/testresults/ipv6-stroke/net2net-ip4-in-ip6-
> ikev2/moon.ip.route
> 
> Fixes: #11629
> 
> Signed-off-by: Jonatan Schlag <jonatan.schlag@ipfire.org>
> ---
>  src/helpers/ipsec-updown | 46 +++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 39 insertions(+), 7 deletions(-)
> 
> diff --git a/src/helpers/ipsec-updown b/src/helpers/ipsec-updown
> index 12ead03..3764085 100644
> --- a/src/helpers/ipsec-updown
> +++ b/src/helpers/ipsec-updown
> @@ -86,13 +86,45 @@ case "${PLUTO_VERB}" in
>  				;;
>  		esac
>  
> -		# Set routes
> -		if isset INTERFACE; then
> -			cmd ip route add "${PLUTO_PEER_CLIENT}" \
> -				dev "${INTERFACE}"
> -		else
> -			cmd ip route add "${PLUTO_PEER_CLIENT}" \
> -				via "${PLUTO_PEER}"
> +		#Get sources IP for routes
> +		SRC_IP=($(ip_get_assigned_addresses_from_net \
> +			"${PLUTO_MY_CLIENT}" "permanent"))
> +
> +		# Set routes if we have a source IP.
> +		# If not the machine does not has a leg on the net
> +		# and we can go on without routes.
> +		if isset SRC_IP; then
> +			# We take the lowest source IP we found,
> +			# which is ugly because the value is unpredictable.
> +			SRC_IP=${SRC_IP[0]}
> +
> +			if isset INTERFACE; then
> +				if ! cmd ip route add \
> +					"${PLUTO_PEER_CLIENT}" \
> +					dev "${INTERFACE}" \
> +					src "${SRC_IP}"; then
> +						log ERROR \
> +							"Could not set routes
> for ${PLUTO_PEER_CLIENT}"
> +				fi
> +			else
> +				# Get the device which we use to peer with
> the other site.
> +				ME_DEVICE = "$(device_get_by_ip_address
> "${PLUTO_ME}")"
> +
> +				# We can only go on if we found a device.
> +				if isset ME_DEVICE; then
> +					if ! cmd ip route add \
> +						"${PLUTO_PEER_CLIENT}" \
> +						dev "${ME_DEVICE}" \
> +						proto static \
> +						src "${SRC_IP}" \
> +						table 220; then
> +							log ERROR \
> +								"Could not
> set routes for ${PLUTO_PEER_CLIENT}"
> +					fi
> +				else
> +					log ERROR "Could not get device for
> ${PLUTO_ME}"
> +				fi
> +			fi
>  		fi
>  		;;
>
  

Patch

diff --git a/src/helpers/ipsec-updown b/src/helpers/ipsec-updown
index 12ead03..3764085 100644
--- a/src/helpers/ipsec-updown
+++ b/src/helpers/ipsec-updown
@@ -86,13 +86,45 @@  case "${PLUTO_VERB}" in
 				;;
 		esac
 
-		# Set routes
-		if isset INTERFACE; then
-			cmd ip route add "${PLUTO_PEER_CLIENT}" \
-				dev "${INTERFACE}"
-		else
-			cmd ip route add "${PLUTO_PEER_CLIENT}" \
-				via "${PLUTO_PEER}"
+		#Get sources IP for routes
+		SRC_IP=($(ip_get_assigned_addresses_from_net \
+			"${PLUTO_MY_CLIENT}" "permanent"))
+
+		# Set routes if we have a source IP.
+		# If not the machine does not has a leg on the net
+		# and we can go on without routes.
+		if isset SRC_IP; then
+			# We take the lowest source IP we found,
+			# which is ugly because the value is unpredictable.
+			SRC_IP=${SRC_IP[0]}
+
+			if isset INTERFACE; then
+				if ! cmd ip route add \
+					"${PLUTO_PEER_CLIENT}" \
+					dev "${INTERFACE}" \
+					src "${SRC_IP}"; then
+						log ERROR \
+							"Could not set routes for ${PLUTO_PEER_CLIENT}"
+				fi
+			else
+				# Get the device which we use to peer with the other site.
+				ME_DEVICE = "$(device_get_by_ip_address "${PLUTO_ME}")"
+
+				# We can only go on if we found a device.
+				if isset ME_DEVICE; then
+					if ! cmd ip route add \
+						"${PLUTO_PEER_CLIENT}" \
+						dev "${ME_DEVICE}" \
+						proto static \
+						src "${SRC_IP}" \
+						table 220; then
+							log ERROR \
+								"Could not set routes for ${PLUTO_PEER_CLIENT}"
+					fi
+				else
+					log ERROR "Could not get device for ${PLUTO_ME}"
+				fi
+			fi
 		fi
 		;;