diff options
Diffstat (limited to 'debian/openssh-server.postinst')
-rw-r--r-- | debian/openssh-server.postinst | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/debian/openssh-server.postinst b/debian/openssh-server.postinst new file mode 100644 index 000000000..cf3fa68ea --- /dev/null +++ b/debian/openssh-server.postinst | |||
@@ -0,0 +1,482 @@ | |||
1 | #!/bin/sh -e | ||
2 | |||
3 | action="$1" | ||
4 | oldversion="$2" | ||
5 | |||
6 | . /usr/share/debconf/confmodule | ||
7 | db_version 2.0 | ||
8 | |||
9 | umask 022 | ||
10 | |||
11 | if [ "$action" != configure ] | ||
12 | then | ||
13 | exit 0 | ||
14 | fi | ||
15 | |||
16 | |||
17 | fix_doc_symlink() { | ||
18 | if [ ! -L /usr/share/doc/openssh-server ] && \ | ||
19 | dpkg --compare-versions "$oldversion" lt-nl 1:4.1p1-5; then | ||
20 | rm -rf /usr/share/doc/openssh-server | ||
21 | ln -s openssh-client /usr/share/doc/openssh-server | ||
22 | fi | ||
23 | } | ||
24 | |||
25 | |||
26 | get_config_option() { | ||
27 | option="$1" | ||
28 | |||
29 | [ -f /etc/ssh/sshd_config ] || return | ||
30 | |||
31 | # TODO: actually only one '=' allowed after option | ||
32 | perl -lne 's/\s+/ /g; print if s/^\s*'"$option"'[[:space:]=]+//i' \ | ||
33 | /etc/ssh/sshd_config | ||
34 | } | ||
35 | |||
36 | |||
37 | set_config_option() { | ||
38 | option="$1" | ||
39 | value="$2" | ||
40 | |||
41 | perl -le ' | ||
42 | $option = $ARGV[0]; $value = $ARGV[1]; $done = 0; | ||
43 | while (<STDIN>) { | ||
44 | chomp; | ||
45 | (my $match = $_) =~ s/\s+/ /g; | ||
46 | if ($match =~ s/^\s*\Q$option\E\s+.*/$option $value/) { | ||
47 | $_ = $match; | ||
48 | $done = 1; | ||
49 | } | ||
50 | print; | ||
51 | } | ||
52 | print "$option $value" unless $done;' \ | ||
53 | "$option" "$value" \ | ||
54 | < /etc/ssh/sshd_config > /etc/ssh/sshd_config.dpkg-new | ||
55 | chown --reference /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-new | ||
56 | chmod --reference /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-new | ||
57 | mv /etc/ssh/sshd_config.dpkg-new /etc/ssh/sshd_config | ||
58 | } | ||
59 | |||
60 | |||
61 | disable_config_option() { | ||
62 | option="$1" | ||
63 | |||
64 | value="$(get_config_option "$option")" | ||
65 | [ "$value" ] || return 0 | ||
66 | |||
67 | perl -le ' | ||
68 | $option = $ARGV[0]; | ||
69 | while (<STDIN>) { | ||
70 | chomp; | ||
71 | (my $match = $_) =~ s/\s+/ /g; | ||
72 | # TODO: actually only one "=" allowed after option | ||
73 | if ($match =~ s/^(\s*\Q$option\E[[:space:]=]+.*)/#$1/i) { | ||
74 | $_ = $match; | ||
75 | } | ||
76 | print; | ||
77 | }' \ | ||
78 | "$option" \ | ||
79 | < /etc/ssh/sshd_config > /etc/ssh/sshd_config.dpkg-new | ||
80 | chown --reference /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-new | ||
81 | chmod --reference /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-new | ||
82 | mv /etc/ssh/sshd_config.dpkg-new /etc/ssh/sshd_config | ||
83 | } | ||
84 | |||
85 | |||
86 | rename_config_option() { | ||
87 | oldoption="$1" | ||
88 | newoption="$2" | ||
89 | |||
90 | value="$(get_config_option "$oldoption")" | ||
91 | [ "$value" ] || return 0 | ||
92 | |||
93 | perl -le ' | ||
94 | $oldoption = $ARGV[0]; $newoption = $ARGV[1]; | ||
95 | while (<STDIN>) { | ||
96 | chomp; | ||
97 | (my $match = $_) =~ s/\s+/ /g; | ||
98 | # TODO: actually only one "=" allowed after option | ||
99 | if ($match =~ s/^(\s*)\Q$oldoption\E([[:space:]=]+)/$1$newoption$2/i) { | ||
100 | $_ = $match; | ||
101 | } | ||
102 | print; | ||
103 | }' \ | ||
104 | "$oldoption" "$newoption" \ | ||
105 | < /etc/ssh/sshd_config > /etc/ssh/sshd_config.dpkg-new | ||
106 | chown --reference /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-new | ||
107 | chmod --reference /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-new | ||
108 | mv /etc/ssh/sshd_config.dpkg-new /etc/ssh/sshd_config | ||
109 | } | ||
110 | |||
111 | |||
112 | remove_obsolete_gssapi() { | ||
113 | disable_config_option GSSAPINoMICAuthentication | ||
114 | disable_config_option GSSUseSessionCCache | ||
115 | disable_config_option GSSAPIUseSessionCredCache | ||
116 | } | ||
117 | |||
118 | |||
119 | host_keys_required() { | ||
120 | hostkeys="$(get_config_option HostKey)" | ||
121 | if [ "$hostkeys" ]; then | ||
122 | echo "$hostkeys" | ||
123 | else | ||
124 | # No HostKey directives at all, so the server picks some | ||
125 | # defaults depending on the setting of Protocol. | ||
126 | protocol="$(get_config_option Protocol)" | ||
127 | [ "$protocol" ] || protocol=1,2 | ||
128 | if echo "$protocol" | grep 1 >/dev/null; then | ||
129 | echo /etc/ssh/ssh_host_key | ||
130 | fi | ||
131 | if echo "$protocol" | grep 2 >/dev/null; then | ||
132 | echo /etc/ssh/ssh_host_rsa_key | ||
133 | echo /etc/ssh/ssh_host_dsa_key | ||
134 | echo /etc/ssh/ssh_host_ecdsa_key | ||
135 | fi | ||
136 | fi | ||
137 | } | ||
138 | |||
139 | |||
140 | create_key() { | ||
141 | msg="$1" | ||
142 | shift | ||
143 | hostkeys="$1" | ||
144 | shift | ||
145 | file="$1" | ||
146 | shift | ||
147 | |||
148 | if echo "$hostkeys" | grep -x "$file" >/dev/null && \ | ||
149 | [ ! -f "$file" ] ; then | ||
150 | echo -n $msg | ||
151 | ssh-keygen -q -f "$file" -N '' "$@" | ||
152 | echo | ||
153 | if which restorecon >/dev/null 2>&1; then | ||
154 | restorecon "$file.pub" | ||
155 | fi | ||
156 | fi | ||
157 | } | ||
158 | |||
159 | |||
160 | create_keys() { | ||
161 | hostkeys="$(host_keys_required)" | ||
162 | |||
163 | create_key "Creating SSH1 key; this may take some time ..." \ | ||
164 | "$hostkeys" /etc/ssh/ssh_host_key -t rsa1 | ||
165 | |||
166 | create_key "Creating SSH2 RSA key; this may take some time ..." \ | ||
167 | "$hostkeys" /etc/ssh/ssh_host_rsa_key -t rsa | ||
168 | create_key "Creating SSH2 DSA key; this may take some time ..." \ | ||
169 | "$hostkeys" /etc/ssh/ssh_host_dsa_key -t dsa | ||
170 | create_key "Creating SSH2 ECDSA key; this may take some time ..." \ | ||
171 | "$hostkeys" /etc/ssh/ssh_host_ecdsa_key -t ecdsa | ||
172 | } | ||
173 | |||
174 | |||
175 | vulnerable_host_keys() { | ||
176 | # If the admin has explicitly put the vulnerable keys back, we | ||
177 | # assume they can look after themselves. | ||
178 | db_fget ssh/vulnerable_host_keys seen | ||
179 | if [ "$RET" = true ]; then | ||
180 | return 0 | ||
181 | fi | ||
182 | |||
183 | hostkeys="$(host_keys_required)" | ||
184 | vulnerable= | ||
185 | for hostkey in $hostkeys; do | ||
186 | [ -f "$hostkey" ] || continue | ||
187 | if ssh-vulnkey -q "$hostkey"; then | ||
188 | vulnerable="${vulnerable:+$vulnerable }$hostkey" | ||
189 | fi | ||
190 | done | ||
191 | if [ "$vulnerable" ]; then | ||
192 | db_subst ssh/vulnerable_host_keys HOST_KEYS "$vulnerable" | ||
193 | db_input critical ssh/vulnerable_host_keys || true | ||
194 | db_go | ||
195 | for hostkey in $vulnerable; do | ||
196 | mv "$hostkey" "$hostkey.broken" || true | ||
197 | mv "$hostkey.pub" "$hostkey.pub.broken" || true | ||
198 | done | ||
199 | create_keys | ||
200 | fi | ||
201 | } | ||
202 | |||
203 | |||
204 | check_password_auth() { | ||
205 | passwordauth="$(get_config_option PasswordAuthentication)" | ||
206 | crauth="$(get_config_option ChallengeResponseAuthentication)" | ||
207 | if [ "$passwordauth" = no ] && \ | ||
208 | ([ -z "$crauth" ] || [ "$crauth" = yes ]); then | ||
209 | db_get ssh/disable_cr_auth | ||
210 | if [ "$RET" = true ]; then | ||
211 | set_config_option ChallengeResponseAuthentication no | ||
212 | fi | ||
213 | fi | ||
214 | } | ||
215 | |||
216 | |||
217 | move_subsystem_sftp() { | ||
218 | subsystem_sftp="$(get_config_option 'Subsystem sftp')" | ||
219 | if [ "$subsystem_sftp" = /usr/lib/sftp-server ] || \ | ||
220 | [ "$subsystem_sftp" = /usr/libexec/sftp-server ]; then | ||
221 | set_config_option 'Subsystem sftp' /usr/lib/openssh/sftp-server | ||
222 | fi | ||
223 | } | ||
224 | |||
225 | |||
226 | fix_loglevel_silent() { | ||
227 | if [ "$(get_config_option LogLevel)" = SILENT ]; then | ||
228 | set_config_option LogLevel QUIET | ||
229 | fi | ||
230 | } | ||
231 | |||
232 | |||
233 | create_sshdconfig() { | ||
234 | if [ -e /etc/ssh/sshd_config ] ; then | ||
235 | # Upgrade an existing sshd configuration. | ||
236 | |||
237 | if (dpkg --compare-versions "$oldversion" lt-nl 1:3.8p1-1 && \ | ||
238 | ! grep -iq ^UsePAM /etc/ssh/sshd_config) || \ | ||
239 | grep -Eiq '^(PAMAuthenticationViaKbdInt|RhostsAuthentication)' \ | ||
240 | /etc/ssh/sshd_config ; then | ||
241 | # Upgrade from pre-3.7: UsePAM needed to maintain standard | ||
242 | # Debian configuration. | ||
243 | # Note that --compare-versions is sadly not reliable enough | ||
244 | # here due to the package split of ssh into openssh-client | ||
245 | # and openssh-server. The extra grep for some deprecated | ||
246 | # options should with any luck be a good enough heuristic. | ||
247 | echo -n 'Upgrading sshd_config (old version in .dpkg-old) ...' | ||
248 | cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-old | ||
249 | perl -pe 's/^(PAMAuthenticationViaKbdInt|RhostsAuthentication)\b/#$1/i' \ | ||
250 | /etc/ssh/sshd_config > /etc/ssh/sshd_config.dpkg-new | ||
251 | echo >> /etc/ssh/sshd_config.dpkg-new | ||
252 | echo 'UsePAM yes' >> /etc/ssh/sshd_config.dpkg-new | ||
253 | chown --reference /etc/ssh/sshd_config \ | ||
254 | /etc/ssh/sshd_config.dpkg-new | ||
255 | chmod --reference /etc/ssh/sshd_config \ | ||
256 | /etc/ssh/sshd_config.dpkg-new | ||
257 | mv /etc/ssh/sshd_config.dpkg-new /etc/ssh/sshd_config | ||
258 | echo | ||
259 | fi | ||
260 | |||
261 | # An empty version means we're upgrading from before the | ||
262 | # package split, so check. | ||
263 | if dpkg --compare-versions "$oldversion" lt 1:3.8.1p1-11; then | ||
264 | check_password_auth | ||
265 | fi | ||
266 | |||
267 | # libexecdir changed, so fix up 'Subsystem sftp'. | ||
268 | if dpkg --compare-versions "$oldversion" lt 1:4.1p1-1; then | ||
269 | move_subsystem_sftp | ||
270 | fi | ||
271 | |||
272 | # Remove obsolete GSSAPI options. | ||
273 | if dpkg --compare-versions "$oldversion" lt 1:4.3p2-8; then | ||
274 | remove_obsolete_gssapi | ||
275 | fi | ||
276 | |||
277 | # This option was renamed in 3.8p1, but we never took care | ||
278 | # of adjusting the configuration file until now. | ||
279 | if dpkg --compare-versions "$oldversion" lt 1:4.7p1-8; then | ||
280 | rename_config_option KeepAlive TCPKeepAlive | ||
281 | fi | ||
282 | |||
283 | # 'LogLevel SILENT' is now equivalent to QUIET. | ||
284 | if dpkg --compare-versions "$oldversion" lt 1:5.4p1-1; then | ||
285 | fix_loglevel_silent | ||
286 | fi | ||
287 | |||
288 | return 0 | ||
289 | fi | ||
290 | |||
291 | cat <<EOF > /etc/ssh/sshd_config | ||
292 | # Package generated configuration file | ||
293 | # See the sshd_config(5) manpage for details | ||
294 | |||
295 | # What ports, IPs and protocols we listen for | ||
296 | Port 22 | ||
297 | # Use these options to restrict which interfaces/protocols sshd will bind to | ||
298 | #ListenAddress :: | ||
299 | #ListenAddress 0.0.0.0 | ||
300 | Protocol 2 | ||
301 | # HostKeys for protocol version 2 | ||
302 | HostKey /etc/ssh/ssh_host_rsa_key | ||
303 | HostKey /etc/ssh/ssh_host_dsa_key | ||
304 | HostKey /etc/ssh/ssh_host_ecdsa_key | ||
305 | #Privilege Separation is turned on for security | ||
306 | UsePrivilegeSeparation yes | ||
307 | |||
308 | # Lifetime and size of ephemeral version 1 server key | ||
309 | KeyRegenerationInterval 3600 | ||
310 | ServerKeyBits 768 | ||
311 | |||
312 | # Logging | ||
313 | SyslogFacility AUTH | ||
314 | LogLevel INFO | ||
315 | |||
316 | # Authentication: | ||
317 | LoginGraceTime 120 | ||
318 | PermitRootLogin yes | ||
319 | StrictModes yes | ||
320 | |||
321 | RSAAuthentication yes | ||
322 | PubkeyAuthentication yes | ||
323 | #AuthorizedKeysFile %h/.ssh/authorized_keys | ||
324 | |||
325 | # Don't read the user's ~/.rhosts and ~/.shosts files | ||
326 | IgnoreRhosts yes | ||
327 | # For this to work you will also need host keys in /etc/ssh_known_hosts | ||
328 | RhostsRSAAuthentication no | ||
329 | # similar for protocol version 2 | ||
330 | HostbasedAuthentication no | ||
331 | # Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication | ||
332 | #IgnoreUserKnownHosts yes | ||
333 | |||
334 | # To enable empty passwords, change to yes (NOT RECOMMENDED) | ||
335 | PermitEmptyPasswords no | ||
336 | |||
337 | # Change to yes to enable challenge-response passwords (beware issues with | ||
338 | # some PAM modules and threads) | ||
339 | ChallengeResponseAuthentication no | ||
340 | |||
341 | # Change to no to disable tunnelled clear text passwords | ||
342 | #PasswordAuthentication yes | ||
343 | |||
344 | # Kerberos options | ||
345 | #KerberosAuthentication no | ||
346 | #KerberosGetAFSToken no | ||
347 | #KerberosOrLocalPasswd yes | ||
348 | #KerberosTicketCleanup yes | ||
349 | |||
350 | # GSSAPI options | ||
351 | #GSSAPIAuthentication no | ||
352 | #GSSAPICleanupCredentials yes | ||
353 | |||
354 | X11Forwarding yes | ||
355 | X11DisplayOffset 10 | ||
356 | PrintMotd no | ||
357 | PrintLastLog yes | ||
358 | TCPKeepAlive yes | ||
359 | #UseLogin no | ||
360 | |||
361 | #MaxStartups 10:30:60 | ||
362 | #Banner /etc/issue.net | ||
363 | |||
364 | # Allow client to pass locale environment variables | ||
365 | AcceptEnv LANG LC_* | ||
366 | |||
367 | Subsystem sftp /usr/lib/openssh/sftp-server | ||
368 | |||
369 | # Set this to 'yes' to enable PAM authentication, account processing, | ||
370 | # and session processing. If this is enabled, PAM authentication will | ||
371 | # be allowed through the ChallengeResponseAuthentication and | ||
372 | # PasswordAuthentication. Depending on your PAM configuration, | ||
373 | # PAM authentication via ChallengeResponseAuthentication may bypass | ||
374 | # the setting of "PermitRootLogin without-password". | ||
375 | # If you just want the PAM account and session checks to run without | ||
376 | # PAM authentication, then enable this but set PasswordAuthentication | ||
377 | # and ChallengeResponseAuthentication to 'no'. | ||
378 | UsePAM yes | ||
379 | EOF | ||
380 | } | ||
381 | |||
382 | fix_statoverride() { | ||
383 | # Remove an erronous override for sshd (we should have overridden ssh) | ||
384 | if [ -x /usr/sbin/dpkg-statoverride ]; then | ||
385 | if dpkg-statoverride --list /usr/sbin/sshd >/dev/null ; then | ||
386 | dpkg-statoverride --remove /usr/sbin/sshd | ||
387 | fi | ||
388 | fi | ||
389 | } | ||
390 | |||
391 | fix_sshd_shell() { | ||
392 | if getent passwd sshd | grep -q ':/bin/false$'; then | ||
393 | usermod -s /usr/sbin/nologin sshd || true | ||
394 | fi | ||
395 | } | ||
396 | |||
397 | setup_sshd_user() { | ||
398 | if ! getent passwd sshd >/dev/null; then | ||
399 | adduser --quiet --system --no-create-home --home /var/run/sshd --shell /usr/sbin/nologin sshd | ||
400 | fi | ||
401 | } | ||
402 | |||
403 | fix_conffile_permissions() { | ||
404 | # Clean up after executable /etc/default/ssh in 1:3.5p1-5. dpkg | ||
405 | # doesn't do this for us; see bug #192981. | ||
406 | chmod 644 /etc/default/ssh | ||
407 | } | ||
408 | |||
409 | remove_old_init_links() { | ||
410 | # Yes, this only works with the SysV init script layout. I know. | ||
411 | # The important thing is that it doesn't actually *break* with | ||
412 | # file-rc ... | ||
413 | if [ -e /etc/rc2.d/S20ssh ]; then | ||
414 | update-rc.d -f ssh remove >/dev/null 2>&1 | ||
415 | fi | ||
416 | rm -f /etc/rc0.d/K??ssh /etc/rc1.d/K??ssh /etc/rc6.d/K??ssh | ||
417 | } | ||
418 | |||
419 | setup_init() { | ||
420 | if [ -x /etc/init.d/ssh ]; then | ||
421 | update-rc.d ssh start 16 2 3 4 5 . >/dev/null | ||
422 | if [ -x /usr/sbin/invoke-rc.d ]; then | ||
423 | invoke-rc.d ssh restart | ||
424 | else | ||
425 | /etc/init.d/ssh restart | ||
426 | fi | ||
427 | fi | ||
428 | } | ||
429 | |||
430 | commit_transfer_conffile () { | ||
431 | CONFFILE="$1" | ||
432 | if [ -e "$CONFFILE.moved-by-preinst" ]; then | ||
433 | rm -f "$CONFFILE.moved-by-preinst" | ||
434 | fi | ||
435 | } | ||
436 | |||
437 | commit_mv_conffile () { | ||
438 | OLDCONFFILE="$1" | ||
439 | NEWCONFFILE="$2" | ||
440 | |||
441 | if [ -e "$OLDCONFFILE.moving" ]; then | ||
442 | echo "Preserving user changes to $NEWCONFFILE ..." | ||
443 | mv -f "$NEWCONFFILE" "$NEWCONFFILE.dpkg-new" | ||
444 | mv -f "$OLDCONFFILE.moving" "$NEWCONFFILE" | ||
445 | elif [ -e "$OLDCONFFILE.dpkg-old" ]; then | ||
446 | rm -f "$OLDCONFFILE.dpkg-old" | ||
447 | fi | ||
448 | } | ||
449 | |||
450 | |||
451 | fix_doc_symlink | ||
452 | create_sshdconfig | ||
453 | create_keys | ||
454 | vulnerable_host_keys | ||
455 | fix_statoverride | ||
456 | if dpkg --compare-versions "$2" lt 1:4.3p2-3; then | ||
457 | fix_sshd_shell | ||
458 | fi | ||
459 | setup_sshd_user | ||
460 | if dpkg --compare-versions "$2" lt 1:3.6.1p2-2; then | ||
461 | fix_conffile_permissions | ||
462 | fi | ||
463 | if dpkg --compare-versions "$2" lt 1:5.2p1-1; then | ||
464 | remove_old_init_links | ||
465 | fi | ||
466 | setup_init | ||
467 | commit_transfer_conffile /etc/default/ssh | ||
468 | commit_transfer_conffile /etc/init.d/ssh | ||
469 | commit_transfer_conffile /etc/pam.d/ssh | ||
470 | commit_mv_conffile /etc/pam.d/ssh /etc/pam.d/sshd | ||
471 | # Renamed to /etc/ssh/moduli in 2.9.9 (!) | ||
472 | if dpkg --compare-versions "$2" lt 1:4.7p1-1; then | ||
473 | rm -f /etc/ssh/primes | ||
474 | fi | ||
475 | if dpkg --compare-versions "$2" lt 1:5.5p1-6; then | ||
476 | rm -f /var/run/sshd/.placeholder | ||
477 | fi | ||
478 | |||
479 | |||
480 | db_stop | ||
481 | |||
482 | exit 0 | ||