Skip to content

Commit

Permalink
[openvpn] modify openvpn configuration in order to allow multiple hos…
Browse files Browse the repository at this point in the history
…ts to connect on a single server w
  • Loading branch information
crotsos committed Apr 3, 2012
1 parent dba1dcb commit 872f6a8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 49 deletions.
17 changes: 8 additions & 9 deletions client_tactics/openvpn/openvpn_tactic.sh
Expand Up @@ -9,22 +9,19 @@ domain=$3
local_node=$4
remote_node=$5
remote_ip=$6
tmp_dir=$8
conf_dir=$7
dst_domain=$7
tmp_dir=$9
conf_dir=$8

# create tmp folder
remote_host=$remote_node.$domain
local_host=$local_node.$domain
dst_dir=$tmp_dir/$remote_host/
dst_dir=$tmp_dir/$dst_domain/

if [ ! -e $dst_dir ]; then
mkdir $dst_dir
fi

# setup required key and certificates
# cp conf/signpost.pem $dst_dir/
# cp conf/signpost.crt $dst_dir/

openssl genrsa -out $dst_dir/vpn.pem 2048

# self sign key
Expand All @@ -51,6 +48,8 @@ crypto-convert \
-D 30758400 \
-K $dst_dir/vpn.crt

# sign the remote domain certificate
echo fetching key $remote_host
crypto-convert \
-k $remote_host \
-t DNS_PUB \
Expand All @@ -60,9 +59,9 @@ crypto-convert \
-i "C=UK,O=signpost,CN=$local_host," \
-T PEM_CERT \
-D 30758400 \
-K $dst_dir/dns.crt
-K $dst_dir/allowed-$remote_host.crt

cat $dst_dir/tmp.crt $dst_dir/dns.crt > $dst_dir/ca.crt
cat $dst_dir/tmp.crt $dst_dir/allowed-*.crt > $dst_dir/ca.crt
# cat $dst_dir/dns.crt > $dst_dir/ca.crt

tmp_dir=`echo $tmp_dir | sed -e 's/\//\\\\\//g' `
Expand Down
71 changes: 39 additions & 32 deletions lib/openvpn.ml
Expand Up @@ -29,10 +29,13 @@ module Manager = struct
ip: string option;
port: int;
pid: int;
dev_id:int;
nodes: string list;
}

type conn_db_type = {
conns : (int, conn_type) Hashtbl.t;
(* connection details for a specific domain *)
conns : (string, conn_type) Hashtbl.t;
mutable max_id : int;
mutable can: unit Lwt.t option;
mutable fd: file_descr option;
Expand Down Expand Up @@ -167,7 +170,6 @@ module Manager = struct
Printf.printf "test %s\n%!" (conf_dir ^ "/vpn.pem");
let _ = Key.create_rsa_key (conf_dir ^ "/vpn.pem") 1024 in

Printf.printf "test\n%!";
(* Create signpost self signed key for the device *)
let convert_struct =
Key.({
Expand All @@ -188,71 +190,76 @@ module Manager = struct
Printf.printf "certificate:%s" local_cert;
return ()

let start_openvpn_server ip port node typ =
let start_openvpn_server ip port node domain typ =
let conn_id = conn_db.max_id + 1 in
conn_db.max_id <- conn_id;
let domain = (sprintf "d%d.%s" Config.signpost_number Config.domain) in
(* /openvpn_tactic.sh 10000 1 d2.signpo.st debian haris 10.10.0.3 tmp/ conf/ *)
(* Generate conf directories and keys *)
let cmd = Unix.getcwd () ^ "/client_tactics/openvpn/openvpn_tactic.sh" in
let exec_cmd = Printf.sprintf "%s %s %d %s %s %s %s %s %s "
cmd port conn_id domain (Nodes.get_local_name ())
node ip Config.conf_dir Config.tmp_dir in
let exec_cmd = Printf.sprintf "%s %s %d %s %s.d%d %s %s %s %s %s "
cmd port conn_id Config.domain (Nodes.get_local_name ())
Config.signpost_number node ip domain Config.conf_dir Config.tmp_dir in
lwt _ = Lwt_unix.system exec_cmd in

(* start server *)
let _ = Unix.create_process "openvpn" [|""; "--config";
(Config.tmp_dir ^ "/" ^ node ^ "." ^domain ^"/" ^ typ ^ ".conf") |]
(Config.tmp_dir ^ "/" ^ domain ^"/" ^ typ ^ ".conf") |]
Unix.stdin Unix.stdout Unix.stderr in
return (conn_id)

let read_pid_from_file filename =
let buf = String.create 100 in
let fd = Unix.openfile filename [Unix.O_RDONLY] 0o640 in
let len = Unix.read fd buf 0 100 in
let pid = int_of_string (String.sub buf 0 (len-1)) in
Printf.printf "[openvpn] process created with pid %d...\n%!" pid;
pid
let read_pid_from_file filename =
let buf = String.create 100 in
let fd = Unix.openfile filename [Unix.O_RDONLY] 0o640 in
let len = Unix.read fd buf 0 100 in
let pid = int_of_string (String.sub buf 0 (len-1)) in
Printf.printf "[openvpn] process created with pid %d...\n%!" pid;
pid

let connect kind args =
match kind with
| "server" ->(
try_lwt
let port = List.nth args 0 in
let node = List.nth args 1 in
let domain = List.nth args 2 in

(*
let domain = node ^ (sprintf ".d%d.%s"
Config.signpost_number Config.domain) in
lwt conn_id = start_openvpn_server "0.0.0.0" port node "server" in
*)
lwt dev_id = start_openvpn_server "0.0.0.0" port
node domain "server" in
Printf.printf "[openvpn] server started..\n%!";
lwt _ = Lwt_unix.sleep 5.0 in
let pid = read_pid_from_file (Config.tmp_dir ^ "/" ^ node ^ "." ^ domain
^"/server.pid") in
Hashtbl.add conn_db.conns pid {ip=None;port=(int_of_string port);pid;};
let pid = read_pid_from_file (Config.tmp_dir ^ "/" ^
domain ^"/server.pid") in
Hashtbl.add conn_db.conns (domain)
{ip=None;port=(int_of_string port);pid;
dev_id;nodes=[node ^ "." ^ Config.domain]};
let ip = Nodes.discover_local_ips
~dev:("tun"^(string_of_int conn_id )) () in
~dev:("tun"^(string_of_int dev_id)) () in
return ((List.hd ip))
with e ->
eprintf "[openvpn] server error: %s\n%!" (Printexc.to_string e);
raise (OpenVpnError((Printexc.to_string e)))
)
| "client" -> (
try_lwt
let ip :: port :: node :: args = args in
let domain = (sprintf "d%d.%s"
Config.signpost_number Config.domain) in
let ip :: port :: node :: domain :: args = args in

lwt conn_id = start_openvpn_server ip port node "client" in
lwt dev_id = start_openvpn_server ip port node domain
"client" in
Printf.printf "[openvpn] server started..\n%!";
lwt _ = Lwt_unix.sleep 5.0 in

let pid = read_pid_from_file (Config.tmp_dir ^ "/" ^
node ^ "." ^ domain ^ "/client.pid") in
Hashtbl.add conn_db.conns pid {ip=Some(ip);
port=(int_of_string port);
pid;};
domain ^ "/client.pid") in
Hashtbl.add conn_db.conns (domain)
{ip=Some(ip); port=(int_of_string port);
pid;dev_id; nodes=[node^ "." ^ Config.domain];};

let ip = Nodes.discover_local_ips ~dev:("tun"^(string_of_int conn_id)) () in
let ip = Nodes.discover_local_ips
~dev:("tun"^(string_of_int dev_id)) () in
return ((List.hd ip))
with ex ->
raise(OpenVpnError(Printexc.to_string ex)))
Expand All @@ -261,9 +268,9 @@ module Manager = struct

let teardown args =
(* kill openvpn pid*)
let id = int_of_string(List.hd args) in
let domain = List.hd args in
(* Destroy state *)
if (Hashtbl.mem conn_db.conns id) then
Hashtbl.remove conn_db.conns id;
if (Hashtbl.mem conn_db.conns domain) then
Hashtbl.remove conn_db.conns domain;
true
end
27 changes: 19 additions & 8 deletions lib/openvpnConnection.ml
Expand Up @@ -63,19 +63,21 @@ let pairwise_connection_test a b =
return (false, "")
(* (true, "127.0.0.2") *)

let start_vpn_server node port client =
let start_vpn_server node port client domain =
let rpc = (Rpc.create_tactic_request "openvpn"
Rpc.CONNECT "server" [(string_of_int openvpn_port); client;]) in
Rpc.CONNECT "server" [(string_of_int openvpn_port); client;domain;]) in
try
lwt res = (Nodes.send_blocking node rpc) in
return (res)
with exn ->
Printf.printf "Failed to start openvpn server on node %s\n%!" node;
raise Openvpn_error

let start_vpn_client dst_ip dst_port host node =
let start_vpn_client dst_ip host dst_port node domain =
let rpc = (Rpc.create_tactic_request "openvpn"
Rpc.CONNECT "client" [dst_ip; (string_of_int openvpn_port); host]) in
Rpc.CONNECT "client" [dst_ip;
(string_of_int openvpn_port);
host;domain;]) in
try
lwt res = (Nodes.send_blocking node rpc) in
return (res)
Expand All @@ -85,14 +87,19 @@ let start_vpn_client dst_ip dst_port host node =

let init_openvpn ip a b =
(* Init server on b *)
lwt b_ip = start_vpn_server a openvpn_port b in
lwt b_ip = start_vpn_server a openvpn_port
(sprintf "%s.d%d" b Config.signpost_number)
(sprintf "%s.d%d" b Config.signpost_number) in
(*Init client on b and get ip *)
lwt a_ip = start_vpn_client ip openvpn_port a b in
lwt a_ip = start_vpn_client ip a openvpn_port
(sprintf "%s.d%d" b Config.signpost_number)
(sprintf "%s.d%d" b Config.signpost_number) in
return (a_ip, b_ip)

let start_local_server () =
(* Maybe load a copy of the Openvpn module and let it
* do the magic? *)

return ()

let connect a b =
Expand All @@ -111,8 +118,12 @@ let connect a b =
else
lwt _ = start_local_server () in
let ip = Config.external_ip in
lwt a_ip = start_vpn_client ip openvpn_port b a in
lwt b_ip = start_vpn_client ip openvpn_port a b in
lwt a_ip = start_vpn_client ip b openvpn_port
(sprintf "%s.d%d" a Config.signpost_number)
(sprintf "%s.d%d" a Config.signpost_number) in
lwt b_ip = start_vpn_client ip a openvpn_port
(sprintf "%s.d%d" b Config.signpost_number)
(sprintf "%s.d%d" b Config.signpost_number) in
return ()


Expand Down

0 comments on commit 872f6a8

Please sign in to comment.