nbd_set_tls(3)

πŸ’… nbd_set_tls β€” ok so this is the TLS glow-up button

Hey bestie, welcome to another page from the libnbd manual (section 3, if you're keeping score πŸŽ€). Today's main character is nbd_set_tls, and honestly? She's the one who decides whether your connection to the NBD server is dressed for the occasion (authenticated + encrypted) or just rolling out of bed (plaintext). Your call, no judgement. ✨

🌸 SYNOPSIS

#include <libnbd.h>

int nbd_set_tls (
      struct nbd_handle *h, int tls
    );

πŸ¦‹ DESCRIPTION

So this is how you tell libnbd whether to enable or require TLS β€” aka authenticated and encrypted connections β€” when it talks to the NBD server. It's giving "bouncer at the club" energy honestly. 🫢

Here are the possible settings, all of them, nothing skipped, periodt:

  • "LIBNBD_TLS_DISABLE" β€” Turn TLS all the way off. This is the default setting, unless you're using nbd_connect_uri(3) with a URI that requires TLS.

Also, you need this setting if you're using nbd_set_opt_mode(3) and you want to interact in plaintext with a server implementing the NBD protocol's "SELECTIVETLS" mode, before you enable TLS with nbd_opt_starttls(3). Real talk though: most NBD servers with TLS support prefer the NBD protocol's "FORCEDTLS" mode, so this kind of manual interaction is lowkey only useful during integration testing. πŸ’€

  • "LIBNBD_TLS_ALLOW" β€” Enable TLS if possible.

Bestie, heads up: this option is insecure (or "best effort," if we're being polite πŸ’…) because in some cases it'll fall back to an unencrypted and/or unauthenticated connection if TLS couldn't be established. If the connection must be encrypted, use "LIBNBD_TLS_REQUIRE" (right below, she's the strict one).

Also, some servers will straight-up drop the connection if TLS fails, so fallback may not even be possible. Not me warning you twice. 😭

  • "LIBNBD_TLS_REQUIRE" β€” Require an encrypted and authenticated TLS connection. Always fail to connect if the connection is not encrypted and authenticated. No notes. No exceptions. πŸ‘‘

On top of calling this, you may also need to supply:

For now, when you're using nbd_connect_uri(3), any URI query parameters related to TLS are not handled automatically. (iykyk, it's a whole thing πŸ™ˆ)

And important: setting the level higher than zero will fail if libnbd was not compiled against gnutls. You can test whether that's the case with nbd_supports_tls(3). ✨

🌈 RETURN VALUE

If the call is successful, the function returns 0. slay. πŸŽ€

πŸ’œ ERRORS

On error, -1 is returned. 😭

Refer to "ERROR HANDLING" in libnbd(3) for how to get further details of the error.

The following parameters must not be NULL: "h". For more information, see "Non-NULL parameters" in libnbd(3).

⭐ HANDLE STATE

nbd_set_tls can be called when the handle is in the following state β€” vibe check time, here's the whole table (yes, every row, I gotchu):

  • Handle created, before connecting β€” βœ… allowed
  • Connecting β€” ❌ error
  • Connecting & handshaking (opt_mode) β€” ❌ error
  • Connected to the server β€” ❌ error
  • Connection shut down β€” ❌ error
  • Handle dead β€” ❌ error
So basically: call her early, before you've started connecting. After that it's a no. 🚫

πŸ”₯ VERSION

This function first appeared in libnbd 1.0.

If you need to test if this function is available at compile time, check if the following macro is defined:

#define LIBNBD_HAVE_NBD_SET_TLS 1

🧚 EXAMPLE

This example is also available as examples/encryption.c in the libnbd source code. Behold, the whole thing, in all her glory:

/* An example showing how to connect to a server which is
 * using TLS encryption.
 *
 * This requires nbdkit, and psktool from gnutls.
 *
 * Both libnbd and nbdkit support TLS-PSK which is a
 * simpler-to-deploy form of encryption.  (Of course
 * certificate-based encryption is also supported, but
 * it’s harder to make a self-contained example).
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <libnbd.h>

#define TMPDIR "/tmp/XXXXXX"
#define KEYS "keys.psk"
#define USERNAME "alice"

static char dir[] = TMPDIR;
static char keys[] = TMPDIR "/" KEYS;
static char cmd[] =
  "psktool -u " USERNAME " -p " TMPDIR "/" KEYS;

/* Remove the temporary keys file when the program
 * exits.
 */
static void
cleanup_keys (void)
{
  unlink (keys);
  rmdir (dir);
}

/* Create the temporary keys file to share with the
 * server.
 */
static void
create_keys (void)
{
  size_t i;

  if (mkdtemp (dir) == NULL) {
    perror ("mkdtemp");
    exit (EXIT_FAILURE);
  }
  i = strlen (cmd) - strlen (TMPDIR) - strlen (KEYS) - 1;
  memcpy (&cmd[i], dir, strlen (TMPDIR));
  memcpy (keys, dir, strlen (TMPDIR));

  if (system (cmd) != 0) {
    fprintf (stderr, "psktool command failed\n");
    exit (EXIT_FAILURE);
  }

  atexit (cleanup_keys);
}

int
main (int argc, char *argv[])
{
  struct nbd_handle *nbd;
  char buf[512];

  create_keys ();

  /* Create the libnbd handle. */
  nbd = nbd_create ();
  if (nbd == NULL) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* Enable TLS in the client. */
  if (nbd_set_tls (nbd, LIBNBD_TLS_REQUIRE) == -1) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* Enable TLS-PSK and pass the keys filename. */
  if (nbd_set_tls_psk_file (nbd, keys) == -1) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* Set the local username for authentication. */
  if (nbd_set_tls_username (nbd, USERNAME) == -1) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* Run nbdkit as a subprocess, enabling and requiring
   * TLS-PSK encryption.
   */
  char *args[] = {
    "nbdkit", "-s", "--exit-with-parent",
    "--tls", "require", "--tls-psk", keys,
    "pattern", "size=1M", NULL
  };
  if (nbd_connect_command (nbd, args) == -1) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* Read the first sector. */
  if (nbd_pread (nbd, buf, sizeof buf, 0, 0) == -1) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* TLS connections must be shut down. */
  if (nbd_shutdown (nbd, 0) == -1) {
    fprintf (stderr, "%s\n", nbd_get_error ());
    exit (EXIT_FAILURE);
  }

  /* Close the libnbd handle. */
  nbd_close (nbd);

  exit (EXIT_SUCCESS);
}
Note the comment in there: "TLS connections must be shut down." That's nbd_shutdown doing her thing, don't skip her. πŸ’…

πŸ‘‘ SEE ALSO

nbd_connect_uri(3), nbd_create(3), nbd_get_tls(3), nbd_get_tls_negotiated(3), nbd_opt_starttls(3), nbd_set_opt_mode(3), nbd_set_tls_certificates(3), nbd_set_tls_priority(3), nbd_set_tls_psk_file(3), nbd_set_tls_username(3), nbd_supports_tls(3), "ENCRYPTION AND AUTHENTICATION" in libnbd(3), libnbd(3).

πŸ“ AUTHORS

Eric Blake

Richard W.M. Jones

Copyright Red Hat

πŸ“œ LICENSE

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA


ok that's the whole page bestie, go encrypt something πŸ¦‹βœ¨

mwah πŸ’‹ β€” this was libnbd-1.25.8, dated 2026-10-13, and that's your sign-off fr fr 🫢

πŸ“¦ where this page comes from