Skip to content

Commit

Permalink
finagle-netty4: Add counter for number of snooping TLS connects
Browse files Browse the repository at this point in the history
Problem / Solution

We want better observability into how many connections have been
established via TLS snooping so add a counter.

Differential Revision: https://phabricator.twitter.biz/D667652
  • Loading branch information
Bryce Anderson authored and jenkins committed May 11, 2021
1 parent b8b61f4 commit 5569615
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ New Features
limit rather than rejecting them. A `buffered_streams` gauge has been added to track the
current number of buffered streams. ``PHAB_ID=D643138``

* finagle-netty4: Added a new counter to keep track of the number of TLS connections that were
started via snooping. ``PHAB_ID=D667652``

Breaking API Changes
~~~~~~~~~~~~~~~~~~~~

Expand Down
3 changes: 3 additions & 0 deletions doc/src/sphinx/metrics/Transport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ ChannelStatsHandler
A gauge of the total number of SSL/TLS connections that are currently open in
the channel.

**tls/snooped_connects**
A counter of the number of TLS connections that were detected via snooping.

IdleChannelHandler
<<<<<<<<<<<<<<<<<<

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.twitter.finagle.netty4.ssl.server

import com.twitter.finagle.Stack.Params
import com.twitter.finagle.netty4.ByteBufConversion
import com.twitter.finagle.param.Stats
import com.twitter.finagle.ssl.TlsSnooping
import com.twitter.finagle.ssl.TlsSnooping.DetectionResult
import io.netty.buffer.ByteBuf
Expand All @@ -28,6 +29,7 @@ private[finagle] final class Netty4TlsSnoopingHandler(params: Params) extends By
// event, so we use this state to keep track of whether we intercepted one or not.
private[this] var channelActiveDeferred = false

private[this] val snoopingCounter = params[Stats].statsReceiver.counter("tls", "snooped_connects")
private[this] val snooper = params[TlsSnooping.Param].snooper

override def handlerAdded(ctx: ChannelHandlerContext): Unit = {
Expand Down Expand Up @@ -79,6 +81,7 @@ private[finagle] final class Netty4TlsSnoopingHandler(params: Params) extends By
ctx.fireUserEventTriggered(Result.Cleartext)

private[this] def secureDetected(ctx: ChannelHandlerContext): Unit = {
snoopingCounter.incr()
ctx.pipeline.addAfter(
ctx.name,
Netty4ServerSslChannelInitializer.HandlerName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package com.twitter.finagle.netty4.ssl.server

import com.twitter.finagle.Stack
import com.twitter.finagle.netty4.ssl.Netty4SslTestComponents
import com.twitter.finagle.param.Stats
import com.twitter.finagle.ssl.OpportunisticTls
import com.twitter.finagle.stats.{InMemoryStatsReceiver, StatsReceiver}
import com.twitter.finagle.transport.Transport
import io.netty.buffer.{ByteBuf, ByteBufAllocator}
import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter}
Expand Down Expand Up @@ -70,8 +72,13 @@ class Netty4TlsSnoopingHandlerTest extends FunSuite with ScalaCheckDrivenPropert
ch.pipeline.get(classOf[UserEventInterceptor]).events.dequeue()
}

private[this] def channel(): EmbeddedChannel = {
new EmbeddedChannel(new Netty4TlsSnoopingHandler(params), new UserEventInterceptor)
private[this] def channel(stats: Option[StatsReceiver] = None): EmbeddedChannel = {
val p = stats match {
case Some(s) => params + Stats(s)
case None => params
}

new EmbeddedChannel(new Netty4TlsSnoopingHandler(p), new UserEventInterceptor)
}

test("recognizes known SSL/TLS handshake prefixes") {
Expand All @@ -95,4 +102,27 @@ class Netty4TlsSnoopingHandlerTest extends FunSuite with ScalaCheckDrivenPropert
ch.writeInbound(arrayToBuf(toShortHandshake))
assert(getEvent(ch) == Netty4TlsSnoopingHandler.Result.Cleartext)
}

test("Increments counter on a valid prefix") {
val stats = new InMemoryStatsReceiver
val ch = channel(Some(stats))

val validPrefix = Array[Byte](0x16, 0x03, 0x00, 0x13, 0x03)
ch.writeInbound(arrayToBuf(validPrefix))

assert(stats.counters(Seq("tls", "snooped_connects")) == 1)
assert(getEvent(ch) == Netty4TlsSnoopingHandler.Result.Secure)
}

test("Doesn't increment counter on an invalid prefix") {
val stats = new InMemoryStatsReceiver
val ch = channel(Some(stats))

// invalid prefix
val invalidPrefix = Array[Byte](0x00, 0x00, 0x00, 0x00, 0x00)
ch.writeInbound(arrayToBuf(invalidPrefix))

assert(stats.counters(Seq("tls", "snooped_connects")) == 0)
assert(getEvent(ch) == Netty4TlsSnoopingHandler.Result.Cleartext)
}
}

0 comments on commit 5569615

Please sign in to comment.