Example #1
0
def main():
    # Get arguments
    config = getConfig()
    cert = x509.Cert(config.ca, config.key, config.cert)
    config.openvpn_args += cert.openvpn_args

    if config.test:
        sys.exit(eval(config.test, None, config.__dict__))

    # Set logging
    utils.setupLog(config.verbose, os.path.join(config.log, 're6stnet.log'))

    logging.trace("Environment: %r", os.environ)
    logging.trace("Configuration: %r", config)
    utils.makedirs(config.state)
    db_path = os.path.join(config.state, 'cache.db')
    if config.ovpnlog:
        plib.ovpn_log = config.log

    exit.signal(0, signal.SIGINT, signal.SIGTERM)
    exit.signal(-1, signal.SIGHUP, signal.SIGUSR2)

    cache = Cache(db_path, config.registry, cert)
    network = cert.network

    if config.client_count is None:
        config.client_count = cache.client_count
    if config.max_clients is None:
        config.max_clients = cache.max_clients

    if config.table is not None:
        logging.warning("--table option is deprecated: use --default instead")
        config.default = True
    if config.default and config.gateway:
        sys.exit("error: conflicting options --default and --gateway")

    if config.disable_proto is None:
        config.disable_proto = DEFAULT_DISABLED_PROTO
    elif 'none' in config.disable_proto:
        config.disable_proto = ()
    if config.default:
        # Make sure we won't tunnel over re6st.
        config.disable_proto = tuple(set(('tcp6', 'udp6')).union(
            config.disable_proto))
    address = ()
    server_tunnels = {}
    forwarder = None
    if config.client:
        config.babel_args.append('re6stnet')
    elif config.max_clients:
        if config.pp:
            pp = [(int(port), proto) for port, proto in config.pp]
            for port, proto in pp:
                if proto in config.disable_proto:
                    sys.exit("error: conflicting options --disable-proto %s"
                             " and --pp %u %s" % (proto, port, proto))
        else:
            pp = [x for x in ((1194, 'udp'), (1194, 'tcp'))
                    if x[1] not in config.disable_proto]
        def ip_changed(ip):
            for family, proto_list in ((socket.AF_INET, ('tcp', 'udp')),
                                       (socket.AF_INET6, ('tcp6', 'udp6'))):
                try:
                    socket.inet_pton(family, ip)
                    break
                except socket.error:
                    pass
            else:
                family = None
            return family, [(ip, str(port), proto) for port, proto in pp
                            if not family or proto in proto_list]
        if config.gw_list:
          gw_list = deque(config.gw_list)
          def remote_gateway(dest):
            gw_list.rotate()
            return gw_list[0]
        else:
          remote_gateway = None
        if len(config.ip) > 1:
            if 'upnp' in config.ip or 'any' in config.ip:
                sys.exit("error: argument --ip can be given only once with"
                         " 'any' or 'upnp' value")
            logging.info("Multiple --ip passed: note that re6st does nothing to"
                " make sure that incoming paquets are replied via the correct"
                " gateway. So without manual network configuration, this can"
                " not be used to accept server connections from multiple"
                " gateways.")
        if 'upnp' in config.ip or not config.ip:
            logging.info('Attempting automatic configuration via UPnP...')
            try:
                from re6st.upnpigd import Forwarder
                forwarder = Forwarder('re6stnet openvpn server')
            except Exception, e:
                if config.ip:
                    raise
                logging.info("%s: assume we are not NATed", e)
            else:
                atexit.register(forwarder.clear)
                for port, proto in pp:
                    forwarder.addRule(port, proto)
                ip_changed = forwarder.checkExternalIp
                address = ip_changed(),
        elif 'any' not in config.ip:
            address = map(ip_changed, config.ip)
            ip_changed = None
        for x in pp:
            server_tunnels.setdefault('re6stnet-' + x[1], x)
Example #2
0
def main():
    parser = utils.ArgParser(fromfile_prefix_chars='@',
        description="re6stnet registry used to bootstrap nodes"
                    " and deliver certificates.")
    _ = parser.add_argument
    _('--port', type=int, default=80,
        help="Port on which the server will listen.")
    _('-4', dest='bind4', default='0.0.0.0',
        help="Bind server to this IPv4.")
    _('-6', dest='bind6', default='::',
        help="Bind server to this IPv6.")
    _('--db', default='/var/lib/re6stnet/registry.db',
        help="Path to SQLite database file. It is automatically initialized"
             " if the file does not exist.")
    _('--dh', required=True,
        help="File containing Diffie-Hellman parameters in .pem format."
             " To generate them, you can use something like:\n"
             "openssl dhparam -out dh2048.pem 2048")
    _('--ca', required=True, help=parser._ca_help)
    _('--key', required=True,
            help="CA private key in .pem format. For example:\nopenssl"
            " genpkey -out ca.key -algorithm rsa -pkeyopt rsa_keygen_bits:2048")
    _('--mailhost', required=True,
            help="SMTP host to send confirmation emails. For debugging"
                 " purpose, it can also be an absolute or existing path to"
                 " a mailbox file")
    _('--prefix-length', default=16, type=int,
            help="Default length of allocated prefixes."
                 " If 0, registration by email is disabled.")
    _('--anonymous-prefix-length', type=int,
            help="Length of allocated anonymous prefixes."
                 " If 0 or unset, anonymous registration is disabled.")
    _('--ipv4', nargs=2, metavar=("IP/N", "PLEN"),
        help="Enable ipv4. Each node is assigned a subnet of length PLEN"
             " inside network IP/N.")
    _('-l', '--logfile', default='/var/log/re6stnet/registry.log',
            help="Path to logging file.")
    _('-r', '--run', default='/var/run/re6stnet',
        help="Path to re6stnet runtime directory:\n"
             "- babeld.sock (option -R of babeld)\n")
    _('-v', '--verbose', default=1, type=int,
            help="Log level. 0 disables logging. 1=WARNING, 2=INFO,"
                 " 3=DEBUG, 4=TRACE. Use SIGUSR1 to reopen log.")
    _('--min-protocol', default=version.min_protocol, type=int,
        help="Reject nodes that are too old. Current is %s." % version.protocol)

    _ = parser.add_argument_group('routing').add_argument
    _('--hello', type=int, default=15,
        help="Hello interval in seconds, for both wired and wireless"
             " connections. OpenVPN ping-exit option is set to 4 times the"
             " hello interval. It takes between 3 and 4 times the"
             " hello interval for Babel to re-establish connection with a"
             " node for which the direct connection has been cut.")

    _ = parser.add_argument_group('tunnelling').add_argument
    _('--encrypt', action='store_true',
        help='Specify that tunnels should be encrypted.')
    _('--client-count', default=10, type=int,
        help="Number of client tunnels to set up.")
    _('--max-clients', type=int,
        help="Maximum number of accepted clients per OpenVPN server. (default:"
             " client-count * 2, which actually represents the average number"
             " of tunnels to other peers)")
    _('--tunnel-refresh', default=300, type=int,
        help="Interval in seconds between two tunnel refresh: the worst"
             " tunnel is closed if the number of client tunnels has reached"
             " its maximum number (client-count).")

    config = parser.parse_args()

    if not version.min_protocol <= config.min_protocol <= version.protocol:
        parser.error("--min-protocol: value must between %s and %s (included)"
                     % (version.min_protocol, version.protocol))

    if config.ipv4:
        ipv4, plen = config.ipv4
        try:
            ip, n = ipv4.split('/')
            config.ipv4 = "%s/%s" % (socket.inet_ntoa(socket.inet_aton(ip)),
                                     int(n)), int(plen)
        except (socket.error, ValueError):
            parser.error("invalid argument --ipv4")

    utils.setupLog(config.verbose, config.logfile)

    if config.max_clients is None:
        config.max_clients = config.client_count * 2

    server = registry.RegistryServer(config)
    def requestHandler(request, client_address, _):
        RequestHandler(request, client_address, server)

    server_dict = {}
    if config.bind4:
        r = HTTPServer4((config.bind4, config.port), requestHandler)
        server_dict[r.fileno()] = r._handle_request_noblock
    if config.bind6:
        r = HTTPServer6((config.bind6, config.port), requestHandler)
        server_dict[r.fileno()] = r._handle_request_noblock
    if server_dict:
        while True:
            args = server_dict.copy(), {}, []
            server.select(*args)
            utils.select(*args)
Example #3
0
def main():
    parser = utils.ArgParser(
        fromfile_prefix_chars='@',
        description="re6stnet registry used to bootstrap nodes"
        " and deliver certificates.")
    _ = parser.add_argument
    _('--port',
      type=int,
      default=80,
      help="Port on which the server will listen.")
    _('-4', dest='bind4', default='0.0.0.0', help="Bind server to this IPv4.")
    _('-6', dest='bind6', default='::', help="Bind server to this IPv6.")
    _('--db',
      default='/var/lib/re6stnet/registry.db',
      help="Path to SQLite database file. It is automatically initialized"
      " if the file does not exist.")
    _('--dh',
      required=True,
      help="File containing Diffie-Hellman parameters in .pem format."
      " To generate them, you can use something like:\n"
      "openssl dhparam -out dh2048.pem 2048")
    _('--ca', required=True, help=parser._ca_help)
    _('--key',
      required=True,
      help="CA private key in .pem format. For example:\nopenssl"
      " genpkey -out ca.key -algorithm rsa -pkeyopt rsa_keygen_bits:2048")
    _('--mailhost',
      required=True,
      help="SMTP host to send confirmation emails. For debugging"
      " purpose, it can also be an absolute or existing path to"
      " a mailbox file")
    _('--prefix-length',
      default=16,
      type=int,
      help="Default length of allocated prefixes."
      " If 0, registration by email is disabled.")
    _('--anonymous-prefix-length',
      type=int,
      help="Length of allocated anonymous prefixes."
      " If 0 or unset, anonymous registration is disabled.")
    _('--ipv4',
      nargs=2,
      metavar=("IP/N", "PLEN"),
      help="Enable ipv4. Each node is assigned a subnet of length PLEN"
      " inside network IP/N.")
    _('-l',
      '--logfile',
      default='/var/log/re6stnet/registry.log',
      help="Path to logging file.")
    _('-r',
      '--run',
      default='/var/run/re6stnet',
      help="Path to re6stnet runtime directory:\n"
      "- babeld.sock (option -R of babeld)\n")
    _('-v',
      '--verbose',
      default=1,
      type=int,
      help="Log level. 0 disables logging. 1=WARNING, 2=INFO,"
      " 3=DEBUG, 4=TRACE. Use SIGUSR1 to reopen log.")
    _('--min-protocol',
      default=version.min_protocol,
      type=int,
      help="Reject nodes that are too old. Current is %s." % version.protocol)

    _ = parser.add_argument_group('routing').add_argument
    _('--hello',
      type=int,
      default=15,
      help="Hello interval in seconds, for both wired and wireless"
      " connections. OpenVPN ping-exit option is set to 4 times the"
      " hello interval. It takes between 3 and 4 times the"
      " hello interval for Babel to re-establish connection with a"
      " node for which the direct connection has been cut.")

    _ = parser.add_argument_group('tunnelling').add_argument
    _('--encrypt',
      action='store_true',
      help='Specify that tunnels should be encrypted.')
    _('--client-count',
      default=10,
      type=int,
      help="Number of client tunnels to set up.")
    _('--max-clients',
      type=int,
      help="Maximum number of accepted clients per OpenVPN server. (default:"
      " client-count * 2, which actually represents the average number"
      " of tunnels to other peers)")
    _('--tunnel-refresh',
      default=300,
      type=int,
      help="Interval in seconds between two tunnel refresh: the worst"
      " tunnel is closed if the number of client tunnels has reached"
      " its maximum number (client-count).")

    config = parser.parse_args()

    if not version.min_protocol <= config.min_protocol <= version.protocol:
        parser.error(
            "--min-protocol: value must between %s and %s (included)" %
            (version.min_protocol, version.protocol))

    if config.ipv4:
        ipv4, plen = config.ipv4
        try:
            ip, n = ipv4.split('/')
            config.ipv4 = "%s/%s" % (socket.inet_ntoa(
                socket.inet_aton(ip)), int(n)), int(plen)
        except (socket.error, ValueError):
            parser.error("invalid argument --ipv4")

    utils.setupLog(config.verbose, config.logfile)

    if config.max_clients is None:
        config.max_clients = config.client_count * 2

    server = registry.RegistryServer(config)

    def requestHandler(request, client_address, _):
        RequestHandler(request, client_address, server)

    server_dict = {}
    if config.bind4:
        r = HTTPServer4((config.bind4, config.port), requestHandler)
        server_dict[r.fileno()] = r._handle_request_noblock
    if config.bind6:
        r = HTTPServer6((config.bind6, config.port), requestHandler)
        server_dict[r.fileno()] = r._handle_request_noblock
    if server_dict:
        while True:
            args = server_dict.copy(), {}, []
            server.select(*args)
            utils.select(*args)
Example #4
0
def main():
    # Get arguments
    config = getConfig()
    cert = x509.Cert(config.ca, config.key, config.cert)
    config.openvpn_args += cert.openvpn_args

    if config.test:
        sys.exit(eval(config.test, None, config.__dict__))

    # Set logging
    utils.setupLog(config.verbose, os.path.join(config.log, "re6stnet.log"))

    logging.trace("Environment: %r", os.environ)
    logging.trace("Configuration: %r", config)
    utils.makedirs(config.state)
    db_path = os.path.join(config.state, "cache.db")
    if config.ovpnlog:
        plib.ovpn_log = config.log

    exit.signal(0, signal.SIGINT, signal.SIGTERM)
    exit.signal(-1, signal.SIGHUP, signal.SIGUSR2)

    cache = Cache(db_path, config.registry, cert)
    network = cert.network

    if config.client_count is None:
        config.client_count = cache.client_count
    if config.max_clients is None:
        config.max_clients = cache.max_clients

    if config.table is not None:
        logging.warning("--table option is deprecated: use --default instead")
        config.default = True
    if config.default and config.gateway:
        sys.exit("error: conflicting options --default and --gateway")

    if "none" in config.disable_proto:
        config.disable_proto = ()
    if config.default:
        # Make sure we won't tunnel over re6st.
        config.disable_proto = tuple(set(("tcp6", "udp6")).union(config.disable_proto))
    address = ()
    server_tunnels = {}
    forwarder = None
    if config.client:
        config.babel_args.append("re6stnet")
    elif config.max_clients:
        if config.pp:
            pp = [(int(port), proto) for port, proto in config.pp]
            for port, proto in pp:
                if proto in config.disable_proto:
                    sys.exit("error: conflicting options --disable-proto %s" " and --pp %u %s" % (proto, port, proto))
        else:
            pp = [x for x in ((1194, "udp"), (1194, "tcp")) if x[1] not in config.disable_proto]

        def ip_changed(ip):
            for family, proto_list in ((socket.AF_INET, ("tcp", "udp")), (socket.AF_INET6, ("tcp6", "udp6"))):
                try:
                    socket.inet_pton(family, ip)
                    break
                except socket.error:
                    pass
            else:
                family = None
            return family, [(ip, str(port), proto) for port, proto in pp if not family or proto in proto_list]

        if config.gw_list:
            gw_list = deque(config.gw_list)

            def remote_gateway(dest):
                gw_list.rotate()
                return gw_list[0]

        else:
            remote_gateway = None
        if len(config.ip) > 1:
            if "upnp" in config.ip or "any" in config.ip:
                sys.exit("error: argument --ip can be given only once with" " 'any' or 'upnp' value")
            logging.info(
                "Multiple --ip passed: note that re6st does nothing to"
                " make sure that incoming paquets are replied via the correct"
                " gateway. So without manual network configuration, this can"
                " not be used to accept server connections from multiple"
                " gateways."
            )
        if "upnp" in config.ip or not config.ip:
            logging.info("Attempting automatic configuration via UPnP...")
            try:
                from re6st.upnpigd import Forwarder

                forwarder = Forwarder("re6stnet openvpn server")
            except Exception, e:
                if config.ip:
                    raise
                logging.info("%s: assume we are not NATed", e)
            else:
                atexit.register(forwarder.clear)
                for port, proto in pp:
                    forwarder.addRule(port, proto)
                ip_changed = forwarder.checkExternalIp
                address = (ip_changed(),)
        elif "any" not in config.ip:
            address = map(ip_changed, config.ip)
            ip_changed = None
        for x in pp:
            server_tunnels.setdefault("re6stnet-" + x[1], x)