Пример #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 enable(cls):
     cmd('mkdir', '-p', cls._conf_dir)
     temp_path = to_tempfile(
         cls._conf(),
         prefix = cls._conf_file
     )
     os.rename(temp_path, cls._conf_file)
     cmd('local-unbound-setup', '-C', cls._conf_dir)
Пример #3
0
    def enable(cls):
        #rc_conf_mod('gateway_enable=YES')
        #rc_conf_mod('net.inet.ip.forwarding=1')
        pf_conf_path = cls.pf_conf_path()
        try:
            pf_conf = [
                line.rstrip() for line in open(pf_conf_path).readlines()
                if not line.endswith(cls._comment + "\n")
            ]
        except FileNotFoundError:
            pf_conf = []
        start, translation_rules, filter_rules = pf_conf_split(pf_conf)
        new_conf = (start + [
            cls._load_anchor, cls._insert_anchor_nat, cls._insert_anchor_rdr
        ] + translation_rules + filter_rules + [cls._insert_anchor_filter])
        new_conf = '\n'.join(new_conf)
        if not new_conf.endswith(
                '\n'):  # required by the pf configuration parser
            new_conf += '\n'
        cmd('mkdir', '-p', os.path.dirname(cls._anchor_conf_file))
        if not os.path.exists(cls._anchor_conf_file):
            cls.overwrite_anchor_conf()
        temp_path = to_tempfile(new_conf, prefix=pf_conf_path)
        cmd('pfctl', '-vnf', temp_path
            )  # checking the new conf before replacing the old conf with it
        os.rename(temp_path, pf_conf_path)

        if pf_is_running():
            cmd('pfctl', '-f', pf_conf_path)
        else:
            rc_conf_mod('pf_enable=YES')
            rc_conf_mod('pf_rules=%s' % pf_conf_path)
            cmd('service', 'pf', 'start')
Пример #4
0
 def disable(cls):
     pf_conf_path = cls.pf_conf_path()
     try:
         pf_conf = [
             line for line in open(pf_conf_path).readlines()
             if not line.endswith(cls._comment + "\n")
         ]
     except FileNotFoundError:
         pass
     else:
         new_conf = ''.join(pf_conf)
         if not new_conf.endswith('\n'):
             new_conf += '\n'
         temp_path = to_tempfile(new_conf, prefix=pf_conf_path)
         cmd('pfctl', '-vnf', temp_path)
         os.rename(temp_path, pf_conf_path)
         if pf_is_running():
             cmd('pfctl' '-f', pf_conf_path)
Пример #5
0
 def minor_upgrade(self, to_version, unattended=False):
     # this function would need to be tested
     freebsd_update_conf = to_tempfile(''.join(
         (re.sub(r'(?<=\b)kernel(?=\b)', '', line) if re.
          match(r'^Components\s', line) else line)
         for line in open('/etc/freebsd-update.conf').readlines()))
     try:
         jail_conf = get_jail_conf()
         currently_running = jail_conf[
             self.name]['$mjail_currently_running_release']
         to_version_major = to_version.split('.')[0]
         running_major = currently_running.split('.')[0]
         if to_version_major != running_major:
             raise Exception(
                 "Can't upgrade from %s to %s. Only minor version upgrade is supported at the moment."
                 % (running_major, to_version_major))
         env = os.environ.copy()
         if unattended:
             env['PAGER'] = 'cat'
         cmd('freebsd-update',
             '-b',
             self.directory,
             '-f',
             freebsd_update_conf,
             '-r',
             to_version,
             'upgrade',
             'install',
             '--currently-running',
             currently_running,
             env=env)
         for _ in range(2):
             cmd('freebsd-update',
                 '-b',
                 self.directory,
                 '-f',
                 freebsd_update_conf,
                 'install',
                 env=env)
         jail_conf[
             self.name]['$mjail_currently_running_release'] = to_version
         jail_conf.write('/etc/jail.conf')
     finally:
         os.remove(freebsd_update_conf)
Пример #6
0
 def disable(cls):
     pf_conf_path = cls.pf_conf_path()
     try:
         pf_conf = [
             line
             for line in open(pf_conf_path).readlines()
             if not line.endswith(cls._comment + "\n")
         ]
     except FileNotFoundError:
         pass
     else:
         new_conf = ''.join(pf_conf)
         if not new_conf.endswith('\n'):
             new_conf += '\n'
         temp_path = to_tempfile(new_conf, prefix = pf_conf_path)
         cmd('pfctl', '-vnf', temp_path)
         os.rename(temp_path, pf_conf_path)
         if pf_is_running():
              cmd('pfctl' '-f', pf_conf_path)
Пример #7
0
 def build(self):
     components = ['base.txz', 'lib32.txz']
     if int(re.match(r'^\d+', self._release).group(0)) < 12: # There's no longer a doc.txz in FreeBSD 12
         components.append('doc.txz')
     cmd('mkdir', '-p', self.directory)
     with TemporaryDirectory() as tempdir:
         with cd(tempdir):
             for component in components:
                 cmd('fetch', self._component_url(component), '-o', component)
                 cmd('tar', 'xvf', component, '-C', self.directory)
             freebsd_update(self.directory, unattended = True)
             cmd(
                 'freebsd-update', '-b', self.directory, 'IDS',
             )
Пример #8
0
 def delete(self):
     cmd('service', 'jail', 'stop', self.name)
     jail_conf = get_jail_conf()
     try:
         jail_block = jail_conf[self.name]
     except KeyError:
         pass
     else:
         try:
             ip4 = jail_block['ip4.addr']
         except KeyError:
             pass
         else:
             assert isinstance(ip4, str) # list of ips not yet supported by mjail
             line = '%s %s\n' % (ip4, self.name)
             lines = [l for l in open('/etc/hosts').readlines() if l != line]
             temp_etc_hosts = to_tempfile(''.join(lines))
             shutil.move(temp_etc_hosts, '/etc/hosts')    
         del jail_conf[self.name]
         jail_conf.write('/etc/jail.conf')
         
     if os.path.exists(self.directory):
         cmd('chflags', '-R', 'noschg', self.directory)
         cmd('rm', '-rf', self.directory)
     PFManager.refresh_anchor()
Пример #9
0
    def delete(self):
        cmd('service', 'jail', 'stop', self.name)
        jail_conf = get_jail_conf()
        try:
            jail_block = jail_conf[self.name]
        except KeyError:
            pass
        else:
            for version in (4, 6):
                try:
                    ip = jail_block['ip%s.addr' % version]
                except KeyError:
                    pass
                else:
                    assert isinstance(
                        ip, str)  # list of ips not yet supported by mjail
                    line = '%s %s\n' % (ip, self.name)
                    lines = [
                        l for l in open('/etc/hosts').readlines() if l != line
                    ]
                    temp_etc_hosts = to_tempfile(''.join(lines))
                    shutil.move(temp_etc_hosts, '/etc/hosts')
            del jail_conf[self.name]
            jail_conf.write('/etc/jail.conf')

        if os.path.exists(self.directory):
            cmd('chflags', '-R', 'noschg', self.directory)
            cmd('rm', '-rf', self.directory)
        PFManager.refresh_anchor()
Пример #10
0
 def minor_upgrade(self, to_version, unattended = False):
     # this function would need to be tested
     freebsd_update_conf = to_tempfile(
         ''.join(
             (re.sub(r'(?<=\b)kernel(?=\b)', '', line) if re.match(r'^Components\s', line) else line)
             for line in
             open('/etc/freebsd-update.conf').readlines()
         )
     )
     try:
         jail_conf = get_jail_conf()
         currently_running = jail_conf[self.name]['$mjail_currently_running_release']
         to_version_major = to_version.split('.')[0]
         running_major = currently_running.split('.')[0]
         if to_version_major != running_major:
             raise Exception(
                 "Can't upgrade from %s to %s. Only minor version upgrade is supported at the moment." % (
                     running_major, to_version_major
                 )
             )
         env = os.environ.copy()
         if unattended:
             env['PAGER'] = 'cat'
         cmd('freebsd-update',
             '-b', self.directory,
             '-f', freebsd_update_conf,
             '-r', to_version, 'upgrade', 'install', '--currently-running', currently_running,
             env = env
         )
         for _ in range(2):
             cmd('freebsd-update',
                 '-b', self.directory,
                 '-f', freebsd_update_conf,
                 'install',
                 env = env
             )
         jail_conf[self.name]['$mjail_currently_running_release'] = to_version
         jail_conf.write('/etc/jail.conf')
     finally:
         os.remove(freebsd_update_conf)
Пример #11
0
    def create(self):
        release = Release()
        if not release.built():
            release.build()

        if os.path.exists(self.directory):
            raise JailAlreadyExists(self.name)

        cmd('cp', '-R', '-v', release.directory, self.directory)

        jail_conf = get_jail_conf()

        if self.name in jail_conf:
            raise JailAlreadyExists(self.name)

        jail_conf[self.name] = jailconf.JailBlock([
            ('$mjail_managed', 'yes'),
            ('$mjail_currently_running_release', str(release)),
            ('host.hostname', self.name)
        ])

        jail_conf.write('/etc/jail.conf')
Пример #12
0
 def ssh_box(self, public_key, internet_facing_port, jail_port=22):
     internet_facing_port = int(internet_facing_port)
     host_sshd_conf = SSHDConf('/etc/ssh/sshd_config')
     if internet_facing_port == int(host_sshd_conf.get('Port', '22')):
         raise ValueError("This port is the ssh port used by the host.")
     root_ssh_dir = os.path.join(self.directory, 'root', '.ssh')
     authorized_keys_file = os.path.join(root_ssh_dir, 'authorized_keys')
     os.makedirs(root_ssh_dir, exist_ok=True)
     cmd('chmod', '700', root_ssh_dir)
     with open(authorized_keys_file, "w") as fp:
         fp.write(public_key)
     cmd('chmod', '600', authorized_keys_file)
     s_conf = SSHDConf(os.path.join(self.directory, 'etc/ssh/sshd_config'))
     for option, value in (('PermitRootLogin', 'prohibit-password'),
                           ('RSAAuthentication',
                            'yes'), ('PubkeyAuthentication', 'yes'),
                           ('PasswordAuthentication',
                            'no'), ('Port', str(jail_port))):
         s_conf.set_option(option, value)
     s_conf.overwrite()
     rc_conf_mod('sshd_enable=YES',
                 f=os.path.join(self.directory, 'etc/rc.conf'))
     self.rdr('tcp', internet_facing_port, jail_port)
Пример #13
0
 def create(self):
     release = Release()
     if not release.built():
         release.build()
     
     if os.path.exists(self.directory):
         raise JailAlreadyExists(self.name)
         
     cmd('cp', '-R', '-v', release.directory, self.directory)
     with open(os.path.join(self.directory, 'etc', 'resolv.conf'), "w") as fp:
         fp.write("nameserver %s\n" % str(jails_network4().network_address + 1))
     
     jail_conf = get_jail_conf()
     
     if self.name in jail_conf:
         raise JailAlreadyExists(self.name)
         
     jail_conf[self.name] = jailconf.JailBlock([
         ('$mjail_managed', 'yes'),
         ('$mjail_currently_running_release', str(release)),
         ('host.hostname', self.name)
     ])
     
     jail_conf.write('/etc/jail.conf')
Пример #14
0
 def ssh_box(self, public_key, internet_facing_port, jail_port = 22):
     internet_facing_port = int(internet_facing_port)
     host_sshd_conf = SSHDConf('/etc/ssh/sshd_config')
     if internet_facing_port == int(host_sshd_conf.get('Port', '22')):
         raise ValueError("This port is the ssh port used by the host.")
     root_ssh_dir = os.path.join(self.directory, 'root', '.ssh')
     authorized_keys_file = os.path.join(root_ssh_dir, 'authorized_keys')
     os.makedirs(root_ssh_dir, exist_ok = True)
     cmd('chmod', '700', root_ssh_dir) 
     with open(authorized_keys_file, "w") as fp:
         fp.write(public_key)
     cmd('chmod', '600', authorized_keys_file)
     s_conf = SSHDConf(os.path.join(self.directory, 'etc/ssh/sshd_config'))
     for option, value in (
         ('PermitRootLogin', 'prohibit-password'),  
         ('RSAAuthentication', 'yes'),
         ('PubkeyAuthentication', 'yes'),
         ('PasswordAuthentication', 'no'),
         ('Port', str(jail_port))
     ):
         s_conf.set_option(option, value)
     s_conf.overwrite()
     rc_conf_mod('sshd_enable=YES', f = os.path.join(self.directory, 'etc/rc.conf'))
     self.rdr('tcp', internet_facing_port, jail_port)
Пример #15
0
 def build(self):
     components = ['base.txz', 'lib32.txz']
     if int(re.match(r'^\d+', self._release).group(
             0)) < 12:  # There's no longer a doc.txz in FreeBSD 12
         components.append('doc.txz')
     cmd('mkdir', '-p', self.directory)
     with TemporaryDirectory() as tempdir:
         with cd(tempdir):
             for component in components:
                 cmd('fetch', self._component_url(component), '-o',
                     component)
                 cmd('tar', 'xvf', component, '-C', self.directory)
             freebsd_update(self.directory, unattended=True)
             cmd(
                 'freebsd-update',
                 '-b',
                 self.directory,
                 'IDS',
             )
Пример #16
0
 def enable(cls):
     #rc_conf_mod('gateway_enable=YES')
     #rc_conf_mod('net.inet.ip.forwarding=1')
     pf_conf_path = cls.pf_conf_path()
     try:
         pf_conf = [
             line.rstrip()
             for line in open(pf_conf_path).readlines()
             if not line.endswith(cls._comment + "\n")
         ]
     except FileNotFoundError:
         pf_conf = []
     start, translation_rules, filter_rules = pf_conf_split(pf_conf)
     new_conf = (
         start
         +
         [cls._load_anchor, cls._insert_anchor_nat, cls._insert_anchor_rdr]
         +
         translation_rules
         +
         filter_rules
         +
         [cls._insert_anchor_filter]
     )
     new_conf = '\n'.join(new_conf)
     if not new_conf.endswith('\n'): # required by the pf configuration parser
         new_conf += '\n'
     cmd('mkdir', '-p', os.path.dirname(cls._anchor_conf_file))
     if not os.path.exists(cls._anchor_conf_file):
         cls.overwrite_anchor_conf()
     temp_path = to_tempfile(new_conf, prefix = pf_conf_path)
     cmd('pfctl', '-vnf', temp_path) # checking the new conf before replacing the old conf with it
     os.rename(temp_path, pf_conf_path)
     
     if pf_is_running():
         cmd('pfctl', '-f', pf_conf_path)
     else:
         rc_conf_mod('pf_enable=YES')
         rc_conf_mod('pf_rules=%s' % pf_conf_path)
         cmd('service', 'pf', 'start')
Пример #17
0
def freebsd_update(directory, unattended):
    if unattended:
        env = os.environ.copy()
        env['PAGER'] = 'cat'
        cmd('freebsd-update', '-b', directory, 'fetch', env=env)
        try:
            cmd('freebsd-update', '-b', directory, 'install', env=env)
        except CalledProcessError as exc:
            if exc.returncode == 1:  # FreeBSD offers no way to tell if that's because there was no update to install
                pass  # or if it comes from another problem
            else:
                raise
    else:
        cmd('freebsd-update', '-b', directory, 'fetch', 'install')
Пример #18
0
def freebsd_update(directory, unattended):
    if unattended:
        env = os.environ.copy()
        env['PAGER'] = 'cat'
        cmd(
            'freebsd-update', '-b', directory, 'fetch',
            env = env   
        )
        try:
            cmd(
                'freebsd-update', '-b', directory, 'install',
                env = env
            )
        except CalledProcessError as exc:
            if exc.returncode == 1: # FreeBSD offers no way to tell if that's because there was no update to install
                pass                # or if it comes from another problem
            else:
                raise
    else:
        cmd('freebsd-update', '-b', directory, 'fetch', 'install')
Пример #19
0
 def overwrite_anchor_conf(cls):
     temp_path = to_tempfile(cls._anchor_conf(),
                             prefix=cls._anchor_conf_file)
     cmd('pfctl', '-vnf', temp_path)
     os.rename(temp_path, cls._anchor_conf_file)
Пример #20
0
 def start(self):
     cmd('service', 'jail', 'start', self.name)
Пример #21
0
 def execute(self, command, *args):
     cmd('jexec', self.name, command, *args)
Пример #22
0
 def stop(self):
     cmd('service', 'jail', 'stop', self.name)
Пример #23
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()
Пример #24
0
 def stop(self):
     cmd('service', 'jail', 'stop', self.name)
Пример #25
0
 def start(self):
     cmd('service', 'jail', 'start', self.name)
Пример #26
0
 def execute(self, command, *args):
     cmd('jexec', self.name, command, *args)
Пример #27
0
 def refresh_anchor(cls):
     cls.overwrite_anchor_conf()
     cmd('pfctl', '-a', 'mjail', '-F', 'all', '-f', cls._anchor_conf_file)
Пример #28
0
 def enable(cls):
     cmd('mkdir', '-p', cls._conf_dir)
     temp_path = to_tempfile(cls._conf(), prefix=cls._conf_file)
     os.rename(temp_path, cls._conf_file)
     cmd('local-unbound-setup', '-C', cls._conf_dir)
Пример #29
0
 def overwrite_anchor_conf(cls):
     temp_path = to_tempfile(cls._anchor_conf(), prefix = cls._anchor_conf_file)
     cmd('pfctl', '-vnf', temp_path)
     os.rename(temp_path, cls._anchor_conf_file)
Пример #30
0
 def refresh_anchor(cls):
     cls.overwrite_anchor_conf()
     cmd('pfctl', '-a', 'mjail', '-F', 'all', '-f',  cls._anchor_conf_file)