Skip to content

NETCONF as an OpenSSH subsystem - #1664

Merged
troglobit merged 5 commits into
mainfrom
netopeer2-vs-openssh
Sep 28, 2026
Merged

troglobit merged 5 commits into
mainfrom
netopeer2-vs-openssh

Conversation

@troglobit

Copy link
Copy Markdown
Contributor

Description

With this PR, NETCONF is served by the OpenSSH daemon as a subsystem instead of libssh embedded in netopeer2-server. sshd authenticates the user and runs a small libnetconf2 helper that bridges the session to a UNIX socket netopeer2-server listens on. The server learns the user from the socket peer credentials, so NACM works as before.

Changes

  • libnetconf2: new opt-in netconf-subsystem helper
  • netopeer2: -U PATH for a UNIX-only endpoint, ietf-netconf-server.yang optional
  • buildroot: new BR2_PACKAGE_LIBNETCONF2_SSH_SUBSYSTEM option, selected by the Infix defconfigs
  • confd: NETCONF is /ssh/netconf/enabled (default true), independent of SSH logins: with logins disabled sshd keeps running on port 830 only
  • Port 830 is NETCONF only (Match LocalPort 830 + ForceCommand); ssh -s <host> netconf also works on the regular SSH ports
  • clish login shell lets the subsystem helper through
  • Existing configurations are migrated

Benefits

  • Default builds no longer ship libssh; netopeer2-server links only libnetconf2, libyang, sysrepo and libcurl
  • One SSH server, one configuration: users, keys, host keys, ciphers and listen addresses are all managed under /ssh
  • ietf-netconf-server.yang and its SSH/TLS models are gone from the default builds, less to configure and explain

Trade-offs

  • NETCONF over TLS, NETCONF call-home and on-device netopeer2-cli are no longer available in default builds. A build without BR2_PACKAGE_LIBNETCONF2_SSH_SUBSYSTEM brings back libssh, TLS, call-home, the CLI and ietf-netconf-server.yang
  • Board factory configs no longer carry an ietf-netconf-server endpoint. Builds that turn the option off must add it back
  • NETCONF is fixed to port 830, on the same addresses as SSH
  • The UNIX socket is mode 0666; access control is left to NACM
  • netconf-state/sessions has no source-host for these sessions

Checklist

Tick relevant boxes, this PR is-a or has-a:

  • Bugfix
    • Regression tests
    • ChangeLog updates (for next release)
  • Feature
    • YANG model change => revision updated?
    • Regression tests added?
    • ChangeLog updates (for next release)
    • Documentation added?
  • Test changes
    • Checked in changed Readme.adoc (make test-spec)
    • Added new test to group Readme.adoc and yaml file
  • Code style update (formatting, renaming)
  • Refactoring (please detail in commit messages)
  • Build related changes
  • Documentation content changes
    • ChangeLog updated (for major changes)
  • Other (please describe):

@troglobit troglobit added the ci:main Build default defconfig, not minimal label Sep 27, 2026
@troglobit troglobit linked an issue Sep 27, 2026 that may be closed by this pull request
Refactor netopeer2-server to act as an OpenSSH subsystem, similar to
how sftp works.  The SSH daemon authenticates the user and runs the
new libnetconf2 netconf-subsystem helper, which bridges the session to
a UNIX socket netopeer2-server listens on.  The peer credentials of
that socket tell the server who the user is, so NACM works as before,
and netopeer2-server no longer needs an SSH implementation (libssh) of
its own.

The libnetconf2 patches add the helper and the API to create a UNIX
endpoint without ietf-netconf-server; the netopeer2 patch teaches the
server to use them.  Buildroot gets an option for this mode, which the
Infix defconfigs select.  A build without it keeps libssh, NETCONF over
TLS, call-home and netopeer2-cli.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
NETCONF becomes a netconf/enabled toggle under the ssh service, and in
the default build depends on it the same way restconf depends on web:
confd adds port 830 to the sshd listen addresses, forces the subsystem
on that port with a Match block, and starts netopeer2-server with -U
on the socket.  ietf-netconf-server has nothing left to describe
there, so it is not loaded and its factory data goes.

The build without the OpenSSH subsystem keeps all of that: confd loads
the SSH and TLS modules, ships the endpoint in the factory config, and
leaves port 830 to netopeer2-server.  The migration therefore comes in
two flavours, one converts an old endpoint into netconf/enabled, the
other only adds the leaf.

sshd runs subsystems through the login shell, so the clish wrapper lets
the helper through, and only the helper, when called with -c.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
syslogd starts in runlevel S and sshd not before runlevel 2, so the
condition never held anything back.  It did cost us: a configuration
change that touches both, a hostname change together with an SSH
change, reloads syslogd, which puts the condition in flux and pauses
sshd; with Finit 4.x a second reload arriving right then loses sshd's
pending reload, and it keeps its old listen addresses.  NETCONF over
sshd makes that a lockout.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A service paused by a condition during a reload lost its own pending
reload if another reload came in before it resumed.  With NETCONF on
sshd this shows up as a lockout: a hostname change together with an
SSH change leaves sshd on its old listen addresses.

Upstream commit f6b394e0 on the 4.x branch.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
@troglobit troglobit added the ci:skip Skip CI for this PR, started jobs are stopped. label Sep 28, 2026
@troglobit
troglobit merged commit e77493e into main Sep 28, 2026
7 checks passed
@troglobit
troglobit deleted the netopeer2-vs-openssh branch September 28, 2026 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:main Build default defconfig, not minimal ci:skip Skip CI for this PR, started jobs are stopped.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Run netopeer2-server as an openssh subsystem

2 participants