plib.py 3.9 KB
Newer Older
1
import logging, errno, os
2
from . import utils
Guillaume Bury's avatar
Guillaume Bury committed
3

Guillaume Bury's avatar
Guillaume Bury committed
4 5 6
here = os.path.realpath(os.path.dirname(__file__))
ovpn_server = os.path.join(here, 'ovpn-server')
ovpn_client = os.path.join(here, 'ovpn-client')
7
ovpn_log = None
Ulysse Beaugnon's avatar
Ulysse Beaugnon committed
8

9
def openvpn(iface, encrypt, *args, **kw):
Ulysse Beaugnon's avatar
Ulysse Beaugnon committed
10
    args = ['openvpn',
11
        '--dev-type', 'tap',
Julien Muchembled's avatar
Julien Muchembled committed
12
        '--dev', iface,
Ulysse Beaugnon's avatar
Ulysse Beaugnon committed
13 14 15
        '--persist-tun',
        '--persist-key',
        '--script-security', '2',
16
        '--up', ovpn_client,
Julien Muchembled's avatar
Julien Muchembled committed
17
        #'--user', 'nobody', '--group', 'nogroup',
Guillaume Bury's avatar
Guillaume Bury committed
18
        ] + list(args)
19 20
    if ovpn_log:
        args += '--log-append', os.path.join(ovpn_log, '%s.log' % iface),
21
    if not encrypt:
22
        args += '--cipher', 'none', '--ncp-disable'
23
    logging.debug('%r', args)
24
    return utils.Popen(args, **kw)
Ulysse Beaugnon's avatar
Ulysse Beaugnon committed
25

26
ovpn_link_mtu_dict = {'udp4': 1432, 'udp6': 1450}
27

28
def server(iface, max_clients, dh_path, fd, port, proto, encrypt, *args, **kw):
Killian Lufau's avatar
Killian Lufau committed
29 30
    if proto == 'udp':
        proto = 'udp4'
31
    client_script = '%s %s' % (ovpn_server, fd)
32
    try:
33
        args = ('--link-mtu', str(ovpn_link_mtu_dict[proto] + 93),
34 35 36
                '--mtu-disc', 'yes') + args
    except KeyError:
        proto += '-server'
37
    return openvpn(iface, encrypt,
Ulysse Beaugnon's avatar
Ulysse Beaugnon committed
38 39
        '--tls-server',
        '--mode', 'server',
40
        '--client-connect', client_script,
41
        '--client-disconnect', client_script,
Guillaume Bury's avatar
Guillaume Bury committed
42
        '--dh', dh_path,
Guillaume Bury's avatar
Guillaume Bury committed
43
        '--max-clients', str(max_clients),
44
        '--port', str(port),
45
        '--proto', proto,
46
        *args, **kw)
Ulysse Beaugnon's avatar
Ulysse Beaugnon committed
47

48

49
def client(iface, address_list, encrypt, *args, **kw):
50
    remote = ['--nobind', '--client']
51 52
    # XXX: We'd like to pass <connection> sections at command-line.
    link_mtu = set()
53
    for ip, port, proto in address_list:
Killian Lufau's avatar
Killian Lufau committed
54 55
        if proto == 'udp':
            proto = 'udp4'
Julien Muchembled's avatar
Julien Muchembled committed
56
        remote += '--remote', ip, port, proto
57 58 59 60
        link_mtu.add(ovpn_link_mtu_dict.get(proto))
    link_mtu, = link_mtu
    if link_mtu:
        remote += '--link-mtu', str(link_mtu), '--mtu-disc', 'yes'
61
    remote += args
62
    return openvpn(iface, encrypt, *remote, **kw)
63

64

Killian Lufau's avatar
Killian Lufau committed
65 66
def router(ip, ip4, src, hello_interval, log_path, state_path, pidfile,
           control_socket, default, hmac, *args, **kw):
67
    ip, n = ip
Killian Lufau's avatar
Killian Lufau committed
68
    hmac_sign, hmac_accept = hmac
69 70
    if ip4:
        ip4, n4 = ip4
71
    cmd = ['babeld',
72 73
            '-h', str(hello_interval),
            '-H', str(hello_interval),
74
            '-L', log_path,
75
            '-S', state_path,
76
            '-I', pidfile,
77
            '-s',
78 79 80 81 82 83
            # Force use of ipv6 subtrees because:
            # - even Linux 2.6.32 has them
            # - the fallback implementation using a separate table
            #   is not equivalent, at least not the way we use babeld
            #   (and we don't need RTA_SRC for ipv4).
            '-C', 'ipv6-subtrees true',
84
            '-C', 'redistribute local deny',
85
            '-C', 'redistribute ip %s/%s eq %s' % (ip, n, n)]
Killian Lufau's avatar
Killian Lufau committed
86 87 88 89 90
    if hmac_sign:
        def key(cmd, id, value):
            cmd += '-C', ('key type blake2s id %s value %s' %
                          (id, value.encode('hex')))
        key(cmd, 'sign', hmac_sign)
91
        default += ' hmac sign'
Killian Lufau's avatar
Killian Lufau committed
92 93 94 95
        if hmac_accept is not None:
            if hmac_accept:
                key(cmd, 'accept', hmac_accept)
            else:
96 97
                default += ' no_hmac_verify true'
    cmd += '-C', 'default ' + default
98 99
    if ip4:
        cmd += '-C', 'redistribute ip %s/%s eq %s' % (ip4, n4, n4)
100 101 102 103 104 105
    if src:
        cmd += '-C', 'install ip ::/0 eq 0 src-prefix ' + src
    elif src is None:
        cmd += '-C', 'redistribute ip ::/0 eq 0'
    cmd += ('-C', 'redistribute deny',
            '-C', 'install pref-src ' + ip)
106 107
    if ip4:
        cmd += '-C', 'install pref-src ' + ip4
108
    if control_socket:
109
        cmd += '-X', '%s' % control_socket
110
    cmd += args
Julien Muchembled's avatar
Julien Muchembled committed
111 112 113 114 115 116
    # WKRD: babeld fails to start if pidfile already exists
    try:
        os.remove(pidfile)
    except OSError, e:
        if e.errno != errno.ENOENT:
            raise
117
    logging.info('%r', cmd)
118
    return utils.Popen(cmd, **kw)