implement --session-timeout

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>
This commit is contained in:
Dmitry Zelenkovsky 2022-10-06 22:37:31 +02:00 committed by Gert Doering
parent 0b980fa4e5
commit f96290ff90
8 changed files with 58 additions and 1 deletions

View 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
-------------------

View 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.

View 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

View 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)

View 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))
{

View 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;

View 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;

View 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 */