示例#1
0
def init(ip4_network):
    check_compatibility()
    address4 = str(ip4_network.network_address + 1)
    netmask = str(ip4_network.netmask)
    rc_conf_mod('cloned_interfaces+=%s' % cloned_if())
    cmd('service', 'netif', 'cloneup')
    rc_conf_mod('ifconfig_%s=inet %s netmask %s' % (cloned_if(), address4, netmask))
    cmd('ifconfig', cloned_if(), 'inet', address4, 'netmask', netmask)
    rc_conf_mod('jail_enable=YES')
    cmd(
        'mkdir', '-p', 
        '/var/mjail/instances/',
        '/var/mjail/releases/',
        '/var/mjail/generated_confs/'
    )
    cmd('chmod', '700', '/var/mjail/instances/', '/var/mjail/releases/')
    cmd('chmod', '755', '/var/mjail/', '/var/mjail/generated_confs/')
    try:
        jail_conf = jailconf.load('/etc/jail.conf')
    except FileNotFoundError:
        jail_conf = jailconf.JailConf()
    jail_conf['exec.start'] = '"/bin/sh /etc/rc"'
    jail_conf['exec.stop'] = '"/bin/sh /etc/rc.shutdown"'
    jail_conf['exec.clean'] = True
    jail_conf['mount.devfs'] = True
    jail_conf['path'] = '"/var/mjail/instances/$name"'
    jail_conf.write('/etc/jail.conf')
    release = Release()
    if not release.built():
        release.build()
    LocalUnboundManager.enable()
    PFManager.enable()
示例#2
0
    def _set_ip(self, ip, version, network):

        if ip not in network:
            raise ValueError("Can't assign this ip to the jail. "
                             "The ip should belong to the network %s" %
                             network)
        jail_conf = get_jail_conf()

        for jail_name, jail_block in jail_conf.jails():
            try:
                ip_addr = jail_block['ip%s.addr' % version]
            except KeyError:
                continue
            if ip_addr == str(ip):
                raise IPAlreadyRegistered
            elif isinstance(ip_addr, (list, tuple)):
                if str(ip) in ip_addr:
                    raise IPAlreadyRegistered

        jail_conf[self.name]['interface'] = cloned_if()
        jail_conf[self.name]['ip%s.addr' % version] = str(ip)

        jail_conf.write('/etc/jail.conf')

        self._update_resolv_conf()

        PFManager.refresh_anchor()

        line = '%s %s\n' % (str(ip), self.name)
        lines = open('/etc/hosts').readlines()
        if line not in lines:
            lines.append(line)
        temp_etc_hosts = to_tempfile(''.join(lines))
        shutil.move(temp_etc_hosts, '/etc/hosts')
示例#3
0
 def set_ip4(self, ip4):
     assert isinstance(ip4, IPv4Address)
     jail_conf = get_jail_conf()
     
     for jail_name, jail_block in jail_conf.jails():
         try:
             ip4_addr = jail_block['ip4.addr']
         except KeyError:
             continue
         if ip4_addr == str(ip4):
             raise IPAlreadyRegistered
         elif isinstance(ip4_addr, (list, tuple)):
             if str(ip4) in ip4_addr:
                 raise IPAlreadyRegistered
                     
     jail_conf[self.name]['interface'] = cloned_if()
     jail_conf[self.name]['ip4.addr'] = str(ip4)
     
     jail_conf.write('/etc/jail.conf')
     
     PFManager.refresh_anchor()
     
     line = '%s %s\n' % (str(ip4), self.name)
     lines = open('/etc/hosts').readlines()
     if line not in lines:
         lines.append(line)
     temp_etc_hosts = to_tempfile(''.join(lines))
     shutil.move(temp_etc_hosts, '/etc/hosts')
示例#4
0
def init(ip4_network: IPv4Network, ip6_network: IPv6Network):
    if not ip4_network.is_private:
        raise ValueError(
            "The network should be private. "
            "see https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses"
        )
    if not ip6_network.is_private or not ip6_network.prefixlen == 64:
        raise ValueError(
            "The network should be a private network as defined in https://tools.ietf.org/html/rfc4193.html"
        )
    check_compatibility()

    rc_conf_mod('cloned_interfaces+=%s' % cloned_if())
    cmd('service', 'netif', 'cloneup')

    address4 = str(ip4_network.network_address + 1)
    netmask = str(ip4_network.netmask)
    rc_conf_mod('ifconfig_%s=inet %s netmask %s' %
                (cloned_if(), address4, netmask))
    cmd('ifconfig', cloned_if(), 'inet', address4, 'netmask', netmask)

    address6 = str(ip6_network.network_address + 1)
    rc_conf_mod('ifconfig_%s_ipv6=inet6 %s prefixlen 64' %
                (cloned_if(), address6))
    cmd('ifconfig', cloned_if(), 'inet6', address6, 'prefixlen', '64')

    rc_conf_mod('jail_enable=YES')
    cmd('mkdir', '-p', '/var/mjail/instances/', '/var/mjail/releases/',
        '/var/mjail/generated_confs/')
    cmd('chmod', '700', '/var/mjail/instances/', '/var/mjail/releases/')
    cmd('chmod', '755', '/var/mjail/', '/var/mjail/generated_confs/')
    try:
        jail_conf = jailconf.load('/etc/jail.conf')
    except FileNotFoundError:
        jail_conf = jailconf.JailConf()
    jail_conf['exec.start'] = '"/bin/sh /etc/rc"'
    jail_conf['exec.stop'] = '"/bin/sh /etc/rc.shutdown"'
    jail_conf['exec.clean'] = True
    jail_conf['mount.devfs'] = True
    jail_conf['path'] = '"/var/mjail/instances/$name"'
    jail_conf.write('/etc/jail.conf')
    release = Release()
    if not release.built():
        release.build()
    LocalUnboundManager.enable()
    PFManager.enable()
示例#5
0
 def _anchor_conf(cls):
     ext_if = get_ext_if()
     filter_rules = []
     translation_rules = []
     jail_conf = get_jail_conf()
     jails = [
         jail_block
         for name, jail_block in jail_conf.jails()
         if (
             jail_block.get('$mjail_managed') == 'yes'
             and
             jail_block.get('ip4.addr')
         )
     ]
     cif = cloned_if()
     def append_jail_line(rules, jail, *strgs, **formats):
         for strg in strgs:
             rules.append(
                 strg.format(
                     ext_if = ext_if,
                     cif = cif,
                     ip4 = jail['ip4.addr'],
                     **formats
                 )
             )
     for jail in jails:
         append_jail_line(
             translation_rules,
             jail,
             'nat on {ext_if} inet from {ip4} to any -> ({ext_if})'
         )
         append_jail_line(
             filter_rules,
             jail,
             'pass quick on {cif} inet proto udp from {ip4} to ({cif}) port 53',
             'pass quick on {cif} inet proto tcp from {ip4} to ({cif}) port 53'
         )
         for key in jail:
             if key.startswith('$mjail_rdr_'):
                 proto, host_port = key[len('$mjail_rdr_'):].split('_')
                 assert proto in ('udp', 'tcp')
                 host_port = int(host_port)
                 jail_port = int(jail[key])
                 append_jail_line(
                     translation_rules,
                     jail,
                     'rdr pass on {ext_if} inet proto {proto} from any to ({ext_if}) port {host_port} -> {ip4} port {jail_port}',
                     proto = proto,
                     host_port = host_port,
                     jail_port = jail_port,
                 )
     filter_rules.append(
         'pass quick on {cif} from ({cif}) to ({cif}:network)'.format(cif = cif),
         # TODO: allow only the host to access the jails but not the jails between them?
         # (could be an option in `mjail init`)
     )
     ruleset = translation_rules + filter_rules + ['']
     return '\n'.join(ruleset)
示例#6
0
def jails_network4():
    try:
        cloned_if_params = output('sysrc', '-n', 'ifconfig_%s' % cloned_if())
    except CalledProcessError:
        raise NoIPv4JailNetwork
    else:
        gd = (re.match(
            r'^inet\s+(?P<inet>{ip_reg})\s+netmask\s+(?P<netmask>{ip_reg})'.
            format(ip_reg=_ip_reg), cloned_if_params).groupdict())
        return IPv4Network((gd['inet'], gd['netmask']), strict=False)
示例#7
0
def jails_network6():
    try:
        cloned_if_params = output('sysrc', '-n',
                                  'ifconfig_%s_ipv6' % cloned_if())
    except CalledProcessError:
        raise NoIPv6JailNetwork
    else:
        gd = (re.match(
            r'^inet6\s+(?P<inet6>{ip6_reg})\s+prefixlen\s+(?P<prefixlen>\d+)'.
            format(ip6_reg=_ip6_reg), cloned_if_params).groupdict())
        return IPv6Network(gd['inet6'] + '/' + gd['prefixlen'], strict=False)
示例#8
0
def interface_ip4():
    strg = output('sysrc', '-n', 'ifconfig_%s' % cloned_if()).strip() 
    return re.match(
        '^inet\s(?P<ip4>{ip_reg})\s*(netmask {ip_reg})?$'.format(ip_reg = _ip_reg),
        strg
    ).groupdict()['ip4']
示例#9
0
def interface_ip4():
    strg = output('sysrc', '-n', 'ifconfig_%s' % cloned_if()).strip()
    return re.match(
        r'^inet\s(?P<ip4>{ip_reg})\s*(netmask {ip_reg})?$'.format(
            ip_reg=_ip_reg), strg).groupdict()['ip4']
示例#10
0
    def _anchor_conf(cls):
        ext_if = get_ext_if()
        filter_rules = []
        translation_rules = []
        jail_conf = get_jail_conf()
        jails = [
            jail_block for name, jail_block in jail_conf.jails()
            if (jail_block.get('$mjail_managed') == 'yes' and (
                jail_block.get('ip4.addr') or jail_block.get('ip6.addr')))
        ]
        cif = cloned_if()
        ext_if_ip6s = external_interface_ip6s()

        def append_jail_line(rules, jail, *strgs, **formats):
            ips = {
                key: jail[jail_key]
                for key, jail_key in (('ip4', 'ip4.addr'), ('ip6', 'ip6.addr'))
                if jail_key in jail
            }

            for strg in strgs:
                rules.append(
                    strg.format(ext_if=ext_if, cif=cif, **ips, **formats))

        for jail in jails:
            if 'ip4.addr' in jail:
                append_jail_line(
                    translation_rules, jail,
                    'nat on {ext_if} inet from {ip4} to any -> ({ext_if})')
                append_jail_line(
                    filter_rules, jail,
                    'pass quick on {cif} inet proto udp from {ip4} to ({cif}) port 53',
                    'pass quick on {cif} inet proto tcp from {ip4} to ({cif}) port 53'
                )
            if 'ip6.addr' in jail:
                try:
                    ext_if_ip6 = ext_if_ip6s[0]
                except IndexError:
                    raise Exception(
                        "Couldn't find a global scope IPv6 address of the external interface"
                    )
                append_jail_line(
                    translation_rules, jail,
                    'nat on {ext_if} inet6 from {ip6} to any -> %s' %
                    ext_if_ip6)
                append_jail_line(
                    filter_rules, jail,
                    'pass quick on {cif} inet6 proto udp from {ip6} to ({cif}) port 53',
                    'pass quick on {cif} inet6 proto tcp from {ip6} to ({cif}) port 53'
                )
            for key in jail:
                if key.startswith('$mjail_rdr_'):
                    proto, host_port = key[len('$mjail_rdr_'):].split('_')
                    assert proto in ('udp', 'tcp')
                    host_port = int(host_port)
                    jail_port = int(jail[key])
                    if 'ip4.addr' in jail:
                        append_jail_line(
                            translation_rules,
                            jail,
                            'rdr pass on {ext_if} inet proto {proto} from any to ({ext_if}) port {host_port} -> {ip4} port {jail_port}',
                            proto=proto,
                            host_port=host_port,
                            jail_port=jail_port,
                        )
                    if 'ip6.addr' in jail:
                        if len(ext_if_ip6s) == 0:
                            raise Exception(
                                "Couldn't find a global scope IPv6 address of the external interface"
                            )
                        if len(ext_if_ip6s) > 1:
                            warnings.warn(
                                "The external interface has many global scope IPv6 addresses. "
                                "The port redirection from port {host_port} to jail {jail_name}:{jail_port} will only occur on "
                                "the address {ext_if_ip6} of the external interface."
                                .format(host_port=host_port,
                                        jail_name=jail.get(
                                            'host.hostname', ''),
                                        jail_port=jail_port,
                                        ext_if_ip6=ext_if_ip6s[0]))
                        append_jail_line(
                            translation_rules,
                            jail,
                            ('rdr pass on {ext_if} inet6 proto {proto} from any to %s port {host_port} -> {ip6} port {jail_port}'
                             % ext_if_ip6s[0]),
                            proto=proto,
                            host_port=host_port,
                            jail_port=jail_port,
                        )
        filter_rules.append(
            'pass quick on {cif} from ({cif}) to ({cif}:network)'.format(
                cif=cif),
            # TODO: allow only the host to access the jails but not the jails between them?
            # (could be an option in `mjail init`)
        )
        ruleset = translation_rules + filter_rules + ['']
        return '\n'.join(ruleset)