Configuring Zones on Solaris 11.3

    Introduction


    My first introduction to container virtualization was with jail in FreeBSD, this approach isolates various services in a secure environment. The disadvantage of jail is that there is no way to create your own network subsystem, unlike Zones Solaris. This publication will discuss the creation of a zone with its own network subsystem, as well as without it.

    Firewall


    As a “firewall”, a packet filter from OpenBSD will be used. Using a packet filter, nat from the zone with its own network subsystem will be implemented, as well as the network restrictions of the global zone. To install the packet filter and run, run the commands:

    pkg install firewall
    svcadm enable firewall
    

    Next, open the file with future rules:

    nano /etc/firewall/pf.conf
    

    in the nano editor add the following lines:

    table  {192.168.1.105,192.168.1.106}
    table  {192.168.0.0/24}
    pass quick on lo0 from any to any no state
    pass quick on vnic0 from any to any
    pass out quick on net0 from  to any nat-to (net0)
    pass in quick on net0 proto tcp from any to 192.168.1.105 port 80 rdr-to 192.168.0.2
    pass in quick on net0 proto tcp from any to  port=22 flags S/SA modulate state
    pass out quick on net0 proto tcp from  to any port {80,443,21,53} flags S/SA modulate state
    pass out quick on net0 proto udp from  to any port=53 keep state
    pass out quick on net0 proto icmp from  to any
    block from any to any fragment
    block from any to any
    block all
    

    Specify which file to use in the packet filter:

    pfctl -f /etc/firewall/pf.conf
    

    In this rule file, I have two tables with a list of ip addresses:

    table  {192.168.1.105,192.168.1.106}
    table  {192.168.0.0/24}
    

    The good table lists the ip addresses of the global zone and the zone that does not have its own network subsystem, if you plan to use several such zones, specify a list of ip addresses separated by a comma. Outgoing traffic will be allowed for these ip addresses, and it will also be possible to connect via ssh. If you plan to organize, for example, a web server in a global zone, or in a zone without a network subsystem, in this case you need to add the following line:

    pass in quick on net0 proto tcp from any to 192.168.1.106 port=80 flags S/SA modulate state
    

    Or a group of ports:

    pass in quick on net0 proto tcp from any to 192.168.1.106 port {80, 443, 21,22} flags S/SA modulate state
    

    In such cases, it is possible to make a connection through http, https, ftp, ssh.

    The nat table shows the subnet of the zone with its own network subsystem, if you plan several such networks, specify them separated by commas. In the line below, “netting” is performed through net0 of all subnets from the nat table.

    pass out quick on net0 from  to any nat-to (net0)
    

    A zone with its own network subsystem can be used as a DMZ , but for this it is necessary to forward the necessary ports, the next line forwards the port of the web server to zone 80, that is, all calls to ip 192.168.1.105 (global zone) will be redirected to ip 192.168.0.2:

    pass in quick on net0 proto tcp from any to 192.168.1.105 port 80 rdr-to 192.168.0.2
    

    It is also necessary to pay attention to the line:

    pass quick on vnic0 from any to any
    

    This line allows any traffic on the vnic0 virtual interface, this interface will act as a gateway. The ip address of this interface is 192.168.0.1, this interface will be active in the global zone, so it must be specified in the rules file. If you plan several gateways for different subnets, then in this case you need to add a similar line with the name of the virtual interface. For example, if you plan on another subnet 192.168.2.0/24 and assigned the adapter vnic5 ip (how to do this will be described in the next chapter) the address 192.168.2.1, then the line will look like this:

    pass quick on vnic5 from any to any
    

    Virtual interfaces that are created for a non-global zone do not need to be specified.

    Zone creation


    You can start this chapter by creating virtual interfaces, and you also need to allow packets to go between the interfaces net0 and vnic0:

    dladm create-vnic -l net0 vnic0
    dladm create-vnic -l net0 vnic1
    ipadm set-ifprop -p forwarding=on -m ipv4 net0
    ipadm set-ifprop -p forwarding=on -m ipv4 vnic0
    

    After creating it is necessary for vnic0 to create an ip address:

    ipadm create-ip vnic0
    ipadm create-addr -T static -a 192.168.0.1/24 vnic0/v4
    

    This is all with virtual interfaces, unless of course you need to create a few more subnets.

    The next step is to create a zfs pool for storing zones, create the pool from the image file:

    mkfile 10g /disk
    

    This command will create a file with a size of 10 gigabytes (specify the size you need), create a pool with the command:

    zpool create zones /disk
    

    Let's create two sections for future zones and assign each quota 5 gigabytes:

    zfs create zones/zone1
    zfs create zones/zone2
    zfs set quota=5g zones/zone1
    zfs set quota=5g zones/zone2
    

    At the time of this writing, Solaris 11.4 was a beta version, with this version added the ability to restrict (not applicable to version 11.3) reading and writing to the zfs partition:

    zfs set writelimit=50mb zones/zone1
    zfs set readlimit=50mb zones/zone2
    

    We proceed directly to the creation of the zone, initially create the zone without its own network subsystem, enter the command:

    zonecfg -z zone1
    

    After creating the basic parameters with the create command, the next step is to remove the anet parameter (contains the network name, mac address, mtu, and so on):

    remove anet
    

    Next, we indicate the path for the future zone, set the autostart of the zone and the type of ip address:

    set zonepath=/zones/zone1
    set autoboot=true
    set ip-type=shared
    

    Next, you need to create a network for the zone:

    add net
    

    The next step is to specify the physical interface and ip address for the zone, and exit the network settings (end):

    set physical=net0
    set address=192.168.1.106/24
    end
    

    Save the changes and exit zonecfg with the commands:

    commit
    exit
    

    Setting the zone occurs after the command:

     zoneadm -z zone1 install
    

    If the speed of access to the Internet is large enough, then the whole process will take no more than 5 minutes. After the zone is installed, it is necessary to start it and perform the initial configuration (hostname, dns, domain search, password for root, create an account), the configuration occurs in the same way as when installing the system. Execute the following commands (to start the zone and initial setup):

    zoneadm -z zone1 boot
    zlogin -C zone1
    

    Wait until the “setup wizard” appears. In the future, it is possible to connect to the zone with the command:

    zlogin zone1
    

    This completes the setup and installation of the zone. Setting up a zone with its own network subsystem is not much different from creating a normal zone, you only need to specify the type of ip address, specify the virtual adapter vnic1 (for which the ip address was not created), and also do not create an ip address for the zone network, ip address will be created when connecting to the zone for the first time (zlogin -C zone2). In order for everything to work correctly, according to this publication, you must specify the ip address 192.168.0.2.

    zonecfg -z zone2
    create
    remove anet
    set zonepath=/zones/zone2
    set autoboot=true
    set ip-type=exclusive
    add net
    set physical=vnic1
    end
    commit
    exit
    zoneadm -z zone2 install
    zoneadm -z zone2 boot
    zlogin -C zone2
    

    After the initial setup is complete, install apache, nano and packet filter, and also run apache and packet filter

    pkg install apache-24
    pkg install firewall
    pkg install nano
    svcadm enable apache24
    svcadm enable firewall
    

    Edit pf.conf:

    nano /etc/firewall/pf.conf
    

    In nano add the lines:

    ip=192.168.0.2
    pass in quick on vnic1 proto tcp from any to $ip port 80 flags S/SA modulate state
    pass out quick on vnic1 proto tcp from $ip to any port {80,443,21,53} flags S/SA modulate state
    pass out quick on vnic1 proto udp from $ip to any port=53 keep state
    pass out quick on vnic1 proto icmp from $ip to any
    block from any to any fragment
    block from any to any
    block all
    

    Specify which file to use in the packet filter:

    pfctl -f /etc/firewall/pf.conf
    

    In this example, the variable $ ip is used, if you specified a different ip address, then just change the first line to the correct address.

    Additionally


    The final chapter will focus on zone restrictions, mounting folders, as well as extended zone permissions. Suppose you need to mount a certain directory from the global zone, for this select the necessary zone:

    zonecfg -z zone1
    

    Next, add the file system:

    add fs
    

    Specify the directory in the global zone (for example, the / test directory):

    set special=/test
    

    Indicate where you want to mount it:

    set dir=/usr/test
    

    The file system type is loopback:

    set type=lofs
    

    We set the permissions on the directory as read-only (if necessary, specify rw for writing, or do not add this parameter at all):

    add options [ro,nodevices]
    

    Exit the file system settings and save the changes:

    end
    commit
    exit
    

    You can also mount the zfs section:

    add dataset
    set name=rpool/export/home
    end
    commit
    

    Restart the zone:

    zoneadm -z zone1 reboot
    

    Now let's limit the RAM, swap and processor usage, select the necessary zone:

    zonecfg -z zone1
    

    Add memory limits:

    add capped-memory
    

    Limit RAM to 1 gigabyte, and swap to 500 megabytes:

    set physical=1024m
    set swap=500m
    end
    commit
    

    Limit the use of each processor core by 30 percent:

    add capped-cpu
    set ncpus=.30
    end
    commit
    

    The final touch, add the default privilege zone, a list of all privileges can be viewed by running the command:

    ppriv -l -v
    

    You can familiarize yourself with the privileges that are used by default (and also which can be added if necessary) in this guide . You can add privileges with the following command (from zonecfg):

    set limitpriv="default,sys_time"
    

    As indicated in this guide , this line will set privileges by default and also allow you to change the system time from a non-global zone. In my opinion, it is better not to add additional privileges for a zone, since a zone with a small number of privileges is more limited in functionality, and therefore more protected.

    Conclusion


    As you can see from this publication, the zones are quite easy to configure, but at the same time they provide a high level of protection (especially zones with their own network subsystem) in conjunction with a packet filter configured to the “everything that is not allowed” policy is disabled. Configuration and deployment takes a minimum of effort in time.

    List of sources that helped me write this publication.

    Zones

    packet filter

    Also popular now: