|
|
cfcb48 |
commit 9a69641b34675de26c3989082795ab97325db55c
|
|
|
cfcb48 |
Author: Paul Wouters <pwouters@redhat.com>
|
|
|
cfcb48 |
Date: Mon Mar 1 14:57:31 2021 -0500
|
|
|
cfcb48 |
|
|
|
cfcb48 |
IKEv2: Fix TCP socket to have IP_XFRM_POLICY sockopt set.
|
|
|
cfcb48 |
|
|
|
cfcb48 |
Without this, transport mode or host-to-host will not properly work
|
|
|
cfcb48 |
on a number of kernels, such as RHEL8 4.18.0-291.el8.x86_64
|
|
|
cfcb48 |
|
|
|
cfcb48 |
Reported by: Sabrina Dubroca <sdubroca@redhat.com>
|
|
|
cfcb48 |
|
|
|
cfcb48 |
diff --git a/programs/pluto/iface_tcp.c b/programs/pluto/iface_tcp.c
|
|
|
cfcb48 |
index 9a66343f3f..3b4f57d07d 100644
|
|
|
cfcb48 |
--- a/programs/pluto/iface_tcp.c
|
|
|
cfcb48 |
+++ b/programs/pluto/iface_tcp.c
|
|
|
cfcb48 |
@@ -52,6 +52,16 @@
|
|
|
cfcb48 |
#include "nat_traversal.h" /* for nat_traversal_enabled which seems like a broken idea */
|
|
|
cfcb48 |
#include "pluto_stats.h"
|
|
|
cfcb48 |
|
|
|
cfcb48 |
+/* work around weird combo's of glibc and kernel header conflicts */
|
|
|
cfcb48 |
+#ifndef GLIBC_KERN_FLIP_HEADERS
|
|
|
cfcb48 |
+# include "linux/xfrm.h" /* local (if configured) or system copy */
|
|
|
cfcb48 |
+# include "libreswan.h"
|
|
|
cfcb48 |
+#else
|
|
|
cfcb48 |
+# include "libreswan.h"
|
|
|
cfcb48 |
+# include "linux/xfrm.h" /* local (if configured) or system copy */
|
|
|
cfcb48 |
+#endif
|
|
|
cfcb48 |
+
|
|
|
cfcb48 |
+
|
|
|
cfcb48 |
static void accept_ike_in_tcp_cb(struct evconnlistener *evcon UNUSED,
|
|
|
cfcb48 |
int accepted_fd,
|
|
|
cfcb48 |
struct sockaddr *sockaddr, int sockaddr_len,
|
|
|
cfcb48 |
@@ -383,6 +393,8 @@ static void iketcp_message_listener_cb(evutil_socket_t unused_fd UNUSED,
|
|
|
cfcb48 |
struct logger from_logger = logger_from(&global_logger, &ifp->iketcp_remote_endpoint);
|
|
|
cfcb48 |
struct logger *logger = &from_logger;
|
|
|
cfcb48 |
|
|
|
cfcb48 |
+ bool v6 = ifp->ip_dev->id_address.version == 6;
|
|
|
cfcb48 |
+
|
|
|
cfcb48 |
switch (ifp->iketcp_state) {
|
|
|
cfcb48 |
|
|
|
cfcb48 |
case IKETCP_OPEN:
|
|
|
cfcb48 |
@@ -443,7 +455,19 @@ static void iketcp_message_listener_cb(evutil_socket_t unused_fd UNUSED,
|
|
|
cfcb48 |
if (impair.tcp_skip_setsockopt_espintcp) {
|
|
|
cfcb48 |
llog(RC_LOG, logger, "IMPAIR: TCP: skipping setsockopt(ESPINTCP)");
|
|
|
cfcb48 |
} else {
|
|
|
cfcb48 |
+ struct xfrm_userpolicy_info policy_in = {
|
|
|
cfcb48 |
+ .action = XFRM_POLICY_ALLOW,
|
|
|
cfcb48 |
+ .sel.family = v6 ? AF_INET6 :AF_INET,
|
|
|
cfcb48 |
+ .dir = XFRM_POLICY_IN,
|
|
|
cfcb48 |
+ };
|
|
|
cfcb48 |
+ struct xfrm_userpolicy_info policy_out = {
|
|
|
cfcb48 |
+ .action = XFRM_POLICY_ALLOW,
|
|
|
cfcb48 |
+ .sel.family = v6 ? AF_INET6 :AF_INET,
|
|
|
cfcb48 |
+ .dir = XFRM_POLICY_OUT,
|
|
|
cfcb48 |
+ };
|
|
|
cfcb48 |
+
|
|
|
cfcb48 |
dbg("TCP: OPEN: socket %d enabling ESPINTCP", ifp->fd);
|
|
|
cfcb48 |
+
|
|
|
cfcb48 |
if (setsockopt(ifp->fd, IPPROTO_TCP, TCP_ULP,
|
|
|
cfcb48 |
"espintcp", sizeof("espintcp"))) {
|
|
|
cfcb48 |
int e = errno;
|
|
|
cfcb48 |
@@ -459,6 +483,24 @@ static void iketcp_message_listener_cb(evutil_socket_t unused_fd UNUSED,
|
|
|
cfcb48 |
free_any_iface_endpoint(&ifp;;
|
|
|
cfcb48 |
return;
|
|
|
cfcb48 |
}
|
|
|
cfcb48 |
+
|
|
|
cfcb48 |
+ if (setsockopt(ifp->fd, IPPROTO_IP, IP_XFRM_POLICY, &policy_in, sizeof(policy_in))) {
|
|
|
cfcb48 |
+ int e = errno;
|
|
|
cfcb48 |
+ llog(RC_LOG, logger,
|
|
|
cfcb48 |
+ "TCP: setsockopt(%d, SOL_TCP, IP_XFRM_POLICY, \"policy_in\") failed; closing socket "PRI_ERRNO,
|
|
|
cfcb48 |
+ ifp->fd, pri_errno(e));
|
|
|
cfcb48 |
+ free_any_iface_endpoint(&ifp;;
|
|
|
cfcb48 |
+ return;
|
|
|
cfcb48 |
+ }
|
|
|
cfcb48 |
+ if (setsockopt(ifp->fd, IPPROTO_IP, IP_XFRM_POLICY, &policy_out, sizeof(policy_out))) {
|
|
|
cfcb48 |
+ int e = errno;
|
|
|
cfcb48 |
+ llog(RC_LOG, logger,
|
|
|
cfcb48 |
+ "TCP: setsockopt(%d, SOL_TCP, IP_XFRM_POLICY, \"policy_out\") failed; closing socket "PRI_ERRNO,
|
|
|
cfcb48 |
+ ifp->fd, pri_errno(e));
|
|
|
cfcb48 |
+ free_any_iface_endpoint(&ifp;;
|
|
|
cfcb48 |
+ return;
|
|
|
cfcb48 |
+ }
|
|
|
cfcb48 |
+
|
|
|
cfcb48 |
}
|
|
|
cfcb48 |
|
|
|
cfcb48 |
/*
|
|
|
cfcb48 |
@@ -650,6 +692,17 @@ stf_status create_tcp_interface(struct state *st)
|
|
|
cfcb48 |
if (impair.tcp_skip_setsockopt_espintcp) {
|
|
|
cfcb48 |
log_state(RC_LOG, st, "IMPAIR: TCP: skipping setsockopt(espintcp)");
|
|
|
cfcb48 |
} else {
|
|
|
cfcb48 |
+ bool v6 = st->st_remote_endpoint.version == 6;
|
|
|
cfcb48 |
+ struct xfrm_userpolicy_info policy_in = {
|
|
|
cfcb48 |
+ .action = XFRM_POLICY_ALLOW,
|
|
|
cfcb48 |
+ .sel.family = v6 ? AF_INET6 :AF_INET,
|
|
|
cfcb48 |
+ .dir = XFRM_POLICY_IN,
|
|
|
cfcb48 |
+ };
|
|
|
cfcb48 |
+ struct xfrm_userpolicy_info policy_out = {
|
|
|
cfcb48 |
+ .action = XFRM_POLICY_ALLOW,
|
|
|
cfcb48 |
+ .sel.family = v6 ? AF_INET6 :AF_INET,
|
|
|
cfcb48 |
+ .dir = XFRM_POLICY_OUT,
|
|
|
cfcb48 |
+ };
|
|
|
cfcb48 |
dbg("TCP: socket %d enabling \"espintcp\"", fd);
|
|
|
cfcb48 |
if (setsockopt(fd, IPPROTO_TCP, TCP_ULP, "espintcp", sizeof("espintcp"))) {
|
|
|
cfcb48 |
log_errno(st->st_logger, errno,
|
|
|
cfcb48 |
@@ -657,6 +710,18 @@ stf_status create_tcp_interface(struct state *st)
|
|
|
cfcb48 |
close(fd);
|
|
|
cfcb48 |
return STF_FATAL;
|
|
|
cfcb48 |
}
|
|
|
cfcb48 |
+ if (setsockopt(fd, IPPROTO_IP, IP_XFRM_POLICY, &policy_in, sizeof(policy_in))) {
|
|
|
cfcb48 |
+ log_errno(st->st_logger, errno,
|
|
|
cfcb48 |
+ "setsockopt(PPROTO_IP, IP_XFRM_POLICY(in)) failed in netlink_espintcp()");
|
|
|
cfcb48 |
+ close(fd);
|
|
|
cfcb48 |
+ return STF_FATAL;
|
|
|
cfcb48 |
+ }
|
|
|
cfcb48 |
+ if (setsockopt(fd, IPPROTO_IP, IP_XFRM_POLICY, &policy_out, sizeof(policy_out))) {
|
|
|
cfcb48 |
+ log_errno(st->st_logger, errno,
|
|
|
cfcb48 |
+ "setsockopt(PPROTO_IP, IP_XFRM_POLICY(out)) failed in netlink_espintcp()");
|
|
|
cfcb48 |
+ close(fd);
|
|
|
cfcb48 |
+ return STF_FATAL;
|
|
|
cfcb48 |
+ }
|
|
|
cfcb48 |
}
|
|
|
cfcb48 |
|
|
|
cfcb48 |
struct iface_endpoint *ifp = alloc_thing(struct iface_endpoint, "TCP iface initiator");
|
|
|
cfcb48 |
commit 7c38cd473d89b8c860ee7e3b8b31cfe012370f1d
|
|
|
cfcb48 |
Author: Paul Wouters <pwouters@redhat.com>
|
|
|
cfcb48 |
Date: Mon Mar 1 15:09:16 2021 -0500
|
|
|
cfcb48 |
|
|
|
cfcb48 |
documentation: small TCP doc update in ipsec.conf.in
|
|
|
cfcb48 |
|
|
|
cfcb48 |
diff --git a/configs/ipsec.conf.in b/configs/ipsec.conf.in
|
|
|
cfcb48 |
index bb2cc16e64..9fa3300176 100644
|
|
|
cfcb48 |
--- a/configs/ipsec.conf.in
|
|
|
cfcb48 |
+++ b/configs/ipsec.conf.in
|
|
|
cfcb48 |
@@ -28,9 +28,10 @@ config setup
|
|
|
cfcb48 |
# dnssec-enable=no
|
|
|
cfcb48 |
#
|
|
|
cfcb48 |
# To enable IKE and IPsec over TCP for VPN server. Requires at least
|
|
|
cfcb48 |
- # Linux 5.7 kernel. For TCP support as a VPN client, specify
|
|
|
cfcb48 |
- # tcp-remote-port=4500 in the client conn section.
|
|
|
cfcb48 |
+ # Linux 5.7 kernel or a kernel with TCP backport (like RHEL8 4.18.0-291)
|
|
|
cfcb48 |
# listen-tcp=yes
|
|
|
cfcb48 |
+ # To enable IKE and IPsec over TCP for VPN client, also specify
|
|
|
cfcb48 |
+ # tcp-remote-port=4500 in the client's conn section.
|
|
|
cfcb48 |
|
|
|
cfcb48 |
# if it exists, include system wide crypto-policy defaults
|
|
|
cfcb48 |
# include /etc/crypto-policies/back-ends/libreswan.config
|