[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [Git][tpo/applications/tor-browser-build][main] Bug 41844: Add script to backup and deploy signing keys



Title: GitLab

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:

Changes:

  • tools/signing/machines-setup/.gitignore
    1
    +signing-keys

  • tools/signing/machines-setup/README.md
    1 1
     This directory contains the scripts used to setup the signing machines.
    
    2 2
     
    
    3
    -It handles everything in the setup, except installation of the signing
    
    4
    -keys, which is done manually.
    
    3
    +It handles everything in the setup. Installation (and backup) of the
    
    4
    +signing keys, is handled separately, using the `deploy-signing-keys` /
    
    5
    +`backup-signing-keys` script.
    
    5 6
     
    
    6 7
     # Deploying changes on the signing machines
    
    7 8
     
    
    ... ... @@ -35,3 +36,20 @@ required packages, create user accounts and setup signing tools.
    35 36
     After running `upload-tbb-to-signing-machine`, open a root shell on the
    
    36 37
     signing machine and run
    
    37 38
     `/signing/tor-browser-build/tools/signing/machines-setup/setup-signing-machine`.
    
    39
    +
    
    40
    +## backup-signing-keys & deploy-signing-keys
    
    41
    +
    
    42
    +Those two scripts takes as argument the ssh hostname of the signing
    
    43
    +machine you want to backup keys from, or deploy keys on. You need to be
    
    44
    +able to connect as root the the signing machine with ssh.
    
    45
    +
    
    46
    +When doing backup of the signing keys it will store the signing keys in
    
    47
    +directory local directory `signing-keys` (relative to the script).
    
    48
    +
    
    49
    +When deploying signing keys, it will take the keys from directory
    
    50
    +`signing-keys`. If deploying a new machine, you should have run
    
    51
    +`setup-signing-machine` on it before deploying keys.
    
    52
    +
    
    53
    +Both scripts can take the `--dry-run` argument to run rsync with
    
    54
    +`--dry-run` to show the files that would be transfered without storing
    
    55
    +the changes.

  • tools/signing/machines-setup/backup-signing-keys
    1
    +deploy-signing-keys
    \ No newline at end of file

  • tools/signing/machines-setup/deploy-signing-keys
    1
    +#!/bin/perl -w
    
    2
    +
    
    3
    +# This script is used to backup and deploy signing keys from/to a signing machine.
    
    4
    +#
    
    5
    +# The script takes as argument the ssh hostname of the signing machine.
    
    6
    +#
    
    7
    +# Use `--dry-run` to show what would be done without applying the changes.
    
    8
    +#
    
    9
    +# See README.md for more details.
    
    10
    +
    
    11
    +use strict;
    
    12
    +use English;
    
    13
    +use FindBin;
    
    14
    +use File::Basename;
    
    15
    +use File::Path qw(make_path);
    
    16
    +use Getopt::Long;
    
    17
    +use Capture::Tiny qw/tee/;
    
    18
    +
    
    19
    +my %signing_keys = (
    
    20
    +
    
    21
    +  gpg => {
    
    22
    +    'private-keys-v1.d' => {
    
    23
    +      path  => '/home/signing-gpg/.gnupg/private-keys-v1.d',
    
    24
    +      owner => 'signing-gpg',
    
    25
    +    },
    
    26
    +    pubring => {
    
    27
    +      path  => '/home/signing-gpg/.gnupg/pubring.kbx',
    
    28
    +      owner => 'signing-gpg',
    
    29
    +    },
    
    30
    +  },
    
    31
    +
    
    32
    +  win => {
    
    33
    +    tpo_cert => {
    
    34
    +      path  => '/home/signing-win/keys/key-1/the_tor_project_inc.crt',
    
    35
    +      owner => 'signing-win',
    
    36
    +    },
    
    37
    +    tpo_key => {
    
    38
    +      path  => '/home/signing-win/keys/key-1/private.pem',
    
    39
    +      owner => 'signing-win',
    
    40
    +    },
    
    41
    +  },
    
    42
    +
    
    43
    +  mar => {
    
    44
    +    torbrowser_nssdb7 => {
    
    45
    +      path  => '/home/signing-mar/nssdb/torbrowser-nssdb7',
    
    46
    +      owner => 'signing-mar',
    
    47
    +    },
    
    48
    +    mullvadbrowser_nssdb_1 => {
    
    49
    +      path  => '/home/signing-mar/nssdb/mullvadbrowser-nssdb-1',
    
    50
    +      owner => 'signing-mar',
    
    51
    +    },
    
    52
    +  },
    
    53
    +
    
    54
    +  macos => {
    
    55
    +    key_1 => {
    
    56
    +      path  => '/home/signing-macos/keys/key-1.p12',
    
    57
    +      owner => 'signing-macos',
    
    58
    +    },
    
    59
    +  },
    
    60
    +
    
    61
    +  aab => {
    
    62
    +    torvpn => {
    
    63
    +      path  => '/home/signing-apk/keys/torvpn.p12',
    
    64
    +      owner => 'signing-apk',
    
    65
    +    },
    
    66
    +  },
    
    67
    +
    
    68
    +  apk => {
    
    69
    +    tba_release => {
    
    70
    +      path => '/home/signing-apk/keys/tba_release.p12',
    
    71
    +      owner => 'signing-apk',
    
    72
    +    },
    
    73
    +    tba_alpha => {
    
    74
    +      path => '/home/signing-apk/keys/tba_alpha.p12',
    
    75
    +      owner => 'signing-apk',
    
    76
    +    },
    
    77
    +    torvpn => {
    
    78
    +      path => '/home/signing-apk/keys/torvpn.p12',
    
    79
    +      owner => 'signing-apk',
    
    80
    +    },
    
    81
    +  },
    
    82
    +
    
    83
    +);
    
    84
    +
    
    85
    +my $backup_dir = "$FindBin::Bin/signing-keys";
    
    86
    +my $signing_machine;
    
    87
    +my $dry_run;
    
    88
    +
    
    89
    +sub exit_error {
    
    90
    +  print STDERR "Error: ", $_[0], "\n";
    
    91
    +  chdir '/';
    
    92
    +  exit (exists $_[1] ? $_[1] : 1);
    
    93
    +}
    
    94
    +
    
    95
    +my @errors;
    
    96
    +sub set_error {
    
    97
    +  my $error = join("\n", @_);
    
    98
    +  print STDERR $error, "\n";
    
    99
    +  push @errors, $error;
    
    100
    +}
    
    101
    +
    
    102
    +sub print_errors {
    
    103
    +  return unless @errors;
    
    104
    +  my $nb_errors = @errors;
    
    105
    +  print STDERR "There was $nb_errors errors:\n";
    
    106
    +  my $i = 1;
    
    107
    +  for my $error (@errors) {
    
    108
    +    print STDERR "*** Error $i:\n$error\n";
    
    109
    +    $i += 1;
    
    110
    +  }
    
    111
    +  print STDERR "\n";
    
    112
    +}
    
    113
    +
    
    114
    +sub run_cmd {
    
    115
    +  my (@cmd) = @_;
    
    116
    +  my $txt_cmd = join(' ', @cmd);
    
    117
    +  print "Running $txt_cmd\n";
    
    118
    +  my $exit_code;
    
    119
    +  my ($stdout, $stderr) = tee {
    
    120
    +    $exit_code = system(@cmd);
    
    121
    +  };
    
    122
    +  return if $exit_code == 0;
    
    123
    +  set_error("Error running $txt_cmd:\n$stderr");
    
    124
    +}
    
    125
    +
    
    126
    +sub backup_key {
    
    127
    +  my ($dir, $keyname) = @_;
    
    128
    +  print "Backing up $signing_keys{$dir}{$keyname}{path}\n";
    
    129
    +  make_path("$backup_dir/$dir") unless -d "$backup_dir/$dir";
    
    130
    +  my @cmd = ('rsync', '-avi', '--chmod=F0600,D0700', $dry_run ? ($dry_run) : (),
    
    131
    +    "root\@$signing_machine:$signing_keys{$dir}{$keyname}{path}",
    
    132
    +    "$backup_dir/$dir/$keyname");
    
    133
    +  run_cmd(@cmd);
    
    134
    +}
    
    135
    +
    
    136
    +sub backup_signing_keys {
    
    137
    +  foreach my $dir (keys %signing_keys) {
    
    138
    +    foreach my $keyname (keys %{$signing_keys{$dir}}) {
    
    139
    +      backup_key($dir, $keyname);
    
    140
    +    }
    
    141
    +  }
    
    142
    +}
    
    143
    +
    
    144
    +sub deploy_key {
    
    145
    +  my ($dir, $keyname) = @_;
    
    146
    +  print "Deploying $signing_keys{$dir}{$keyname}{path}\n";
    
    147
    +  my @cmd = ('rsync', '-avi', '--no-owner', '--no-group', $dry_run ? ($dry_run) : (),
    
    148
    +    '--chmod=F0600,D0700', "--chown=$signing_keys{$dir}{$keyname}{owner}",
    
    149
    +    "$backup_dir/$dir/$keyname", "root\@$signing_machine:$signing_keys{$dir}{$keyname}{path}");
    
    150
    +  if (!-e "$backup_dir/$dir/$keyname") {
    
    151
    +    set_error("Missing file or directory $backup_dir/$dir/$keyname",
    
    152
    +              "Cannot deploy $signing_keys{$dir}{$keyname}{path}");
    
    153
    +    return;
    
    154
    +  }
    
    155
    +  run_cmd(@cmd);
    
    156
    +}
    
    157
    +
    
    158
    +sub confirm_deploy {
    
    159
    +  return if $dry_run;
    
    160
    +  print "Are you sure you want to deploy keys to $signing_machine?\n";
    
    161
    +  print "This will overwrite existing files.\n";
    
    162
    +  print "You can check the changes before applying them with '--dry-run'\n";
    
    163
    +  print "Enter 'yes' to validate.\n";
    
    164
    +  my $word = <STDIN>;
    
    165
    +  chomp $word;
    
    166
    +  return if lc($word) eq 'yes';
    
    167
    +  print STDERR "Not doing anything.\n";
    
    168
    +  exit 1;
    
    169
    +}
    
    170
    +
    
    171
    +sub deploy_signing_keys {
    
    172
    +  confirm_deploy;
    
    173
    +  foreach my $dir (keys %signing_keys) {
    
    174
    +    foreach my $keyname (keys %{$signing_keys{$dir}}) {
    
    175
    +      deploy_key($dir, $keyname);
    
    176
    +    }
    
    177
    +  }
    
    178
    +}
    
    179
    +
    
    180
    +sub set_options {
    
    181
    +  my @options = qw(dry-run);
    
    182
    +  my %val;
    
    183
    +  Getopt::Long::GetOptionsFromArray(\@_, \%val, @options) || exit 1;
    
    184
    +  $dry_run = '--dry-run' if $val{'dry-run'};
    
    185
    +  exit_error "Usage: $PROGRAM_NAME [--dry-run] <signing-machine>" unless @_ == 1;
    
    186
    +  $signing_machine = $_[0];
    
    187
    +}
    
    188
    +
    
    189
    +my %actions = (
    
    190
    +  'deploy-signing-keys' => \&deploy_signing_keys,
    
    191
    +  'backup-signing-keys' => \&backup_signing_keys,
    
    192
    +);
    
    193
    +
    
    194
    +set_options(@ARGV);
    
    195
    +
    
    196
    +my $action = fileparse($PROGRAM_NAME);
    
    197
    +exit_error "Unknown action $action" unless $actions{$action};
    
    198
    +$actions{$action}->($signing_machine);
    
    199
    +
    
    200
    +print_errors;

  • _______________________________________________
    tor-commits mailing list -- tor-commits@xxxxxxxxxxxxxxxxxxxx
    To unsubscribe send an email to tor-commits-leave@xxxxxxxxxxxxxxxxxxxx