Wednesday, August 14, 2013

Simpler Audit Logging Example for WildFly 8.0.0.Alpha4

Tomaz on the WildFly team pointed out that my previous blog post on secure audit logging in WildFly 8.0.0.Alpha4 was a bit too scary :-) So I'd like to point out that that was probably the most complicated setup possible, and to walk through a few simpler examples here while explaining a bit more what goes on. These features are available in WildFly 8.0.0.Alpha4 and later. You can get it from here.

WildFly out of the box comes preconfigured for audit logging to $WILDFLY_HOME/standalone/data/audit-log.log., the only thing you need to do is to enable it. There is a section in $WILDFLY_HOME/standalone/configuration/standalone.xml which contains the configuration for the audit log:
        <audit-log>
            <formatters>
                <json-formatter name="json-formatter">
            </json-formatter></formatters>
            <handlers>
                <file-handler formatter="json-formatter" name="file" path="audit-log.log" relative-to="jboss.server.data.dir">
                </file-handler>
            </handlers>
            <logger enabled="false" log-boot="true" log-read-only="false">
                <handlers>
                    <handler name="file">
                </handler></handlers>
            </logger>
        </audit-log>
This config contains the only audit log formatter we have at the moment, the JSON formatter which formats the audit log records.
It also contains a file-handler called file which points to the file which it should log to.
The file file-handler references the 'json-formatter' which means this handler uses 'json-formatter' to format its log records.
Finally the logger entry references the 'file' handler which means that the 'file' handler will be used for logging audit log records.
The attributes of the logger element mean that we will audit log the operation that happen on boot, that we will not log read-only operations, and that audit logging is not enabled. The not enabled part takes precedence, so we don't log anything at all.

Now if you start up WildFly by running (of course change ~/Downloads/wildfly-8.0.0.Alpha4 to wherever you have installed WildFly)
$cd ~/Downloads/wildfly-8.0.0.Alpha4/bin/
$./standalone.sh
you will see no $WILDFLY_HOME/standalone/data/audit-log.log. file. This is because we need to enable audit logging.



Enable audit logging

In another terminal window go to WildFly's bin directory, start our command-line interface and execute the operation to change the enabled attribute to true:

$cd ~/Downloads/wildfly-8.0.0.Alpha4/bin/

[~/Downloads/wildfly-8.0.0.Alpha4/bin]
$./jboss-cli.sh 
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect 
[standalone@localhost:9990 /] /core-service=management/access=audit/logger=audit-log:write-attribute(name=enabled,value=true){"outcome" => "success"}
[standalone@localhost:9990 /] 
If you look in $WILDFLY_HOME/standalone/configuration/standalone.xml again, you will see that the value of the enabled attribute we saw earlier is now true.

Now, if you look, you will see that $WILDFLY_HOME/standalone/data/audit-log.log has been created, and it contains the following:
$more data/audit-log.log
2013-08-14 15:26:16 - {
    "type" : "core",
    "r/o" : false,
    "booting" : false,
    "user" : "$local",
    "domainUUID" : null,
    "access" : "NATIVE",
    "remote-address" : "127.0.0.1/127.0.0.1",
    "success" : true,
    "ops" : [{
        "address" : [
            {
                "core-service" : "management"
            },
            {
                "access" : "audit"
            },
            {
                "logger" : "audit-log"
            }
        ],
        "operation" : "write-attribute",
        "name" : "enabled",
        "value" : true,
        "operation-headers" : {"caller-type" : "user"}
    }]
}

The actual contents of the fields is explained in the documentation but a few things worth pointing out is that access=NATIVE means it came from the native management interface, and ops contains the operation that we executed to enable audit logging.

Enable syslog logging

First you need a syslog server which can accept connections via UDP or TCP/IP. I am on OS X, so I enabled my local syslog server to accept UDP connections on port 514 by following these tips. If you are on linux you probably have rsyslog installed, so you would typically modify /etc/rsyslog.conf to include the following directives
...
$ModLoad imudp.so
$UDPServerRun 514
...

Then restart the syslog service. I think the OS X link shows you how to do that, and for linux you need to restart the rsyslogd service. In the worst case reboot, and start up wildfly and the command-line interface again ;-)

Then in the command-line interface window, execute these following commands to add a syslog handler called mysyslog:
[standalone@localhost:9990 /] batch 
[standalone@localhost:9990 / #] /core-service=management/access=audit/syslog-handler=mysyslog:add(formatter=json-formatter)
#1 /core-service=management/access=audit/syslog-handler=mysyslog:add(formatter=json-formatter)
[standalone@localhost:9990 / #] /core-service=management/access=audit/syslog-handler=mysyslog/protocol=udp:add(host=localhost,port=514)
#2 /core-service=management/access=audit/syslog-handler=mysyslog/protocol=udp:add(host=localhost,port=514)
[standalone@localhost:9990 / #] run-batch 
The batch executed successfully
Then add a reference to mysyslog to the logger:
[standalone@localhost:9990 /] /core-service=management/access=audit/logger=audit-log/handler=mysyslog:add
{"outcome" => "success"}

You should now see the executed commands logged in $WILDFLY_HOME/standalone/data/audit-log.log., e.g.:
2013-08-14 15:55:20 - {
    "type" : "core",
    "r/o" : false,
    "booting" : false,
    "user" : "$local",
    "domainUUID" : null,
    "access" : "NATIVE",
    "remote-address" : "127.0.0.1/127.0.0.1",
    "success" : true,
    "ops" : [{
        "operation" : "composite",
        "address" : [],
        "steps" : [
            {
                "address" : [
                    {
                        "core-service" : "management"
                    },
                    {
                        "access" : "audit"
                    },
                    {
                        "syslog-handler" : "mysyslog"
                    }
                ],
                "operation" : "add",
                "formatter" : "json-formatter",
                "operation-headers" : {"caller-type" : "user"},
                "max-length" : null,
                "syslog-format" : null,
                "truncate" : null,
                "max-failure-count" : null
            },
            {
                "address" : [
                    {
                        "core-service" : "management"
                    },
                    {
                        "access" : "audit"
                    },
                    {
                        "syslog-handler" : "mysyslog"
                    },
                    {
                        "protocol" : "udp"
                    }
                ],
                "operation" : "add",
                "port" : 514,
                "host" : "localhost",
                "operation-headers" : {"caller-type" : "user"}
            }
        ],
        "operation-headers" : {"caller-type" : "user"}
    }]
}
2013-08-14 15:56:34 - {
    "type" : "core",
    "r/o" : false,
    "booting" : false,
    "user" : "$local",
    "domainUUID" : null,
    "access" : "NATIVE",
    "remote-address" : "127.0.0.1/127.0.0.1",
    "success" : true,
    "ops" : [{
        "address" : [
            {
                "core-service" : "management"
            },
            {
                "access" : "audit"
            },
            {
                "logger" : "audit-log"
            },
            {
                "handler" : "mysyslog"
            }
        ],
        "operation" : "add",
        "operation-headers" : {"caller-type" : "user"}
    }]
}
And if you look at syslog,
  • On OS X, open the Console.app and go to 'All Messages'
  • On Linux, look in /var/log/messages
In any case you should see the logger handler reference add in syslog
14/08/2013 15:56:35.000 2013-08-14T15: 56:35.529+01:00 localhost WildFly 2348 - - 2013-08-14 15:56:34 - {
    "type" : "core",
    "r/o" : false,
    "booting" : false,
    "user" : "$local",
    "domainUUID" : null,
    "access" : "NATIVE",
    "remote-address" : "127.0.0.1/127.0.0.1",
    "success" : true,
    "ops" : [{
        "address" : [
            {
                "core-service" : "management"
            },
            {
                "access" : "audit"
            },
            {
                "logger" : "audit-log"
            },
            {
                "handler" : "mysyslog"
            }
        ],
        "operation" : "add",
        "operation-headers" : {"caller-type" : "user"}
    }]
(The reason you did not see the add of the handler is that the audit log subsystem does not actually start using it until the logger handler reference is added). If you execute the following command in the command-line interface
[standalone@localhost:9990 /] /system-property=test123:add(value=testing)
{"outcome" => "success"}
You should see the operation get logged in both syslog and the file.

Finally, if you look at $WILDFLY_HOME/standalone/configuration/standalone.xml again you will see that the syslog handler and reference have been persisted:

        <audit-log>
            <formatters>
                <json-formatter name="json-formatter"/>
            </formatters>
            <handlers>
                <file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
                <syslog-handler name="mysyslog" formatter="json-formatter">
                    <udp host="localhost" port="514"/>
                </syslog-handler>
            </handlers>
            <logger log-boot="true" log-read-only="false" enabled="true">
                <handlers>
                    <handler name="file"/>
                    <handler name="mysyslog"/>
                </handlers>
            </logger>
        </audit-log>

No comments: