summaryrefslogtreecommitdiff
path: root/src/share/mh/diagnostics
blob: 7e76da607a752fdd57406ac4b758bdc98db45ac2 (plain)
  1. # -*-shell-script-*-
  2. # This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)
  3. # Monkeysphere host diagnostics subcommand
  4. #
  5. # The monkeysphere scripts are written by:
  6. # Jameson Rollins <jrollins@finestructure.net>
  7. # Jamie McClelland <jm@mayfirst.org>
  8. # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
  9. #
  10. # They are Copyright 2008-2009, and are all released under the GPL,
  11. # version 3 or later.
  12. # check on the status and validity of the key and public certificates
  13. diagnostics() {
  14. local seckey
  15. local keysfound
  16. local curdate
  17. local warnwindow
  18. local warndate
  19. local create
  20. local expire
  21. local uid
  22. local fingerprint
  23. local badhostkeys
  24. local sshd_config
  25. local problemsfound=0
  26. # FIXME: what's the correct, cross-platform answer?
  27. sshd_config=/etc/ssh/sshd_config
  28. seckey=$(gpg_host --list-secret-keys --fingerprint --with-colons --fixed-list-mode)
  29. keysfound=$(echo "$seckey" | grep -c ^sec:)
  30. curdate=$(date +%s)
  31. # warn when anything is 2 months away from expiration
  32. warnwindow='2 months'
  33. warndate=$(advance_date $warnwindow +%s)
  34. if ! id monkeysphere >/dev/null ; then
  35. echo "! No monkeysphere user found! Please create a monkeysphere system user with bash as its shell."
  36. problemsfound=$(($problemsfound+1))
  37. fi
  38. if ! [ -d "$SYSDATADIR" ] ; then
  39. echo "! no $SYSDATADIR directory found. Please create it."
  40. problemsfound=$(($problemsfound+1))
  41. fi
  42. echo "Checking host GPG key..."
  43. if (( "$keysfound" < 1 )); then
  44. echo "! No host key found."
  45. echo " - Recommendation: run 'monkeysphere-server gen-key'"
  46. problemsfound=$(($problemsfound+1))
  47. elif (( "$keysfound" > 1 )); then
  48. echo "! More than one host key found?"
  49. # FIXME: recommend a way to resolve this
  50. problemsfound=$(($problemsfound+1))
  51. else
  52. create=$(echo "$seckey" | grep ^sec: | cut -f6 -d:)
  53. expire=$(echo "$seckey" | grep ^sec: | cut -f7 -d:)
  54. fingerprint=$(echo "$seckey" | grep ^fpr: | head -n1 | cut -f10 -d:)
  55. # check for key expiration:
  56. if [ "$expire" ]; then
  57. if (( "$expire" < "$curdate" )); then
  58. echo "! Host key is expired."
  59. echo " - Recommendation: extend lifetime of key with 'monkeysphere-server extend-key'"
  60. problemsfound=$(($problemsfound+1))
  61. elif (( "$expire" < "$warndate" )); then
  62. echo "! Host key expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)
  63. echo " - Recommendation: extend lifetime of key with 'monkeysphere-server extend-key'"
  64. problemsfound=$(($problemsfound+1))
  65. fi
  66. fi
  67. # and weirdnesses:
  68. if [ "$create" ] && (( "$create" > "$curdate" )); then
  69. echo "! Host key was created in the future(?!). Is your clock correct?"
  70. echo " - Recommendation: Check clock ($(date +%F_%T)); use NTP?"
  71. problemsfound=$(($problemsfound+1))
  72. fi
  73. # check for UserID expiration:
  74. echo "$seckey" | grep ^uid: | cut -d: -f6,7,10 | \
  75. while IFS=: read create expire uid ; do
  76. # FIXME: should we be doing any checking on the form
  77. # of the User ID? Should we be unmangling it somehow?
  78. if [ "$create" ] && (( "$create" > "$curdate" )); then
  79. echo "! User ID '$uid' was created in the future(?!). Is your clock correct?"
  80. echo " - Recommendation: Check clock ($(date +%F_%T)); use NTP?"
  81. problemsfound=$(($problemsfound+1))
  82. fi
  83. if [ "$expire" ] ; then
  84. if (( "$expire" < "$curdate" )); then
  85. echo "! User ID '$uid' is expired."
  86. # FIXME: recommend a way to resolve this
  87. problemsfound=$(($problemsfound+1))
  88. elif (( "$expire" < "$warndate" )); then
  89. echo "! User ID '$uid' expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)
  90. # FIXME: recommend a way to resolve this
  91. problemsfound=$(($problemsfound+1))
  92. fi
  93. fi
  94. done
  95. # FIXME: verify that the host key is properly published to the
  96. # keyservers (do this with the non-privileged user)
  97. # FIXME: check that there are valid, non-expired certifying signatures
  98. # attached to the host key after fetching from the public keyserver
  99. # (do this with the non-privileged user as well)
  100. # FIXME: propose adding a revoker to the host key if none exist (do we
  101. # have a way to do that after key generation?)
  102. # Ensure that the ssh_host_rsa_key file is present and non-empty:
  103. echo
  104. echo "Checking host SSH key..."
  105. if [ ! -s "${SYSDATADIR}/ssh_host_rsa_key" ] ; then
  106. echo "! The host key as prepared for SSH (${SYSDATADIR}/ssh_host_rsa_key) is missing or empty."
  107. problemsfound=$(($problemsfound+1))
  108. else
  109. if [ $(ls -l "${SYSDATADIR}/ssh_host_rsa_key" | cut -f1 -d\ ) != '-rw-------' ] ; then
  110. echo "! Permissions seem wrong for ${SYSDATADIR}/ssh_host_rsa_key -- should be 0600."
  111. problemsfound=$(($problemsfound+1))
  112. fi
  113. # propose changes needed for sshd_config (if any)
  114. if ! grep -q "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$" "$sshd_config"; then
  115. echo "! $sshd_config does not point to the monkeysphere host key (${SYSDATADIR}/ssh_host_rsa_key)."
  116. echo " - Recommendation: add a line to $sshd_config: 'HostKey ${SYSDATADIR}/ssh_host_rsa_key'"
  117. problemsfound=$(($problemsfound+1))
  118. fi
  119. if badhostkeys=$(grep -i '^HostKey' "$sshd_config" | grep -v "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$") ; then
  120. echo "! $sshd_config refers to some non-monkeysphere host keys:"
  121. echo "$badhostkeys"
  122. echo " - Recommendation: remove the above HostKey lines from $sshd_config"
  123. problemsfound=$(($problemsfound+1))
  124. fi
  125. # FIXME: test (with ssh-keyscan?) that the running ssh
  126. # daemon is actually offering the monkeysphere host key.
  127. fi
  128. fi
  129. # FIXME: look at the ownership/privileges of the various keyrings,
  130. # directories housing them, etc (what should those values be? can
  131. # we make them as minimal as possible?)
  132. # FIXME: look to see that the ownertrust rules are set properly on the
  133. # authentication keyring
  134. # FIXME: make sure that at least one identity certifier exists
  135. # FIXME: look at the timestamps on the monkeysphere-generated
  136. # authorized_keys files -- warn if they seem out-of-date.
  137. # FIXME: check for a cronjob that updates monkeysphere-generated
  138. # authorized_keys?
  139. echo
  140. echo "Checking for MonkeySphere-enabled public-key authentication for users ..."
  141. # Ensure that User ID authentication is enabled:
  142. if ! grep -q "^AuthorizedKeysFile[[:space:]]\+${SYSDATADIR}/authorized_keys/%u$" "$sshd_config"; then
  143. echo "! $sshd_config does not point to monkeysphere authorized keys."
  144. echo " - Recommendation: add a line to $sshd_config: 'AuthorizedKeysFile ${SYSDATADIR}/authorized_keys/%u'"
  145. problemsfound=$(($problemsfound+1))
  146. fi
  147. if badauthorizedkeys=$(grep -i '^AuthorizedKeysFile' "$sshd_config" | grep -v "^AuthorizedKeysFile[[:space:]]\+${SYSDATADIR}/authorized_keys/%u$") ; then
  148. echo "! $sshd_config refers to non-monkeysphere authorized_keys files:"
  149. echo "$badauthorizedkeys"
  150. echo " - Recommendation: remove the above AuthorizedKeysFile lines from $sshd_config"
  151. problemsfound=$(($problemsfound+1))
  152. fi
  153. if [ "$problemsfound" -gt 0 ]; then
  154. echo "When the above $problemsfound issue"$(if [ "$problemsfound" -eq 1 ] ; then echo " is" ; else echo "s are" ; fi)" resolved, please re-run:"
  155. echo " monkeysphere-server diagnostics"
  156. else
  157. echo "Everything seems to be in order!"
  158. fi
  159. }