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