#!/usr/bin/perl use strict; use warnings; use Digest::SHA qw/hmac_sha256_hex/; use Getopt::Long qw(:config auto_help); use Pod::Usage; my $key; my $prefix; my $n = 0; my $noauth = 0; my $stronger = 0; GetOptions("k=s" => \$key, "p=s" => \$prefix, "n=i" => \$n, "a" => \$noauth, 'S' => \$stronger) or pod2usage(1); my @hosts = @ARGV; @hosts = (@hosts, map {"host$_"} (1 .. $n) ) if $n > 0; if(!@hosts) { pod2usage("You must specify a list of hosts that will communicate."); } if (!defined $key) { print STDERR "Generating one time use key...\n"; my $data; open FH, "/dev/urandom" or open FH, "/dev/random" or die "could not find random source to generate key, specify key with -k"; read FH,$key,2048; close FH; } my $kid = substr hmac_sha256_hex('kid',$key), 0, 32; if (!defined $prefix) { $prefix = "fdcc:" . substr($kid,0,4) . ':' . substr $kid,4,4; } print "Key id is $kid\n"; print "Network prefix is ${prefix}::/48\n"; my %hosts = ( 'cybertron' => 1, 'lexx'=> 2, 'butterfly' => 3, 'severance'=> 4 ); sub generate_file { my ($i,$host) = @_; my $self = $prefix."::".$i; my $fn = "setup_crypto_$host"; print STDERR "Writing $fn - $self\n"; # print STDERR "Host $host.crypto has IP $self\n"; open my $fh, '>', $fn or die "$!: could not open $fn for writing"; print $fh <<"EOF"; #!/bin/sh #Generated by $0 #Key id is $kid #Network prefix is ${prefix}::/48 EOF print $fh <<'EOF'; DEV=${1:-$IFACE} if [ -z "$DEV" ]; then echo usage: $0 '' echo pass the network device as an argument or place in /etc/network/if-up.d/ to automatically load. exit 1; fi [ "$IFACE" != "lo" ] || exit 0 EOF print $fh <<"OEOF"; setkey -c <($ip, $self); next if $ip eq $self; $addkey->($self, $ip); } print $fh "EOF\n\n"; print $fh "ifconfig \$DEV del $self/64\n"; print $fh "ifconfig \$DEV add $self/64\n"; my $perm = (stat $fh)[2] & 07777; chmod(($perm & 0700) | 0111, $fh); close $fh; } my %hs; for(my $i = 0; $i <= $#hosts; $i++) { $hs{$hosts[$i]} = $i + 1; generate_file($i + 1,$hosts[$i]); } open my $hfh, '>', "hosts_crypto" or die "$!: hosts_crypto"; print STDERR "Writing hosts_crypto\n"; print $hfh "#Add this to your /etc/hosts file\n#local network is ${prefix}::/48\n"; foreach (@hosts) { my $ip = $prefix . "::" . $hs{$_}; print $hfh "$ip $_.crypto\n"; } close $hfh; __END__ =head1 SYNOPSIS createnet.prl - create a local IPSec secured network =head2 SIMPLE USAGE ./createnet myhost1 myhost2 myhost3 ... Where the hosts all reside on the same network link. This will generate the files 'setup_crypto_myhostX' for each hostname and a hosts_crypto file. Run the setup files as root on the corresponding machine (or add to /etc/network/if-up.d/ to have it auto-load) and add the contents of hosts_crypto to the end of ecah machines /etc/hosts file or your local DNS server. Now any access via the name myhost1.crypto will be encrypted. =head2 OPTIONS -k KEYSTRING - specify a master key, if not specified a random cryptographic key is chosen and then discarded after the individual host files are created. If you want to add to the same network later without rekeying all the hosts, you must specify and reuse the same master key argument. -p PREFIX - the ULA network prefix to use, a suitable one will be auto-generated from the master key if not specified. -n NUMBER - number of additional host entries to create. useful if you do not know all the machine names immediately and will edit them in later. -a do not include authentication header in addition to encryption. Since each key is unique and unshared, actually knowing the right key is generally enough for authentication in many cases and allows more space for data in the packet. Disable based on your particular setup. -S enable stronger encryption at the cost of some overhead. Generally not needed and may not be compatible with older IPSec stacks. replaces hmac-md5 with hmac-sha256 and aes128-cbc with aes256-cbc.