Score:1

Drop connections with a mismatching client certificate CN in nginx TCP reverse proxy

gb flag

I'm using nginx to add TLS functionality on top of an existing TCP server (Redis) by proxying it like so (please read on before saying "Redis has builtin TLS support"):

stream {
  server {
    listen 6379 ssl;

    ssl_certificate /etc/ssl/private/tls.crt;
    ssl_certificate_key /etc/ssl/private/tls.key;

    ssl_client_certificate /etc/ssl/private/ca.crt;
    ssl_verify_client on;

    proxy_pass redis:679;
  }
}

However, this will accept all client certificates that have been signed by the specified CA. I'd like to only accept client certificates with a specific CN: cn=api. When proxying HTTP I can use an if statement like this

if ($ssl_client_s_dn != "CN=api") {
  return 403;
}

However, it seems that if statements like that are not allowed in stream servers. As a workaround I've used a map statement to route requests that don't match the CN to a nonexistent upstream like this:

stream {
  upstream redis_backend {
    server redis:6379;
  }

  map $ssl_client_s_dn $backend_svr {
    "CN=api" redis_backend;
    default null;
  }

  server {
    ...

    proxy_pass $backend_svr;
  }
}

However, I can't help but feel that there must be a better way to reject the connection for mismatching client certificates.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.