Práctica: Instalación de Pares Clave Pública y Privada con Seudoterminales

Escriba un guión que automatice el proceso de instalar comunicaciones seguras ssh mediante clave pública-privada entre una máquina origen y una familia de máquinas.

Recordemos como se establece una autentificación por clave pública-privada. La generación de una pareja de claves pública-privada se realiza ejecutando en el cliente ssh-keygen:

$ ssh-keygen  -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx user@machine

Las claves se almacenan por defecto en ~/.ssh/, quedando el directorio así:

$ ls -l
total 12
-rw-------  1 user user  883 2005-08-13 14:16 id_rsa
-rw-r--r--  1 user user  223 2005-08-13 14:16 id_rsa.pub
-rw-r--r--  1 user user 1344 2005-08-04 02:14 known_hosts

Los ficheros id_rsa e id_rsa.pub contienen respectivamente las claves privada y pública. El fichero known_hosts contiene la lista de las claves públicas de las máquinas reconocidas.

Ahora se debe copiar la clave pública al servidor, al fichero ~/.ssh/authorized_keys. Para ello se utiliza el comando ssh-copy-id:

$ssh-copy-id -i ~/.ssh/id_rsa.pub user@machine1
$ssh-copy-id -i ~/.ssh/id_rsa.pub user@machine2

ssh-copy-id es un script que se conecta a la máquina y copia el archivo (indicado por la opción -i) en ~/.ssh/authorized_keys, y ajusta los permisos a los valores adecuados.

Casiano Rodríguez León
2010-03-22
SRC="pp2.jpg" ALT="PP2">PP2 moodlepsmodulosperlmonksperldocgoogleetsiiullpcgull
Sig: Práctica: Calculo usando Seudoterminales Sup: Automatización de Guiones Pty Ant: Automatización de Guiones Pty
Casiano Rodríguez León
2011-02-07
es/">googleetsiiullpcgullLHPLHP moodleperlcriticpbpblogsgoogle code project hosting
Sig: Práctica: Calculo usando Seudoterminales Sup: Automatización de Guiones Pty Ant: Automatización de Guiones Pty
Casiano Rodríguez León
2011-02-21
dríguez León
2011-02-21 HTML> uch method $AUTOLOAD"; 186 } 187 188 sub DESTROY { 189 } 190 191 1; 192 193 ####################################################################### 194 package IO::Pty::Script::Answer; 195 use Carp; 196 use strict; 197 our $AUTOLOAD; 198 199 sub new { 200 my $class = shift; 201 my $self = { @_ }; 202 bless $self, $class; 203 } 204 205 use overload q("") => \&strqa; 206 sub strqa { 207 my $self = shift; 208 209 my $r = $self->answer(); 210 my $s = $self->overpassed(); 211 my $d = $self->delayed(); 212 return <<"EOL"; 213 <<r = '$r' 214 s = '$s' 215 d = '$d'>> 216 EOL 217 } 218 219 sub redirect { 220 my ($src,$dst) = @_; 221 my $buf = ''; 222 my $read = sysread($src, $buf, 1); 223 if (defined $read && $read) { 224 syswrite($dst,$buf,$read); 225 } 226 else { # EOF 227 print STDERR "Nothing from $src"; 228 print "$read\n" if defined($read); 229 } 230 return $buf; 231 } 232 233 sub keyboard { 234 my $self = shift; 235 my $escape = shift; 236 my $return_value = shift; 237 238 my $char; 239 my $pty = $self->pty(); 240 my $ws = $self->sel(); 241 my $rs = IO::Select->new(); 242 $rs->add(\*STDIN, $pty); 243 WHILE_NOT_ESCAPE_OR_EOF: 244 { # infinite loop 245 my @ready = $rs->can_read(IO::Pty::Script::TIMEOUT); 246 if (@ready) { 247 @ready = reverse @ready if (@ready >1) and ($ready[0] != $pty); 248 if ($ready[0] == $pty) { 249 my $read = sysread($pty, $char, 1); 250 if (defined $read && $read) { 251 syswrite(STDOUT,$char,$read); 252 } 253 else { # EOF 254 last WHILE_NOT_ESCAPE_OR_EOF 255 } 256 } 257 elsif ($ws->can_write(IO::Pty::Script::TIMEOUT)) { # Algo en STDIN 258 my $read = sysread(STDIN, $char, 1); 259 last WHILE_NOT_ESCAPE_OR_EOF if $char eq $escape; 260 if (defined $read && $read) { 261 syswrite($pty,$char,$read); 262 } 263 else { 264 last WHILE_NOT_ESCAPE_OR_EOF 265 } 266 } 267 } 268 redo; 269 } 270 return $return_value; 271 } 272 273 sub deadline { 274 ${$_[0]->{deadline}} = $_[1] if @_ >1; 275 ${$_[0]->{deadline}}; 276 } 277 278 sub parenthesis { 279 return @{$_[0]->{parenthesis}}; 280 } 281 282 sub can_read { 283 my $self = shift; 284 my $deadline = shift; 285 my $sel = $self->{sel}; 286 287 return $sel->can_read($deadline); 288 } 289 290 sub can_write { 291 my $self = shift; 292 my $deadline = shift; 293 my $sel = $self->{sel}; 294 295 return $sel->can_write($deadline); 296 } 297 298 sub AUTOLOAD { 299 my $self = shift; 300 301 $AUTOLOAD =~ /.*::(\w+)/; 302 my $subname = $1; 303 carp "No such method $AUTOLOAD " unless (defined($subname)); 304 no strict 'refs'; 305 if (exists($self->{$subname})) { 306 *{$AUTOLOAD} = sub { 307 $_[0]->{$subname} = $_[1] if @_ >1; 308 $_[0]->{$subname} 309 }; 310 $self->{$subname} = $_[0] if @_; 311 return $self->{$subname}; 312 } 313 carp "No such method $AUTOLOAD"; 314 } 315 316 sub DESTROY { 317 } 318 319 1;

Veamos un ejemplo de uso:

lhp@nereida:~/Lperl/src/perl_networking/ch2/IO-Pty-Script/script$ cat -n ptyconnect4.pl
 1  #!/usr/bin/perl -sw -I../lib
 2  use strict;
 3  use IO::Pty::Script qw{TIMEOUT DEFAULT_DEADLINE chats};
 4
 5  my %script;
 6  our($c, $d, $p, $f); # Inicializadas via -s switch
 7
 8  $p = '' unless defined($p);
 9  $d = DEFAULT_DEADLINE unless defined($d);
10  $f = '' unless defined($f);
11  die "Usage:$0 -c=command -p=key -d=deadline -f=script\n"
12                                        unless defined($c);
13  my $prompt = '[$>]\s+';
14
15  $script{'ssh -l casiano etsii'} = [
16  '.*password:\s'           => "$p\n",
17  '(word:\s)|(login: )|(> )' => "$f\n",
18  $prompt                    => "exit\n"
19  ];
20
21  #$script{'ssh -l casiano etsii'} = [
22  #'.*password:\s'           => "$p\n",
23  #'.*q para salir.\s\s\s\s' => "millo\n",
24  #'word:\s'                 => "$p\n",
25  #'(word:\s)|(login: )|(> )' => "$f\n",
26  #$prompt                    => "exit\n"
27  #];
28
29  $script{'ssh -l casiano beowulf'} = [
30  '.*password:\s'           => "$p\n",
31  $prompt                   => "$f\n",
32  $prompt                   => "exit\n"
33  ];
34
35  #$script{'ssh europa'} = [
36  #$prompt                   => "$f\n",
37  #$prompt                   => [\&titi, 1, 2, "tres"],
38  #$prompt                   => "exit\n"
39  #];
40
41  $script{'ssh europa'} = [
42  $prompt                   => "$f\n",
43  $prompt                   => [\&titi, 1, 2, "tres"],
44  $prompt                   => sub { my $self = shift; $self->keyboard("\cD"); "ls\n" },
45  $prompt                   => "echo 'Despues de la interaccion'\n",
46  $prompt                   => "exit\n"
47  ];
48
49  sub tutu {
50    print "<<sub tutu:\n";
51    print $_[0];
52    my @par = $_[0]->parenthesis();
53    print "Paréntesis: @par\n";
54    print "Es posible leer en la terminal\n" if $_[0]->can_read(TIMEOUT);
55    print "Es posible escribir en la terminal\n" if $_[0]->can_write(TIMEOUT);
56    print "end sub tutu>>\n";
57    "8*2\n"
58  }
59
60  sub titi {
61    local $" = "\nsub titi:";
62    print "<<sub titi: @_>>\n";
63    "date\n";
64  }
65
66  $script{bc} = [
67  'warranty..\s\s' => "5*9.5\n",
68  '(\d+)\.?(\d*)\s+' => \&tutu,
69  '\d+\.?\d*\s+' => "4*2\n",
70  '\d+\.?\d*\s+' => "quit",
71  ];
72
73  my $bc = IO::Pty::Script->new(
74            command => 'bc',
75            deadline => 4,
76            script => $script{bc},
77            defaultaction => sub { print $_[0] }
78          );
79
80  my $s = IO::Pty::Script->new(
81            command => $c,
82            deadline => $d,
83            script => $script{$c},
84            defaultaction => sub { print $_[0] }
85          );
86  chats($bc, $s);

Sigue un ejemplo de ejecución:

lhp@nereida:~/Lperl/src/perl_networking/ch2/IO-Pty-Script/script$ ptyconnect4.pl -c='ssh -l casiano beowulf' -p=password -d=3 -f='ls'
<<r = 'bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
'
s = ''
d = '0'>>
<<sub tutu:
<<r = '47.5
'
s = ''
d = '0'>>
Paréntesis: 47 5
Es posible escribir en la terminal
end sub tutu>>
<<r = '16
'
s = ''
d = '0'>>
<<r = '8
'
s = ''
d = '0'>>
<<r = 'casiano@beowulf's password: '
s = ''
d = '0'>>
<<r = '
Linux beowulf 2.6.15-1-686 #2 Mon Mar 6 15:27:08 UTC 2006 i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Jun  5 13:24:42 2006 from nereida.deioc.ull.es
casiano@beowulf:~$ '
s = ''
d = '0'>>
<<r = 'bc_pty2.pl  _Inline  passwd_pty.pl  pilock.pl  src         try6
bc_pty6.pl  log      pi             pi.pl      ssh_pty.pl
casiano@beowulf:~$ '
s = ''
d = '0'>>
lhp@nereida:~/Lperl/src/perl_networking/ch2/IO-Pty-Script/script$



Subsecciones
Casiano Rodríguez León
2011-03-19