Mailing List Archive

Implementing IP_FREEBIND in OpenSSH
Hello,

We have a following proposal to implement IP_FREEBIND in OpenSSH
=========
There are multiple customer requests implementing for sshd the possibility
to bind to the specific IP address which is not (yet) configured on any
interface. Relevant RHEL/Fedora bug links:
https://bugzilla.redhat.com/show_bug.cgi?id=1096081,
https://bugzilla.redhat.com/show_bug.cgi?id=1936538

When there is defined multiple ListenAddress (local and non-local or yet
non-existent) in sshd_config, the initial startup does fail only on
non-local address, but the overall start is successful. This results in
sshd listening only on localhost address which is usually not very useful.

It may be useful for users to avoid startup failure and errors in the logs
during openssh daemon startup when listening to a specific address.

There was an upstream feature request
https://bugzilla.mindrot.org/show_bug.cgi?id=2512

The downside is a lack of diagnostics in cases when the ListenAddress is
specified with an error (e.g.typo).

Implementing IP_FREEBIND and allowing sshd to bind and listen on an ip,
even if networkmanager has not yet finished setting up the network. A basic
implementation is rather simple, e.g
https://bugzilla.mindrot.org/attachment.cgi?id=2763

To avoid the downside mentioned before, it can be avoided by providing
either a separate configuration option (ListenAddressNonlocal) or some
syntax sugar when specifying the IP address.

The solution can be made more or less portable: BSD systems support similar
functionality SO_BINDANY, which can make it more acceptable upstream.
FreeBSD support different flag names with the same semantics in different
versions: IP_FREEBIND, IP_NONLOCALOK for older versions,
IP_BINDANY/IPV6_BINDANY. Using such options in FreeBSD and other BSD
systems may require extra privileges.

https://www.freebsd.org/cgi/man.cgi?query=nsd.conf&sektion=5&manpath=freebsd-release-ports

https://github.com/wahern/cqueues/issues/66

Use requires root rights/special privilegies in FreeBSD. Linux allows this
without capabilities

(from https://github.com/microsoft/WSL/issues/460)

Old versions of FreeBSD used IP_NONLOCALOK with the same semantics and
limitation.

See also
https://lists.nlnetlabs.nl/pipermail/unbound-users/2017-November/004985.html
patch for unbound desired to solve a similar problem.

Windows and Solaris seem not to have the option with IP_FREEBIND semantics.

=========
Is there any interest in this proposal?

Many thanks in advance!
--
Dmitry Belyavskiy
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Implementing IP_FREEBIND in OpenSSH [ In reply to ]
On Mon, 26 Jul 2021, Dmitry Belyavskiy wrote:

> The solution can be made more or less portable: BSD systems support similar
> functionality SO_BINDANY, which can make it more acceptable upstream.
> FreeBSD support different flag names with the same semantics in different
> versions: IP_FREEBIND, IP_NONLOCALOK for older versions,
> IP_BINDANY/IPV6_BINDANY. Using such options in FreeBSD and other BSD
> systems may require extra privileges.

I don't know whether IP_FREEBIND is exactly equivalent to SO_BINDANY.

The getsockopt(2) manual page on OpenBSD talks discusses SO_BINDANY
primarily in the context of transparent proxying and mentions that
packet filter rules need to be configured to actually use it. It
isn't clear whether it offers the same "prospective use" as what you
want from IP_FREEBIND.

Couldn't you achieve the same result without modification to sshd
by using the ip_nonlocal_bind flag in the Linux kernel?

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Implementing IP_FREEBIND in OpenSSH [ In reply to ]
Dear Damien,

On Tue, Jul 27, 2021 at 2:55 AM Damien Miller <djm@mindrot.org> wrote:

> On Mon, 26 Jul 2021, Dmitry Belyavskiy wrote:
>
> > The solution can be made more or less portable: BSD systems support
> similar
> > functionality SO_BINDANY, which can make it more acceptable upstream.
> > FreeBSD support different flag names with the same semantics in different
> > versions: IP_FREEBIND, IP_NONLOCALOK for older versions,
> > IP_BINDANY/IPV6_BINDANY. Using such options in FreeBSD and other BSD
> > systems may require extra privileges.
>
> I don't know whether IP_FREEBIND is exactly equivalent to SO_BINDANY.
>
> The getsockopt(2) manual page on OpenBSD talks discusses SO_BINDANY
> primarily in the context of transparent proxying and mentions that
> packet filter rules need to be configured to actually use it. It
> isn't clear whether it offers the same "prospective use" as what you
> want from IP_FREEBIND.
>

Quoting https://man.openbsd.org/getsockopt.2

SO_BINDANY allows the socket to be bound to addresses which are not local
to the machine, so it can be used to make a transparent proxy. Note that
this option is limited to the superuser.

It looks like that it solves the problem under discussion, but has its
downsides.


>
> Couldn't you achieve the same result without modification to sshd
> by using the ip_nonlocal_bind flag in the Linux kernel?
>

Yes, it is a possible workaround, but this flag is system-level one, so it
doesn't provide any granularity.


--
Dmitry Belyavskiy
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Implementing IP_FREEBIND in OpenSSH [ In reply to ]
On Tue, 27 Jul 2021, Dmitry Belyavskiy wrote:

> >
> > Couldn't you achieve the same result without modification to sshd
> > by using the ip_nonlocal_bind flag in the Linux kernel?
> >
>
> Yes, it is a possible workaround, but this flag is system-level one, so it
> doesn't provide any granularity.

Perhaps make ip_nonlocal_bind=2 allow root to bind non-locally without
restriction. That might solve the problem for sshd and all other network
daemons?

Otherwise, I don't want to add another configuration directive for a
niche, platform-specific feature when the same effect could be achieved
though existing configuration (systemd dependencies, socket activation,
wildcard bind plus packet filtering, etc).

If SO_BINDANY does turn out to be cross platform without heavy caveats,
then perhaps a flag on this existing Listen directive would be more
acceptable, e.g. "Listen 111.222.33.44 bindany" - there is prior art
for such flags in the existing "rdomain" one.

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Implementing IP_FREEBIND in OpenSSH [ In reply to ]
Dear Damien,

On Wed, Jul 28, 2021 at 1:19 AM Damien Miller <djm@mindrot.org> wrote:

> On Tue, 27 Jul 2021, Dmitry Belyavskiy wrote:
>
> Perhaps make ip_nonlocal_bind=2 allow root to bind non-locally without
> restriction. That might solve the problem for sshd and all other network
> daemons?
>

Yes. It's one of the currently recommended workarounds.

If SO_BINDANY does turn out to be cross platform without heavy caveats,
> then perhaps a flag on this existing Listen directive would be more
> acceptable, e.g. "Listen 111.222.33.44 bindany" - there is prior art
> for such flags in the existing "rdomain" one.
>

Yes, it's the reasonable syntax for this purpose. Many thanks for the clue!


--
Dmitry Belyavskiy
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev