#!/sbin/openrc-run description="OpenBSD Secure Shell server" description_checkconfig="Verify configuration file" description_reload="Reload configuration" extra_commands="checkconfig" extra_started_commands="reload" # NOTE: SSHD_* variables are deprecated and will be removed in future! : "${sshd_disable_keygen:="${SSHD_DISABLE_KEYGEN:-"no"}"}" : "${cfgfile:=${SSHD_CONFIG:-"${SSHD_CONFDIR:-"/etc/ssh"}/sshd_config"}}" pidfile="${SSHD_PIDFILE:-"/run/$RC_SVCNAME.pid"}" command="${SSHD_BINARY:-"/usr/sbin/sshd"}" command_args="${command_args:-${SSHD_OPTS:-}}" required_files="$cfgfile" generate_host_key_type() { local bit_size key_type key_type=$1 if [ ! -f /etc/ssh/ssh_host_"${key_type}"_key ]; then case $key_type in ecdsa) bit_size="$ecdsa_bit_size";; rsa) bit_size="$rsa_bit_size";; esac einfo "Generating $key_type SSH host key..." ssh-keygen \ -q \ -f /etc/ssh/ssh_host_"$key_type"_key \ -N '' \ -t "$key_type" \ ${bit_size:+ -b ${bit_size}} || return 1 fi } generate_host_keys() { local type if [ -z "$key_types_to_generate" ] && [ -z "$ecdsa_bit_size" ] && [ -z "$rsa_bit_size" ]; then ssh-keygen -A return fi for type in ${key_types_to_generate:-dsa ecdsa ed25519 rsa}; do generate_host_key_type "$type" || return 1 done } print_config() { "$command" -f "$cfgfile" -G 2>/dev/null } match_config() { print_config | grep -iqxE -e "$1" } print_listen_addresses() { print_config | awk '$1 == "listenaddress" && $2 !~ /^(0.0.0.0|\[::\])/ { print $2 }' } depend() { use logger dns after entropy if [ "${rc_need+set}" = "set" ] ; then : # Do nothing, the user has explicitly set rc_need else # shellcheck disable=SC2155 local x addrs="$(print_listen_addresses)" if [ -n "$addrs" ] ; then need net ewarn "You are binding an interface in ListenAddress statement in your sshd_config!" ewarn "You must add rc_need=\"net.FOO\" to your /etc/conf.d/sshd" ewarn "where FOO is the interface(s) providing the following address(es):" for x in $addrs; do ewarn " ${x%:*}" done fi fi } update_command() { if [ -x /usr/sbin/sshd.krb5 ] && command="/usr/sbin/sshd.krb5" \ match_config "(Kerberos|GSSAPI)Authentication yes"; then command="${SSHD_BINARY:-"/usr/sbin/sshd.krb5"}" elif [ -x /usr/sbin/sshd.pam ] && command="/usr/sbin/sshd.pam" \ match_config "UsePAM yes"; then command="${SSHD_BINARY:-"/usr/sbin/sshd.pam"}" fi } checkconfig() { update_command warn_deprecated_var SSHD_BINARY warn_deprecated_var SSHD_CONFDIR warn_deprecated_var SSHD_CONFIG cfgfile warn_deprecated_var SSHD_DISABLE_KEYGEN sshd_disable_keygen warn_deprecated_var SSHD_OPTS command_args warn_deprecated_var SSHD_PIDFILE if [ ! -d /var/empty ] ; then mkdir -p /var/empty || return 1 fi if ! yesno "$sshd_disable_keygen"; then generate_host_keys || return 1 fi [ "$pidfile" != "/run/sshd.pid" ] \ && command_args="$command_args -o PidFile=$pidfile" [ "$cfgfile" != "/etc/ssh/sshd_config" ] \ && command_args="$command_args -f $cfgfile" # shellcheck disable=SC2086 "$command" -t $command_args || return 1 } start_pre() { checkconfig } stop_pre() { update_command if [ "${RC_CMD}" = "restart" ] ; then checkconfig || return 1 fi } stop_post() { if [ "$RC_RUNLEVEL" = "shutdown" ]; then _sshd_pids=$(pgrep "sshd-session:") if [ -n "$_sshd_pids" ]; then ebegin "Shutting down ssh connections" # shellcheck disable=SC2086 kill -TERM $_sshd_pids >/dev/null 2>&1 eend 0 fi fi } reload() { checkconfig || return 1 ebegin "Reloading $RC_SVCNAME" start-stop-daemon --signal HUP \ --exec "$command" --pidfile "$pidfile" eend $? } warn_deprecated_var() { local varname="$1" local replacement="${2:-}" eval "test -n \"\$$varname\"" || return 0 ewarn "Variable \$$varname is deprecated and will be removed in the future!" # shellcheck disable=SC2015 [ "$replacement" ] && ewarn "Use \$$replacement instead of \$$varname." ||: }