Skip to content

Commit a856428

Browse files
committed
sudo_logsrvd: Add option to disable client host name check
The tls_checkhost setting in the [server] section can be used to disable host name and IP address checking in the client's certificate when tls_checkpeer is enabled. This makes it possible to use a single certificate for multiple clients and avoids DNS lookups when the client connects.
1 parent d7484d7 commit a856428

5 files changed

Lines changed: 107 additions & 21 deletions

File tree

docs/sudo_logsrvd.conf.mdoc.in

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.\"
22
.\" SPDX-License-Identifier: ISC
33
.\"
4-
.\" Copyright (c) 2019-2025 Todd C. Miller <[email protected]>
4+
.\" Copyright (c) 2019-2026 Todd C. Miller <[email protected]>
55
.\"
66
.\" Permission to use, copy, modify, and distribute this software for any
77
.\" purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
1515
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1616
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1717
.\"
18-
.Dd November 29, 2025
18+
.Dd February 21, 2026
1919
.Dt SUDO_LOGSRVD.CONF @mansectform@
2020
.Os Sudo @PACKAGE_VERSION@
2121
.Sh NAME
@@ -183,6 +183,29 @@ database is used.
183183
The path to the server's certificate file, in PEM format.
184184
The default value is
185185
.Pa /etc/ssl/sudo/certs/logsrvd_cert.pem .
186+
.It tls_checkhost = bool
187+
If true and
188+
.Em tls_checkpeer
189+
is also enabled,
190+
.Nm sudo_logsrvd
191+
will perform a reverse DNS lookup of the client's IP address for TLS
192+
connections.
193+
In order to be considered valid, either the IP address or the resolved
194+
hostname must be present in the client certificate's Subject
195+
Alternative Name (SAN), or the host name must match the Common Name
196+
(CN) if no SAN is present.
197+
.Pp
198+
Disabling
199+
.Em tls_checkhost
200+
makes it possible to use the same client certificate on multiple
201+
systems, regardless of the client host name or IP address.
202+
.Pp
203+
The
204+
.Em tls_checkhost
205+
setting only has an effect when
206+
.Em tls_checkpeer
207+
is also enabled.
208+
Defaults to true.
186209
.It tls_checkpeer = bool
187210
If true, client certificates will be validated by
188211
.Nm sudo_logsrvd ;
@@ -193,11 +216,10 @@ authority, the
193216
.Em tls_cacert
194217
setting must be set to a CA bundle that contains the CA certificate
195218
used to generate the client certificate.
196-
To validate the certificate,
197-
.Nm sudo_logsrvd
198-
will perform a reverse DNS lookup of the client's IP address.
199-
In order to be considered valid, either the IP address or the
200-
resolved hostname must be present in the client certificate.
219+
Validation of the client's IP address and host name is controlled
220+
by the
221+
.Em tls_checkhost
222+
setting.
201223
The default value is
202224
.Em false .
203225
.It tls_ciphers_v12 = string
@@ -357,6 +379,16 @@ The path to the server's certificate file, in PEM format.
357379
The default is to use the value specified in the
358380
.Sx server
359381
section.
382+
.It tls_checkhost = bool
383+
If true and
384+
.Em tls_checkpeer
385+
is also enabled,
386+
.Nm sudo_logsrvd
387+
will perform a reverse DNS lookup of the client's IP address for TLS
388+
connections.
389+
The default is to use the value specified in the
390+
.Sx server
391+
section.
360392
.It tls_checkpeer = bool
361393
If true, the relay host's certificate will be validated by
362394
.Nm sudo_logsrvd ;
@@ -840,6 +872,11 @@ Sudo log server configuration file
840872
# Defaults to true.
841873
#tls_verify = true
842874

875+
# If true, client certificates being validated by the server must have a
876+
# matching host name or IP address in the Subject Alternative Name (SAN).
877+
# Defaults to true. Only has an effect when tls_checkpeer is also true.
878+
#tls_checkhost = true
879+
843880
# If true, client certificates will be validated by the server;
844881
# clients without a valid certificate will be unable to connect.
845882
# By default, client certs are not checked.

examples/sudo_logsrvd.conf.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939
# Defaults to true.
4040
#tls_verify = true
4141

42+
# If true, client certificates being validated by the server must have a
43+
# matching host name or IP address in the Subject Alternative Name (SAN).
44+
# Defaults to true. Only has an effect when tls_checkpeer is also true.
45+
#tls_checkhost = true
46+
4247
# If true, client certificates will be validated by the server;
4348
# clients without a valid certificate will be unable to connect.
4449
# By default, client certs are not checked.

logsrvd/logsrvd.c

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SPDX-License-Identifier: ISC
33
*
4-
* Copyright (c) 2019-2025 Todd C. Miller <[email protected]>
4+
* Copyright (c) 2019-2026 Todd C. Miller <[email protected]>
55
*
66
* Permission to use, copy, modify, and distribute this software for any
77
* purpose with or without fee is hereby granted, provided that the above
@@ -1339,14 +1339,13 @@ start_protocol(struct connection_closure *closure)
13391339

13401340
#if defined(HAVE_OPENSSL)
13411341
static int
1342-
verify_peer_identity(int preverify_ok, X509_STORE_CTX *ctx)
1342+
verify_peer(int preverify_ok, X509_STORE_CTX *ctx, bool check_host)
13431343
{
1344-
HostnameValidationResult result;
13451344
struct connection_closure *closure;
13461345
SSL *ssl;
13471346
X509 *current_cert;
13481347
X509 *peer_cert;
1349-
debug_decl(verify_peer_identity, SUDO_DEBUG_UTIL);
1348+
debug_decl(verify_peer, SUDO_DEBUG_UTIL);
13501349

13511350
current_cert = X509_STORE_CTX_get_current_cert(ctx);
13521351

@@ -1376,15 +1375,30 @@ verify_peer_identity(int preverify_ok, X509_STORE_CTX *ctx)
13761375
ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
13771376
closure = (struct connection_closure *)SSL_get_ex_data(ssl, 1);
13781377

1379-
result = validate_hostname(peer_cert, closure->name, closure->ipaddr);
1380-
if (result != MatchFound) {
1381-
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
1382-
"hostname validation failed");
1383-
debug_return_int(0);
1378+
if (check_host) {
1379+
const HostnameValidationResult result =
1380+
validate_hostname(peer_cert, closure->name, closure->ipaddr);
1381+
if (result != MatchFound) {
1382+
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
1383+
"hostname validation failed");
1384+
debug_return_int(0);
1385+
}
13841386
}
13851387
debug_return_int(1);
13861388
}
13871389

1390+
static int
1391+
verify_peer_identity(int preverify_ok, X509_STORE_CTX *ctx)
1392+
{
1393+
return verify_peer(preverify_ok, ctx, true);
1394+
}
1395+
1396+
static int
1397+
verify_peer_identity_nohost(int preverify_ok, X509_STORE_CTX *ctx)
1398+
{
1399+
return verify_peer(preverify_ok, ctx, false);
1400+
}
1401+
13881402
/*
13891403
* Set the TLS verify callback to verify_peer_identity().
13901404
*/
@@ -1397,9 +1411,15 @@ set_tls_verify_peer(void)
13971411

13981412
if (server_ctx != NULL && logsrvd_conf_server_tls_check_peer()) {
13991413
/* Verify server cert during the handshake. */
1400-
SSL_CTX_set_verify(server_ctx,
1401-
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1402-
verify_peer_identity);
1414+
if (logsrvd_conf_server_tls_check_host()) {
1415+
SSL_CTX_set_verify(server_ctx,
1416+
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1417+
verify_peer_identity);
1418+
} else {
1419+
SSL_CTX_set_verify(server_ctx,
1420+
SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1421+
verify_peer_identity_nohost);
1422+
}
14031423
}
14041424
if (relay_ctx != NULL && logsrvd_conf_relay_tls_check_peer()) {
14051425
/* Verify relay cert during the handshake. */
@@ -1552,7 +1572,7 @@ new_connection(int sock, bool tls, const union sockaddr_union *sa_un,
15521572
goto bad;
15531573
}
15541574

1555-
if (logsrvd_conf_server_tls_check_peer()) {
1575+
if (logsrvd_conf_server_tls_check_host()) {
15561576
/* Hostname to verify in certificate during handshake. */
15571577
char hbuf[NI_MAXHOST];
15581578
const int error = getnameinfo(&sa_un->sa, salen, hbuf,

logsrvd/logsrvd.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SPDX-License-Identifier: ISC
33
*
4-
* Copyright (c) 2019-2022 Todd C. Miller <[email protected]>
4+
* Copyright (c) 2019-2022, 2025-2026 Todd C. Miller <[email protected]>
55
*
66
* Permission to use, copy, modify, and distribute this software for any
77
* purpose with or without fee is hereby granted, provided that the above
@@ -218,6 +218,7 @@ struct timespec *logsrvd_conf_relay_connect_timeout(void);
218218
struct timespec *logsrvd_conf_relay_timeout(void);
219219
time_t logsrvd_conf_relay_retry_interval(void);
220220
#if defined(HAVE_OPENSSL)
221+
bool logsrvd_conf_server_tls_check_host(void);
221222
bool logsrvd_conf_server_tls_check_peer(void);
222223
SSL_CTX *logsrvd_server_tls_ctx(void);
223224
bool logsrvd_conf_relay_tls_check_peer(void);

logsrvd/logsrvd_conf.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ static struct logsrvd_config {
112112
char *tls_dhparams_path;
113113
char *tls_ciphers_v12;
114114
char *tls_ciphers_v13;
115+
int tls_check_host;
115116
int tls_check_peer;
116117
int tls_verify;
117118
SSL_CTX *ssl_ctx;
@@ -265,6 +266,12 @@ logsrvd_server_tls_ctx(void)
265266
return logsrvd_config->server.ssl_ctx;
266267
}
267268

269+
bool
270+
logsrvd_conf_server_tls_check_host(void)
271+
{
272+
return logsrvd_config->server.tls_check_host;
273+
}
274+
268275
bool
269276
logsrvd_conf_server_tls_check_peer(void)
270277
{
@@ -781,6 +788,20 @@ cb_tls_verify(struct logsrvd_config *config, const char *str, size_t offset)
781788
debug_return_bool(true);
782789
}
783790

791+
static bool
792+
cb_tls_checkhost(struct logsrvd_config *config, const char *str, size_t offset)
793+
{
794+
int *p = (int *)((char *)config + offset);
795+
int val;
796+
debug_decl(cb_tls_checkhost, SUDO_DEBUG_UTIL);
797+
798+
if ((val = sudo_strtobool(str)) == -1)
799+
debug_return_bool(false);
800+
801+
*p = val;
802+
debug_return_bool(true);
803+
}
804+
784805
static bool
785806
cb_tls_checkpeer(struct logsrvd_config *config, const char *str, size_t offset)
786807
{
@@ -1118,6 +1139,7 @@ static struct logsrvd_config_entry server_conf_entries[] = {
11181139
{ "tls_dhparams", cb_tls_dhparams, offsetof(struct logsrvd_config, server.tls_dhparams_path) },
11191140
{ "tls_ciphers_v12", cb_tls_ciphers12, offsetof(struct logsrvd_config, server.tls_ciphers_v12) },
11201141
{ "tls_ciphers_v13", cb_tls_ciphers13, offsetof(struct logsrvd_config, server.tls_ciphers_v13) },
1142+
{ "tls_checkhost", cb_tls_checkhost, offsetof(struct logsrvd_config, server.tls_check_host) },
11211143
{ "tls_checkpeer", cb_tls_checkpeer, offsetof(struct logsrvd_config, server.tls_check_peer) },
11221144
{ "tls_verify", cb_tls_verify, offsetof(struct logsrvd_config, server.tls_verify) },
11231145
#endif
@@ -1662,6 +1684,7 @@ logsrvd_conf_alloc(void)
16621684
goto bad;
16631685
}
16641686
config->server.tls_verify = true;
1687+
config->server.tls_check_host = true;
16651688
config->server.tls_check_peer = false;
16661689
#endif
16671690

0 commit comments

Comments
 (0)