Go to main content

Securing Users and Processes in Oracle® Solaris 11.4

Exit Print View

Updated: November 2020

Locking Down Resources by Using Extended Privileges

Extended privilege policy can limit attacker access to a system when an attack on an application is successful. An extended policy rule limits the scope of the effect of a privilege assignment to just the resource that is in the rule. Extended policy rules are expressed by enclosing the privileges between curly braces, followed by a colon and the associated resource. For more discussion, see Expanding a User or Role's Privileges. For examples of the syntax, see the ppriv(1) and privileges(7) man pages.

Both administrators and regular users can lock down resources by using extended privileges. Administrators can create extended privilege rules for users, ports, and applications. Regular users can use the command line or write scripts that use the ppriv -r command to prevent applications from writing files outside of user-specified directories.

How to Apply Extended Privilege Policy to a Port

The service for the Network Time Protocol (NTP) uses the privileged port 123 for udp traffic. Privileges are required for this service to run. This example procedure modifies the service manifest to protect other ports from being accessed by a malicious user who might gain the privileges that are assigned to this port.

Before You Begin

You must assume the root role. For more information, see Using Your Assigned Administrative Rights.

  1. Read the default service manifest entry for the port.

    From the following /lib/svc/manifest/network/ntp.xml start method entry, the net_privaddr, proc_lock_memory, and sys_time privileges could be used on other processes:


    The removed privileges specified by !file_link_any,!proc_info,!proc_session prevent the service from signaling or observing any other processes, and from creating hard links as a way of renaming files. That is, the process that is started by the service is only able to bind to NTP's port 123, not to any of the other privileged ports.

    If a hacker could exploit the service to start another process, that process would be similarly limited.

  2. Modify the start and restart methods to limit the net_privaddr privilege to this port only.
    # svccfg -s ntp editprop -a
    1. Search for the string net_privaddr.
    2. Uncomment the entries that contain net_privaddr.
    3. In both entries, replace net_privaddr with {net_privaddr}:123/udp.

      The extended privilege policy removes all privileges from this service except the specified privileges plus the basic privileges that are not specified. Therefore, the set of over eighty potentially exploitable privileges is reduced to less than eight.

  3. Restart the service to use the extended privilege policy.
    # svcadm restart ntp
  4. Verify that the service is using extended privilege.
    # svcprop -s ntp | grep privileges
    start/privileges    astring  basic,!file_link_any,!proc_info,!proc_session,
    restart/privileges  astring  basic,!file_link_any,!proc_info,!proc_session,

How to Lock Down the MySQL Service

At installation, the MySQL database is configured to run with the full privileges of root over an unprotected port. In this task, you assign extended privilege policy to the MySQL service in a rights profile. After the rights profile becomes the exec method of the service, MySQL runs over a protected port as the user mysql with limited database access by non-MySQL processes.

Before You Begin

The initial user can install the package. The remaining steps must be performed by the root role. For more information, see Using Your Assigned Administrative Rights.

  1. Install the MySQL package.
    # pkg search basename:mysql
    basename ... pkg:/database/mysql-57@version
    # pfexec pkg install mysql-57
  2. Display the FMRI and state of the MySQL service.
    # svcs mysql
    STATE          STIME    FMRI
    disabled       May_15   svc:/application/database/mysql:version_57
  3. Create a rights profile that modifies the execution method of the service.

    The service manifest for this service specifies that the execution method is a shell script wrapper, /lib/svc/method/mysql_57.

    # svcprop -s mysql | grep manifest
    ... astring     /lib/svc/manifest/application/database/mysql_57.xml
    # grep exec= /lib/svc/manifest/application/database/mysql_57.xml
                    exec='/lib/svc/method/mysql_57 start'
                    exec='/lib/svc/method/mysql_57 stop'

    Use the /lib/svc/method/mysql_57 wrapper for the command in the profile.

    $ su -
    Password: xxxxxxxx
    # profiles -p "MySQL Service"
    MySQL Service> set desc="Locking down the MySQL Service"
    MySQL Service> add cmd=/lib/svc/method/mysql_57
    MySQL Service:mysql_57> set privs=basic
    MySQL Service:mysql_57> add privs={net_privaddr}:3306/tcp
    MySQL Service:mysql_57>  add privs={file_write}:/var/mysql/5.7/data/*
    MySQL Service:mysql_57>  add privs={file_write}:/tmp/mysql.sock
    MySQL Service:mysql_57>  add privs={file_write}:/var/tmp/ib*
    MySQL Service:mysql_57> end
    MySQL Service>  set uid=mysql
    MySQL Service>  set gid=mysql
    MySQL Service>  exit

    The file_write privilege is a basic privilege granted by default to all processes. By explicitly enumerating the writable paths, write access is restricted to just those paths. This constraint applies to the specified executable and its child processes.

  4. Make the default port for MySQL a privileged port.
    # ipadm set-prop -p extra_priv_ports+=3306 tcp
    # ipadm show-prop -p extra_priv_ports tcp
    tcp   extra_priv_ports    rw   2049,4045,  3306         2049,4045  1-65535

    The net_privaddr privilege is required to bind to a privileged port. In the case of MySQL, binding to the default port number, 3306, does not normally require this privilege.

  5. Assign the rights profile to the MySQL service and tell the service to use it.
    # svccfg -s mysql:version_57
    ...version_57> setprop method_context/profile="MySQL Service"
    ...version_57> setprop method_context/use_profile=true
    ...version_57> refresh
    ...version_57> exit
  6. Enable the service.

    The last component of the FMRI, mysql:version_57, is sufficient to uniquely specify the service.

    #  svcadm enable  mysql:version_57
  7. (Optional) Verify that the service is running with the rights that are specified in the MySQL Service rights profile.
    # ppriv $(pgrep mysql)
    103697:   /usr/mysql/5.7/bin/mysqld --basedir=/usr/mysql/5.7 
    flags =   PRIV_XPOLICY
          Extended policies:  
            E: basic,!file_write
            I: basic,!file_write
            P: basic,!file_write
            L: all
    103609:  /bin/sh /usr/mysql/5.7/bin/mysqld_safe --user=mysql 
    flags =  PRIV_XPOLICY
          Extended policies:
            E: basic,!file_write           
            I: basic,!file_write
            P: basic,!file_write
            L: all

How to Assign Specific Privileges to the Apache HTTP Server

This procedure locks down the web server daemon by assigning to it only the privileges it needs. The web server can only bind to port 80, and can only write to files that the webservd daemon owns. No apache24 service processes run as root.

Before You Begin

You must assume the root role. For more information, see Using Your Assigned Administrative Rights.

  1. Create the web server rights profile.
    # profiles -p "Apache2"
    profiles:Apache2> set desc="Apache HTTP Server Extended Privilege"
    profiles:Apache2> add cmd=/lib/svc/method/http-apache24
    profiles:Apache2:http-apache24> add privs={net_privaddr}:80/tcp
    ...http-apache24> add privs={zone}:/system/volatile/apache2
    ...http-apache24> add privs={zone}:/var/apache2/2.4/logs/*
    ...http-apache24> add privs={zone}:/var/user
    ...http-apache24> add privs={file_write}:/var/user/webserv*
    ...http-apache24> add privs={file_write}:/tmp/*
    ...http-apache24> add privs={file_write}:/system/volatile/apache*
    ...http-apache24> add privs={file_write}:/proc/*
    ...http-apache24> add privs=basic,proc_priocntl
    ...http-apache24> set uid=webservd
    ...http-apache24> set gid=webservd
    ...http-apache24> end
    ---Apache2> exit
  2. Add the rights profile to the apache24 SMF start method.
    # svccfg -s apache24
    svc:/network/http:Apache2> listprop start/exec
    start/exec	 astring	"/lib/svc/method/http-apache24 start"
    svc:/network/http:Apache2> setprop start/profile="Apache2"
    svc:/network/http:Apache2> setprop start/use_profile=true
    svc:/network/http:Apache2> refresh
    svc:/network/http:Apache2> exit

    When the apache24 service is enabled, the Apache2 profile will be used.

  3. Enable the apache24 service.
    # svcadm enable apache24
  4. Verify that web server is working.

    Open a browser and type localhost in the Firefox URL field.

Next Steps

To verify that the privileges are applied correctly, continue with How to Determine Which Privileges the Apache HTTP Server Is Using.

How to Determine Which Privileges the Apache HTTP Server Is Using

In this task, you determine which privileges the web server is using by creating a debug version of the Apache2 rights profile.

Before You Begin

You have completed How to Assign Specific Privileges to the Apache HTTP Server. The apache24 service is disabled. You are in the root role.

  1. Clone the Apache2 profile to call a different command.

    Debugging a command is simpler than debugging an SMF service. The apachectl command starts the Apache service interactively.

    # profiles -p "Apache2"
    profiles:Apache2> set name="Apache-debug"
    profiles:Apache-debug> sel <Tab><Tab>
    profiles:Apache-debug:http-apache24> set id=/usr/apache2/2.4/bin/apachectl
    profiles:Apache-debug:apachectl> end
    profiles:Apache-debug> exit

    For more information, see the apachectl(8) man page.

  2. Assign the cloned profile to the webservd account.
    # usermod -K profiles+=Apache-debug webservd
  3. Switch to the webservd identity.
    # su - webservd
  4. (Optional) Verify the identity.
    # id   
    uid=80(webservd) gid=80(webservd)
  5. Start the web service in debug mode in a profile shell.

    Do not use SMF directly. Use the command in the Apache-debug rights profile.

    $ pfbash
    # ppriv -De /usr/apache2/2.4/bin/apachectl start
  6. In the root role, examine the privileges of the first http daemon.
    # ppriv $(pgrep httpd|head -1)
    2999:   httpd
      5         Extended policies:
      6                 {net_privaddr}:80/tcp
      7                 {zone}:/system/volatile/apache2
      8                 {zone}:/var/apache2/2.4/logs/*
      9                 {zone}:/var/user
     10                 {file_write}:/var/user/webserv*
     11                 {file_write}:/tmp/*
     12                 {file_write}:/system/volatile/apache*
     13                 {file_write}:/proc/*
     14         E: basic,!file_write,!proc_info,proc_priocntl
     15         I: basic,!file_write,!proc_info,proc_priocntl
     16         P: basic,!file_write,!proc_info,proc_priocntl
     17         L: all