728x90

You can use the Wowza Streaming Engine™ REST API to create and manage applications in Wowza Streaming Engine media server software. This Quick Start article shows how to use cURL to query the REST API to create and manage a live streaming application.

Notes:

Contents


Create an application
Update an application's settings
Add custom properties to an application
Restart an application
Get a list of applications

Create an application


Create an application (named testlive) for live streaming with Wowza Streaming Engine default settings:

curl - X POST --header 'Accept:application/json; charset=utf-8' --header 'Content-Type:application/json; charset=utf-8' http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive -d'
{
   "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive",
   "name": "testlive",
   "appType": "Live",
   "clientStreamReadAccess": "*",
   "clientStreamWriteAccess": "*",
   "description": "A basic live application",
   "streamConfig": {
      "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/streamconfiguration",
      "streamType": "live"
   }
}
'

The command should return a response that looks something like this:

{
   "success": true,
   "message": "Application (testlive) created successfully."
}

You could also create the application testlive with password authentication by adding securityConfig and ModuleCoreSecurity to the request:

curl -X POST --header 'Accept:application/json; charset=utf-8' --header 'Content-Type:application/json; charset=utf-8' http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive -d'
{
   "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive",
   "name": "testlive",
   "appType": "Live",
   "description": "A live application with password authentication",
   "streamConfig": {
      "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/streamconfiguration",
      "streamType": "live"
   },
   "securityConfig": {
      "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/security",
      "secureTokenVersion": 0,
      "clientStreamWriteAccess": "*",
      "publishRequirePassword": true,
      "publishPasswordFile": "",
      "publishRTMPSecureURL": "",
      "publishIPBlackList": "",
      "publishIPWhiteList": "",
      "publishBlockDuplicateStreamNames": false,
      "publishValidEncoders": "",
      "publishAuthenticationMethod": "digest",
      "playMaximumConnections": 0,
      "playRequireSecureConnection": false,
      "secureTokenSharedSecret": "",
      "secureTokenUseTEAForRTMP": false,
      "secureTokenIncludeClientIPInHash": false,
      "secureTokenHashAlgorithm": "",
      "secureTokenQueryParametersPrefix": "",
      "secureTokenOriginSharedSecret": "",
      "playIPBlackList": "",
      "playIPWhiteList": "",
      "playAuthenticationMethod": "none"
   },
   "modules": {
      "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/modules",
      "moduleList": [{
          "order": 0,
          "name": "base",
          "description": "Base",
          "class": "com.wowza.wms.module.ModuleCore"
      }, {
         "order": 1,
          "name": "logging",
          "description": "Client Logging",
          "class": "com.wowza.wms.module.ModuleClientLogging"
      }, {
          "order": 2,
          "name": "flvplayback",
          "description": "FLVPlayback",
          "class": "com.wowza.wms.module.ModuleFLVPlayback"
      }, {
          "order": 3,
          "name": "ModuleCoreSecurity",
          "description": "Core Security Module for Applications",
          "class": "com.wowza.wms.security.ModuleCoreSecurity"
      }]
   }
}
'

Here's how you would create the application testlive with password authentication and three live stream packetizers enabled:

curl -X POST --header 'Accept:application/json; charset=utf-8' --header 'Content-Type:application/json; charset=utf-8' http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive -d'
{
   "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive",
   "name": "testlive",
   "appType": "Live",
   "description": "A live application with password authentication and packetizers",
   "streamConfig": {
      "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/streamconfiguration",
      "streamType": "live",
     "liveStreamPacketizer": [
         "cupertinostreamingpacketizer",
         "smoothstreamingpacketizer",
         "sanjosestreamingpacketizer"
      ]
   },
   "securityConfig": {
      "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/security",
      "secureTokenVersion": 0,
      "clientStreamWriteAccess": "*",
      "publishRequirePassword": true,
      "publishPasswordFile": "",
      "publishRTMPSecureURL": "",
      "publishIPBlackList": "",
      "publishIPWhiteList": "",
      "publishBlockDuplicateStreamNames": false,
      "publishValidEncoders": "",
      "publishAuthenticationMethod": "digest",
      "playMaximumConnections": 0,
      "playRequireSecureConnection": false,
      "secureTokenSharedSecret": "",
      "secureTokenUseTEAForRTMP": false,
      "secureTokenIncludeClientIPInHash": false,
      "secureTokenHashAlgorithm": "",
      "secureTokenQueryParametersPrefix": "",
      "secureTokenOriginSharedSecret": "",
      "playIPBlackList": "",
      "playIPWhiteList": "",
      "playAuthenticationMethod": "none"
   },
   "modules": {
      "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/modules",
      "moduleList": [{
          "order": 0,
          "name": "base",
          "description": "Base",
          "class": "com.wowza.wms.module.ModuleCore"
      }, {
          "order": 1,
          "name": "logging",
          "description": "Client Logging",
          "class": "com.wowza.wms.module.ModuleClientLogging"
      }, {
          "order": 2,
          "name": "flvplayback",
          "description": "FLVPlayback",
          "class": "com.wowza.wms.module.ModuleFLVPlayback"
      }, {
          "order": 3,
          "name": "ModuleCoreSecurity",
          "description": "Core Security Module for Applications",
          "class": "com.wowza.wms.security.ModuleCoreSecurity"
      }]
   }
}
'

Update an application's settings


Update the application testlive to include the MPEG-DASH packetizer:

curl -X PUT --header 'Accept:application/json; charset=utf-8' --header 'Content-Type:application/json; charset=utf-8' http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive -d'
{
  "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive",
  "name":" testlive",
  "appType": "Live",
  "streamConfig": {
      "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/streamconfiguration",
      "streamType": "live",
      "liveStreamPacketizer": [
         "cupertinostreamingpacketizer",
         "smoothstreamingpacketizer",
         "sanjosestreamingpacketizer",
         "mpegdashstreamingpacketizer"
      ]
  }
}
'

The command should return a response that looks something like this:

{
  "success": true,
  "message": "Saved"
}

Add custom properties to an application


Update the testlive application to include a custom module called MyCustomModule:

curl -X PUT --header 'Accept:application/json; charset=utf-8' --header 'Content-Type:application/json; charset=utf-8' http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/adv -d'
{
   "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/adv",
   "version": "1430682096000",
   "modules": [{
       "order": 0,
       "name": "base",
       "description": "Base",
       "class": "com.wowza.wms.module.ModuleCore"
   }, {
       "order": 0,
       "name": "logging",
       "description": "Client Logging",
       "class": "com.wowza.wms.module.ModuleClientLogging"
   }, {
       "order": 0,
       "name": "flvplayback",
       "description": "FLVPlayback",
       "class": "com.wowza.wms.module.ModuleFLVPlayback"
   }, {
       "order": 0,
       "name": "ModuleDRMVerimatrix",
       "description": "ModuleDRMVerimatrix",
       "class": "com.wowza.wms.drm.module.verimatrix.ModuleDRMVerimatrix"
   }, {
       "order": 0,
       "name": "ModuleDRMBuyDRM",
       "description": "ModuleDRMBuyDRM",
       "class": "com.wowza.wms.drm.module.buydrm.ModuleDRMBuyDRM"
   }, {
       "order": 0,
       "name": "ModulePushPublish",
       "description": "Module Push Publish",
       "class": "com.wowza.wms.pushpublish.module.ModulePushPublish"
   }, {
       "order": 0,
       "name": "MyCustomModule",
       "description": "Module Custom Module",
       "class": "com.my.custom.path.MyCustomModule"
   }],
   "advancedSettings": [{
       "enabled": false,
       "canRemove": true,
       "name": "debugAACTimecodes",
       "value": "false",
       "defaultValue": "false",
       "type": "Boolean",
       "sectionName": "cupertinostreamingpacketizer",
       "section": "/Root/Application/LiveStreamPacketizer",
       "documented": true
   }, {
       "enabled": false,
       "canRemove": true,
       "name": "debugMP3Timecodes",
       "value": "false",
       "defaultValue": "false",
       "type": "Boolean",
       "sectionName": "cupertinostreamingpacketizer",
       "section": "/Root/Application/LiveStreamPacketizer",
       "documented": true
   }, {
       "enabled": false,
       "canRemove": true,
       "name": "cupertinoChunkDurationTarget",
       "value": "0",
       "defaultValue": "10000",
       "type": "Integer",
       "sectionName": "cupertinostreamingpacketizer",
       "section": "/Root/Application/LiveStreamPacketizer",
       "documented": true
   }, {
       "enabled": true,
       "canRemove": false,
       "name": "myCustomPropertyName",
       "value": "myValue",
       "defaultValue": null,
       "type": "String",
       "sectionName": "Application",
       "section": "/Root/Application",
       "documented": false
   }]
}
'

The result is that your application's configuration includes the following custom modules and properties:

<Modules>
	<Module>
		<Name>base</Name>
		<Description>Base</Description>
		<Class>com.wowza.wms.module.ModuleCore</Class>
	</Module>
	<Module>
		<Name>logging</Name>
		<Description>Client Logging</Description>
		<Class>com.wowza.wms.module.ModuleClientLogging</Class>
	</Module>
	<Module>
		<Name>flvplayback</Name>
		<Description>FLVPlayback</Description>
		<Class>com.wowza.wms.module.ModuleFLVPlayback</Class>
	</Module>
	<Module>
		<Name>ModuleDRMVerimatrix</Name>
		<Description>ModuleDRMVerimatrix</Description>
		<Class>com.wowza.wms.drm.module.verimatrix.ModuleDRMVerimatrix</Class>
	</Module>
	<Module>
		<Name>ModuleDRMBuyDRM</Name>
		<Description>ModuleDRMBuyDRM</Description>
		<Class>com.wowza.wms.drm.module.buydrm.ModuleDRMBuyDRM</Class>
	</Module>
	<Module>
		<Name>ModulePushPublish</Name>
		<Description>Module Push Publish</Description>
		<Class>com.wowza.wms.pushpublish.module.ModulePushPublish</Class>
	</Module>
	<Module>
		<Name>MyCustomModule</Name>
		<Description>Module Custom Module</Description>
		<Class>com.my.custom.path.MyCustomModule</Class>
	</Module>
</Modules>
<!-- Properties defined here will be added to the IApplication.getProperties() and IApplicationInstance.getProperties() collections -->
<Properties>
	<Property>
		<Name>myCustomPropertyName</Name>
		<Value>myValue</Value>
		<Type>String</Type>
	</Property>
</Properties>

Restart an application


Restart the application testlive:

curl -X PUT --header 'Accept:application/json; charset=utf-8' http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive/actions/restart

Get a list of applications


Get a list of all applications on an instance of Wowza Streaming Engine:

curl -X GET --header 'Accept:application/json; charset=utf-8' http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications

The command should return a response that looks something like this:

{
   "restURI": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications",
   "applications": [{
      "id": "live",
      "href":"http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/live",
      "appType": "Live",
      "dvrEnabled": false,
      "drmEnabled": false,
      "transcoderEnabled": false
   }, {
      "id": "vod",
      "href": "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/vod",
      "appType": "VOD",
      "dvrEnabled": false,
      "drmEnabled": false,
      "transcoderEnabled": false
   }]
}

If you're having problems or want to discuss this article, post in our forum.

728x90

Reference documentation for the Wowza Streaming Engine™ media server software REST API is available through the open-source Swagger 1.2 framework. Swagger presents the documentation, which describes every resource and operation in the API, on a single webpage represented using the JSON Schema.

To use the Wowza Streaming Engine REST API reference documentation, you must enable the documentation server that comes with your Wowza Streaming Engine instance. Then you can download and view the content locally.

Notes:
  • Wowza Streaming Engine 4.3.0 or later is required.  
  • A Subscription or Perpetual license for Wowza Streaming Engine includes access to the REST API. A separate license is not required.

Configure the Wowza Streaming Engine REST API documentation server


Wowza Streaming Engine software includes a documentation server, or servlet, that provides the REST API reference documentation through a Swagger-based webpage. The documentation server is disabled by default. To use it, you must enable the servlet and disable servlet authentication in your instance's Server.xml file.

  1. On the computer with Wowza Streaming Engine installed, go to [install-dir]/conf and open Server.xml file in a text editor.
  2. Locate the <DocumentationServerEnable> property in the <RESTInterface> section and specify true, like this:
    <DocumentationServerEnable>true</DocumentationServerEnable>

Note: By default, the documentation server uses port 8089. To use a different port, change <DocumentationServerPort>8089</DocumentationServerPort> to <DocumentationServerPort>[port-number]</DocumentationServerPort>.

  1. Locate the <DocumentationServerAuthenticationMethod> property and specify none, like this:
<DocumentationServerAuthenticationMethod>none</DocumentationServerAuthenticationMethod>

Note: The documentation server uses CORS headers. If you're using Wowza Streaming Engine 4.5.0 or later, CORS is enabled by default. If you're using Wowza Streaming Engine 4.3.0 or 4.4.x, you must enable CORS by adding the <restUserHTTPHeaders> property to the <RESTInterface>/<Properties> section of the Server.xmlfile, like this:

<Properties>
<Property>
    <Name>restUserHTTPHeaders</Name>
    <Value>Access-Control-Allow-Origin:*|Access-Control-Allow-Methods:OPTIONS,GET,PUT,DELETE,POST|Access-Control-Allow-Headers:Content-Type</Value>
</Property>
</Properties>

For more information, see How to add HTTP headers to Wowza Streaming Engine REST API responses.

Finally, to use the Try it out! buttons to execute queries from within Swagger, you must turn off API authentication.

  1. Locate the <AuthenticationMethod> property and specify none, like this:
<AuthenticationMethod>none</AuthenticationMethod>
  1. Restart Wowza Streaming Engine.

Top

Download and view the documentation


After you've configured Wowza Streaming Engine to use the documentation server, you can download and view the content.

Note: Wowza Streaming Engine must be running in order to open the Swagger doc.

  1. Download the Swagger webpage and content.
  2. Extract the zipped contents of the download to any location on your computer.  
  3. Go to [package-root] and open index.html in a web browser.  
  4. In the upper-right corner of the index.html webpage, enter the URL of the Wowza Streaming Engine server that has the REST API documentation servlet enabled, for example:
    http://[wowza-ip-address]:8089/api-docs
  5. Click Explore.

Note: To access the REST API documentation server on a remote Wowza Streaming Engine instance, do the following:

  1. On the computer that has the Wowza Streaming Engine REST API documentation you want to view, open Server.xml in a text editor and add the remote computer's IP address to the <RESTInterface>/<IPWhiteList> property. For details on configuring the <IPWhiteList> property, see Connect to remote Streaming Engine from local Streaming Engine Manager.
  2. Restart Wowza Streaming Engine.
  3. On the computer where you've downloaded the Swagger content, open the index.html webpage and enter the URL of the Wowza Streaming Engine server that has the REST API that you want to view using the following format: http://[wowza-ip-address]:8089/api-docs.

Top

More resources



If you're having problems or want to discuss this article, post in our forum.

728x90

/** libkeccak-tiny

*

* A single-file implementation of SHA-3 and SHAKE.
*
* Implementor: David Leon Gil
* License: CC0, attribution kindly requested. Blame taken too,
* but not liability.
*/
#include "sha3.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef memset_s
# define memset_s(W,WL,V,OL) memset(W,V,OL)
#endif
/******** The Keccak-f[1600] permutation ********/
/*** Constants. ***/
static const uint8_t rho[24] = \
{ 1, 3, 6, 10, 15, 21,
28, 36, 45, 55, 2, 14,
27, 41, 56, 8, 25, 43,
62, 18, 39, 61, 20, 44};
static const uint8_t pi[24] = \
{10, 7, 11, 17, 18, 3,
5, 16, 8, 21, 24, 4,
15, 23, 19, 13, 12, 2,
20, 14, 22, 9, 6, 1};
static const uint64_t RC[24] = \
{1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
/*** Helper macros to unroll the permutation. ***/
#define rol(x, s) (((x) << s) | ((x) >> (64 - s)))
#define REPEAT6(e) e e e e e e
#define REPEAT24(e) REPEAT6(e e e e)
#define REPEAT5(e) e e e e e
#define FOR5(v, s, e) \
v = 0; \
REPEAT5(e; v += s;)
/*** Keccak-f[1600] ***/
static inline void keccakf(void* state) {
uint64_t* a = (uint64_t*)state;
uint64_t b[5] = {0};
uint64_t t = 0;
uint8_t x, y;
for (int i = 0; i < 24; i++) {
// Theta
FOR5(x, 1,
b[x] = 0;
FOR5(y, 5,
b[x] ^= a[x + y]; ))
FOR5(x, 1,
FOR5(y, 5,
a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))
// Rho and pi
t = a[1];
x = 0;
REPEAT24(b[0] = a[pi[x]];
a[pi[x]] = rol(t, rho[x]);
t = b[0];
x++; )
// Chi
FOR5(y,
5,
FOR5(x, 1,
b[x] = a[y + x];)
FOR5(x, 1,
a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))
// Iota
a[0] ^= RC[i];
}
}
/******** The FIPS202-defined functions. ********/
/*** Some helper macros. ***/
#define _(S) do { S } while (0)
#define FOR(i, ST, L, S) \
_(for (size_t i = 0; i < L; i += ST) { S; })
#define mkapply_ds(NAME, S) \
static inline void NAME(uint8_t* dst, \
const uint8_t* src, \
size_t len) { \
FOR(i, 1, len, S); \
}
#define mkapply_sd(NAME, S) \
static inline void NAME(const uint8_t* src, \
uint8_t* dst, \
size_t len) { \
FOR(i, 1, len, S); \
}
mkapply_ds(xorin, dst[i] ^= src[i]) // xorin
mkapply_sd(setout, dst[i] = src[i]) // setout
#define P keccakf
#define Plen 200
// Fold P*F over the full blocks of an input.
#define foldP(I, L, F) \
while (L >= rate) { \
F(a, I, rate); \
P(a); \
I += rate; \
L -= rate; \
}
/** The sponge-based hash construction. **/
static inline int hash(uint8_t* out, size_t outlen,
const uint8_t* in, size_t inlen,
size_t rate, uint8_t delim) {
if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
return -1;
}
uint8_t a[Plen] = {0};
// Absorb input.
foldP(in, inlen, xorin);
// Xor in the DS and pad frame.
a[inlen] ^= delim;
a[rate - 1] ^= 0x80;
// Xor in the last block.
xorin(a, in, inlen);
// Apply P
P(a);
// Squeeze output.
foldP(out, outlen, setout);
setout(a, out, outlen);
memset_s(a, 200, 0, 200);
return 0;
}
/*** Helper macros to define SHA3 and SHAKE instances. ***/
#define defshake(bits) \
int shake##bits(uint8_t* out, size_t outlen, \
const uint8_t* in, size_t inlen) { \
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \
}
#define defsha3(bits) \
int sha3_##bits(uint8_t* out, size_t outlen, \
const uint8_t* in, size_t inlen) { \
if (outlen > (bits/8)) { \
return -1; \
} \
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x06); \
}
#define defkeccak(bits) \
int keccak_##bits(uint8_t* out, size_t outlen, \
const uint8_t* in, size_t inlen) { \
if (outlen > (bits/8)) { \
return -1; \
} \
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \
}
/*** FIPS202 SHAKE VOFs ***/
defshake(128)
defshake(256)
/*** FIPS202 SHA3 FOFs ***/
defsha3(224)
defsha3(256)
defsha3(384)
defsha3(512)
/*** pre-FIPS202 Keccak standard ***/
defkeccak(256)


728x90

LAMP stack refers to Linux, Apache, MySQL and PHP . With this bundle you can create web applications / services with Linux serving as the OS, Apache as the Web-Server, MySQL as the database server and PHP as the server-side programming language.

So what is ModSecurity?

ModSecurity is an open-source Web Application Firewall (WAF). It sits before your Web Server and so is able to monitor the incoming as well as the outgoing traffic. With this, we can, to some extent, prevent attacks, information leakage, etc..

Installation

Installing LAMP Stack:

Installing the LAMP Stack on Ubuntu is a breeze! You have this meta-package called lamp-serverthat lets you install all the required packages and configures them so that you're ready to start playing at the end of it.

So open up a terminal and type,

$ sudo apt-get update && sudo apt-get install -y lamp-server^

Supply your password upon prompt and it'll proceed with the installation. In between, you'll be prompted to set the MySQL root user's password. After that, when you get your terminal prompt back, you should have a fully working LAMP stack, ready to go!

Don't believe me? Check it out yourself by browsing to http://localhost/. You should be able to see the default Apache page.

Default locations:

  • Apache Webroot: /var/www/html/
  • Apache Config: 1/etc/apache2/
  • Apache Log folder: /var/log/apache2/
  • PHP config: /etc/php5/
  • php.ini location for PHP Apps served by Apache: /etc/php5/apache2/php.ini

Installing ModSecurity

We are going to be installing ModSecurity as a module to Apache, so, please key in the following command in a terminal.

$ sudo apt-get install libapache2-modsecurity

Once that has finished installing, you can verify that ModSecurity has been installed and is running by running the following command:

$ apache2ctl -M | grep -i security

security2_module (shared)

Installing ModSecurity Core Rule Set

You might have noticed during installation that a package called modsecurity-crs got installed when you installed ModSecurity. That is the ModSecurity Core Rule Set, which is an OWASPproject of ModSecurity rules that you can use to defend yourself against common web application attacks.

Installing the Github version

Some people like installing the Github version, since it provides more flexibility in terms of fetching any updates, switching between branches, etc.. To install the ModSecurity CRS from its Github repo, we need to replace the /usr/share/modsecurity-crs directory and then clone the repo at that location.

  $ sudo rm -rf /usr/share/modsecurity-crs
  $ sudo apt-get install -y git
  $ sudo git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/share/modsecurity-crs

Finally, just copy/rename the example setup file to have a .confextension.

  $ sudo cp /usr/share/modsecurity-crs/modsecurity_crs_10_setup.conf.example /usr/share/modsecurity-crs/modsecurity_crs_10_setup.conf

Now we can continue with the following steps.

To set up the ModSecurity CRS, lets first switch to the /usr/share/modsecurity-crs directory.

$ cd /usr/share/modsecurity-crs

To activate the rules that you need, you need to place it in the activated_rules directory. First let's include the setup file by creating a soft link to it from the activated_rules directory.

$ sudo ln -s ../modsecurity_crs_10_setup.conf activated_rules/modsecurity_crs_10_setup.conf

Next, we'll include all the base_rules,

$ for f in `ls base_rules`; do sudo ln -s ../base_rules/$f activated_rules/$f; done

Now you're activated_rules directory should look something like this:

$ ll activated_rules/
total 20
drwxr-xr-x 2 root root 4096 Jun 26 14:15 ./
drwxr-xr-x 9 root root 4096 Jun 26 13:56 ../
lrwxrwxrwx 1 root root   44 Jun 26 14:07 modsecurity_35_bad_robots.data -> ../base_rules/modsecurity_35_bad_robots.data
lrwxrwxrwx 1 root root   42 Jun 26 14:07 modsecurity_35_scanners.data -> ../base_rules/modsecurity_35_scanners.data
lrwxrwxrwx 1 root root   49 Jun 26 14:07 modsecurity_40_generic_attacks.data -> ../base_rules/modsecurity_40_generic_attacks.data
lrwxrwxrwx 1 root root   42 Jun 26 14:07 modsecurity_50_outbound.data -> ../base_rules/modsecurity_50_outbound.data
lrwxrwxrwx 1 root root   50 Jun 26 14:07 modsecurity_50_outbound_malware.data -> ../base_rules/modsecurity_50_outbound_malware.data
lrwxrwxrwx 1 root root   32 Jun 26 14:15 modsecurity_crs_10_setup.conf -> ../modsecurity_crs_10_setup.conf
lrwxrwxrwx 1 root root   57 Jun 26 14:07 modsecurity_crs_20_protocol_violations.conf -> ../base_rules/modsecurity_crs_20_protocol_violations.conf
lrwxrwxrwx 1 root root   56 Jun 26 14:07 modsecurity_crs_21_protocol_anomalies.conf -> ../base_rules/modsecurity_crs_21_protocol_anomalies.conf
lrwxrwxrwx 1 root root   52 Jun 26 14:07 modsecurity_crs_23_request_limits.conf -> ../base_rules/modsecurity_crs_23_request_limits.conf
lrwxrwxrwx 1 root root   49 Jun 26 14:07 modsecurity_crs_30_http_policy.conf -> ../base_rules/modsecurity_crs_30_http_policy.conf
lrwxrwxrwx 1 root root   48 Jun 26 14:07 modsecurity_crs_35_bad_robots.conf -> ../base_rules/modsecurity_crs_35_bad_robots.conf
lrwxrwxrwx 1 root root   53 Jun 26 14:07 modsecurity_crs_40_generic_attacks.conf -> ../base_rules/modsecurity_crs_40_generic_attacks.conf
lrwxrwxrwx 1 root root   59 Jun 26 14:07 modsecurity_crs_41_sql_injection_attacks.conf -> ../base_rules/modsecurity_crs_41_sql_injection_attacks.conf
lrwxrwxrwx 1 root root   49 Jun 26 14:07 modsecurity_crs_41_xss_attacks.conf -> ../base_rules/modsecurity_crs_41_xss_attacks.conf
lrwxrwxrwx 1 root root   52 Jun 26 14:07 modsecurity_crs_42_tight_security.conf -> ../base_rules/modsecurity_crs_42_tight_security.conf
lrwxrwxrwx 1 root root   45 Jun 26 14:07 modsecurity_crs_45_trojans.conf -> ../base_rules/modsecurity_crs_45_trojans.conf
lrwxrwxrwx 1 root root   55 Jun 26 14:07 modsecurity_crs_47_common_exceptions.conf -> ../base_rules/modsecurity_crs_47_common_exceptions.conf
lrwxrwxrwx 1 root root   62 Jun 26 14:07 modsecurity_crs_48_local_exceptions.conf.example -> ../base_rules/modsecurity_crs_48_local_exceptions.conf.example
lrwxrwxrwx 1 root root   54 Jun 26 14:07 modsecurity_crs_49_inbound_blocking.conf -> ../base_rules/modsecurity_crs_49_inbound_blocking.conf
lrwxrwxrwx 1 root root   46 Jun 26 14:07 modsecurity_crs_50_outbound.conf -> ../base_rules/modsecurity_crs_50_outbound.conf
lrwxrwxrwx 1 root root   55 Jun 26 14:07 modsecurity_crs_59_outbound_blocking.conf -> ../base_rules/modsecurity_crs_59_outbound_blocking.conf
lrwxrwxrwx 1 root root   49 Jun 26 14:07 modsecurity_crs_60_correlation.conf -> ../base_rules/modsecurity_crs_60_correlation.conf
-rw-r--r-- 1 root root 5720 Jul 12  2013 README

You can include other rules found in other directories in the same way as well. Just remember to place all the rules you want activated in the activated_rules directory.

Now, let's head to the /etc/modsecurity/ directory to continue with the configuration.

$ cd /etc/modsecurity

Copy the recommended configuration file and name it modsecurity.conf

$ cp modsecurity.conf-recommended modsecurity.conf

Open the modsecurity.conf file and change the line that reads SecRuleEngine DetectionOnlyto SecRuleEngine On . This changes ModSecurity from a passive monitoring mode to an active blocking mode. The rest of the default configurations that ship with the modsecurity-crspackage on Ubuntu are more than sufficient. However, if you're interested in tweaking them, please refer to the ModSecurity Reference Manual. Here's the diff of the recommended file and the actual configuration file,

$ diff modsecurity.conf-recommended modsecurity.conf
7c7
< SecRuleEngine DetectionOnly
---
> SecRuleEngine On

One final configuration file to tweak - the /etc/apache2/mods-available/security2.conf . Add the line IncludeOptional /usr/share/modsecurity-crs/activated_rules/*.conf to it and so you're configuration file would read,

<IfModule security2_module>
        # Default Debian dir for modsecurity's persistent data
        SecDataDir /var/cache/modsecurity

        # Include all the *.conf files in /etc/modsecurity.
        # Keeping your local configuration in that directory
        # will allow for an easy upgrade of THIS file and
        # make your life easier
        IncludeOptional /etc/modsecurity/*.conf
        IncludeOptional /usr/share/modsecurity-crs/activated_rules/*.conf
</IfModule>

Finally, we reload Apache for all the changes to take effect.

$ sudo service apache2 reload

Testing if it all works!

We can test if it all works, by sending some typical malicious requests to our Web Server and see if the requests are being blocked.

## XSS
$ curl 'http://localhost/?q="><script>alert(1)</script>'
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /
on this server.</p>
<hr>
<address>Apache/2.4.7 (Ubuntu) Server at localhost Port 80</address>
</body></html>

## SQLi
$ curl "http://localhost/?q='1 OR 1=1"
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /
on this server.</p>
<hr>
<address>Apache/2.4.7 (Ubuntu) Server at localhost Port 80</address>
</body></html>

And yay! It works! If you're curious to know more, you can look in the ModSecurity Audit Log file at /var/log/apache2/modsec_audit.log

And that's it! We now have a working LAMP Stack with ModSecurity and the ModSecurity CRS installed. If you want to customize your ModSecurity installation further and fine-tune it or write your own rules or disable some of them, please refer to the ModSecurity Reference Manual.

Note: In the above post, we just discussed how to install the LAMP Stack, ModSecurity WAF with the ModSecurity CRS on Ubuntu 16.04. Please do NOT assume your server is magically secured because of this. Please do not use this in production.


+ Recent posts