How To
Summary
This tutorial will outline how to run commands as the root (sudo) user at app startup.
Steps
In this tutorial we will set up a simple QRadar app that will display a list of UNIX users in the QRadar app's container. At startup we will add a new user called testuser
that will appear in the UNIX user list - using the adduser
command. The adduser
command requires sudo priviledges, and as such will require use of the as_root
feature.
Please note that running commands/doing work at app startup is discouraged, instead apps should run commands/do work at image build time.
Prerequisites
This tutorial requires the following dependencies:
- QRadar App SDK v2
Create the App
Create a new folder for the app:
mkdir AsRootApp && cd AsRootApp
Use the QRadar App SDK to initialise the app code:
qapp create
Write the Manifest
Open the manifest.json
file to edit some values to make it more relevant to the app, making it look like this:
{
"name": "As Root",
"description": "App showing using the as_root feature",
"version": "1.0",
"image": "qradar-app-base:2.0.0",
"areas": [
{
"id": "QAsRoot",
"text": "As Root",
"description": "As Root area showing list of all UNIX users",
"url": "index",
"required_capabilities": []
}
],
"uuid": "<your unique app UUID>"
}
This manifest defines an area called QAsRoot
that will serve the app user interface.
Write the Jinja Template
Delete app/templates/hello.html
and create a new file app/templates/users.html
:
<!DOCTYPE html>
<html>
<head>
<title>As Root</title>
</head>
<body>
<p id="description">
This app has added a new user called 'testuser' using 'as_root', the UNIX users in the app container are:
</p>
<ul id="user-list">
{% for user in users %}
<li>{{user}}</li>
{% endfor %}
</ul>
</body>
</html>
This Jinja template provides the entire user interface for the app, primarily displaying all UNIX users in the app's Docker container in a list.
Create the App Endpoint
Add the app HTTP endpoints by editing app/views.py
:
import pwd
from flask import Blueprint, render_template
# pylint: disable=invalid-name
viewsbp = Blueprint('viewsbp', __name__, url_prefix='/')
# Simple endpoint that renders and serves 'users.html', displaying all UNIX
# users on the system
@viewsbp.route('/')
@viewsbp.route('/index')
def users():
# Get all UNIX users and store their names in a list
user_list = []
for user in pwd.getpwall():
user_list.append(user[0])
# Render users.html using the retrieved user list
return render_template('users.html', users=user_list)
This sets up the app endpoint to retrieve the list of UNIX users and then injects the user list into the Jinja template.
Write the Create User Startup Script
Add a new script container/run/add_user.sh
:
# Create a new user called 'testuser', with a home directory (/home/testuser)
as_root adduser testuser -m
And add a new file container/run/ordering.txt
:
/opt/app-root/container/run/add_user.sh
These two files define the startup behaviour of the app, with ordering.txt
pointing to the file to execute on startup, in our case add_user.sh
, and add_user.sh
adding a new user called testuser
.
The add_user.sh
script uses the as_root
feature, which allows apps to run commands as the root (sudo) user at startup.
Test the app locally
The app is now ready to test out, which can be done by running the app locally using the QRadar App SDK:
qapp run
The QRadar App SDK will report the port that the app is running on, allowing you to access the app at http://localhost:<app port>
.
as_root
The as_root
feature allows app developers the ability to run commands as the root user at app startup.
Limitations
The as_root
option is only available at app start up, if it is used during normal runtime operation it will fail.
Considerations
The as_root
option should only be used when necessary, and is subject to strict validation (on submission to X-Force Exchange) - there should be a justified and necessary reason for using it.
Document Location
Worldwide
Was this topic helpful?
Document Information
Modified date:
30 March 2021
UID
ibm16437471