Loading...
Searching...
No Matches
Server sessions

# Init

Server must start with initialization. Its capabilities are determined by the context used when accepting new NETCONF sessions. Few capabilities that cannot be learnt from the context are set with separate functions nc_server_set_capab_withdefaults() and generally nc_server_set_capability().

Context does not only determine server modules, but its overall functionality as well. For every RPC the server should support, an nc_rpc_clb callback should be set on that node in the context using nc_set_rpc_callback(). Server then calls these as appropriate during poll.

Just like in the client, you can let libnetconf2 establish SSH or TLS transport or do it yourself and only provide the file descriptors of the connection.

To be able to accept any connections, the server must first be configured.

## Functions List

Available in nc_server.h.

- nc_server_set_capab_withdefaults()
- nc_server_set_capability()
- nc_server_endpt_count()
- nc_server_add_endpt_unix_socket_listen()
- nc_server_del_endpt_unix_socket()

# Server Configuration

To successfully accept connections on a server, you first need to configure it. The libnetconf2 server natively supports the ietf-netconf-server YANG module. This allows for a bigger scaling and flexibility of the NETCONF server. By using ietf-netconf-server YANG data you can express network configurations in a standardized and hierarchical format, enabling you to define complex network structures with greater ease.

The process of configuring a server is comprised of two steps. The first step is creating the configuration data and the second is applying it. The server supports two forms of the configuration data - YANG data and YANG diff.

## YANG data

Configuring the server using YANG data simplifies the management of network services. With YANG data, you build a structured configuration tree and apply it as a whole. This approach is user-friendly, allowing you to modify the configuration by adding or deleting nodes, and then deploying the updated configuration tree in its entirety, providing a way to manage your server's settings. The libnetconf2 library exports API functions that can help you with creation or deletion of the YANG data.

## YANG diff

YANG diff, enriched with operation attributes, offers advanced configuration control. It empowers the user to make precise changes within the configuration tree, enabling operations like specific node deletions, additions, and modifications. On the other hand, unlike YANG data, YANG diff represents only a subtree of the changes expecting the whole configuration to be managed externally. For example this is done by the tool sysrepo.

## Usage

To be able to configure the server, the required models first need to be implemented. To do this, see nc_server_config_load_modules(). Not all of the ietf-netconf-server (and all of its associated modules) features are enabled. If you wish to see which features are enabled, extract them from the context after calling the mentioned function.

If you wish not to create the YANG data yourself, you may use the library's functions to do this for you. For example nc_server_config_add_address_port() creates YANG data corresponding to an SSH/TLS endpoint. You can then apply this data by calling nc_server_config_setup_data() (or nc_server_config_setup_diff() for diff). See examples/server.c for a simple example.

You may also create entries in the keystore or truststore. For example the asymmetric key and certificate entries in the keystore can be then referenced as the SSH hostkeys or TLS server certificates, respectively. As for the truststore, you may create public key and certificate entries, which can then be used as SSH user's public keys or TLS server's end-entity/trust-anchor certificates, respectively.

## Functions List

Available in nc_server.h.

- nc_server_config_load_modules()
- nc_server_config_setup_diff()
- nc_server_config_setup_data()
- nc_server_config_setup_path()
- nc_server_config_add_address_port()
- nc_server_config_del_endpt()
- nc_server_config_add_keystore_asym_key()
- nc_server_config_del_keystore_asym_key()
- nc_server_config_add_keystore_cert()
- nc_server_config_del_keystore_cert()
- nc_server_config_add_truststore_pubkey()
- nc_server_config_del_truststore_pubkey()
- nc_server_config_add_truststore_cert()
- nc_server_config_del_truststore_cert()

# SSH

To successfully accept an SSH session you must configure at least one host key. You may create this data yourself or by using nc_server_config_add_ssh_hostkey().

It is important to decide whether the users that can connect to the SSH server should be obtained from the configuration or from the system. If the YANG feature local-users-supported is enabled (the default), then the authorized users are derived from the configuration. When a client connects to the server, he must be found in the configuration and he must authenticate to all of his configured authentication methods. If the feature is disabled, then the system will be used to try to authenticate the client via one of the three methods - publickey, keyboard-interactive or password (only one of them has to succeed).

If the local users are supported then each SSH endpoint can define it's own authorized clients and their authentication methods. For example if you wish to create an SSH user that can authenticate using a password, use nc_server_config_add_ssh_user_password(). Another option for authorized clients is to reference another endpoint's clients, however be careful not to create a cyclic reference (see nc_server_config_add_ssh_endpoint_client_ref()).

The Public Key authentication method is supported. If you wish to use this method, you need to specify the given user's public keys, which will be compared with the key(s) presented by the SSH client when authenticating. One option is to configure the public keys directly in the ietf-netconf-server YANG data (inline-definition). Other option is to configure the keys' data in the ietf-trustore module's YANG data and then reference them (truststore-reference). The final option is to set the global path to file with public keys. This path may contain special tokens, see nc_server_ssh_set_authkey_path_format(). If the path is set and the use-system-keys container is present in the data for the client wishing to authenticate, then the keys from the file will be used for authentication. If the YANG feature local-users-supported is disabled, then it's neccessary to set the path format using nc_server_ssh_set_authkey_path_format().

The Keyboard Interactive authentication method is also supported. It can be done in three ways. If libpam is found, Linux PAM is used to handle the authentication. You need to specify the service name using nc_server_ssh_set_pam_conf_filename(). Else if the standard functions for accessing local users are found on the system, they are used. The only Keyboard Interactive challenge will be the given user's password (that is if he's found on the system). Either way, you can always define your own callback to perform the authentication, see nc_server_ssh_set_interactive_auth_clb(). The callback has a higher priority than the other two methods.

There are also some other optional settings.

## Functions List

Available in nc_server.h.

- nc_server_config_add_ssh_hostkey()
- nc_server_config_del_ssh_hostkey()
- nc_server_config_add_ssh_keystore_ref()
- nc_server_config_del_ssh_keystore_ref()
- nc_server_config_add_ssh_user_pubkey()
- nc_server_config_del_ssh_user_pubkey()
- nc_server_config_add_ssh_user_password()
- nc_server_config_del_ssh_user_password()
- nc_server_config_add_ssh_user_interactive()
- nc_server_config_del_ssh_user_interactive()
- nc_server_config_del_ssh_user()
- nc_server_config_add_ssh_truststore_ref()
- nc_server_config_del_ssh_truststore_ref()
- nc_server_config_add_ssh_endpoint_client_ref()
- nc_server_config_del_ssh_endpoint_client_ref()
- nc_server_ssh_set_authkey_path_format()
- nc_server_ssh_set_pam_conf_filename()
- nc_server_ssh_set_interactive_auth_clb()

# TLS

TLS works with endpoints too, but its options differ significantly from the SSH ones, especially in the cert-to-name options that TLS uses to derive usernames from client certificates.

If you wish to listen on a TLS endpoint, you need to configure the endpoint's server certificate (see nc_server_config_add_tls_server_cert()).

To accept client certificates, they must first be considered trusted. For each TLS endpoint you may configure two types of client certificates. The first type are end-entity (client) certificates. These are certificates that belong to given clients. These certificates need to be trusted. The second type are trust-anchor (certificate authority) certificates, which carry over the trust (a chain of trust). Another option is to reference another TLS endpoint's end-entity certificates, however be careful not to create a cyclic reference (see nc_server_config_add_tls_endpoint_client_ref()).

Then, from each trusted client certificate a username must be derived for the NETCONF session. This is accomplished by finding a matching cert-to-name entry.

There are some further options. For example you can configure the TLS version and ciphers to be used.

You may also choose to use a Certificate Revocation List. These lists are downloaded from the URIs specified in the x509 CRLDistributionPoints extensions. Be mindful that if any CRL is successfully downloaded and set, then at least one of them has to belong to the peer (e.g. the client) certificate (in other words it has to be issued by peer's CA).

## Functions List

Available in nc_server.h.

- nc_server_config_add_tls_server_cert()
- nc_server_config_del_tls_server_cert()
- nc_server_config_add_tls_keystore_ref()
- nc_server_config_del_tls_keystore_ref()
- nc_server_config_add_tls_client_cert()
- nc_server_config_del_tls_client_cert()
- nc_server_config_add_tls_client_cert_truststore_ref()
- nc_server_config_del_tls_client_cert_truststore_ref()
- nc_server_config_add_tls_ca_cert()
- nc_server_config_del_tls_ca_cert()
- nc_server_config_add_tls_ca_cert_truststore_ref()
- nc_server_config_del_tls_ca_cert_truststore_ref()
- nc_server_config_add_tls_endpoint_client_ref()
- nc_server_config_del_tls_endpoint_client_ref()
- nc_server_config_add_tls_ctn()
- nc_server_config_del_tls_ctn()

# FD

If you used a tunneling software, which does its own authentication, you can accept a NETCONF session on its file descriptors with nc_accept_inout().

## Functions List

Available in nc_server.h.

- nc_accept_inout()

# Call Home

Call Home works with endpoints just like standard sessions, but the options are organized a bit differently and endpoints are added for CH clients. You may choose one of two approaches for creating a new Call Home session (or in other words making a server connect to a client). The first is to set all the required callbacks by calling nc_server_ch_set_dispatch_data(). By setting the callbacks, the server will automatically start connecting to a client, whenever a new Call Home client is created. The second approach is to create the Call Home thread manually. To do this, you need to call nc_connect_ch_client_dispatch(), which then creates a new thread and the server will start to connect. Unix socket Call Home sessions are not supported.

## Functions List

Available in nc_server.h.

- nc_server_config_add_ch_address_port()
- nc_server_config_del_ch_client()
- nc_server_config_del_ch_endpt()
- nc_server_config_add_ch_persistent()
- nc_server_config_add_ch_period()
- nc_server_config_del_ch_period()
- nc_server_config_add_ch_anchor_time()
- nc_server_config_del_ch_anchor_time()
- nc_server_config_add_ch_idle_timeout()
- nc_server_config_del_ch_idle_timeout()
- nc_server_config_add_ch_reconnect_strategy()
- nc_server_config_del_ch_reconnect_strategy()
- nc_server_config_add_ch_ssh_hostkey()
- nc_server_config_del_ch_ssh_hostkey()
- nc_server_config_add_ch_ssh_keystore_ref()
- nc_server_config_del_ch_ssh_keystore_ref()
- nc_server_config_add_ch_ssh_user_pubkey()
- nc_server_config_del_ch_ssh_user_pubkey()
- nc_server_config_add_ch_ssh_user_password()
- nc_server_config_del_ch_ssh_user_password()
- nc_server_config_add_ch_ssh_user_interactive()
- nc_server_config_del_ch_ssh_user_interactive()
- nc_server_config_del_ch_ssh_user()
- nc_server_config_add_ch_ssh_truststore_ref()
- nc_server_config_del_ch_ssh_truststore_ref()
- nc_server_config_add_ch_tls_server_cert()
- nc_server_config_del_ch_tls_server_cert()
- nc_server_config_add_ch_tls_keystore_ref()
- nc_server_config_del_ch_tls_keystore_ref()
- nc_server_config_add_ch_tls_client_cert()
- nc_server_config_del_ch_tls_client_cert()
- nc_server_config_add_ch_tls_client_cert_truststore_ref()
- nc_server_config_del_ch_tls_client_cert_truststore_ref()
- nc_server_config_add_ch_tls_ca_cert()
- nc_server_config_del_ch_tls_ca_cert()
- nc_server_config_add_ch_tls_ca_cert_truststore_ref()
- nc_server_config_del_ch_tls_ca_cert_truststore_ref()
- nc_server_config_add_ch_tls_ctn()
- nc_server_config_del_ch_tls_ctn()

# Connecting And Cleanup

When accepting connections with nc_accept(), all the endpoints are examined and the first with a pending connection is used. To remove all CH clients, endpoints, and free any used dynamic memory, destroy the server.

## Functions List

Available in nc_server.h.

- nc_accept()