Add support for AddressFamily and ConnectTimeout in the .ssh/config when using --remote-ssh-config.
This commit is contained in:
parent
478b0e1b9d
commit
1856e3a79d
5 changed files with 66 additions and 3 deletions
|
|
@ -1,3 +1,7 @@
|
||||||
|
# 0.4.3
|
||||||
|
|
||||||
|
* Add support for AddressFamily and ConnectTimeout in the .ssh/config when using `--remote-ssh-config`.
|
||||||
|
|
||||||
# 0.4.2
|
# 0.4.2
|
||||||
|
|
||||||
* Support `--remote-ssh-config [path-to-ssh-config]` as an argument in case extra params are required beyond `--remote-port` or `--remote-user`. Note: `--remote-host` must still be set, but it can be an 'alias' represented by the 'Host' value in the ssh config.
|
* Support `--remote-ssh-config [path-to-ssh-config]` as an argument in case extra params are required beyond `--remote-port` or `--remote-user`. Note: `--remote-host` must still be set, but it can be an 'alias' represented by the 'Host' value in the ssh config.
|
||||||
|
|
|
||||||
6
debian/changelog
vendored
6
debian/changelog
vendored
|
|
@ -1,3 +1,9 @@
|
||||||
|
enroll (0.4.3) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Add support for AddressFamily and ConnectTimeout in the .ssh/config when using `--remote-ssh-config`.
|
||||||
|
|
||||||
|
-- Miguel Jacq <mig@mig5.net> Fri, 16 Jan 2026 11:00 +1100
|
||||||
|
|
||||||
enroll (0.4.2) unstable; urgency=medium
|
enroll (0.4.2) unstable; urgency=medium
|
||||||
|
|
||||||
* Support `--remote-ssh-config [path-to-ssh-config]` as an argument in case extra params are required beyond `--remote-port` or `--remote-user`. Note: `--remote-host` must still be set, but it can be an 'alias' represented by the 'Host' value in the ssh config.
|
* Support `--remote-ssh-config [path-to-ssh-config]` as an argument in case extra params are required beyond `--remote-port` or `--remote-user`. Note: `--remote-host` must still be set, but it can be an 'alias' represented by the 'Host' value in the ssh config.
|
||||||
|
|
|
||||||
|
|
@ -379,6 +379,10 @@ def _remote_harvest(
|
||||||
sock = None
|
sock = None
|
||||||
hostkey_name = connect_host
|
hostkey_name = connect_host
|
||||||
|
|
||||||
|
# Timeouts derived from ssh_config if set (ConnectTimeout).
|
||||||
|
# Used both for socket connect (when we create one) and Paramiko handshake/auth.
|
||||||
|
connect_timeout: Optional[float] = None
|
||||||
|
|
||||||
if remote_ssh_config:
|
if remote_ssh_config:
|
||||||
from paramiko.config import SSHConfig # type: ignore
|
from paramiko.config import SSHConfig # type: ignore
|
||||||
from paramiko.proxy import ProxyCommand # type: ignore
|
from paramiko.proxy import ProxyCommand # type: ignore
|
||||||
|
|
@ -411,14 +415,58 @@ def _remote_harvest(
|
||||||
else:
|
else:
|
||||||
key_filename = str(Path(str(ident)).expanduser())
|
key_filename = str(Path(str(ident)).expanduser())
|
||||||
|
|
||||||
|
# Honour OpenSSH ConnectTimeout (seconds) if present.
|
||||||
|
if hcfg.get("connecttimeout"):
|
||||||
|
try:
|
||||||
|
connect_timeout = float(str(hcfg.get("connecttimeout")))
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
connect_timeout = None
|
||||||
|
|
||||||
proxycmd = hcfg.get("proxycommand")
|
proxycmd = hcfg.get("proxycommand")
|
||||||
|
|
||||||
|
# AddressFamily support: inet (IPv4 only), inet6 (IPv6 only), any (default).
|
||||||
|
addrfam = str(hcfg.get("addressfamily") or "any").strip().lower()
|
||||||
|
family: Optional[int] = None
|
||||||
|
if addrfam == "inet":
|
||||||
|
family = _socket.AF_INET
|
||||||
|
elif addrfam == "inet6":
|
||||||
|
family = _socket.AF_INET6
|
||||||
|
|
||||||
if proxycmd:
|
if proxycmd:
|
||||||
|
# ProxyCommand provides the transport; AddressFamily doesn't apply here.
|
||||||
sock = ProxyCommand(str(proxycmd))
|
sock = ProxyCommand(str(proxycmd))
|
||||||
|
elif family is not None:
|
||||||
|
# Enforce the requested address family by pre-connecting the socket and
|
||||||
|
# passing it into Paramiko via sock=.
|
||||||
|
last_err: Optional[OSError] = None
|
||||||
|
infos = _socket.getaddrinfo(
|
||||||
|
connect_host, connect_port, family, _socket.SOCK_STREAM
|
||||||
|
)
|
||||||
|
for af, socktype, proto, _, sa in infos:
|
||||||
|
s = _socket.socket(af, socktype, proto)
|
||||||
|
if connect_timeout is not None:
|
||||||
|
s.settimeout(connect_timeout)
|
||||||
|
try:
|
||||||
|
s.connect(sa)
|
||||||
|
sock = s
|
||||||
|
break
|
||||||
|
except OSError as e:
|
||||||
|
last_err = e
|
||||||
|
try:
|
||||||
|
s.close()
|
||||||
|
except Exception:
|
||||||
|
pass # nosec
|
||||||
|
if sock is None and last_err is not None:
|
||||||
|
raise last_err
|
||||||
elif hostkey_name != connect_host:
|
elif hostkey_name != connect_host:
|
||||||
# If HostKeyAlias is used, connect to HostName via a socket but
|
# If HostKeyAlias is used, connect to HostName via a socket but
|
||||||
# use HostKeyAlias for known_hosts lookups.
|
# use HostKeyAlias for known_hosts lookups.
|
||||||
sock = _socket.create_connection((connect_host, connect_port))
|
sock = _socket.create_connection(
|
||||||
|
(connect_host, connect_port), timeout=connect_timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
# If we created a socket (sock!=None), pass hostkey_name as hostname so
|
||||||
|
# known_hosts lookup uses HostKeyAlias (or whatever hostkey_name resolved to).
|
||||||
ssh.connect(
|
ssh.connect(
|
||||||
hostname=hostkey_name if sock is not None else connect_host,
|
hostname=hostkey_name if sock is not None else connect_host,
|
||||||
port=connect_port,
|
port=connect_port,
|
||||||
|
|
@ -427,6 +475,9 @@ def _remote_harvest(
|
||||||
sock=sock,
|
sock=sock,
|
||||||
allow_agent=True,
|
allow_agent=True,
|
||||||
look_for_keys=True,
|
look_for_keys=True,
|
||||||
|
timeout=connect_timeout,
|
||||||
|
banner_timeout=connect_timeout,
|
||||||
|
auth_timeout=connect_timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
# If no username was explicitly provided, SSH may have selected a default.
|
# If no username was explicitly provided, SSH may have selected a default.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "enroll"
|
name = "enroll"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
description = "Enroll a server's running state retrospectively into Ansible"
|
description = "Enroll a server's running state retrospectively into Ansible"
|
||||||
authors = ["Miguel Jacq <mig@mig5.net>"]
|
authors = ["Miguel Jacq <mig@mig5.net>"]
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
%global upstream_version 0.4.2
|
%global upstream_version 0.4.3
|
||||||
|
|
||||||
Name: enroll
|
Name: enroll
|
||||||
Version: %{upstream_version}
|
Version: %{upstream_version}
|
||||||
|
|
@ -43,6 +43,8 @@ Enroll a server's running state retrospectively into Ansible.
|
||||||
%{_bindir}/enroll
|
%{_bindir}/enroll
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Jan 16 2026 Miguel Jacq <mig@mig5.net> - %{version}-%{release}
|
||||||
|
- Add support for AddressFamily and ConnectTimeout in the .ssh/config when using `--remote-ssh-config`.
|
||||||
* Tue Jan 13 2026 Miguel Jacq <mig@mig5.net> - %{version}-%{release}
|
* Tue Jan 13 2026 Miguel Jacq <mig@mig5.net> - %{version}-%{release}
|
||||||
- Support `--remote-ssh-config [path-to-ssh-config]` as an argument in case extra params are required beyond `--remote-port` or `--remote-user`. Note: `--remote-host` must still be s
|
- Support `--remote-ssh-config [path-to-ssh-config]` as an argument in case extra params are required beyond `--remote-port` or `--remote-user`. Note: `--remote-host` must still be s
|
||||||
et, but it can be an 'alias' represented by the 'Host' value in the ssh config.
|
et, but it can be an 'alias' represented by the 'Host' value in the ssh config.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue