--- Begin Message ---
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
--- End Message ---