Add bin/archive_id for saving gpg and ssh secrets
dblume

dblume commited on 2025-05-09 23:53:22
Showing 3 changed files, with 109 additions and 4 deletions.


It's an important script. Always back up your secrets when you
bring up a new computer. May as well have the script ready to go.
... ...
@@ -69,9 +69,11 @@ See [config.dlma.com](http://config.dlma.com) for more.
69 69
     1. .config/nvim/init.vim
70 70
     2. .config/nvim/colors/nvim\_desert.vim
71 71
     3. .local/share/nvim/site/plugin/ plugins
72
-4. .gitconfig and .gitignore
73
-5. [Ghostty](https://ghostty.org/) config in .config/ghostty/config
74
-6. Shell script to set the [Catppuccin Mocha](https://github.com/mbadolato/iTerm2-Color-Schemes/blob/master/generic/catppuccin-mocha.sh) color scheme.
72
+4. bin directory with:
73
+    1. set\_colorscheme, a script to set the [Catppuccin Mocha](https://github.com/mbadolato/iTerm2-Color-Schemes/blob/master/generic/catppuccin-mocha.sh) color scheme.
74
+    2. archive\_id, a script to archive your gpg secrets and .ssh keys
75
+5. .gitconfig and .gitignore
76
+6. [Ghostty](https://ghostty.org/) config in .config/ghostty/config
75 77
 7. .tmux.conf
76 78
 8. .inputrc, for vi mode and a [partially matched command history traversal](http://askubuntu.com/questions/59846/bash-history-search-partial-up-arrow/59855#59855).
77 79
 9. .editrc, for vi mode and tab word completion in macOS.
... ...
@@ -0,0 +1,103 @@
1
+#!/usr/bin/env bash
2
+set -eu -o pipefail # See: https://sipb.mit.edu/doc/safe-shell/
3
+
4
+declare -r script_name=$(basename "${BASH_SOURCE[0]}")
5
+declare -a archdirs=(".ssh" ".gnupg")
6
+declare -a archfiles=(".bash_history" ".crontab" ".gitconfig.local"
7
+                      ".gnuplot_history" ".localrc" ".python_history"
8
+                      ".sqlite_history" ".telnet_history" "bin/archive_id")
9
+declare -i dry_run=0
10
+
11
+## exit the shell (with status 2) after printing the message
12
+usage() {
13
+    echo "\
14
+$script_name -hn <id>
15
+
16
+Backup .ssh and .gnupg to an encrypted zip file so you can copy that over
17
+first and then rsync the rest.
18
+
19
+    -h      Print this help text
20
+    -n      Perform a dry run, to see what'll change
21
+
22
+    id      id/email associated with your gpg keys to archive
23
+"
24
+    exit 2;
25
+}
26
+
27
+## Process the options
28
+while getopts "hn" OPTION
29
+do
30
+  case $OPTION in
31
+    h) usage;;
32
+    n) dry_run=1;;
33
+    \?) usage;;
34
+  esac
35
+done
36
+
37
+shift $((OPTIND - 1))
38
+
39
+if [ $# -ne 1 ]; then
40
+  echo "Error: This script requires an argument, the id (email address) of your gpg secret."
41
+  usage
42
+fi
43
+declare -r gpg_id="$1"
44
+declare -r backup_dir="$HOSTNAME"_"${gpg_id//.}"_archive_$(date "+%Y-%m-%d_%H%M%S")
45
+echo DXB $gpg_id DXB $backup_dir
46
+
47
+# Copy archive directories to backup_dir
48
+for i in "${archdirs[@]}"
49
+do
50
+    if [ -e "$HOME"/"$i" ]; then
51
+        # We use rsync --no-specials to exclude .gnupg's named sockets.
52
+        ((dry_run==0)) && mkdir -p "${backup_dir}"/"$(dirname "$i")" && rsync -axr --no-specials "$HOME"/"$i" "${backup_dir}"
53
+    else
54
+        >&2 echo "$i" does not exist in "$HOME"
55
+    fi
56
+done
57
+
58
+# Copy archive files to backup_dir
59
+for i in "${archfiles[@]}"
60
+do
61
+    if [ -e "$HOME"/"$i" ]; then
62
+        ((dry_run==0)) && mkdir -p "${backup_dir}"/"$(dirname "$i")" && cp -p "$HOME"/"$i" "${backup_dir}"/"$i"
63
+    else
64
+        >&2 echo "$i" does not exist in "$HOME"
65
+    fi
66
+done
67
+
68
+if [ $dry_run -eq 0 ]; then
69
+    # Also gpg --export the keys, in case .gnupg doesn't restore right.
70
+    gpg --export --armor ${gpg_id} > "${backup_dir}"/gpg_${gpg_id}_pub_keys.asc
71
+    echo "Now doing secret keys for ${gpg_id}."
72
+    gpg --export-secret-keys --pinentry-mode loopback --armor --export-options backup ${gpg_id} > "${backup_dir}"/gpg_${gpg_id}_secret_keys.asc
73
+    echo "Now doing secret subkeys for ${gpg_id}."
74
+    gpg --export-secret-subkeys --pinentry-mode loopback --armor --export-options backup ${gpg_id} > "${backup_dir}"/gpg_${gpg_id}_secret_subkeys.asc
75
+    #gpg --export-options backup > "${backup_dir}"/keyring.gpg --export
76
+    gpg --export-ownertrust > "${backup_dir}"/gpg_${gpg_id}_ownertrust.txt
77
+    
78
+    cat << EOF > "${backup_dir}"/README.txt
79
+This is a backup of .gnupg and .ssh, and some other files.
80
+I also gpg exported the public and private keys for ${gpg_id}. Restore them with:
81
+
82
+gpg --import gpg_${gpg_id}_pub_keys.asc
83
+gpg --pinentry-mode loopback --import gpg_${gpg_id}_secret_keys.asc
84
+gpg --import gpg_${gpg_id}_secret_subkeys.asc
85
+gpg --import-ownertrust gpg_${gpg_id}_ownertrust.txt
86
+
87
+And then trust the imported keys with:
88
+gpg --edit-key ${gpg_id}
89
+gpg> trust
90
+Your decision? 5
91
+EOF
92
+fi
93
+
94
+if [ $dry_run -eq 0 ]; then
95
+    echo Your archive files are backed up to "${backup_dir}"
96
+    echo You will now be asked for a password to encrypt the backup to a zip file.
97
+    zip -er "${backup_dir}" "${backup_dir}" && rm -r "${backup_dir}"
98
+    echo Done.
99
+else
100
+    echo Your archive files would have been backed up to "${backup_dir}"
101
+    echo Dry run completed.
102
+fi
103
+
... ...
@@ -8,7 +8,7 @@ declare -a dotfiles=(".bashrc" ".bash_profile" ".vimrc" ".editrc" ".gitconfig"
8 8
                      ".gdbinit" ".config/gitui/key_bindings.ron" ".visidatarc"
9 9
                      ".config/i3/config" ".config/i3status/config"
10 10
                      ".config/dunst/dunstrc" ".config/alacritty/alacritty.toml"
11
-                     "bin/set_colorscheme")
11
+                     "bin/set_colorscheme" "bin/archive_id")
12 12
 declare -i dry_run=0
13 13
 
14 14
 ## exit the shell (with status 2) after printing the message
15 15