Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock ocserv/0.11.6-2, this update includes four simple patches cherry picked from upstream later releases, used to improve firewall handling and MTU/MSS calculation. Patches are attached. Regards, Aron
From 9f735613c496a17461f60a75caf2f394ae781d4c Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos <n...@redhat.com> Date: Thu, 23 Feb 2017 09:54:05 +0100 Subject: [PATCH 7/7] worker-vpn: use TCP_INFO on linux to obtain accurate MTU information This provides a more accurate value than the one obtained using the TCP MSS value. The latter is affected by many factors (such as tcp options), to provide a reliable value. Signed-off-by: Nikos Mavrogiannopoulos <n...@redhat.com> --- src/worker-vpn.c | 80 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/src/worker-vpn.c b/src/worker-vpn.c index ea80ebd..311fc2a 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -48,7 +48,7 @@ #include <signal.h> #include <poll.h> -#if defined(__linux__) &&!defined(IPV6_PATHMTU) +#if defined(__linux__) && !defined(IPV6_PATHMTU) # define IPV6_PATHMTU 61 #endif @@ -942,11 +942,45 @@ void mtu_ok(worker_st * ws) x += r % diff; \ } +int get_pmtu_approx(worker_st *ws) +{ + socklen_t sl; + int ret, e; + +#if defined(__linux__) && defined(TCP_INFO) + struct tcp_info ti; + sl = sizeof(ti); + + ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_INFO, &ti, &sl); + if (ret == -1) { + e = errno; + oclog(ws, LOG_INFO, "error in getting TCP_INFO: %s", + strerror(e)); + return -1; + } else { + return ti.tcpi_pmtu; + } +#else + int max = -1; + + sl = sizeof(max); + ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_MAXSEG, &max, &sl); + if (ret == -1) { + e = errno; + oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s", + strerror(e)); + return -1; + } else { + MSS_ADJUST(max); + return max; + } +#endif +} + static int periodic_check(worker_st * ws, struct timespec *tnow, unsigned dpd) { - socklen_t sl; - int max, e, ret; + int max, ret; time_t now = tnow->tv_sec; time_t periodic_check_time = PERIODIC_CHECK_TIME; @@ -1036,20 +1070,11 @@ int periodic_check(worker_st * ws, struct timespec *tnow, unsigned dpd) } if (ws->conn_type != SOCK_TYPE_UNIX && ws->udp_state != UP_DISABLED) { - sl = sizeof(max); - ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_MAXSEG, &max, &sl); - if (ret == -1) { - e = errno; - oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s", - strerror(e)); - } else { - MSS_ADJUST(max); - /*oclog(ws, LOG_DEBUG, "TCP MSS is %u", max); */ - if (max > 0 && max < ws->link_mtu) { - oclog(ws, LOG_DEBUG, "reducing MTU due to TCP MSS to %u", - max); - link_mtu_set(ws, max); - } + max = get_pmtu_approx(ws); + if (max > 0 && max < ws->link_mtu) { + oclog(ws, LOG_DEBUG, "reducing MTU due to TCP/PMTU to %u", + max); + link_mtu_set(ws, max); } } @@ -1571,7 +1596,7 @@ static int connect_handler(worker_st * ws) struct http_req_st *req = &ws->req; struct pollfd pfd[4]; unsigned pfd_size; - int e, max, ret, t; + int max, ret, t; char *p; unsigned rnd; #ifdef HAVE_PPOLL @@ -1580,7 +1605,6 @@ static int connect_handler(worker_st * ws) unsigned tls_pending, dtls_pending = 0, i; struct timespec tnow; unsigned ip6; - socklen_t sl; sigset_t emptyset, blockset; sigemptyset(&blockset); @@ -1693,19 +1717,11 @@ static int connect_handler(worker_st * ws) /* Attempt to use the TCP connection maximum segment size to set a more * precise MTU. */ if (ws->conn_type != SOCK_TYPE_UNIX) { - sl = sizeof(max); - ret = getsockopt(ws->conn_fd, IPPROTO_TCP, TCP_MAXSEG, &max, &sl); - if (ret == -1) { - e = errno; - oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s", - strerror(e)); - } else { - MSS_ADJUST(max); - if (max > 0 && max < ws->vinfo.mtu) { - oclog(ws, LOG_INFO, - "reducing MTU due to TCP MSS to %u (from %u)", max, ws->vinfo.mtu); - ws->vinfo.mtu = max; - } + max = get_pmtu_approx(ws); + if (max > 0 && max < ws->vinfo.mtu) { + oclog(ws, LOG_DEBUG, "reducing MTU due to TCP/PMTU to %u", + max); + link_mtu_set(ws, max); } } -- 2.1.4
From 1233f67c3f89bce5f8300c22de8c745d2ae7e9dd Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos <n...@redhat.com> Date: Wed, 22 Feb 2017 16:22:55 +0100 Subject: [PATCH 6/7] worker-vpn: corrected calculation for MTU via TCP MSS Signed-off-by: Nikos Mavrogiannopoulos <n...@redhat.com> --- src/worker-vpn.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/worker-vpn.c b/src/worker-vpn.c index 2a00ef9..ea80ebd 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -74,6 +74,13 @@ #define CSTP_DTLS_OVERHEAD 1 #define CSTP_OVERHEAD 8 +#define IP_HEADER_SIZE 20 +#define IPV6_HEADER_SIZE 40 +#define TCP_HEADER_SIZE 20 +#define UDP_HEADER_SIZE 8 + +#define MSS_ADJUST(x) x += TCP_HEADER_SIZE + ((ws->proto == AF_INET)?(IP_HEADER_SIZE):(IPV6_HEADER_SIZE)) + struct worker_st *global_ws = NULL; static int terminate = 0; @@ -1036,7 +1043,7 @@ int periodic_check(worker_st * ws, struct timespec *tnow, unsigned dpd) oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s", strerror(e)); } else { - max -= 13; + MSS_ADJUST(max); /*oclog(ws, LOG_DEBUG, "TCP MSS is %u", max); */ if (max > 0 && max < ws->link_mtu) { oclog(ws, LOG_DEBUG, "reducing MTU due to TCP MSS to %u", @@ -1485,11 +1492,6 @@ static void set_socket_timeout(worker_st * ws, int fd) } } -#define IP_HEADER_SIZE 20 -#define IPV6_HEADER_SIZE 40 -#define TCP_HEADER_SIZE 8 -#define UDP_HEADER_SIZE 8 - /* wild but conservative guess; this ciphersuite has the largest overhead */ #define MAX_CSTP_CRYPTO_OVERHEAD (CSTP_OVERHEAD+tls_get_overhead(GNUTLS_TLS1_0, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1)) #define MAX_DTLS_CRYPTO_OVERHEAD (CSTP_DTLS_OVERHEAD+tls_get_overhead(GNUTLS_DTLS1_0, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1)) @@ -1698,7 +1700,7 @@ static int connect_handler(worker_st * ws) oclog(ws, LOG_INFO, "error in getting TCP_MAXSEG: %s", strerror(e)); } else { - max -= 13; + MSS_ADJUST(max); if (max > 0 && max < ws->vinfo.mtu) { oclog(ws, LOG_INFO, "reducing MTU due to TCP MSS to %u (from %u)", max, ws->vinfo.mtu); -- 2.1.4
From 6e83ea5217f4789f21ce2be706747d7d0aba07f5 Mon Sep 17 00:00:00 2001 From: John Thiltges <jthiltg...@unl.edu> Date: Mon, 9 Jan 2017 15:45:22 -0600 Subject: [PATCH 3/7] ocserv-fw should send all traffic to the device-specific forwarding chain After adding port-specific rules to FORWARD and creating SEC_FORWARD_CHAIN with route-specific rules, send any remaining FORWARD traffic to SEC_FORWARD_CHAIN. --- src/ocserv-fw | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ocserv-fw b/src/ocserv-fw index 3653364..1c2899a 100755 --- a/src/ocserv-fw +++ b/src/ocserv-fw @@ -270,6 +270,10 @@ else iptables -A ${SEC_FORWARD_CHAIN} -i ${DEVICE} -j ACCEPT -m comment --comment "${COMMENT}" fi +# send traffic to the route chain +iptables -A FORWARD -i ${DEVICE} -j ${SEC_FORWARD_CHAIN} --match comment --comment "${COMMENT}" +ip6tables -A FORWARD -i ${DEVICE} -j ${SEC_FORWARD_CHAIN} --match comment --comment "${COMMENT}" + execute_next_script exit 0 -- 2.1.4
From 3ba8abea378f9278da377705986810556803d26e Mon Sep 17 00:00:00 2001 From: John Thiltges <jthiltg...@unl.edu> Date: Mon, 9 Jan 2017 12:28:19 -0600 Subject: [PATCH 2/7] ocserv-fw should still create a chain if restrict-user-to-routes is set ocserv-fw only creates SEC_FORWARD_CHAIN if ports are being blocked. This leads to an error if restrict-user-to-routes is used without any port blocking. Since ocserv-fw is only called if restrict-user-to-routes or -ports is set, remove the conditional check for creating the chain. --- src/ocserv-fw | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/ocserv-fw b/src/ocserv-fw index b4c7516..3653364 100755 --- a/src/ocserv-fw +++ b/src/ocserv-fw @@ -204,12 +204,13 @@ for i in $OCSERV_DNS6;do allow_dns6 $i done +# create the chain +FORWARD_CHAIN="${SEC_FORWARD_CHAIN}" +iptables -N "${FORWARD_CHAIN}" +ip6tables -N "${FORWARD_CHAIN}" + # block ports - if needed if test -n "${OCSERV_DENY_PORTS}";then - FORWARD_CHAIN="${SEC_FORWARD_CHAIN}" - iptables -N "${FORWARD_CHAIN}" - ip6tables -N "${FORWARD_CHAIN}" - set ${OCSERV_DENY_PORTS} while test $# -gt 1; do proto=$1 @@ -224,10 +225,6 @@ if test -n "${OCSERV_DENY_PORTS}";then done else if test -n "${OCSERV_ALLOW_PORTS}";then - FORWARD_CHAIN="${SEC_FORWARD_CHAIN}" - iptables -N "${FORWARD_CHAIN}" - ip6tables -N "${FORWARD_CHAIN}" - set ${OCSERV_ALLOW_PORTS} while test $# -gt 1; do proto=$1 -- 2.1.4