sshmitm.forwarders.netconf module

NETCONF forwarder — EXPERIMENTAL

Warning

This forwarder is experimental. It has known protocol gaps and bugs that can cause session failures with modern NETCONF implementations. Do not use in production without understanding the limitations documented below.

Testing

Two test setups are recommended — one against a legacy RFC 4742 server to verify baseline functionality, and one against a modern RFC 6242 server to reproduce the chunked-framing failure described below.

Legacy server: yuma123 / netconfd (RFC 4742, ``]]>]]>`` framing)

Install from the distribution package manager:

# Debian / Ubuntu
sudo apt install yuma123

Start the server (requires root or CAP_NET_BIND_SERVICE for port 830):

sudo netconfd --no-startup --superuser=$USER

netconfd uses RFC 4742 framing and is therefore compatible with the current forwarder. Use this setup to test the happy path.

Modern server: netopeer2 (RFC 6242, chunked framing)

Build and install libyang, sysrepo, libnetconf2, and netopeer2 from source following the upstream documentation at CESNET/netopeer2. This setup is more involved but represents current real-world NETCONF deployments and will reproduce the chunked-framing failure in this forwarder.

Client

netconf-console is a lightweight Python client suitable for both setups:

pip install netconf-console

# Basic <get> request
netconf-console --host=localhost --port=830 -u admin --get

Alternatively use yangcli, which ships with yuma123:

yangcli user=admin server=localhost

Inserting SSH-MITM between client and server

netconf-console → SSH-MITM (10022) → netconfd / netopeer2 (830)

Start SSH-MITM:

ssh-mitm server --remote-host localhost --remote-port 830 --listen-port 10022

Point the client at SSH-MITM:

netconf-console --host=localhost --port=10022 -u admin --get

With the yuma123 server the session should complete successfully. With netopeer2 the session will stall or produce garbled output, demonstrating the RFC 6242 gap documented below.

Known limitations and bugs

RFC 6242 chunked framing not implemented (critical)

RFC 6242 (the current standard for NETCONF-over-SSH) requires chunk-based message framing:

#4\ndata\n##\n

Only the legacy ]]>]]> end-of-message terminator from RFC 4742 is implemented. Modern NETCONF devices and clients negotiate chunked framing during the <hello> exchange. When either side uses chunked framing the forwarder will silently corrupt or drop messages, or the session will hang waiting for a terminator that never arrives.

No timeout in read_netconf_data()

The reader loops forever until the ]]>]]> terminator is seen. A connection that drops mid-message, or any peer that uses chunked framing, will cause the forwarder thread to hang indefinitely.

Busy-loop with artificial latency

read_netconf_data() sleeps 50 ms before every recv() call. This adds unnecessary per-message latency and wastes CPU in a polling loop instead of blocking on the channel.

No capability negotiation interception

The <hello> exchange where client and server negotiate capabilities (including the framing version) passes through unexamined. The MITM cannot advertise, suppress, or rewrite capabilities.

No message-id tracking

NETCONF RPC messages carry a message-id attribute that correlates requests with responses. This forwarder does not parse message-ids, so audit logs cannot reliably pair requests with their responses in sessions with concurrent or pipelined RPCs.

class sshmitm.forwarders.netconf.NetconfBaseForwarder(session)

Bases: ExecForwarder

Base class for NETCONF SSH-subsystem forwarders.

Parameters:

session (Session)

property client_channel: Channel | None

Returns the client channel for the current plugin type

forward()

Forwards data between the client and the server

Return type:

None

read_netconf_data(chan, responses=1)
Parameters:
  • chan (Channel)

  • responses (int, default: 1)

Return type:

bytes

class sshmitm.forwarders.netconf.NetconfForwarder(session)

Bases: NetconfBaseForwarder

Transparent MITM forwarder for the NETCONF SSH subsystem (RFC 6242).

Intercepts NETCONF messages between client and server. See the module docstring for a full list of known limitations before using this class.

Parameters:

session (Session)

forward()

Forwards data between the client and the server

Return type:

None