Skip to content

SSL connection

Daniel Frantík edited this page Jul 20, 2026 · 7 revisions

API-SSL (TikConnectionType.ApiSsl) is the binary MikroTik API over TLS. By default, the certificate chain is not validated — any server certificate is accepted, so the communication is encrypted but you are not protected against a man-in-the-middle. This is opt-in behavior via AllowInvalidCertificate (see Certificate validation below); set it to false for standard OS chain/hostname validation, or supply a custom CertificateValidationCallback for pinning/custom CA trust.

Why a certificate is required on MikroTik

MikroTik's API-SSL can technically operate in two modes:

  1. With a certificate — standard TLS session
  2. Without a certificate — anonymous Diffie-Hellman (ADH) cipher

However, .NET's SslStream does not support anonymous DH cipher suites — they are intentionally disabled for security reasons and cannot be enabled. This means that if no certificate is assigned to the api-ssl service on MikroTik, the TLS handshake will fail with an AuthenticationException. The certificate requirement is therefore a .NET limitation, not a MikroTik API requirement.

MikroTik setup

You can create a self-signed certificate directly on the router (see below) or use your own certificate (not covered here).

  • Create and sign a CA certificate (replace 192.168.88.1 with your MikroTik's IP)
/certificate add name=mikrotik-CA common-name=mikrotik-CA key-usage=key-cert-sign,crl-sign
/certificate sign mikrotik-CA ca-crl-host=192.168.88.1
  • Create and sign a server certificate
/certificate add name=api-ssl-server common-name=192.168.88.1
/certificate sign api-ssl-server ca=mikrotik-CA
  • Enable api-ssl and assign the certificate
/ip service set api-ssl disabled=no certificate=api-ssl-server

Code example

Use TikConnectionType.ApiSsl — everything else is identical to a plain API connection.

using (var connection = ConnectionFactory.OpenConnection(TikConnectionType.ApiSsl, host, user, pass))
{
    // do something useful
}

Certificate validation

TikConnectionSetup exposes two properties that control how the server certificate is validated, shared with the REST RestSsl transport:

  • AllowInvalidCertificate (bool, default true) — when true, any server certificate is accepted (matches tik4net's historical behavior, back-compat default). When false, standard OS chain and hostname validation applies — the connection fails unless the certificate is trusted.
  • CertificateValidationCallback (RemoteCertificateValidationCallback) — an optional custom validation delegate. When set, it takes full control of the decision and AllowInvalidCertificate is ignored. Use this for certificate pinning or trusting a private CA without installing it into the OS store.
var setup = new TikConnectionSetup(host, user, pass)
{
    AllowInvalidCertificate = false, // reject self-signed/invalid certs
    // or, for cert pinning / custom CA trust:
    CertificateValidationCallback = (sender, cert, chain, errors) =>
        cert.GetCertHashString() == expectedPinnedThumbprint,
};
using var connection = setup.CreateApiSslConnection(); // or CreateApiSslConnectionAsync()

Note: ConnectionFactory (the older/classic entry point) has no way to configure this — ApiConnection is internal, so only TikConnectionSetup can reach these properties. This mirrors the existing gap for ConnectTimeout, which is likewise honored by TikConnectionSetup but not by every transport created via ConnectionFactory. ConnectionFactory.OpenConnection connections keep the historical accept-all behavior.

The default (AllowInvalidCertificate = true) is unchanged from prior tik4net versions, so existing code keeps working as-is; a future major version may flip the default to false.

Notes

  • api-ssl is available since RouterOS 6.1
  • A certificate must be assigned to the api-ssl service on MikroTik — anonymous DH mode is not supported by .NET
  • By default, the certificate chain is not verified by tik4net — see Certificate validation to opt into strict validation or pinning
  • tik4net uses SslProtocols.None, which lets the OS negotiate the best available TLS version (TLS 1.2 or 1.3); TLS 1.0 is not used

Clone this wiki locally