Version 13

    Design notes for work on https://issues.jboss.org/browse/WFLY-456 (formerly https://issues.jboss.org/browse/AS7-444).

     

    My current development topic branch for this is https://github.com/kabir/wildfly/tree/WFLY-456-audit-log (More current than https://github.com/bstansberry/jboss-as/tree/AS7-444, note that these are personal branches; I make no guarantees not to change its commit history.)  This branch is based on work previously done by John Bailey.

     

    Design notes:

    1) Processing location in OperationContext

     

    a) when done

    b) when decision to not proceed is made in OperationContext

     

    2) Log record format:

     

    a) date

    b) read-only?

    c) boot?

    d) (if boot) version (as string???)

    e) rollback?

    f) userid (TODO get this somehow)

    g) uuid (for domain ops only, to track across processes)

    h) isServer?

    i) primary (domain or server) model hash

    j) if (!isServer) secondary (host) model hash

    k) overall hash

    l) num operations

    m) operations (one at a time)

    n) length of a->j (scan from end to last boot during validation; alternative is to write the length first and scan from beginning to last boot)

     

    3) Index record format:

     

    a) overall hash

     

    4) Mgmt operations

     

    a) truncate (back to last boot)

    i) don't discard previous; just write under a different file name

    b) read log (params -- from (default 0); batch-size (default 20; -1 means all))

    c) validate log

    d) config changes

     

    5) Validation:

     

    a) compare persisted model hash to current model

    b) scan back through log to last config-file-modified boot or version-change boot. We stop at version-change boot to avoid spurious validation problems resulting from changes in model construction across versions

    c) recreate by re-running ops

     

    -- validation problems

     

    a) need to verify model hash at each stage -- special controller that ignores all runtime ops

      i) problem -- how to recreate domain ops involving remote slaves that don't exist?

      ii) problem -- ops with attachments -- attachments won't exist

      iii) this "special controller" could end up duplicating a lot of logic just for validation

    b) reads and runtime ops cannot be verified against model; it can only be confirmed that their hash is consistent with subsequent hashes in the log. Tamper resistant as modification would require modifying all subsequent log entries, but not tamper proof as this could be done.

     

    6) Domain mode

     

    a) tracking requests from master to slaves

    apply a uuid to requests

    -- as a header

    include uuid in log record

     

    b) detecting host.xml config changes at boot

    problem -- can't detect host.xml config changes at boot, as model changes may be due to domain.xml stuff coming from the master

    so, independent domain and host logging

    but, what about non-model affecting ops? log twice?

     

    c) domain logging on slaves? only if --backup-dc is set? -- no simpler to just log

     

    d) remote-slave-only logging on master?

    yes, to maintain a complete record of what was done

     

    7) Non-model-affecting ops

     

    a) re-calculating the model hash for all such ops is too expensive

    b) store the hash(es) in the ModelController along with the model

    c) provide the hash along with the model to OperationContext

    d) when model is updated recalc hashes

     

    8) Config

     

    a) <audit-log> element

    b) part of <management> section

    c) resource is /core-service=audit-log

    d) attributes

    i) path (NO -- we need to know the location when first logging, before we have processed ops to set it)

    ii) relative-to (NO -- we need to know the location when first logging, before we have processed ops to set it)

    iii) log-read-only?

    iv) daily-rolling??? (hassle; tempting to defer to later release but it's probably necessary immediately)

     

    9) Other issues

     

    a) disable logging overhead for dev scenarios

      i) to disable it during initial boot (until whatever config element that turns it on/off is read) -- maintain log data in memory and only write on last boot op

    b) parallel boot handlers should not log

    c) fluctuating model hashes

      i) if op took the controller lock, that lock ensures proper ordering of model hashes

      ii) if op does not take controller lock (reads) earlier model hashes can intermix with later -- validation needs to account for this

     

     

    Suggested configuration

    Only relevant elements to audit logging have been included in the following examples.

    jboss-as-config (i.e. standlone.xml and host.xml)

    This defines a set of audit-log-appenders which are referenced by the audit-log element. Having the audit-log-appenders defined seperately from the core audit-log, and the core audit-log referencing those appenders allows us to later allow separate appenders for the jmx subsystem.

     

    Currently encryption/tamper detection is not a requirement so all logs are done in clear text. If encryption/tamper detection later becomes a requirement this could be added by for example an audit-log-formatters section which configures whatever we would like to use for encryption/tamper detection and the file-audit-log-appender and syslog-audit-log-appender could individually be made to reference an audit-log-formatter.

        <xs:complexType name="domain-managementType">
            <xs:annotation>
                <xs:documentation>
                    Domain-wide default configuration settings for the management of standalone servers and a Host Controller.
                </xs:documentation>
            </xs:annotation>
            <xs:sequence>
                <xs:element name="security-realms" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="security-realm" type="security-realmType" minOccurs="1"
                                        maxOccurs="unbounded"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="outbound-connections" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="ldap" type="ldapType" minOccurs="1" /> <!-- TODO minOccurs only while ldap is only supported connection. -->
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="audit-log" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence minOccurs="0">
                            <xs:element name="audit-log-appenders" type="audit-log-appendersType"/>
                            <xs:element name="logger" type="audit-log-loggerType"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    
        <xs:complexType name="audit-log-appendersType">
            <xs:annotation>
                <xs:documentation>
                    Declaration of management operation audit logging appenders.
                </xs:documentation>
            </xs:annotation>
            <xs:choice minOccurs="1" maxOccurs="unbounded">
                <xs:element name="file-appender" type="file-audit-log-appenderType"/>
                <xs:element name="syslog-appender" type="syslog-audit-log-appenderType"/>
            </xs:choice>
        </xs:complexType>
    
        <xs:complexType name="file-audit-log-appenderType">
            <xs:annotation>
                <xs:documentation>
                    Configuration of a simple file appender for the audit log. This writes to a local file without any encryption or tamper detection applied to the file.
                </xs:documentation>
            </xs:annotation>
            <xs:attribute name="name" type="xs:string" use="required">
                <xs:annotation>
                    <xs:documentation>
                        The name of the appender. The name must be unique across all types of appender.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="path" type="xs:string" use="required">
                <xs:annotation>
                    <xs:documentation>
                        The path of the audit log.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="relative-to" use="optional" type="xs:string">
                <xs:annotation>
                    <xs:documentation>
                        The name of another previously named path, or of one of the
                        standard paths provided by the system. If 'relative-to' is
                        provided, the value of the 'path' attribute is treated as
                        relative to the path specified by this attribute.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    
        <xs:complexType name="syslog-audit-log-appenderType">
            <xs:annotation>
                <xs:documentation>
                        Configuration of a syslog appender for the audit log. This writes to syslog without any encryption or tamper detection applied to the file.
                </xs:documentation>
            </xs:annotation>
            <xs:choice minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        The configuration of the protocol to use communication with the syslog server. See your syslog provider's documentation for configuration options.
                    </xs:documentation>
                </xs:annotation>
                <xs:element name="udp" type="udp-audit-log-protocolType">
                </xs:element>
                <xs:element name="tcp" type="tcp-audit-log-protocolType">
                </xs:element>
                <xs:element name="tls" type="tls-audit-log-protocolType">
                </xs:element>
            </xs:choice>
    
            <xs:attribute name="name" type="xs:string" use="required">
                <xs:annotation>
                    <xs:documentation>
                        The name of the appender. The name must be unique across all types of appender.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="syslog-format" type="xs:token" default="RFC5424">
                <xs:annotation>
                    <xs:documentation>
                        The format to use for the syslog messages. See your syslog provider's documentation for what is supported.
                    </xs:documentation>
                </xs:annotation>
                <xs:simpleType>
                    <xs:restriction>
                        <xs:enumeration value="RFC5424">
                            <xs:annotation>
                                <xs:documentation>Format the syslog data according to the RFC-5424 standard</xs:documentation>
                            </xs:annotation>
                        </xs:enumeration>
                        <xs:enumeration value="RFC3164">
                            <xs:annotation>
                                <xs:documentation>Format the syslog data according to the RFC-3164 standard</xs:documentation>
                            </xs:annotation>
                        </xs:enumeration>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
    
            <!-- TODO appname, level etc-->
        </xs:complexType>
    
        <xs:complexType name="base-audit-log-protocolType">
            <xs:attribute name="host" default="localhost">
                <xs:annotation>
                    <xs:documentation>
                        The host of the syslog server.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="port" default="514">
                <xs:annotation>
                    <xs:documentation>
                        The port of the syslog server.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    
        <xs:complexType name="udp-audit-log-protocolType">
            <xs:annotation>
                <xs:documentation>Configure udp as the protocol for communicating with the syslog server</xs:documentation>
            </xs:annotation>
            <xs:complexContent>
                <xs:extension base="base-audit-log-protocolType"/>
            </xs:complexContent>
        </xs:complexType>
    
        <xs:complexType name="tcp-audit-log-protocolType">
            <xs:annotation>
                <xs:documentation>Configure tcp as the protocol for communicating with the syslog server</xs:documentation>
            </xs:annotation>
            <xs:complexContent>
                <xs:extension base="base-audit-log-protocolType">
                    <xs:attribute name="message-transfer" type="xs:token" default="NON_TRANSPARENT_FRAMING">
                        <xs:annotation>
                            <xs:documentation>
                                The message transfer setting as described in section 3.4 of RFC-6587. See your syslog provider's
                                documentation for what is supported
                            </xs:documentation>
                        </xs:annotation>
                        <xs:simpleType>
                            <xs:restriction>
                                <xs:enumeration value="OCTET_COUNTING">
                                    <xs:annotation>
                                        <xs:documentation>
                                            Use the octet counting format for message transfer as described in section 3.4.1 of RFC-6587.
                                        </xs:documentation>
                                    </xs:annotation>
                                </xs:enumeration>
                                <xs:enumeration value="NON_TRANSPARENT_FRAMING">
                                    <xs:annotation>
                                        <xs:documentation>
                                            Use the non-transparent-framing format for message transfer as described in section 3.4.1 of RFC-6587.
                                        </xs:documentation>
                                    </xs:annotation>
                                </xs:enumeration>
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:attribute>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    
        <xs:complexType name="tls-audit-log-protocolType">
            <xs:annotation>
                <xs:documentation>Configure tls as the protocol for communicating with the syslog server</xs:documentation>
            </xs:annotation>
            <xs:complexContent>
                <xs:extension base="tcp-audit-log-protocolType">
                    <xs:sequence>
                        <xs:element name="truststore" type="keyStoreType" minOccurs="0">
                            <xs:annotation>
                                <xs:documentation>
                                    Configuration of a keystore to use to create a trust manager to verify the server certificate for encrypted comminications.
                                    If the server certificate is signed off by a signing authority, tls can be used without a truststore.
                                </xs:documentation>
                            </xs:annotation>
                        </xs:element>
                        <xs:element name="client-certificate-store" type="keyStoreType" minOccurs="0">
                            <xs:annotation>
                                <xs:documentation>
                                    Configuration of a keystore containing a client certificate and a private key, e.g. in PKCS12 format. This turns on authenticating 
                                    the clients against the syslog server.
                                </xs:documentation>
                            </xs:annotation>
                        </xs:element>
                    </xs:sequence>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    
        <xs:complexType name="audit-log-loggerType">
            <xs:annotation>
                <xs:documentation>
                    Declaration of management operation audit logging configuration coming from the model controller core.
                </xs:documentation>
            </xs:annotation>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="appenders" type="audit-log-appenders-refType" minOccurs="0"/>
            </xs:choice>
            <xs:attribute name="log-read-only" type="xs:boolean" default="false">
                <xs:annotation>
                    <xs:documentation>
                        Whether operations that do not modify the configuration or any runtime services should be logged.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="enabled" type="xs:boolean" default="true">
                <xs:annotation>
                    <xs:documentation>
                        Whether audit logging is enabled.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    
        <xs:complexType name="audit-log-appenders-refType">
            <xs:annotation>
                <xs:documentation>
                    References to audit-log-appenders defined in the audit-log-appenders section
                </xs:documentation>
            </xs:annotation>
            <xs:choice minOccurs="1">
                <xs:element name="appender" type="audit-log-appender-refType" minOccurs="0"/>
            </xs:choice>
        </xs:complexType>
    
        <xs:complexType name="audit-log-appender-refType">
            <xs:annotation>
                <xs:documentation>
                    A reference to an audit-log-appender defined in the audit-log-appenders section
                </xs:documentation>
            </xs:annotation>
            <xs:attribute name="appender" type="xs:string" use="required"/>
        </xs:complexType>
    
    
    

     

    jboss-as-jmx (jmx subsystem)

    We currently do not allow for the jmx subsystem to have separate appenders so they will be shared with the core audit logging. The commented out appenders shows how allowing separate appenders for the jmx subsystem could be done in future.

     

        <xs:complexType name="subsystem">
          <xs:sequence>
             <xs:element name="expose-resolved-model" type="resolvedModelType" minOccurs="0" maxOccurs="1"/>
             <xs:element name="expose-expression-model" type="expressionModelType" minOccurs="0" maxOccurs="1"/>
             <xs:element name="remoting-connector" type="remotingConnectorRefType" minOccurs="0"/>
             <xs:element name="audit-log" type="audit-logType" minOccurs="0"/>
          </xs:sequence>
        </xs:complexType>
    
    
    
        <xs:complexType name="audit-logType">
            <xs:annotation>
                <xs:documentation>
                    Declaration of management operation audit logging configuration.
                </xs:documentation>
            </xs:annotation>
            <!-- 
             Don't allow separate appenders for jmx for now
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="appenders" type="audit-log-appenders-refType" minOccurs="0"/>
            </xs:choice>
             -->
            <xs:attribute name="log-read-only" type="xs:boolean" default="false">
                <xs:annotation>
                    <xs:documentation>
                        Whether operations that do not modify the configuration or any runtime services should be logged.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="enabled" type="xs:boolean" default="true">
                <xs:annotation>
                    <xs:documentation>
                        Whether audit logging is enabled.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    
        <!--
        Don't allow separate appenders for jmx for now
        <xs:complexType name="audit-log-appenders-refType">
            <xs:annotation>
              <xs:documentation>
                 References to audit-log-appenders defined in the audit-log-appenders section
              </xs:documentation>
            </xs:annotation>
            <xs:choice minOccurs="1">
                <xs:element name="appender" type="audit-log-appender-refType" minOccurs="0"/>
            </xs:choice>
        </xs:complexType>
    
        <xs:complexType name="audit-log-appender-refType">
             <xs:annotation>
               <xs:documentation>
                  A reference to an audit-log-appender defined in the audit-log-appenders section
               </xs:documentation>
             </xs:annotation>
             <xs:attribute name="appender" type="xs:string" use="required"/>
        </xs:complexType>
        -->
    
    
    

     

    Sample standalone.xml configuration:

     

        <management>
            <security-realms>
            --SNIP--
            </security-realms>
            <audit-log>
                <appenders>
                    <file-appender name="file" path="audit-log.log" relative-to="jboss.server.data.dir"/>
                    <syslog-appender name="syslog" syslog-format="RFC5424">
                        <udp host="localhost" port="514"/>
                    </syslog-appender>
                </appenders>
                <logger log-read-only="true" enabled="true">
                    <appenders>
                        <appender name="file"/>
                        <appender name="syslog"/>
                    </appenders>
                </logger>
            </audit-log>
            <management-interfaces>
            --SNIP--
            </management-interfaces>
        </management>
    
    

     

    When we get to separating out jmx appenders for a later release, the sample jmx configuration will be along the lines of the following. This would allow users to have separate audit logs for JMX and the native controller. For now JMX just uses whatever is configured in the domain-management section.

     

            <subsystem xmlns="urn:jboss:domain:jmx:1.2">
                <expose-resolved-model/>
                <expose-expression-model/>
                <remoting-connector/>
                <audit-log log-read-only="true" enabled="true">
                    <appenders>
                        <!-- Reference one or more of the appenders from the domain-management section -->
                        <appender name="file"/>
                        <appender name="syslog"/>
                    </appenders>
                </audit-log>
             <subsystem>