summaryrefslogtreecommitdiff
path: root/extra/openssh/sshd.initd
blob: 477cdbc619f7fcf9270fe2d3e674020ccbd49bac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/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
}

get_conf() {
	awk "/^$1/{ print \$2 }" "$cfgfile" 2>/dev/null
}

conf_enabled() {
	[ "$(get_conf "$1")" = "yes" ]
}

depend() {
	use logger dns
	after entropy

	if [ "${rc_need+set}" = "set" ] ; then
		: # Do nothing, the user has explicitly set rc_need
	else
		local x warn_addr
		# shellcheck disable=SC2013
		for x in $(get_conf ListenAddress) ; do
			case "$x" in
				0.0.0.0|0.0.0.0:*) ;;
				::|\[::\]*) ;;
				*) warn_addr="$warn_addr $x" ;;
			esac
		done
		if [ -n "$warn_addr" ] ; 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):"
			ewarn "$warn_addr"
		fi
	fi
}

update_command() {
	if conf_enabled KerberosAuthentication || conf_enabled GSSAPIAuthentication && [ -r /usr/sbin/sshd.krb5 ]; then
		command="${SSHD_BINARY:-"/usr/sbin/sshd.krb5"}"
	elif conf_enabled UsePAM && [ -r /usr/sbin/sshd.pam ]; 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 "${command##*/}")
		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." ||:
}