Beginning in Streams 4.0.0, there are a couple of security enhancements relating to Streams jobs and their corresponding PE processes.  The first enhancement is the ability to have all jobs within a Streams instance run as a configured user, rather than the default of running the jobs under the user that started the domain and instance.  This can be very useful in many scenarios such as applications that require special OS privileges, or even scenarios where you want to have the Streams jobs run as a user with reduced privileges.  To take advantage of this new support, there are a few domain and instance management setup rules that need to be followed.

Note:  streamtool commands require a ZooKeeper connection string parameter as well, but these examples assume the STREAMS_ZKCONNECT environment variable was set accordingly.  The same can be done for the domain name by setting the STREAMS_DOMAIN_ID environment variable.

Running Streams Domain Controller as System Services

To run Streams jobs and PEs with these advanced security settings, Streams Domain Controller services must be run as system services.  Follow these steps:

  1. Install the Streams product as root (or as normal Streams administrative user) into an install path where all your desired Streams job users are authorized to the entire install path.  This means these users need to have execute (“x” flag) authority to every individual level of the root install path, and read and execute (“r” and “x” flags) for the IBM Streams portion of the install path. Installing as root user into the default /opt/ibm installation directory typically sets this all up correctly. If you install as a user into a user home directory, its very possible or likely that the “x” flag isn’t enabled for other users, and you will encounter errors as you proceed.
  2. Running as root user, source streamsprofile.sh and run:
    streamtool registerdomainhost -d <domain_name>

    This sets up your Streams domain controller as a system service.  Additional details for setting up an enterprise production domain with high availability can be found here.  This step can optionally be performed after step 3, with the only restriction being it must be performed before the domain is started.

  3. Running as your Streams administrative user, source streamsprofile.sh and run “streamtool mkdomain -d <domain_name>”  (creating the same domain that you used for registerdomainhost).
  4. Optionally run “streamtool genkey” so you don’t have to enter credentials for further streamtool commands.
  5. Run "streamtool adduserdomainrole -d <domain_name> DomainUser <user_name>" to give the user authorization to the domain and instances.
  6. Start the domain using "streamtool start domain"
  7. Verify the Streams domain controller started as a system service by running "streamtool getdomainstate –long". The controller service should show its running as a system service, along with the process ID of the service.  For example: controller(28062:system)

Running Job as Configured User

By default, when a job is submitted, the processes are run using the Instance Owner credential.  Follow the these steps to configure the instance to run jobs as a different user:

  1. Create an instance using the following command:
    streamtool mkinstance -i myinst --property instance.runAsUser=myinstuser

    Setting the instance.runAsUser property to the user you wish to use for running Streams jobs.  Additional properties and resource definitions will typically need to be added to the mkinstance command.  In Streams 4.0.0.1, the instance.runAsUser user must be in the primary group of the domain owner. In 4.0.1.0 and later, any user can be specified as long as they have access to the installation image.

  2. Start the instance using “streamtool start instance“.
  3. To verify the instance.runAsUser is being used correctly, go to the logs directory for the domain and check if the log files are owned by the instance.runAsUser. Typically the logs directory is located at /tmp/Streams-<domainname>/logs/<hostname>/instances/<instancename>.
  4. Alternatively, you can also do a “ps aux | grep streams-sam” and make sure the Streams application management process is running as the correct instance.runAsUser.
  5. For the application you want to submit, make sure the application does not have any paths referenced that point to a file system location that the instance.runAsUser is not authorized to. If this occurs, you will have PE processes that will never go healthy. You can “debug” this by setting instanceTrace.defaultLevel=trace, submit the job, and check the pec logs for PE processes that don’t go healthy.

Running PE with Special Operating System Capabilities

A second security enhancement that was changed in Streams 4.0.0 and beyond, is how an administrator and developer tag team to provide the ability for operators within a Streams application to run with special operating system capabilities.  Using special capabilities can be necessary in cases where a Streams application needs to access a protected system resource, for example a network adapter.  To enable this support for an operator with a Streams job, you need to do the following:

  1. Read the security information for Linux users and Infosphere Streams jobs and the Linux man pages for capabilities.
  2. Add a capability element to the contextType definition of your operator.  Any Linux capability can be added to the XML definition of the operator. For Example:
    <context>
      <providesSingleThreadedContext>Never</providesSingleThreadedContext>
       <capability>CAP_NET_RAW+eip CAP_NET_ADMIN+eip</capability>
    </context>
  3. Build your application using the Streams’ compiler’s -s (–static-link) option.  The special capability functionality is only supported when running a statically linked Streams application.
  4. Follow steps above to run the domain controller services as system services.  It is crucial that the domain controller services on all hosts are running as system services. If this is not done, the special capabilities can not be set on the application executable.
  5. When creating a streams instance, specify the canSetPeOSCapabilities to true.  For example, make a streams instance using this command:
    streamtool mkinstance -i myinst --property instance.canSetPeOSCapabilities=true
  6. Verify the domain.applicationBundlesPath and instance.applicationBundlesPath are not set to a path in a network file system.  By default these paths are set to point to a local file system directory, so if you haven’t explicitly set them, the values should be fine.  If they are set to a path in a network file system, you will need to change at least this instance’s instance.applicationBundlesPath to point to a local file system path.

Join The Discussion