fiddyspence's blog

Influxdb Over SSL

I’ve been messing with monitoring a bit recently, and have a project on simmer that, in principle at least, is going to use influxdb for data storage. The project needs to collect data from public sources, so I wanted some decent protection for the process (with better control over the TLS etc). More detail to follow, but the initial steps are these:

The plan for the future is to replace the front end just proxy to influxdb with an app with a bit more intelligence - in the first instance, I plan to extract the certificate CN and use that to tag the data - for the time being, this’ll do. Doing so will also alleviate a lot of aggro about restricting access using usernames and passwords and stuff.

I’m a lazy goit, so I’ve repurposed puppet agent certs for this activity, to save managing my own CA.

Step 1 is to bind influx only to the loopback interface for each endpoint (by default there are 3 - admin, meta and http)

  enabled = true
  bind-address = "localhost:8086"

Step 2, in steps our old friend Apache (note - this is TLS1.2 only, so I lied about SSL)

Listen 8087 https
<VirtualHost *:8087>
    SSLProxyEngine on
    SSLProtocol TLSv1.2
    # Not looked at this for a few months - this might be out of date again already
    SSLHonorCipherOrder     on
    SSLCertificateFile      /etc/httpd/ssl/cert.pem
    SSLCertificateKeyFile   /etc/httpd/ssl/private.pem
    SSLCertificateChainFile /etc/httpd/ssl/ca_crt.pem
    SSLCACertificateFile    /etc/httpd/ssl/ca.pem
    SSLCARevocationFile     /etc/httpd/ssl/crl.pem
    SSLCARevocationCheck    chain
    SSLVerifyClient         require
    SSLVerifyDepth          1
    SSLOptions              +StdEnvVars +ExportCertData
    RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
    RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
    RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
    ProxyPass / http://localhost:8086/
    ProxyPassReverse / http://localhost:8086/

And that’s pretty much it - you just need a few lines of ruby or pythong and you’re off:

@http ||= Net::HTTP.new(@influxhost, @influxport)
@http.use_ssl = @ssl
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
@http.cert = OpenSSL::X509::Certificate.new(File.read(@sslcert))
@http.ca_file = @sslca
@http.key = OpenSSL::PKey::RSA.new(File.read(@sslkey))
uri = URI.parse("http#{@ssl ? 's' : ''}://#{@influxhost}:#{@influxport}/write?db=noise")
request = Net::HTTP::Post.new(uri.request_uri)
request.body = "volume,host=#{Socket.gethostname}, value=#{value.round(1)}"