Lukko¶
What is Lukko?¶
Lukko is a SSH server.
It is not (yet) a drop-in for other SSH implementations such as OpenSSH. Lukko is currently used for shared hosting environments with a large number of user accounts where each session runs in a separate container. Maybe it will evolve into a general-purpose SSH server eventually, but that is not a priority.
Configuration¶
Lukko loads the configuration file
/etc/cm4all/lukko/lukko.conf.
The following top-level settings are recognized:
translation_server: consult this translation server to configure child processes; must start with/(absolute path) or@(abstract socket).populate_io_buffers:yespopulates all I/O buffers on startup. This reduces waits for Linux kernel VM compaction/migration.
Listener¶
The listener section describes how Lukko listens for incoming SSH
connections. Example:
listener {
bind "*:22"
#interface "eth0"
#zeroconf_service "lukko"
}
Known attributes:
bind: an adddress to bind to. May be the wildcard*or an IPv4/IPv6 address followed by a port. IPv6 addresses should be enclosed in square brackets to disambiguate the port separator. Local sockets start with a slash/, and abstract sockets start with the symbol@.interface: limit this listener to the given network interface.mode: for local socket files, this specifies the octal file mode.mptcp:yesenables Multi-Path TCPack_timeout: close the connection if transmitted data remains unacknowledged by the client for this number of seconds. By default, dead connections can remain open for up to 20 minutes.keepalive:yesenables the socket optionSO_KEEPALIVE. This causes some traffic for the keepalive probes, but allows detecting disappeared clients even when there is no traffic.v6only:nodisables IPv4 support on IPv6 listeners (IPV6_V6ONLY). The default isyes.reuse_port:yesenables the socket optionSO_REUSEPORT, which allows multiple sockets to bind to the same port.zeroconf_service: if specified, then register this listener as Zeroconf service in the local Avahi daemon.zeroconf_domain(optional): The name of the Zeroconf domain.zeroconf_interface: publish the Zeroconf service only on the given interface.zeroconf_protocol(optional): Publish only protocolinetorinet6.zeroconf_weight: publish the Zeroconf service with the specified “weight”, i.e. ask a load balancer to use this weight when choosing nodes. The value is a decimal number; the implied default value is1.0. For example, if you specify0.5, you expect this node to get only half as many connections as others.tag: a string sent to the translation server in aLISTENER_TAGpacket.max_connections_per_ip: specifies the maximum number of connections from each IP address.tarpit:yesenables a naive denial-of-service protection: clients that connect too often or fail authentication get delayed responses. The exact conditions and the delay is currently hard-coded. The default isno.verbose_errors:yessends internal error messages to the client onstderr.host_key_file: Load a SSH host (secret) key from a file. This option may appear more than once to load keys from multiple files to load multiple host keys (with different key algorithms). If no host key is loaded, then the default host key files are used (host_ed25519_key,host_ecdsa_key,host_rsa_key); this option is only needed if certain listeners need a special non-standard host key.
authorized_host_key_file: Enablehostbasedauthentication on this listener and load public keys from a text file that will be authorized unconditionally (see Host-Based Authentication). This option may appear more than once to load keys from multiple files.exec_reject_stderr:yesmeans when anexecrequest on a session channel is rejected (e.g. for SFTP-only accounts), Lukko pretends the request has succeeded, but prints an error message onstderr. This is a slight protocol violation but may be less confusing for users than the normal OpenSSH client error message “shell request failed on channel 0”.pond_server: send log messages to this Pond server.proxy_to: act as proxy, forward all incoming connections after the authentication phase to the specified target. See Proxy Mode Configuration for details.proxy_to_zeroconf: act as proxy, forward all incoming connections after the authentication phase to the specified Zeroconf cluster.accept_client_address: If enabled, then accept the real client address from the client duringhostbasedauthentication. This way, Lukko shows the real client address in the log and in :env:`$SSH_CLIENT`.
Proxy Mode Configuration¶
When acting as a proxy (with the proxy_to setting), Lukko forward
all incoming connections after the authentication phase to another
server. The connection to this target is authenticated using the SSH
host key with the “hostbased” method.
Individual target hosts can be configured with a target_host
section:
target_host "foo" {
address "192.168.1.100"
}
Known attributes:
address: The host’s address. If not specified, then the name of the section is parsed instead.host_key_file: A text file containing the host public key (or many keys, one per line). This option may appear more than once.send_client_address: If enabled, then send the real client address to the target server. This requires enableaccept_client_addresson its listener.
Zeroconf cluster¶
The zeroconf_cluster section describes a destination for the
proxy_to_zeroconf setting:
zeroconf_cluster "name" {
zeroconf_service "lukko-internal"
zeroconf_interface "internal"
}
Known attributes:
zeroconf_service: The name of the Zeroconf service.zeroconf_domain(optional): The name of the Zeroconf service.zeroconf_interface(optional): Look up only on this network interface.zeroconf_protocol(optional): Limit lookups toinetorinet6.host_key_file: A text file containing the host public key (or many keys, one per line). This option may appear more than once.send_client_address: If enabled, then send the real client address to the target server. This requires enableaccept_client_addresson its listener.
Control Listener¶
The control section creates a listener for control datagrams that
can be used to control certain behavior at runtime. Example:
control {
bind "@lukko-control"
}
control {
bind "*"
interface "eth1"
multicast_group "224.0.0.123"
}
Known attributes:
bind: an adddress to bind to. May be the wildcard*or an IPv4/IPv6 address followed by a port. IPv6 addresses should be enclosed in square brackets to disambiguate the port separator. Local sockets start with a slash/, and abstract sockets start with the symbol@.multicast_group: join this multicast group, which allows receiving multicast commands. Value is a multicast IPv4/IPv6 address. IPv6 addresses may contain a scope identifier after a percent sign (%).interface: limit this listener to the given network interface.
The protocol is defined here: https://github.com/CM4all/libcommon/blob/master/src/net/control/Protocol.hxx
Lukko implements only a subset of the commands:
VERBOSEDISABLE_ZEROCONFENABLE_ZEROCONFTERMINATE_CHILDREN
Prometheus Exporter¶
The prometheus_exporter section is optional and can describe a
simple HTTP listener which exposes statistics in the Prometheus
format.
Example:
prometheus_exporter {
bind "*:8022"
interface "eth1"
}
prometheus_exporter {
bind "/run/cm4all/lukko/prometheus_exporter.socket"
}
Known attributes (same meaning as in a listener block):
bindinterfacemodev6onlyreuse_port
Translation Server¶
Lukko can delegate certain decisions (user database, how to execute
commands) to a different process running on the same computer, called
a “translation server”. This translation server may, for example,
consult a database to look up user accounts instead of reading
/etc/passwd and can make complex decicions based on that data.
Only the translation server has access to all of Lukko’s process
spawner features, which includes a light-weight container engine.
Information about the translation protocol can be found here:
Authentication¶
Public Key Authentication¶
Public keys in ~/.ssh/authorized_keys and
/etc/cm4all/lukko/authorized_keys are allowed to log in.
Lukko supports the OpenSSH file format and implements the following
options:
command: Forced command.port-forwarding,no-port-forwarding: Allow or disallow port forwarding.pty,no-pty: Allow or disallow tty allocation.restrict: Enable all restrictions, i.e. is an alias forno-port-forwardingandno-pty.home-read-only: Mount the home directory read-only.
The following OpenSSH options are not implemented and are ignored silently:
user-rc,no-user-rcagent-forwarding,no-agent-forwardingX11-forwarding,no-X11-forwarding
Password Authentication¶
Passwords are verified by the translation server, therefore this authentication method is only available if a translation server is configured.
Host-Based Authentication¶
Host-based authentication can be enabled on a listener with the authorized_host_key_file setting. Authentication requests using one of these configured host keys are allowed to log in.