]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
implement --session-timeout
authorDmitry Zelenkovsky <dmitry@zelenkovsky.com>
Thu, 6 Oct 2022 20:37:31 +0000 (22:37 +0200)
committerGert Doering <gert@greenie.muc.de>
Fri, 7 Oct 2022 16:08:13 +0000 (18:08 +0200)
Disconnect clients after session-timeout expires.
session-timeout can be defined in ccd files in order to limit
per-user connection time.

Signed-off-by: Dmitry Zelenkovsky <dmitry@zelenkovsky.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20221006203731.13529-1-a@unstable.cc>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25352.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
Changes.rst
doc/man-sections/link-options.rst
doc/man-sections/server-options.rst
src/openvpn/forward.c
src/openvpn/init.c
src/openvpn/openvpn.h
src/openvpn/options.c
src/openvpn/options.h

index 275f8d647624a727dd2d3b72a3bd21bc580f18a3..25325b22b40ebd06b534216381902eca8b690974 100644 (file)
@@ -87,6 +87,12 @@ Data channel offloading with ovpn-dco
     this implies that peers must be running 2.6.0+ in order to have P2P-NCP
     which brings DATA_V2 packet support.
 
+Session timeout
+    It is now possible to terminate a session (or all) after a specified amount
+    of seconds has passed session commencement. This behaviour can be configured
+    using ``--session-timeout``. This option can be configured on the server, on
+    the client or can also be pushed.
+
 
 Deprecated features
 -------------------
index 373193aa365da37b210c87a2eeb5663fac9b0627..eb098a0f89e7becac5b185ea522aec9783c42af8 100644 (file)
@@ -427,6 +427,17 @@ the local and the remote host.
   default) and you are using either ``--secret`` (shared-secret key mode)
   or TLS mode with ``--tls-auth``.
 
+--session-timeout n
+  Raises :code:`SIGTERM` for the client instance after ``n`` seconds since
+  the beginning of the session, forcing OpenVPN to disconnect.
+  In client mode, OpenVPN will disconnect and exit, while in server mode
+  all client sessions are terminated.
+
+  This option can also be specified in a client instance config file
+  using ``--client-config-dir`` or dynamically generated using a
+  ``--client-connect`` script. In these cases, only the related client
+  session is terminated.
+
 --socket-flags flags
   Apply the given flags to the OpenVPN transport socket. Currently, only
   :code:`TCP_NODELAY` is supported.
index 54ea8b66cd725cd19668d67beb915488982c6a82..9d0c73b697c5f581c12ec247ebaa57969a2462b8 100644 (file)
@@ -426,7 +426,7 @@ fast hardware. SSL/TLS authentication must be used in this mode.
   ``--inactive``, ``--ping``, ``--ping-exit``, ``--ping-restart``,
   ``--setenv``, ``--auth-token``, ``--persist-key``, ``--persist-tun``,
   ``--echo``, ``--comp-lzo``, ``--socket-flags``, ``--sndbuf``,
-  ``--rcvbuf``
+  ``--rcvbuf``, ``--session-timeout``
 
 --push-remove opt
   Selectively remove all ``--push`` options matching "opt" from the option
index 6a45b9e910b98b650de09dee223d0ed2b2a246ab..bee24f0d4ce0d2198cb4b245c0529e29aa551ebe 100644 (file)
@@ -630,6 +630,21 @@ encrypt_sign(struct context *c, bool comp_frag)
     buffer_turnover(orig_buf, &c->c2.to_link, &c->c2.buf, &b->read_tun_buf);
 }
 
+/*
+ * Should we exit due to session timeout?
+ */
+static void
+check_session_timeout(struct context *c)
+{
+    if (c->options.session_timeout
+        && event_timeout_trigger(&c->c2.session_interval, &c->c2.timeval,
+                                 ETT_DEFAULT))
+    {
+        msg(M_INFO, "Session timeout, exiting");
+        register_signal(c, SIGTERM, "session-timeout");
+    }
+}
+
 /*
  * Coarse timers work to 1 second resolution.
  */
@@ -681,6 +696,13 @@ process_coarse_timers(struct context *c)
         return;
     }
 
+    /* kill session if time is over */
+    check_session_timeout(c);
+    if (c->sig->signal_received)
+    {
+        return;
+    }
+
     /* restart if ping not received */
     check_ping_restart(c);
     if (c->sig->signal_received)
index c88c09155274196cbf49fe77b8d8b23bb48eb586..d87923665add597d86b1bdf52be4bbd1bd73e8e3 100644 (file)
@@ -1320,6 +1320,13 @@ do_init_timers(struct context *c, bool deferred)
         event_timeout_init(&c->c2.inactivity_interval, c->options.inactivity_timeout, now);
     }
 
+    /* initialize inactivity timeout */
+    if (c->options.session_timeout)
+    {
+        event_timeout_init(&c->c2.session_interval, c->options.session_timeout,
+                           now);
+    }
+
     /* initialize pings */
     if (dco_enabled(&c->options))
     {
index dd69ac031f08816f4332dbf8f3f6b4e37830836d..1b699b93ada71db6e031691eb7855396fd4b89c3 100644 (file)
@@ -288,6 +288,8 @@ struct context_2
     struct event_timeout inactivity_interval;
     int64_t inactivity_bytes;
 
+    struct event_timeout session_interval;
+
     /* the option strings must match across peers */
     char *options_string_local;
     char *options_string_remote;
index e44993c03b93861ca76f0648b9305db2e11abed4..01117d98299ed6f2f47bf0f00b1ebbc27a5ce8a3 100644 (file)
@@ -261,6 +261,7 @@ static const char usage_message[] =
     "                  for m seconds.\n"
     "--inactive n [bytes] : Exit after n seconds of activity on tun/tap device\n"
     "                  produces a combined in/out byte count < bytes.\n"
+    "--session-timeout n: Limit connection time to n seconds.\n"
     "--ping-exit n   : Exit if n seconds pass without reception of remote ping.\n"
     "--ping-restart n: Restart if n seconds pass without reception of remote ping.\n"
     "--ping-timer-rem: Run the --ping-exit/--ping-restart timer only if we have a\n"
@@ -1823,6 +1824,7 @@ show_settings(const struct options *o)
     SHOW_INT(keepalive_ping);
     SHOW_INT(keepalive_timeout);
     SHOW_INT(inactivity_timeout);
+    SHOW_INT(session_timeout);
     SHOW_INT64(inactivity_minimum_bytes);
     SHOW_INT(ping_send_timeout);
     SHOW_INT(ping_rec_timeout);
@@ -6597,6 +6599,11 @@ add_option(struct options *options,
             }
         }
     }
+    else if (streq(p[0], "session-timeout") && p[1] && !p[2])
+    {
+        VERIFY_PERMISSION(OPT_P_TIMER);
+        options->session_timeout = positive_atoi(p[1]);
+    }
     else if (streq(p[0], "proto") && p[1] && !p[2])
     {
         int proto;
index e83bc0ed851186fa969a6439c4548a23f2685d5e..7e0ed7792923b6febbef9b7e795a4c8ca28eb9b2 100644 (file)
@@ -324,6 +324,8 @@ struct options
     int inactivity_timeout;     /* --inactive */
     int64_t inactivity_minimum_bytes;
 
+    int session_timeout;        /* Force-kill session after n seconds */
+
     int ping_send_timeout;      /* Send a TCP/UDP ping to remote every n seconds */
     int ping_rec_timeout;       /* Expect a TCP/UDP ping from remote at least once every n seconds */
     bool ping_timer_remote;     /* Run ping timer only if we have a remote address */