morgan pushed to branch main at The Tor Project / Applications / tor-browser-build Commits: 7fb9dced by Nicolas Vigier at 2026-08-12T11:49:32+02:00 Bug 41844: Add script to backup and deploy signing keys - - - - - 4 changed files: - + tools/signing/machines-setup/.gitignore - tools/signing/machines-setup/README.md - + tools/signing/machines-setup/backup-signing-keys - + tools/signing/machines-setup/deploy-signing-keys Changes: ===================================== tools/signing/machines-setup/.gitignore ===================================== @@ -0,0 +1 @@ +signing-keys ===================================== tools/signing/machines-setup/README.md ===================================== @@ -1,7 +1,8 @@ This directory contains the scripts used to setup the signing machines. -It handles everything in the setup, except installation of the signing -keys, which is done manually. +It handles everything in the setup. Installation (and backup) of the +signing keys, is handled separately, using the `deploy-signing-keys` / +`backup-signing-keys` script. # Deploying changes on the signing machines @@ -35,3 +36,20 @@ required packages, create user accounts and setup signing tools. After running `upload-tbb-to-signing-machine`, open a root shell on the signing machine and run `/signing/tor-browser-build/tools/signing/machines-setup/setup-signing-machine`. + +## backup-signing-keys & deploy-signing-keys + +Those two scripts takes as argument the ssh hostname of the signing +machine you want to backup keys from, or deploy keys on. You need to be +able to connect as root the the signing machine with ssh. + +When doing backup of the signing keys it will store the signing keys in +directory local directory `signing-keys` (relative to the script). + +When deploying signing keys, it will take the keys from directory +`signing-keys`. If deploying a new machine, you should have run +`setup-signing-machine` on it before deploying keys. + +Both scripts can take the `--dry-run` argument to run rsync with +`--dry-run` to show the files that would be transfered without storing +the changes. ===================================== tools/signing/machines-setup/backup-signing-keys ===================================== @@ -0,0 +1 @@ +deploy-signing-keys \ No newline at end of file ===================================== tools/signing/machines-setup/deploy-signing-keys ===================================== @@ -0,0 +1,200 @@ +#!/bin/perl -w + +# This script is used to backup and deploy signing keys from/to a signing machine. +# +# The script takes as argument the ssh hostname of the signing machine. +# +# Use `--dry-run` to show what would be done without applying the changes. +# +# See README.md for more details. + +use strict; +use English; +use FindBin; +use File::Basename; +use File::Path qw(make_path); +use Getopt::Long; +use Capture::Tiny qw/tee/; + +my %signing_keys = ( + + gpg => { + 'private-keys-v1.d' => { + path => '/home/signing-gpg/.gnupg/private-keys-v1.d', + owner => 'signing-gpg', + }, + pubring => { + path => '/home/signing-gpg/.gnupg/pubring.kbx', + owner => 'signing-gpg', + }, + }, + + win => { + tpo_cert => { + path => '/home/signing-win/keys/key-1/the_tor_project_inc.crt', + owner => 'signing-win', + }, + tpo_key => { + path => '/home/signing-win/keys/key-1/private.pem', + owner => 'signing-win', + }, + }, + + mar => { + torbrowser_nssdb7 => { + path => '/home/signing-mar/nssdb/torbrowser-nssdb7', + owner => 'signing-mar', + }, + mullvadbrowser_nssdb_1 => { + path => '/home/signing-mar/nssdb/mullvadbrowser-nssdb-1', + owner => 'signing-mar', + }, + }, + + macos => { + key_1 => { + path => '/home/signing-macos/keys/key-1.p12', + owner => 'signing-macos', + }, + }, + + aab => { + torvpn => { + path => '/home/signing-apk/keys/torvpn.p12', + owner => 'signing-apk', + }, + }, + + apk => { + tba_release => { + path => '/home/signing-apk/keys/tba_release.p12', + owner => 'signing-apk', + }, + tba_alpha => { + path => '/home/signing-apk/keys/tba_alpha.p12', + owner => 'signing-apk', + }, + torvpn => { + path => '/home/signing-apk/keys/torvpn.p12', + owner => 'signing-apk', + }, + }, + +); + +my $backup_dir = "$FindBin::Bin/signing-keys"; +my $signing_machine; +my $dry_run; + +sub exit_error { + print STDERR "Error: ", $_[0], "\n"; + chdir '/'; + exit (exists $_[1] ? $_[1] : 1); +} + +my @errors; +sub set_error { + my $error = join("\n", @_); + print STDERR $error, "\n"; + push @errors, $error; +} + +sub print_errors { + return unless @errors; + my $nb_errors = @errors; + print STDERR "There was $nb_errors errors:\n"; + my $i = 1; + for my $error (@errors) { + print STDERR "*** Error $i:\n$error\n"; + $i += 1; + } + print STDERR "\n"; +} + +sub run_cmd { + my (@cmd) = @_; + my $txt_cmd = join(' ', @cmd); + print "Running $txt_cmd\n"; + my $exit_code; + my ($stdout, $stderr) = tee { + $exit_code = system(@cmd); + }; + return if $exit_code == 0; + set_error("Error running $txt_cmd:\n$stderr"); +} + +sub backup_key { + my ($dir, $keyname) = @_; + print "Backing up $signing_keys{$dir}{$keyname}{path}\n"; + make_path("$backup_dir/$dir") unless -d "$backup_dir/$dir"; + my @cmd = ('rsync', '-avi', '--chmod=F0600,D0700', $dry_run ? ($dry_run) : (), + "root\@$signing_machine:$signing_keys{$dir}{$keyname}{path}", + "$backup_dir/$dir/$keyname"); + run_cmd(@cmd); +} + +sub backup_signing_keys { + foreach my $dir (keys %signing_keys) { + foreach my $keyname (keys %{$signing_keys{$dir}}) { + backup_key($dir, $keyname); + } + } +} + +sub deploy_key { + my ($dir, $keyname) = @_; + print "Deploying $signing_keys{$dir}{$keyname}{path}\n"; + my @cmd = ('rsync', '-avi', '--no-owner', '--no-group', $dry_run ? ($dry_run) : (), + '--chmod=F0600,D0700', "--chown=$signing_keys{$dir}{$keyname}{owner}", + "$backup_dir/$dir/$keyname", "root\@$signing_machine:$signing_keys{$dir}{$keyname}{path}"); + if (!-e "$backup_dir/$dir/$keyname") { + set_error("Missing file or directory $backup_dir/$dir/$keyname", + "Cannot deploy $signing_keys{$dir}{$keyname}{path}"); + return; + } + run_cmd(@cmd); +} + +sub confirm_deploy { + return if $dry_run; + print "Are you sure you want to deploy keys to $signing_machine?\n"; + print "This will overwrite existing files.\n"; + print "You can check the changes before applying them with '--dry-run'\n"; + print "Enter 'yes' to validate.\n"; + my $word = <STDIN>; + chomp $word; + return if lc($word) eq 'yes'; + print STDERR "Not doing anything.\n"; + exit 1; +} + +sub deploy_signing_keys { + confirm_deploy; + foreach my $dir (keys %signing_keys) { + foreach my $keyname (keys %{$signing_keys{$dir}}) { + deploy_key($dir, $keyname); + } + } +} + +sub set_options { + my @options = qw(dry-run); + my %val; + Getopt::Long::GetOptionsFromArray(\@_, \%val, @options) || exit 1; + $dry_run = '--dry-run' if $val{'dry-run'}; + exit_error "Usage: $PROGRAM_NAME [--dry-run] <signing-machine>" unless @_ == 1; + $signing_machine = $_[0]; +} + +my %actions = ( + 'deploy-signing-keys' => \&deploy_signing_keys, + 'backup-signing-keys' => \&backup_signing_keys, +); + +set_options(@ARGV); + +my $action = fileparse($PROGRAM_NAME); +exit_error "Unknown action $action" unless $actions{$action}; +$actions{$action}->($signing_machine); + +print_errors; View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/7f... -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/7f... You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
participants (1)
-
morgan (@morgan)