sshmitm.forwarders.netconf module

NETCONF forwarder — EXPERIMENTAL

Warning

This forwarder is experimental. Protocol gaps remain; 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 confirm the chunked-framing implementation.

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

Modern server: netopeer2 (RFC 6242, chunked framing)

Build and install libyang, sysrepo, libnetconf2, and netopeer2 from source following the upstream documentation at CESNET/netopeer2.

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

Known limitations

No notification support (Phase 5)

NETCONF event notifications (RFC 5277 create-subscription) are forwarded transparently but not tracked or intercepted.

RPC hooks (Phase 3)

Subclasses can override NetconfBaseForwarder.handle_rpc_request() and NetconfBaseForwarder.handle_rpc_reply() to inspect or rewrite individual RPC operations without touching the framing layer. The reference logging plugin is sshmitm.plugins.netconf.log_session.NetconfLoggingForwarder.

class sshmitm.forwarders.netconf.NetconfBaseForwarder(session)

Bases: ExecForwarder

Base class for NETCONF SSH-subsystem forwarders.

Provides message framing for both RFC 4742 (EOM ]]>]]>) and RFC 6242 (chunked \n#<size>\n<data>...\n##\n) framing, with configurable read timeouts.

Parameters:

session (Session)

READ_TIMEOUT: float = 30.0

Default timeout in seconds for reading one complete NETCONF message.

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

handle_client_data(data)

Parse client data as an RPC and invoke handle_rpc_request().

Parameters:

data (bytes)

Return type:

bytes

handle_rpc_reply(message_id, element)

Called for each server RPC reply after the <hello> exchange.

message_id is the message-id attribute of the <rpc-reply>. element is the parsed <rpc-reply> element.

Return a modified element to rewrite the reply, or None to forward the original bytes unchanged. The default implementation always returns None.

Parameters:
  • message_id (str)

  • element (Element)

Return type:

Element | None

handle_rpc_request(message_id, operation, element)

Called for each client RPC after the <hello> exchange.

message_id is the message-id attribute of the <rpc> element. operation is the local name of the operation (e.g. "get-config"). element is the parsed <rpc> Element.

Return a modified element to rewrite the message, or None to forward the original bytes unchanged. The default implementation always returns None.

Parameters:
  • message_id (str)

  • operation (str)

  • element (Element)

Return type:

Element | None

handle_server_data(data)

Parse server data as an rpc-reply and invoke handle_rpc_reply().

Parameters:

data (bytes)

Return type:

bytes

read_netconf_message(chan, timeout=None)

Read one complete NETCONF message from chan.

Framing is detected automatically from the first two bytes:

  • \n# → RFC 6242 chunked framing (\n#<size>\n<data>...\n##\n)

  • anything else → RFC 4742 EOM framing (]]>]]>), including the <hello> exchange that opens every RFC 6242 session.

Raises TimeoutError if no complete message arrives within timeout seconds (defaults to READ_TIMEOUT).

Parameters:
  • chan (Channel)

  • timeout (float | None, default: None)

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