This tutorial aims to help you get started with using DTLS with Vermont. As required by , Vermont supports DTLS over UDP and DTLS over SCTP. Since Vermont has no support for TCP, there is also no support for TLS over TCP.
In order to use DTLS, Vermont must have been built with DTLS support turned on which in turn requires a recent and decent version of OpenSSL. If you get the following error message, then you have to rebuild Vermont.
DTLS over UDP not supported!
See the INSTALL file that ships with the source code for more information on how to enable DTLS support.
If you want to comply with RFC 5101, you have to set up a certification authority (CA) or, at least, create some self-signed certificates. This is necessary to allow the exporter to verify the identity of the collector and vice versa. However, managing a CA can be a pain. It is even dispensable in some scenarios like when you are running experiments to asses the performance impact of DTLS. In this case, you can take advantage of anonymous cipher suites which are defined by TLS. These cipher suites basically skip the authentication process which makes certificates unnecessary. There is a caveat, though: Not using proper authentication makes man-in-the-middle attacks possible and therefore puts your application at risk. Assuming that you are using Vermont in a controlled (lab) environment for testing purposes, anonymous ciphers are yet an option.
Setting up a secure IPFIX connection using anonymous ciphers is simple: You just specify ''DTLS_OVER_UDP'' or ''DTLS_OVER_SCTP'' as the transport protocol. Here is an example for an exporter configuration:
<ipfixExporter id="8"> <collector> <ipAddress>127.0.0.1</ipAddress> <transportProtocol>DTLS_OVER_UDP</transportProtocol> </collector> </ipfixExporter>
The corresponding collector configuration is also pretty straight forward:
<ipfixCollector id="1"> <listener> <transportProtocol>DTLS_OVER_UDP</transportProtocol> </listener> <next>2</next> </ipfixCollector>
If you want to fully comply with RFC 5101 and defeat man-in-the-middle attacks, you have to swallow the bitter pill and deal with the creation of X.509 certificates.
Certificates and the corresponding private keys are stored in ASN.1 data structures defined by X.509v3. These data structures are serialized for file storage using a rule set known as Distinguished Encoding Rules (*DER). The output of this encoding process is *binary data** which can be written directly into a file in the file system. Thus, the file is in DER format. Another format is called Privacy Enhanced Mail (*PEM) and *is basically a base64 encoded DER file. The advantage of PEM is that it only uses ASCII printable characters which means that you can view PEM files in your favorite text editor. Another important aspect is that you can **store multiple certificates and private keys in one PEM file****. Some people take advantage of this fact and store a certificate plus the corresponding private key in one file.
Here is an example for a certificate in PEM format:
-----BEGIN CERTIFICATE----- MIICFjCCAX+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADAdMRswGQYDVQQDExJWZXJt b250IGV4YW1wbGUgQ0EwHhcNMDkwMzAzMTczNDE2WhcNMjkwMjI2MTczNDE2WjAU ..... 0sgU6LzjmSs6Kg== -----END CERTIFICATE-----
Due to the flexibility of PEM files, Vermont only supports certificates and private keys in PEM format.
Before we look into creating X.509 certificates, we want to see how we can examine existing certificates. OpenSSL is the tool that we choose for this task. If the certificate we want to inspect is stored in a file named ''collector_cert.pem'', then we can use the following command to transform the certificate into human-readable format:
$ openssl x509 -in collector_cert.pem -noout -text
The output of this command might look as follows. Some details have been left out for the sake of brevity.
Certificate: Data: Version: 3 (0x2) Serial Number: 3 (0x3) Signature Algorithm: sha1WithRSAEncryption Issuer: CN=Vermont example CA Validity Not Before: Mar 3 17:34:16 2009 GMT Not After : Feb 26 17:34:16 2029 GMT Subject: CN=Collector Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:c8:a8:bc:ed:e1:4a:1c:e6:7c:db:f2:41:26:99: 0c:97:9f:52:4f:4f:ec:06:35:2f:32:ec:3c:88:13: .... Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Subject Key Identifier: 48:B1:AF:25:4D:6C:97:56:64:84:2F:3F:F7:E6:CD:26:C9:95:0F:E9 X509v3 Authority Key Identifier: keyid:F9:79:19:E7:91:26:27:24:EC:78:65:8C:BB:CD:10:8F:A2:1A:DC:05 X509v3 Subject Alternative Name: DNS:collector.example.com Signature Algorithm: sha1WithRSAEncryption 5e:63:1a:f2:ff:c0:dd:b6:3f:ef:f0:14:3d:6c:67:95:e1:ab: 1a:ef:e8:16:fc:0d:f6:4f:2e:7d:05:2f:02:ff:27:d0:f0:0a: ....
The pieces of information that are most relevant for Vermont are:
The subject's most specific Common Name (CN) of the certificate we are looking at is "Collector". The certificate has also one X509v3 Subject Alternative Name of type DNS which is "collector.example.com". Keep in mind, though, that there may be multiple Subject Alternative Names.
Managing a Public key infrastructure (PKI) including Certificate Authorities (CAs) is a complex task and beyond the scope of this tutorial. We rather want to limit this discussion to the creation of self-signed certificates. Here is an example that creates a self-signed certificate with subject name ''/CN=exporter.example.com'' and writes it to ''exporter_cert.pem'' in PEM format. The required 1024 bit RSA key is generated at the same time and written to ''exporter_key.pem''. The latter file must be kept secret because it contains the public as well as the private part of the RSA key. The certificate which is stored in ''exporter_cert.pem'' can be shared with others.
$ openssl req -subj "/CN=exporter.example.com" -newkey rsa:1024 -x509 -out exporter_cert.pem -keyout exporter_key.pem -nodes
Every peer that takes part in an IPFIX connection must have an identity. In real life, the identity of a person is the combination of their first and last name and their date of birth. In the IPFIX world, an identity is basically a Fully Qualified Domain Name (FQDN) such as ''exporter.example.com''. For authentication purposes, every IPFIX endpoint is required to possess a certificate that has the endpoint's FQDN in the subject's Common Name (CN) or in one of the Subject Alternative Names. It goes without saying that the endpoint must also possess the corresponding private key in order to convince its peers that it is the legitimate owner of this certificate.
One important aspect is that the FQDN which serves as the ID does not need to map to an IP address that is assigned to the endpoint when doing a DNS lookup. Only a string comparison is performed as part of the authentication process. The DNS database is not checked.
As soon as you have all necessary certificates and private keys available, it is easy to setup Vermont to use these for DTLS connections. There is only one more detail that needs some discussion which is where the application looks for CA certificates. You basically have two options:
All certificates stored in the file pointed to by ''CAfile'' are read during startup and considered as trusted root CAs. This option is probably the easiest one, but it does not scale beyond a certain number of certificates. With CApath, you can specify a directory that is searched as soon as a specific CA certificate is needed for the verification of another certificate. The file name that is searched for is the hash of the Distinguished Name (DN) of the certificate that is needed. See the man page of OpenSSL's SSL_CTX_load_verify_locations function for more information.
The local certificate, the matching private key and the file system paths for ''CAfile'' and ''CApath'' are specified on a per-exporter basis. As a consequence, an exporter authenticates to all collectors using the same certificate and therefore the same identity.
For each collector the exporter should send IPFIX data to, the IP address, the transport protocol as well as the expected FQDN must be specified. Please note, that only one FQDN can be specified per collector.
Look at this configuration snippet which serves as an example for an exporter configuration:
<ipfixExporter id="8"> <cert>configs/example_certs/exporter_cert.pem</cert> <key>configs/example_certs/exporter_key.pem</key> <CAfile>configs/example_certs/vermontCA.pem</CAfile> <CApath>/etc/ssl/certs</CApath> <collector> <ipAddress>127.0.0.1</ipAddress> <transportProtocol>DTLS_OVER_UDP</transportProtocol> <peerFqdn>collector.example.com</peerFqdn> </collector> </ipfixExporter>
During connection setup, the peer must present a certificate which has ''collector.example.com'' stored in either its most specific Common Name (CN) or in one of its potentially many subject alternative names of type DNS.
The configuration of a collector is similar to the one of an exporter. The major difference is that multiple FQDNs can be specified via the ''<peerFqdn>'' element. This makes perfect sense because a collector uses a listening socket that accepts connection setup requests from multiple peers which have different identities (i.e. FQDNs).
<ipfixCollector id="1"> <cert>configs/example_certs/collector_cert.pem</cert> <key>configs/example_certs/collector_key.pem</key> <CAfile>configs/example_certs/vermontCA.pem</CAfile> <CApath>/etc/ssl/certs</CApath> <listener> <transportProtocol>DTLS_OVER_UDP</transportProtocol> <peerFqdn>ex352.example.com</peerFqdn> <peerFqdn>exporter.example.com</peerFqdn> </listener> <next>2</next> </ipfixCollector>
In this example, Vermont accepts incoming DTLS connections from any peer. However, as part of the DTLS handshake, the peer must present a certificate that has either ''ex352.example.com'' or ''exporter.example.com'' mentioned in its Common Name (CN) or in one of its subject alternative names of type DNS.