Commit ecbe625a authored by Guillaume Bury's avatar Guillaume Bury

Cleaner configuration

parent 5cd60b35
import utils import utils
import sqlite3 import sqlite3, xmlrpclib
import xmlrpclib
class PeersDB: class PeerManager:
def __init__(self, dbPath): def __init__(self, dbPath):
utils.log('Connectiong to peers database', 4) utils.log('Connectiong to peers database', 4)
self.db = sqlite3.connect(dbPath, isolation_level=None) self.db = sqlite3.connect(dbPath, isolation_level=None)
utils.log('Preparing peers database', 4) utils.log('Preparing peers database', 4)
...@@ -37,3 +36,14 @@ class PeersDB: ...@@ -37,3 +36,14 @@ class PeersDB:
def unusePeer(self, id): def unusePeer(self, id):
utils.log('Updating peers database : unusing peer ' + str(id), 5) utils.log('Updating peers database : unusing peer ' + str(id), 5)
self.db.execute("UPDATE peers SET used = 0 WHERE id = ?", (id,)) self.db.execute("UPDATE peers SET used = 0 WHERE id = ?", (id,))
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)
...@@ -20,24 +20,23 @@ def openvpn(*args, **kw): ...@@ -20,24 +20,23 @@ def openvpn(*args, **kw):
# '--ping-exit', '3', # '--ping-exit', '3',
'--group', 'nogroup', '--group', 'nogroup',
'--verb', str(utils.config.verbose), '--verb', str(utils.config.verbose),
] + list(args) + utils.config.openvpn_args ] + list(args)
if utils.config.verbose >= 5: utils.log(str(args), 5)
print repr(args)
return subprocess.Popen(args, **kw) return subprocess.Popen(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(serverIp, pipe_fd, *args, **kw): def server(serverIp, network, max_clients, 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' % (serverIp, len(utils.config.vifibnet)), '--up', 'ovpn-server %s/%u' % (serverIp, len(network)),
'--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,
'--max-clients', str(utils.config.max_clients), '--max-clients', str(max_clients),
*args, **kw) *args, **kw)
def client(serverIp, pipe_fd, *args, **kw): def client(serverIp, pipe_fd, *args, **kw):
...@@ -50,7 +49,7 @@ def client(serverIp, pipe_fd, *args, **kw): ...@@ -50,7 +49,7 @@ 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(internal_ip, network, interface_list, **kw): def babel(network, internal_ip, interface_list, **kw):
utils.log('Starting babel', 3) utils.log('Starting babel', 3)
args = ['babeld', args = ['babeld',
'-C', 'redistribute local ip %s' % (internal_ip), '-C', 'redistribute local ip %s' % (internal_ip),
......
#!/usr/bin/env python #!/usr/bin/env python
import argparse, math, random, select, smtplib, sqlite3, string, struct, socket, time import argparse, math, random, select, smtplib, sqlite3, string, socket, time, traceback
from email.mime.text import MIMEText
from functools import wraps
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
from email.mime.text import MIMEText
from OpenSSL import crypto from OpenSSL import crypto
import traceback import utils
# To generate server ca and key with correct serial # To generate server ca and key with correct serial
# openssl req -nodes -new -x509 -key ca.key -set_serial 0x120010db80042 -days 365 -out ca.crt # openssl req -nodes -new -x509 -key ca.key -set_serial 0x120010db80042 -days 365 -out ca.crt
...@@ -73,7 +72,6 @@ class main(object): ...@@ -73,7 +72,6 @@ class main(object):
else: else:
self.db.execute("INSERT INTO vifib VALUES ('',null,null)") self.db.execute("INSERT INTO vifib VALUES ('',null,null)")
# Loading certificates # Loading certificates
with open(self.config.ca) as f: with open(self.config.ca) as f:
self.ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) self.ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
...@@ -88,6 +86,8 @@ class main(object): ...@@ -88,6 +86,8 @@ class main(object):
server4.register_instance(self) server4.register_instance(self)
server6 = SimpleXMLRPCServer6(('::', self.config.port), requestHandler=RequestHandler, allow_none=True) server6 = SimpleXMLRPCServer6(('::', self.config.port), requestHandler=RequestHandler, allow_none=True)
server6.register_instance(self) server6.register_instance(self)
# Main loop
while True: while True:
try: try:
r, w, e = select.select([server4, server6], [], []) r, w, e = select.select([server4, server6], [], [])
...@@ -179,8 +179,7 @@ class main(object): ...@@ -179,8 +179,7 @@ class main(object):
def declare(self, handler, address): def declare(self, handler, address):
client_address, ip, port, proto = address client_address, ip, port, proto = address
#client_address, _ = handler.client_address #client_address, _ = handler.client_address
client_ip1, client_ip2 = struct.unpack('>QQ', socket.inet_pton(socket.AF_INET6, client_address)) client_ip = binFromIp(client_address)
client_ip = bin(client_ip1)[2:].rjust(64, '0') + bin(client_ip2)[2:].rjust(64, '0')
if client_ip.startswith(self.network): if client_ip.startswith(self.network):
prefix = client_ip[len(self.network):] prefix = client_ip[len(self.network):]
prefix, = self.db.execute("SELECT prefix FROM vifib WHERE prefix <= ? ORDER BY prefix DESC LIMIT 1", (prefix,)).next() prefix, = self.db.execute("SELECT prefix FROM vifib WHERE prefix <= ? ORDER BY prefix DESC LIMIT 1", (prefix,)).next()
......
#!/usr/bin/env python #!/usr/bin/env python
from OpenSSL import crypto
import argparse, os, subprocess, sqlite3, sys, xmlrpclib import argparse, os, subprocess, sqlite3, sys, xmlrpclib
from OpenSSL import crypto
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
......
import os, random, traceback import os, random, traceback
import plib, utils, db import plib, utils, db
class TunnelManager: class TunnelManager:
def __init__(self, write_pipe, peers_db): def __init__(self, write_pipe, peer_db):
self._write_pipe = write_pipe self._write_pipe = write_pipe
self._peers_db = peers_db self._peer_db = peer_db
self._connection_dict = {} self._connection_dict = {}
self.client_count = client_count self._client_count = client_count
self.refresh_count = refresh_count self._refresh_count = refresh_count
self.free_interface_set = set(('client1', 'client2', 'client3', 'client4', 'client5', self.free_interface_set = set(('client1', 'client2', 'client3', 'client4', 'client5',
'client6', 'client7', 'client8', 'client9', 'client10')) 'client6', 'client7', 'client8', 'client9', 'client10'))
...@@ -25,7 +23,7 @@ class TunnelManager: ...@@ -25,7 +23,7 @@ class TunnelManager:
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)
self.free_interface_set.add(iface) self.free_interface_set.add(iface)
self.peers_db.unusePeer(id) self.peer_db.unusePeer(id)
del self.connection_dict[id] del self.connection_dict[id]
def _removeSomeTunnels(self): def _removeSomeTunnels(self):
...@@ -38,30 +36,19 @@ class TunnelManager: ...@@ -38,30 +36,19 @@ class TunnelManager:
p, iface = self._connection_dict.pop(peer_id) p, iface = self._connection_dict.pop(peer_id)
p.kill() p.kill()
self.free_interface_set.add(iface) self.free_interface_set.add(iface)
self._peers_db.unusePeer(peer_id) self._peer_db.unusePeer(peer_id)
def _makeNewTunnels(self): def _makeNewTunnels(self):
try: try:
for peer_id, ip, port, proto in self._peers_db.getUnusedPeers(self._client_count - len(self._connection_dict), self._write_pipe): for peer_id, ip, port, proto in self._peer_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 = self.free_interface_set.pop() iface = self.free_interface_set.pop()
self._connection_dict[peer_id] = ( openvpn.client( ip, write_pipe, '--dev', iface, '--proto', proto, '--rport', str(port), self._connection_dict[peer_id] = ( openvpn.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) ), os.O_WRONLY|os.O_CREAT|os.O_TRUNC) ),
iface) iface)
self._peers_db.usePeer(peer_id) self._peer_db.usePeer(peer_id)
except KeyError: except KeyError:
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 argparse, time import argparse, time, struct, socket
from OpenSSL import crypto from OpenSSL import crypto
...@@ -6,6 +6,10 @@ def log(message, verbose_level): ...@@ -6,6 +6,10 @@ def log(message, verbose_level):
if config.verbose >= verbose_level: if config.verbose >= verbose_level:
print time.strftime("%d-%m-%Y %H:%M:%S : " + message) print time.strftime("%d-%m-%Y %H:%M:%S : " + message)
def binFromIp(ip):
ip1, ip2 = struct.unpack('>QQ', socket.inet_pton(socket.AF_INET6, ip))
return bin(client_ip1)[2:].rjust(64, '0') + bin(client_ip2)[2:].rjust(64, '0')
def ipFromBin(prefix): def ipFromBin(prefix):
prefix = hex(int(prefix, 2))[2:] prefix = hex(int(prefix, 2))[2:]
ip = '' ip = ''
......
#!/usr/bin/env python #!/usr/bin/env python
import argparse, errno, math, os, select, subprocess, sys, time, traceback 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, tunnel
def getConfig(): def getConfig():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
...@@ -45,27 +45,31 @@ def getConfig(): ...@@ -45,27 +45,31 @@ def getConfig():
def main(): def main():
# Get arguments # Get arguments
config = getConfig() config = getConfig()
network = utils.networkFromCa(config.ca)
internal_ip = utils.ipFromCert(network, config.cert)
# Init db and tunnels
peer_db = db.PeerManager(utils.config.db)
tunnel_manager = tunnelmanager.TunnelManager(write_pipe, peer_db, config.client_count, config.refresh_count)
# 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(network, internal_ip, ['vifibnet'] + tunnel_manager.free_interface_set,
stdout=os.open(os.path.join(utils.config.log, 'vifibnet.babeld.log'),
os.O_WRONLY | os.O_CREAT | os.O_TRUNC), stderr=subprocess.STDOUT) os.O_WRONLY | os.O_CREAT | os.O_TRUNC), stderr=subprocess.STDOUT)
# Create and open read_only pipe to get connect/disconnect events from openvpn # Create and open read_only pipe to get server events
utils.log('Creating pipe for server events', 3) utils.log('Creating pipe for server events', 3)
r_pipe, write_pipe = os.pipe() r_pipe, write_pipe = os.pipe()
read_pipe = os.fdopen(r_pipe) read_pipe = os.fdopen(r_pipe)
# Setup the tunnel manager
peers_db = db.PeersDB(utils.config.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', server_process = plib.server(internal_ip, network, config.max_clients, write_pipe,
'--dev', 'vifibnet', *utils.ovpnArgs(config.openvpn_args, config.ca, config.cert),
stdout=os.open(os.path.join(utils.config.log, 'vifibnet.server.log'), os.O_WRONLY | os.O_CREAT | os.O_TRUNC)) stdout=os.open(os.path.join(utils.config.log, 'vifibnet.server.log'), os.O_WRONLY | os.O_CREAT | os.O_TRUNC))
tunnelManager.refresh() tunnel_manager.refresh()
# Timed refresh initializing # Timed refresh initializing
next_refresh = time.time() + utils.config.refresh_time next_refresh = time.time() + config.refresh_time
# main loop # main loop
try: try:
...@@ -73,11 +77,11 @@ def main(): ...@@ -73,11 +77,11 @@ def main():
ready, tmp1, tmp2 = select.select([read_pipe], [], [], ready, tmp1, tmp2 = select.select([read_pipe], [], [],
max(0, next_refresh - timhttp://blogs.lesechos.fr/dominique-seux/de-mondialiser-les-telecoms-a11339.htmle.time())) max(0, next_refresh - timhttp://blogs.lesechos.fr/dominique-seux/de-mondialiser-les-telecoms-a11339.htmle.time()))
if ready: if ready:
tunnelManager.handle_message(read_pipe.readline()) peer_db.handle_message(read_pipe.readline())
if time.time() >= next_refresh: if time.time() >= next_refresh:
peers_db.populate(100) peer_db.populate(100)
tunnelManager.refresh() tunnel_manager.refresh()
next_refresh = time.time() + utils.config.refresh_time next_refresh = time.time() + config.refresh_time
except KeyboardInterrupt: except KeyboardInterrupt:
return 0 return 0
......
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