Commit 8c83df36 authored by Guillaume Bury's avatar Guillaume Bury

Fixing config

parent 96b58da8
...@@ -2,6 +2,7 @@ Bugs : ...@@ -2,6 +2,7 @@ Bugs :
When no peer is avalaible without the --no-boot option, it crash When no peer is avalaible without the --no-boot option, it crash
To be done : To be done :
Replace comments at the beginning of functions with docstrings
Do a clean-up in the import Do a clean-up in the import
To be discuss: To be discuss:
......
#!/usr/bin/env python #!/usr/bin/env python
import subprocess import os, subprocess
import utils import utils
import os
# TODO: "Objectify" this module ?
# Needed : verbose, network ( previous vifibnet), max-clients, dh, internalIp
def openvpn(*args, **kw): def openvpn(*args, **kw):
args = ['openvpn', args = ['openvpn',
...@@ -26,12 +28,12 @@ def openvpn(*args, **kw): ...@@ -26,12 +28,12 @@ def openvpn(*args, **kw):
# TODO : set iface up when creating a server/client # TODO : set iface up when creating a server/client
# ! check working directory before launching up script ? # ! check working directory before launching up script ?
def server(ip, pipe_fd, *args, **kw): def server(serverIp, pipe_fd, *args, **kw):
utils.log('Starting server', 3) utils.log('Starting server', 3)
return openvpn( return openvpn(
'--tls-server', '--tls-server',
'--mode', 'server', '--mode', 'server',
'--up', 'ovpn-server %s/%u' % (ip, len(utils.config.vifibnet)), '--up', 'ovpn-server %s/%u' % (serverIp, len(utils.config.vifibnet)),
'--client-connect', 'ovpn-server ' + str(pipe_fd), '--client-connect', 'ovpn-server ' + str(pipe_fd),
'--client-disconnect', 'ovpn-server ' + str(pipe_fd), '--client-disconnect', 'ovpn-server ' + str(pipe_fd),
'--dh', utils.config.dh, '--dh', utils.config.dh,
...@@ -48,13 +50,13 @@ def client(serverIp, pipe_fd, *args, **kw): ...@@ -48,13 +50,13 @@ def client(serverIp, pipe_fd, *args, **kw):
'--route-up', 'ovpn-client ' + str(pipe_fd), '--route-up', 'ovpn-client ' + str(pipe_fd),
*args, **kw) *args, **kw)
def babel(**kw): def babel(internal_ip, network, interface_list, **kw):
utils.log('Starting babel', 3) utils.log('Starting babel', 3)
args = ['babeld', args = ['babeld',
'-C', 'redistribute local ip %s' % (utils.config.internal_ip), '-C', 'redistribute local ip %s' % (internal_ip),
'-C', 'redistribute local deny', '-C', 'redistribute local deny',
# Route VIFIB ip adresses # Route VIFIB ip adresses
'-C', 'in ip %s::/%u' % (utils.ipFromBin(utils.config.vifibnet), len(utils.config.vifibnet)), '-C', 'in ip %s::/%u' % (utils.ipFromBin(network), len(network)),
# Route only addresse in the 'local' network, # Route only addresse in the 'local' network,
# or other entire networks # or other entire networks
#'-C', 'in ip %s' % (config.internal_ip), #'-C', 'in ip %s' % (config.internal_ip),
...@@ -66,7 +68,7 @@ def babel(**kw): ...@@ -66,7 +68,7 @@ def babel(**kw):
] ]
if utils.config.babel_state: if utils.config.babel_state:
args += '-S', utils.config.babel_state args += '-S', utils.config.babel_state
args = args + ['vifibnet'] + list(tunnelmanager.free_interface_set) args = args + interface_list
utils.log(str(args), 5) utils.log(str(args), 5)
return subprocess.Popen(args, **kw) return subprocess.Popen(args, **kw)
import os, random, traceback import os, random, traceback
import plib, utils, db import plib, utils, db
free_interface_set = set(('client1', 'client2', 'client3', 'client4', 'client5',
'client6', 'client7', 'client8', 'client9', 'client10'))
class TunnelManager: class TunnelManager:
def __init__(self, write_pipe, peers_db): def __init__(self, write_pipe, peers_db, client_count, refresh_count):
self.write_pipe = write_pipe self.write_pipe = write_pipe
self.peers_db = peers_db self.peers_db = peers_db
self.connection_dict = {} self.connection_dict = {}
self.client_count = client_count
self.refresh_count = refresh_count
self.free_interface_set = set(('client1', 'client2', 'client3', 'client4', 'client5',
'client6', 'client7', 'client8', 'client9', 'client10'))
def refresh(self): def refresh(self):
self.cleanDeads() self.cleanDeads()
...@@ -21,12 +24,12 @@ class TunnelManager: ...@@ -21,12 +24,12 @@ class TunnelManager:
p, iface = self.connection_dict[id] p, iface = self.connection_dict[id]
if p.poll() != None: if p.poll() != None:
utils.log('Connection with %s has failed with return code %s' % (id, p.returncode), 3) utils.log('Connection with %s has failed with return code %s' % (id, p.returncode), 3)
free_interface_set.add(iface) self.free_interface_set.add(iface)
self.peers_db.unusePeer(id) self.peers_db.unusePeer(id)
del self.connection_dict[id] del self.connection_dict[id]
def removeSomeTunnels(self): def removeSomeTunnels(self):
for i in range(0, max(0, len(self.connection_dict) - utils.config.client_count + utils.config.refresh_count)): for i in range(0, max(0, len(self.connection_dict) - self.client_count + self.refresh_count)):
peer_id = random.choice(self.connection_dict.keys()) peer_id = random.choice(self.connection_dict.keys())
kill(peer_id) kill(peer_id)
...@@ -34,14 +37,14 @@ class TunnelManager: ...@@ -34,14 +37,14 @@ class TunnelManager:
utils.log('Killing the connection with id ' + str(peer_id), 2) utils.log('Killing the connection with id ' + str(peer_id), 2)
p, iface = self.connection_dict.pop(peer_id) p, iface = self.connection_dict.pop(peer_id)
p.kill() p.kill()
free_interface_set.add(iface) self.free_interface_set.add(iface)
self.peers_db.unusePeer(peer_id) self.peers_db.unusePeer(peer_id)
def makeNewTunnels(self): def makeNewTunnels(self):
try: try:
for peer_id, ip, port, proto in self.peers_db.getUnusedPeers(utils.config.client_count - len(self.connection_dict), self.write_pipe): for peer_id, ip, port, proto in self.peers_db.getUnusedPeers(self.client_count - len(self.connection_dict), self.write_pipe):
utils.log('Establishing a connection with id %s (%s:%s)' % (peer_id, ip, port), 2) utils.log('Establishing a connection with id %s (%s:%s)' % (peer_id, ip, port), 2)
iface = free_interface_set.pop() iface = self.free_interface_set.pop()
self.connection_dict[peer_id] = ( plib.client( ip, write_pipe, '--dev', iface, '--proto', proto, '--rport', str(port), self.connection_dict[peer_id] = ( plib.client( ip, write_pipe, '--dev', iface, '--proto', proto, '--rport', str(port),
stdout=os.open(os.path.join(utils.config.log, 'vifibnet.client.%s.log' % (peer_id,)), stdout=os.open(os.path.join(utils.config.log, 'vifibnet.client.%s.log' % (peer_id,)),
os.O_WRONLY|os.O_CREAT|os.O_TRUNC) ), iface) os.O_WRONLY|os.O_CREAT|os.O_TRUNC) ), iface)
...@@ -50,3 +53,14 @@ class TunnelManager: ...@@ -50,3 +53,14 @@ class TunnelManager:
utils.log("Can't establish connection with %s : no available interface" % ip, 2) utils.log("Can't establish connection with %s : no available interface" % ip, 2)
except Exception: except Exception:
traceback.print_exc() traceback.print_exc()
def handle_message(msg):
script_type, arg = msg.split()
if script_type == 'client-connect':
utils.log('Incomming connection from %s' % (arg,), 3)
elif script_type == 'client-disconnect':
utils.log('%s has disconnected' % (arg,), 3)
elif script_type == 'route-up':
utils.log('External Ip : ' + arg, 3)
else:
utils.log('Unknow message recieved from the openvpn pipe : ' + msg, 1)
import time import argparse, time
import argparse
from OpenSSL import crypto from OpenSSL import crypto
config = None
def log(message, verbose_level): def log(message, verbose_level):
if config.verbose >= verbose_level: if config.verbose >= verbose_level:
...@@ -20,65 +18,38 @@ def ipFromPrefix(vifibnet, prefix, prefix_len): ...@@ -20,65 +18,38 @@ def ipFromPrefix(vifibnet, prefix, prefix_len):
ip_t = (vifibnet + prefix).ljust(128, '0') ip_t = (vifibnet + prefix).ljust(128, '0')
return ipFromBin(ip_t) return ipFromBin(ip_t)
def getConfig(): def networkFromCa(ca_path):
global config
parser = argparse.ArgumentParser(
description='Resilient virtual private network application')
_ = parser.add_argument
# Server address MUST be a vifib address ( else requests will be denied )
_('--server', required=True,
help='Address for peer discovery server')
_('--server-port', required=True, type=int,
help='Peer discovery server port')
_('-l', '--log', default='/var/log',
help='Path to vifibnet logs directory')
_('--client-count', default=2, type=int,
help='Number of client connections')
# TODO: use maxpeer
_('--max-clients', default=10, type=int,
help='the number of peers that can connect to the server')
_('--refresh-time', default=300, type=int,
help='the time (seconds) to wait before changing the connections')
_('--refresh-count', default=1, type=int,
help='The number of connections to drop when refreshing the connections')
_('--db', default='/var/lib/vifibnet/peers.db',
help='Path to peers database')
_('--dh', required=True,
help='Path to dh file')
_('--babel-state', default='/var/lib/vifibnet/babel_state',
help='Path to babeld state-file')
_('--verbose', '-v', default=0, type=int,
help='Defines the verbose level')
_('--ca', required=True,
help='Path to the certificate authority file')
_('--cert', required=True,
help='Path to the certificate file')
_('--ip', required=True, dest='external_ip',
help='Ip address of the machine on the internet')
# Openvpn options
_('openvpn_args', nargs=argparse.REMAINDER,
help="Common OpenVPN options (e.g. certificates)")
config = parser.parse_args()
# Get network prefix from ca.crt # Get network prefix from ca.crt
with open(config.ca, 'r') as f: with open(ca_path, 'r') as f:
ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
config.vifibnet = bin(ca.get_serial_number())[3:] return bin(ca.get_serial_number())[3:]
def ipFromCert(network, cert_path):
# Get ip from cert.crt # Get ip from cert.crt
with open(config.cert, 'r') as f: with open(cert_path, 'r') as f:
cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
subject = cert.get_subject() subject = cert.get_subject()
prefix, prefix_len = subject.CN.split('/') prefix, prefix_len = subject.CN.split('/')
config.internal_ip = ipFromPrefix(config.vifibnet, prefix, int(prefix_len)) return ipFromPrefix(network, prefix, int(prefix_len))
log('Intranet ip : %s' % (config.internal_ip,), 3)
def ovpnArgs(optional_args, ca_path, cert_path)
# Treat openvpn arguments # Treat openvpn arguments
if config.openvpn_args[0] == "--": if optional_args[0] == "--":
del config.openvpn_args[0] del optional_args[0]
config.openvpn_args.append('--ca') optional_args.append('--ca')
config.openvpn_args.append(config.ca) optional_args.append(config.ca)
config.openvpn_args.append('--cert') optional_args.append('--cert')
config.openvpn_args.append(config.cert) optional_args.append(config.cert)
return optional_args
log("Configuration completed", 1)
\ No newline at end of file
...@@ -3,22 +3,48 @@ import argparse, errno, math, os, select, subprocess, sys, time, traceback ...@@ -3,22 +3,48 @@ import argparse, errno, math, os, select, subprocess, sys, time, traceback
from OpenSSL import crypto from OpenSSL import crypto
import db, plib, upnpigd, utils, tunnelmanager import db, plib, upnpigd, utils, tunnelmanager
def handle_message(msg): def getConfig():
script_type, arg = msg.split() parser = argparse.ArgumentParser(
if script_type == 'client-connect': description='Resilient virtual private network application')
utils.log('Incomming connection from %s' % (arg,), 3) _ = parser.add_argument
# TODO: check if we are not already connected to it # Server address MUST be a vifib address ( else requests will be denied )
elif script_type == 'client-disconnect': _('--server', required=True,
utils.log('%s has disconnected' % (arg,), 3) help='Address for peer discovery server')
elif script_type == 'route-up': _('--server-port', required=True, type=int,
# TODO: save the external ip received help='Peer discovery server port')
utils.log('External Ip : ' + arg, 3) _('-l', '--log', default='/var/log',
else: help='Path to vifibnet logs directory')
utils.log('Unknow message recieved from the openvpn pipe : ' + msg, 1) _('--client-count', default=2, type=int,
help='Number of client connections')
# TODO: use maxpeer
_('--max-clients', default=10, type=int,
help='the number of peers that can connect to the server')
_('--refresh-time', default=300, type=int,
help='the time (seconds) to wait before changing the connections')
_('--refresh-count', default=1, type=int,
help='The number of connections to drop when refreshing the connections')
_('--db', default='/var/lib/vifibnet/peers.db',
help='Path to peers database')
_('--dh', required=True,
help='Path to dh file')
_('--babel-state', default='/var/lib/vifibnet/babel_state',
help='Path to babeld state-file')
_('--verbose', '-v', default=0, type=int,
help='Defines the verbose level')
_('--ca', required=True,
help='Path to the certificate authority file')
_('--cert', required=True,
help='Path to the certificate file')
_('--ip', required=True, dest='external_ip',
help='Ip address of the machine on the internet')
# Openvpn options
_('openvpn_args', nargs=argparse.REMAINDER,
help="Common OpenVPN options (e.g. certificates)")
return parser.parse_args()
def main(): def main():
# Get arguments # Get arguments
utils.getConfig() config = getConfig()
# Launch babel on all interfaces. WARNING : you have to be root to start babeld # Launch babel on all interfaces. WARNING : you have to be root to start babeld
babel = plib.babel(stdout=os.open(os.path.join(utils.config.log, 'vifibnet.babeld.log'), babel = plib.babel(stdout=os.open(os.path.join(utils.config.log, 'vifibnet.babeld.log'),
...@@ -31,7 +57,7 @@ def main(): ...@@ -31,7 +57,7 @@ def main():
# Setup the tunnel manager # Setup the tunnel manager
peers_db = db.PeersDB(utils.config.db) peers_db = db.PeersDB(utils.config.db)
tunnelManager = tunnelmanager.TunnelManager(write_pipe, peers_db) tunnelManager = tunnelmanager.TunnelManager(write_pipe, peers_db, utils.config.client_count, utils.config.refresh_count)
# Establish connections # Establish connections
serverProcess = plib.server(utils.config.internal_ip, write_pipe, '--dev', 'vifibnet', serverProcess = plib.server(utils.config.internal_ip, write_pipe, '--dev', 'vifibnet',
...@@ -45,9 +71,9 @@ def main(): ...@@ -45,9 +71,9 @@ def main():
try: try:
while True: while True:
ready, tmp1, tmp2 = select.select([read_pipe], [], [], ready, tmp1, tmp2 = select.select([read_pipe], [], [],
max(0, next_refresh - time.time())) max(0, next_refresh - timhttp://blogs.lesechos.fr/dominique-seux/de-mondialiser-les-telecoms-a11339.htmle.time()))
if ready: if ready:
handle_message(read_pipe.readline()) tunnelManager.handle_message(read_pipe.readline())
if time.time() >= next_refresh: if time.time() >= next_refresh:
peers_db.populate(10) peers_db.populate(10)
tunnelManager.refresh() tunnelManager.refresh()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment