Tom Menari writes:
> Can anyone reccomend a client configuration for IPsec from a roaming
> Linux machine that works with OpenBSD's ipsecctl?
>
> I have tried Openswan and racoon and both have thier problems.
> Currently using X509 certificates but if anyone has public keys
> working that would be good too.
I've got an OpenBSD road warrior that connects to a Debian server
running racoon. So far I haven't connected a Linux road warrior to an
OpenBSD machine but the following setup might work.
If you decide to use public keys you've got to convert the keys
between the file format used by OpenBSD and the format used by Racoon
and Openswan. I've put a Perl script that converts public keys
between both formats at the end of this message. The script requires
the Perl modules Parse::RecDescent and Crypt::OpenSSL::RSA, which are
both available as packages under OpenBSD and Debian.
Run the script on your OpenBSD machine to convert your machine's
public key into the file format that is accepted by racoon. Example:
./plainrsa-convert < /etc/isakmpd/local.pub
Copy the output into the file /etc/racoon/certs/pubkeys.rsa on the
Linux machine. You can put the OpenBSD machine's IP address in front
of the key. Example:
192.168.0.1 : PUB 0sAgUAF2T29ovO...
Run the command plainrsa-gen, which comes with the racoon package, to
create a key on the Linux machine. Example:
plainrsa-gen -f /etc/racoon/certs/privatekey.rsa
Extract the public key from the key file and convert the key to the
format accepted by OpenBSD. Example:
grep ": PUB" privatekey.rsa | sed 's/^#//' | ./plainrsa-convert
Assuming that your client's host name is roadwarrior.example.org, put
the output of the above command into the file
/etc/isakmpd/pubkeys/fqdn/roadwarrior.example.org on your OpenBSD
machine.
I'm not sure what to put into /etc/ipsec.conf on the OpenBSD machine.
I think that something like this should work:
ike passive from any to 192.168.0.1 \
srcid server.example.org \
dstid roadwarrior.example.org
Put the following directives into the file /etc/racoon/racoon.conf on
the Linux machine. Don't forget to modify the IP address and the
identifiers.
------8<------8<------8<------8<------8<------8<------8<------8<------
# /etc/racoon/racoon.conf
path certificate "/etc/racoon/certs";
## phase 1 proposals (for IKE SA)
# connection to server.example.org
remote 192.168.0.1 {
exchange_mode main;
certificate_type plain_rsa "privatekey.rsa";
peers_certfile plain_rsa "pubkeys.rsa";
my_identifier fqdn "roadwarrior.example.org";
peers_identifier fqdn "server.example.org";
dpd_delay 30;
lifetime time 1 hour;
proposal {
encryption_algorithm aes;
hash_algorithm sha1;
authentication_method rsasig;
dh_group modp1024;
}
}
## phase 2 proposal (for IPsec SA).
# quick mode description for all connections
sainfo anonymous {
encryption_algorithm aes, 3des;
authentication_algorithm hmac_sha256, hmac_sha1, hmac_md5;
compression_algorithm deflate;
lifetime time 20 minutes;
}
------8<------8<------8<------8<------8<------8<------8<------8<------
#!/usr/bin/perl -w
# Convert public keys from and to the format used by Racoon.
# Written and placed in the public domain by Andreas Voegele.
use strict;
use Parse::RecDescent;
use Crypt::OpenSSL::RSA;
use MIME::Base64;
sub pem2rfc {
my $key = shift;
my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key($key);
my ($n, $e) = $rsa_pub->get_key_parameters();
my $eb = $e->to_bin();
return encode_base64(pack("C", length($eb)) . $eb . $n->to_bin(), '');
}
sub rfc2pem {
my $key = shift;
my $decoded = decode_base64($key);
my $len = unpack("C", substr($decoded, 0, 1));
my $e = Crypt::OpenSSL::Bignum->new_from_bin(substr($decoded, 1, $len));
my $n = Crypt::OpenSSL::Bignum->new_from_bin(substr($decoded, 1 + $len));
my $rsa_pub = Crypt::OpenSSL::RSA->new_key_from_parameters($n, $e);
return $rsa_pub->get_public_key_x509_string();
}
my $grammar = q {
input: item(s)
item: pempubkey | rfcpubkey | other
pempubkey: m{-----BEGIN PUBLIC KEY-----.*?-----END PUBLIC KEY-----}s
{ print ": PUB 0s" . ::pem2rfc($item[1]), "\n"; }
rfcpubkey: addr(0..2) ':' 'PUB' m{0s[A-Za-z0-9+/=]+}
{ print ::rfc2pem(substr($item[4], 2)); }
addr: ( ipv4addr | ipv6addr ) <skip: ''> prefix(?) | 'any'
ipv4addr: /(?:\\d{1,3}\\.){3}\\d{1,3}/
ipv6addr: /[[:xdigit:]:]*:[[:xdigit:]:]*:[[:xdigit:]:]*/
prefix: m{/\d{1,3}}
other: /.*/
};
my $parser = new Parse::RecDescent($grammar);
undef $/;
my $input = <>;
$parser->input($input);