Skip to content

Commit 28c01a0

Browse files
authored
Merge pull request #253 from github/leaked-ssh-keys-detect
Detect leaked ssh keys in backup snapshots
2 parents 4ce63ac + 6b4790e commit 28c01a0

File tree

9 files changed

+824
-0
lines changed

9 files changed

+824
-0
lines changed

bin/ghe-backup

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,5 +247,9 @@ else
247247
exit 1
248248
fi
249249

250+
# Detect if the created backup contains any leaked ssh keys
251+
echo "Checking for leaked ssh keys ..."
252+
ghe-detect-leaked-ssh-keys -s "$GHE_SNAPSHOT_DIR" || true
253+
250254
# Make sure we exit zero after the conditional
251255
true

bin/ghe-restore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ GHE_RESTORE_SNAPSHOT_PATH="$(ghe-restore-snapshot-path "$snapshot_id")"
6666
GHE_RESTORE_SNAPSHOT=$(basename "$GHE_RESTORE_SNAPSHOT_PATH")
6767
export GHE_RESTORE_SNAPSHOT
6868

69+
# Detect if the backup we are restoring has a leaked ssh key
70+
echo "Checking for leaked keys in the backup snapshot that is being restored ..."
71+
ghe-detect-leaked-ssh-keys -s "$GHE_RESTORE_SNAPSHOT_PATH" || true
72+
6973
# Figure out whether to use the tarball or rsync restore strategy based on the
7074
# strategy file written in the snapshot directory.
7175
GHE_BACKUP_STRATEGY=$(cat "$GHE_RESTORE_SNAPSHOT_PATH/strategy")
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/bin/bash
2+
#/ Usage: ghe-detect-leaked-ssh-key [-s <snapshot-id>]
3+
#/
4+
#/ This utility will check each snapshot's existing SSH host keys against the list
5+
#/ of known leaked SSH host keys from GitHub Enterprise packages.
6+
#/
7+
#/ OPTIONS:
8+
#/ -h | --help Show this message.
9+
#/ -s |--snapshot <snapshot-id> Scan the snapshot with the given id.
10+
#/ Available snapshots may be listed under the data directory.
11+
#/
12+
set -e
13+
14+
usage() {
15+
grep '^#/' < "$0" | cut -c 4-
16+
}
17+
18+
TEMPDIR=$(mktemp -d)
19+
20+
# Parse args.
21+
ARGS=$(getopt --name "$0" --long help,snapshot: --options hs -- "$@") || {
22+
usage
23+
exit 2
24+
}
25+
eval set -- $ARGS
26+
27+
while [ $# -gt 0 ]; do
28+
case "$1" in
29+
-h|--help)
30+
usage
31+
exit 2
32+
;;
33+
-s|--snapshot)
34+
shift 2
35+
snapshot=$1
36+
;;
37+
--)
38+
shift
39+
break
40+
;;
41+
esac
42+
shift
43+
done
44+
45+
ppid_script=$(ps -o args= $PPID | awk '{print $2}')
46+
if [ -n "$ppid_script" ]; then
47+
ppid_name=$(basename $ppid_script)
48+
fi
49+
50+
# Bring in the backup configuration
51+
. $( dirname "${BASH_SOURCE[0]}" )/ghe-backup-config
52+
53+
fingerprint_blacklist=$(cat "$GHE_BACKUP_ROOT/share/github-backup-utils/ghe-ssh-leaked-host-keys-list.txt")
54+
55+
keys="ssh_host_dsa_key.pub ssh_host_ecdsa_key.pub ssh_host_ed25519_key.pub ssh_host_rsa_key.pub"
56+
57+
# Get all the host ssh keys tar from all snapshots directories
58+
if [ -n "$snapshot" ]; then
59+
ssh_tars=$(find "$snapshot" -maxdepth 1 -type f -iname 'ssh-host-keys.tar')
60+
else
61+
ssh_tars=$(find "$GHE_DATA_DIR" -maxdepth 2 -type f -iname 'ssh-host-keys.tar')
62+
fi
63+
64+
# Store the current backup snapshot folder
65+
if [ -L "$GHE_DATA_DIR/current" ]; then
66+
current_dir=$(readlink -f "$GHE_DATA_DIR/current")
67+
fi
68+
69+
leaked_keys_found=false
70+
current_bkup=false
71+
for tar_file in $ssh_tars; do
72+
for key in $keys; do
73+
if $(tar -tvf "$tar_file" $key &>/dev/null); then
74+
tar -C $TEMPDIR -xvf "$tar_file" $key &>/dev/null
75+
fingerprint=$(ssh-keygen -lf $TEMPDIR/$key | cut -d ' ' -f 2)
76+
if echo "$fingerprint_blacklist" | grep -q "$fingerprint"; then
77+
leaked_keys_found=true
78+
if [ "$current_dir" == $(dirname "$tar_file") ]; then
79+
current_bkup=true
80+
echo "* Leaked key found in current backup snapshot."
81+
else
82+
echo "* Leaked key found in backup snapshot."
83+
fi
84+
echo "* Snapshot file: $tar_file"
85+
echo "* Key file: $key"
86+
echo "* Key: $fingerprint"
87+
echo
88+
fi
89+
fi
90+
done
91+
done
92+
93+
if $leaked_keys_found; then
94+
if echo "$ppid_name" | grep -q 'ghe-restore'; then
95+
echo
96+
echo "* The snapshot that is being restored contains a leaked SSH host key."
97+
echo "* We recommend rolling the SSH host keys after completing the restore."
98+
echo "* Roll the keys either manually or with ghe-ssh-roll-host-keys on the appliance."
99+
echo "* (An upgrade may be required)"
100+
echo
101+
elif echo "$ppid_name" | grep -q 'ghe-backup'; then
102+
echo "* The current backup contains leaked SSH host keys."
103+
echo "* We strongly recommend rolling your SSH host keys and making a new backup."
104+
echo "* Roll the keys either manually or with ghe-ssh-roll-host-keys on the appliance."
105+
echo "* (An upgrade may be required)"
106+
else
107+
if $current_bkup; then
108+
echo "* The current backup contains leaked SSH host keys."
109+
echo "* Current backup directory: $current_dir"
110+
echo "* We strongly recommend rolling your SSH host keys and making a new backup."
111+
echo "* Roll the keys either manually or with ghe-ssh-roll-host-keys on the appliance."
112+
echo "* (An upgrade may be required)"
113+
fi
114+
echo
115+
echo "* One or more older backup snapshots contain leaked SSH host keys."
116+
echo "* No immediate action is needed but when you use one of these older snapshots for a restore, "
117+
echo "* please make sure to roll the SSH host keys after restore."
118+
echo "* Roll the keys either manually or with ghe-ssh-roll-host-keys on the appliance."
119+
echo "* (An upgrade may be required)"
120+
echo
121+
fi
122+
fi
123+
124+
# Cleanup temp dir
125+
rm -rf $TEMPDIR

0 commit comments

Comments
 (0)