Provided by: weakforced_2.10.2-1build1_amd64 bug

NAME

       wforce.conf - configuration file for wforce daemon

DESCRIPTION

       This  file  is read by wforce and is a Lua script containing Lua commands to implement (a)
       configuration of the wforce daemon and (b) functions that control  the  operation  of  the
       wforce daemon in response to HTTP commands, specifically “report”, “allow” and “reset”.

       An alternative version of this file can be specified with

              wforce -C private_wforce.conf ...

CONFIGURATION-ONLY FUNCTIONS

       The  following functions are for configuration of wforce only, and cannot be called inside
       the allow/report/reset functions:

       • setACL(<list of netmasks>) - Set the access control  list  for  the  HTTP  Server.   For
         example, to allow access from any IP address, specify:

                  setACL({"0.0.0.0/0"})

       • addACL(<netmask>)  -  Add a netmask to the access control list for the HTTP server.  For
         example, to allow access from 127.0.0.0/8, specify:

                  addACL("127.0.0.0/8")

       • addWebHook(<list of events>, <config key map>) - Add a webhook for the specified events,
         with  the  specified  configuration keys.  See wforce_webhook(5) for the list of events,
         supported configuration keys, and details of the HTTP(S) POST sent to webhook URLs.  For
         example:

                  config_keys={}
                  config_keys["url"] = "http://webhooks.example.com:8080/webhook/"
                  config_keys["secret"] = "verysecretcode"
                  events = { "report", "allow" }
                  addWebHook(events, config_keys)

       • addCustomWebHook(<custom  webhook  name>,  <config  key  map>)  -  Add a custom webhook,
         i.e. one which can be called from Lua (using  “runCustomWebHook()”  -  see  below)  with
         arbitrary  data,  using the specified configuration keys.  See wforce_webhook(5) for the
         supported config keys, and details of the  HTTP(S)  POST  sent  to  webhook  URLs.   For
         example:

                  config_keys={}
                  config_keys["url"] = "http://webhooks.example.com:8080/webhook/"
                  config_keys["secret"] = "verysecretcode"
                  addCustomWebHook("mycustomhook", config_keys)

       • addCustomStat(<stat name>) - Add a custom counter which can be used to track statistics.
         The stats for custom counters are logged every 5 minutes.  The  counter  is  incremented
         with the “incCustomStat” command.  For example:

                  addCustomStat("custom_stat1")

       • setSiblings(<list  of  IP/Host[:port[:protocol]]>)  -  Set the list of siblings to which
         stats db and blacklist/whitelist data should be replicated.  If port is not specified it
         defaults  to  4001.   If protocol is not specified it defaults to udp.  This function is
         safe to call while wforce is running.  For example:

                  setSiblings({"127.0.1.2", "sibling1.example.com:4004", "[::1]:4004:tcp"})

       • setSiblingsWithKey(<list of {IP/Host[:port[:protocol]], Encryption Key>) - Identical  to
         setSiblings()  except that it allows an encryption key to be specified for each sibling.
         For example:

                    setSiblingsWithKey({{"127.0.1.2", "Ay9KXgU3g4ygK+qWT0Ut4gH8PPz02gbtPeXWPdjD0HE="}, {"127.0.1.3:4004:tcp", "KaiQkCHloe2ysXv2HbxBAFqHI4N8+ahmwYwsbYlDdF0="}})

       • addSibling(<IP/Hostname[:port[:protocol]]>) - Add a sibling to the  list  to  which  all
         stats  db  and  blacklist/whitelist  data  should be replicated.  Use [] to enclose IPv6
         addresses.  If port is not specified it defaults to 4001.  If protocol is not  specified
         it  defaults  to  udp.   This  function  is  safe  to call while wforce is running.  For
         example:

                  addSibling("192.168.1.23")
                  addSibling("192.168.1.23:4001:udp")
                  addSibling("192.168.1.23:4003:tcp")
                  addSibling("[::1]:4003:tcp")
                  addSibling("sibling1.example.com")

       • addSiblingWithKey(<IP[:port[:protocol]]>, <Encryption Key>) - Identical to addSibling(),
         except that an encryption key is specified to enable per-sibling encryption.For example:

                    addSiblingWithKey("192.168.1.23", "Ay9KXgU3g4ygK+qWT0Ut4gH8PPz02gbtPeXWPdjD0HE=")

       • removeSibling(<IP/Host[:port[:protocol]]>)  -  Remove a sibling to the list to which all
         stats db and blacklist/whitelist data should be replicated.   Use  []  to  enclose  IPv6
         addresses.   If port is not specified it defaults to 4001.  If protocol is not specified
         it defaults to udp.  This function is  safe  to  call  while  wforce  is  running.   For
         example:

                  removeSibling("192.168.1.23")
                  removeSibling("sibling1.example.com:4001:udp")
                  removeSibling("[::1]:4003:tcp")

       • siblingListener(<IP[:port]>)  -  Listen  for  reports  from siblings on the specified IP
         address and port.  If port is not specified it defaults to  4001.   Wforce  will  always
         listen on both UDP and TCP ports.  For example:

                  siblingListener("0.0.0.0:4001")
                  siblingListener("[::1]:4001")

       • setSiblingConnectTimeout(<timeout  ms>)  -  Sets  a  timeout  in  milliseconds  for  new
         connections to siblings.  Defaults to 5000 ms (5 seconds).  For example:

                  setSiblingConnectTimeout(1000)

       • setMaxSiblingQueueSize(<size>) - Sets the maximum size of the send  and  receive  queues
         for  replication  events  waiting  to  be processed.  Defaults to 5000.  This is only to
         handle short-term spikes in load/latency - if error messages relating to the recv  queue
         max size being reached are seen, then you should consider using sharded string stats dbs
         (newShardedStringStatsDB),   and/or   tuning   the   stats   db   expiry   sleep    time
         (twSetExpireSleep).

                  setMaxSiblingQueueSize(10000)

       • setNamedReportSinks(<name>,  <list  of IP[:port]>) - Set a named list of report sinks to
         which all received reports should be forwarded over UDP.  Reports will be  sent  to  the
         configured  report  sinks  for a given name in a round-robin fashion if more than one is
         specified.  Reports are sent separately to each named  report  sink.   If  port  is  not
         specified  it  defaults  to  4501.   Replaces  the  deprecated  “setReportSinks()”.  For
         example:

                  setNamedReportSinks("logstash", {"127.0.1.2", "127.0.1.3:4501"})

       • addNamedReportSink(<name>, <IP[:port]>) - Add a report sink to the named list  to  which
         all  received  reports  should  be  forwarded  over  UDP.   Reports  will be sent to the
         configured report sinks for a given name in a round-robin fashion if more  than  one  is
         specified.   Reports  are  sent  separately  to  each named report sink.  If port is not
         specified it defaults to 4501.  Replaces the deprecated “addReportSink()”.  For example:

                  addNamedReportSink("logstash", "192.168.1.23")

       • webserver(<IP:port>, <password>) - (deprecated - see addListener() instead)  Listen  for
         HTTP  commands  on  the  specified  IP  address  and  port.   The  password  is  used to
         authenticate client connections using basic authentication.  For example:

                  webserver("0.0.0.0:8084", "super")

       • addListener(<IP:port>, <useSSL>, <cert file>, <key file>, <options>) - (replacement  for
         webserver())  Listen  for HTTP commands on the specified IP address and port.  If useSSL
         is true, then HTTPS must be used, and cert_file and key file are  used,  otherwise  they
         are  empty.  Options contains a list of key value pairs to configure the TLS connection;
         these       follow       the       command       line       option       names        in
         https://www.openssl.org/docs/manmaster/man3/SSL_CONF_cmd.html.        For       example,
         “min_protocol” to set the minimum TLS protocol version.  You can add as  many  listeners
         as you choose.  For example:

                  addListener("0.0.0.0:8084", false, "", "", {})
                  addListener("1.2.3.4:1234", true, "/etc/wforce/cert.pem", "/etc/wforce/key.pem", {minimum_protocol="TLSv1.2"})
                  addListener("[::1]:9000", true, "/etc/wforce/cert.pem", "/etc/wforce/key.pem", {minimum_protocol="TLSv1.3"})

       • setWebserverPassword(<Password>)  -  (replacement for webserver password parameter) Sets
         the basic authentication password for access to the webserver.  This has been  decoupled
         from  the addListener() command because multiple listeners can now be created, which was
         not previously possible.  For example:

                  setWebserverPassword("foobar")

       • controlSocket(<IP[:port]>) - Listen for control connections on the specified IP  address
         and port.  If port is not specified it defaults to 5199.  For example:

                  controlSocket("0.0.0.0:4004")

       • setKey(<key>) - Use the specified key for authenticating connections from siblings.  The
         key can be generated with makeKey() from the console.  See wforce(1) for instructions on
         running  a  console  client.   Returns  false  if the key could not be set (e.g. invalid
         base64).  For example:

                  if not setKey("Ay9KXgU3g4ygK+qWT0Ut4gH8PPz02gbtPeXWPdjD0HE=")
                      then
                        ...

       • setNumLuaStates(<num states>) - Set the number of Lua Contexts that will be  created  to
         run   allow/report/reset   commands.   Defaults  to  10  if  not  specified.   See  also
         setNumWorkerThreads()  and  setNumSiblingThreads().   Should  be  at  least   equal   to
         NumWorkerThreads + NumSiblingThreads.  For example:

                  setNumLuaStates(10)

       • setNumWorkerThreads(<num  threads>)  - Set the number of threads in the pool used to run
         allow/report/reset  commands.   Each  thread  uses  a   separate   Lua   Context,   (see
         setNumLuaStates()).  Defaults to 4 if not specified.  For example:

                  setNumWorkerThreads(4)

       • setNumSiblingThreads(<num  threads>)  -  Set  the  number of threads in the pool used to
         process reports received from siblings.  Each thread uses a separate  Lua  Context,  the
         number  of  which  is  set with setNumLuaStates().  Defaults to 2 if not specified.  For
         example:

                  setNumSiblingThreads(2)

       • setNumWebHookThreads(<num threads>) - Set the number of threads in the pool used to send
         webhook events.  Defaults to 5 if not specified.  For example:

                  setNumWebHookThreads(2)

       • setMaxWebserverConns(<max  conns>) - Set the maximum number of active connections to the
         webserver.  This can be used to limit the effect of too  many  queries  to  wforce.   It
         defaults to 10,000.  For example:

                  setMaxWebserverConns(5000)

       • setNumWebHookConnsPerThread(<num conns>) - Set the maximum number of connections used by
         each WebHook thread.  Defaults to 10  if  not  specified.   This  setting  replaces  the
         deprecated “num_conns” per-hook configuration setting.  For example:

                  setNumWebHookConnsPerThread(50)

       • setWebHookQueueSize(<queue  size>)  -  Set the size of the queue for webhook events.  If
         the queue gets too big, then webhooks will be discarded, and an error  will  be  logged.
         The default queue size is 50000, which should be appropriate for most use-cases.

                  setWebHookQueueSize(100000)

       • setWebHookTimeoutSecs(<timeout  secs>)  -  Set  the  maximum time a request can take for
         webhooks.  For example:

                  setWebHookTimeoutSecs(2)

       • newGeoIP2DB(<db name>, <filename>) - Opens and initializes a GeoIP2  database.   A  name
         must  be  chosen,  and  the  filename of the database to open must also be supplied.  To
         obtain an object allowing  lookups  to  be  performed  against  the  database,  use  the
         getGeoIP2DB() function.  For example:

                  newGeoIP2DB("CityDB", "/usr/share/GeoIP/GeoLite2-City.mmdb")

       • initGeoIPDB()  - (Deprecated - use newGeoIP2DB()) Initializes the country-level IPv4 and
         IPv6 GeoIP Legacy databases.  If either  of  these  databases  is  not  installed,  this
         command will fail and wforce will not start.  For example:

                  initGeoIPDB()

       • initGeoIPCityDB() - (Deprecated - use newGeoIP2DB()) Initializes the city-level IPv4 and
         IPv6 GeoIP Legacy databases.  If either  of  these  databases  is  not  installed,  this
         command  will  fail  and  wforce  will not start.  Ensure these databases have the right
         names if you’re using the free/lite  DBs  -  you  may  need  to  create  symbolic  links
         e.g. GeoIPCityv6.dat -> GeoLiteCityv6.dat.  For example:

                  initGeoIPCityDB()

       • initGeoIPISPDB()  -  (Deprecated - use newGeoIP2DB()) Initializes the ISP-level IPv4 and
         IPv6 GeoIP Legacy databases.  If either  of  these  databases  is  not  installed,  this
         command will fail and wforce will not start.  For example:

                  initGeoIPISPDB()

       • newDNSResolver(<resolver  name>)  -  Create a new DNS resolver object with the specified
         name.  Note this does not return the  resolver  object  -  that  is  achieved  with  the
         getDNSResolver() function.  For example:

                  newDNSResolver("MyResolver")

       • setHLLBits(<num  bits>)  - Set the accuracy of the HyperLogLog algorithm.  The value can
         be between 4-30, with a high  number  being  more  accurate  at  the  expense  of  using
         (potentially a lot) more memory.  The default value is 6.  If you require more accuracy,
         consider increasing slightly, but check your memory usage carefully.

       • setCountMinBits(<eps>, <gamma>) - Set the accuracy of the CountMin algorithm.  The value
         of  eps  can  be  between  0.01  and  1, with a lower number giving more accuracy at the
         expense of memory.  The default is 0.05.  The value of gamma is between 0 and 1, with  a
         higher  number  giving  higher  accuracy.  The default for gamma is 0.2.  If you require
         more accuracy, consider changing these values slightly,  but  check  your  memory  usage
         carefully.

       • newStringStatsDB(<stats  db name>, <window size>, <num windows>, <field map>) - Create a
         new StatsDB object with the specified name.  Note this does not return the object - that
         is achieved with the getStringStatsDB() function.  For example:

                  field_map = {}
                  field_map["countLogins"] = "int"
                  field_map["diffPasswords"] = "hll"
                  field_map["countCountries"] = "countmin"
                  newStringStatsDB("OneHourDB", 900, 4, field_map)

       • newShardedStringStatsDB(<stats db name>, <window size>, <num windows>, <field map>, <num
         shards>) - Identical to “newStringStatsDB” except that it creates a sharded DB, which is
         more  scalable  at  higher  query loads.  A good starting value for the number of shards
         might be 10.

       • StringStatsDB:twSetv4Prefix(<prefix>) - Set the prefix to use for any IPv4  ComboAddress
         keys  stored  in  the  db.   For  example,  specify  24  to group statistics for class C
         networks.  For example:

                  statsdb:twSetv4Prefix(24)

       • StringStatsDB:twSetv6Prefix(<prefix>) - Set the prefix to use for any IPv6  ComboAddress
         keys stored in the db.  For example:

                  statsdb:twSetv4Prefix(64)

       • StringStatsDB:twSetMaxSize(<size>)  - Set the maximum number of keys to be stored in the
         db.  When the db reaches that size, keys will be expired on a LRU  basis.   The  default
         size is 500K keys.  For example:

                  statsdb:twSetMaxSize(1000000)

       • StringStatsDB:twEnableReplication()  -  Enable  replication  for  this  db; only makes a
         difference if siblings have been configured.  For example:

                  statsdb:twEnableReplication()

       • disableBuiltinBlacklists() - Disable the built-in blacklisting checks, enabling them  to
         be checked from Lua instead.  For example:

                  disableBuiltinBlacklists()

       • blacklistPersistDB(<ip>,  <port>)  - Make the blacklist persistent by storing entries in
         the specified redis DB.  The IP address is a string, and port should be 6379 unless  you
         are running redis on a non-standard port.  If this option is specified, wforce will read
         all the blacklist entries from the redis DB on startup.  For example:

                  blacklistPersistDB("127.0.0.1", 6379)

       • blacklistPersistReplicated() - Store blacklist entries that have been replicated in  the
         redis DB.  By default, replicated blacklist entries will not be persisted.  If you use a
         local redis DB for each wforce server, then use this config option.  If you use a single
         redis  instance  for  all wforce servers, then you should not specify this option, as it
         will cause unnecessary writes to the redis DB.  For example:

                  blacklistPersistReplicated()

       • blacklistRedisUsername() - Set the Redis username for authentication to  the  redis  DB.
         For example:

                  blacklistRedisUsername("foobar")

       • blacklistRedisPassword()  -  Set  the Redis password for authentication to the redis DB.
         For example:

                  blacklistRedisPassword("secret")

       • blacklistPersistConnectTimeout() -  Set  the  connect  timeout  for  connecting  to  the
         persistent  redis  DB.   If  the  timeout  is exceeded during connection at startup then
         wforce will exit, otherwise during normal operation if the timeout is exceeded, an error
         will be logged.  For example:

                  blacklistPersistConnectTimeout(2)

       • blacklistPersistRWTimeout(,  )  -  Set the timeout for reading from/writing to the Redis
         DB.  For example:

                  blacklistPersistRWTimeout(0, 50000)

       • disableBuiltinWhitelists() - Disable the built-in whitelisting checks, enabling them  to
         be checked from Lua instead.  For example:

                  disableBuiltinWhitelists()

       • whitelistPersistDB(<ip>,  <port>)  - Make the whitelist persistent by storing entries in
         the specified redis DB.  The IP address is a string, and port should be 6379 unless  you
         are running redis on a non-standard port.  If this option is specified, wforce will read
         all the whitelist entries from the redis DB on startup.  For example:

                  whitelistPersistDB("127.0.0.1", 6379)

       • whitelistRedisUsername() - Set the Redis username for authentication to  the  redis  DB.
         For example:

                  whitelistRedisUsername("foobar")

       • whitelistRedisPassword()  -  Set  the Redis password for authentication to the redis DB.
         For example:

                  whitelistRedisPassword("secret")

       • whitelistPersistReplicated() - Store whitelist entries that have been replicated in  the
         redis DB.  By default, replicated whitelist entries will not be persisted.  If you use a
         local redis DB for each wforce server, then use this config option.  If you use a single
         redis  instance  for  all wforce servers, then you should not specify this option, as it
         will cause unnecessary writes to the redis DB.  For example:

                  whitelistPersistReplicated()

       • whitelistPersistConnectTimeout() -  Set  the  connect  timeout  for  connecting  to  the
         persistent  redis  DB.   If  the  timeout  is exceeded during connection at startup then
         wforce will exit, otherwise during normal operation if the timeout is exceeded, an error
         will be logged.  For example:

                  whitelistPersistConnectTimeout(2)

       • whitelistPersistRWTimeout(,  )  -  Set the timeout for reading from/writing to the Redis
         DB.  For example:

                  whitelistPersistRWTimeout(0, 50000)

       • setBlacklistIPRetMsg() - Set the message to be returned to clients whose IP  address  is
         blacklisted.   The  strings  “{ip}”  and “{login}” will be substituted for the actual IP
         address and login name.  For example:

                  setBlacklistIPRetMsg("Go away your IP {ip} is blacklisted")

       • setBlacklistLoginRetMsg() - Set the message to be returned to  clients  whose  login  is
         blacklisted.   The  strings  “{ip}”  and “{login}” will be substituted for the actual IP
         address and login name.  For example:

                  setBlacklistLoginRetMsg("Go away your login {login} is blacklisted")

       • setBlacklistIPLoginRetMsg() - Set the  message  to  be  returned  to  clients  whose  IP
         address/login  is blacklisted.  The strings “{ip}” and “{login}” will be substituted for
         the actual IP address and login name.  For example:

                  setBlacklistIPLoginRetMsg("Go away your IP {ip}/Login {login} is blacklisted")

       • setAllow(<allow func>) - Tell wforce to use the specified Lua function for handling  all
         “allow” commands.  For example:

                  setAllow(allow)

       • setReport(<report  func>)  -  Tell wforce to use the specified Lua function for handling
         all “report” commands.  For example:

                  setReport(report)

       • setReset(<reset func>) - Tell wforce to use the specified Lua function for handling  all
         “reset” commands.  For example:

                  setReset(reset)

       • setCanonicalize(<canonicalize func>) - Tell wforce to use the specified Lua function for
         handling all “canonicalisation” functionality.  This function is responsible for mapping
         multiple  aliases  for  a  user  to  a  single  login  string, e.g. ncook, neil.cook and
         neil.cook@foobar.com would all map to neil.cook@foobar.com.  Use  Lua  modules  such  as
         LuaSQL-MySQL  (luarocks  install  luasql-mysql) or LuaLDAP (luarocks install lualdap) to
         perform lookups in user databases.  For example:

                  setCanonicalize(canonicalize)

       • setCustomEndpoint(<name of endpoint>, <boolean>, <custom lua function>) - Create  a  new
         custom  REST  endpoint  with  the  given name, which when invoked will call the supplied
         custom lua function.  This allows admins to arbitrarily extend the wforce REST API  with
         new REST endpoints.  Admins can create as many custom endpoints as they require.  Custom
         endpoints can only be accessed via a  POST  method,  and  all  arguments  as  passed  as
         key-value  pairs of a top-level “attrs” json object (these will be split into two tables
         - one for single-valued attrs, and the other for multi-valued attrs - see CustomFuncArgs
         below).  If the boolean argument is true, then all arguments to the custom function will
         be sent to all configured named report sinks.   Return  information  is  passed  with  a
         boolean  “success”  and  “r_attrs”  json  object containing return key-value pairs.  See
         wforce.conf.example for an example.  For example:

                  function custom(args)
                    for k,v in pairs(args.attrs) do
                      infoLog("custom func argument attrs", { key=k, value=v });
                    end
                    -- return consists of a boolean, followed by { key-value pairs }
                    return true, { key=value }
                  end
                  setCustomEndpoint("custom", false, custom)
                  -- Set boolean to true to enable arguments to be sent to all
                  -- report sinks
                  -- setCustomEndpoint("custom", true, custom)

       • setCustomGetEndpoint(<name of endpoint>, <custom lua function>) - Create  a  new  custom
         REST  endpoint  accessible via a GET command (setCustomEndpoint() only works with POST).
         The return value of the function is a string, which will be passed to the HTTP client as
         a text/plain response body.  For example:

                  function textIPBlacklist()
                      local ipbl = getIPBlacklist()
                      local ret_table = {}
                      for i,j in pairs(ipbl)
                      do
                          for k,v in pairs(j)
                          do
                              if k == "ip"
                              then
                                  table.insert(ret_table, v)
                              end
                          end
                      end
                      local s =  table.concat(ret_table, "\n") .. "\n"
                      return s
                  end

                  setCustomGetEndpoint("textIPBlacklist", textIPBlacklist)

       • setVerboseAllowLog()  -  When  logging  allow  requests,  for  performance reaons, allow
         requests returning 0 will not be logged by default.  In  order  to  log  allow  requests
         returning 0, use this function.  For example:

                  setVerboseAllowLog()

       • addSyncHost(<sync  host address>, <sync host password>, <replication address>, <callback
         address>) - If you wish wforce to synchronize the contents of its StatsDBs with the rest
         of  a cluster, then use this configuration command.  If any sync hosts are added, wforce
         will attempt to contact them in turn and find a host which has been up longer  than  the
         number  of  seconds  specified  in setMinSyncHostUptime().  The sync host address should
         include a port (it defaults to 8084).  If  successful,  the  sync  host  will  send  the
         contents  of  its  StatsDBs to this wforce instance on the replication address specified
         (this address should have the same port as configured in siblingListener() and  defaults
         to  4001),  and  when  it  is  finished it will notify this instance of wforce using the
         callback address (this address should have the same port as configured in webserver  and
         defaults  to  8084).   N.B.   It  should  be  noted that the encryption key of the local
         instance is sent to the sync host, so to protect the confidentiality of the key, you may
         want to consider running an HTTPS reverse proxy in front of the sync host.  For example:

                  -- Add 10.2.3.1:8084 as a sync host,
                  -- and use the password "super"
                  -- Send the DB dump to 10.2.1.1:4001
                  -- and let me know on 10.2.1.1:8084 when the dump is finished
                  addSyncHost("10.2.3.1:8084", "super", "10.2.1.1:4001", "10.2.1.1:8084")
                  -- Add https://10.2.3.1:8084 as a sync host,
                  -- and use the password "super"
                  -- Send the DB dump to https://10.2.1.1:4001
                  addSyncHost("https://host1.example.com:8084", "super", "10.2.1.1:4001", "https://host2.example.com:8084")

       • setMinSyncHostUptime(<seconds>)  - The minimum time that any sync host must have been up
         for it to be able to send me the contents of its DBs.  Defaults to 3600.  For example:

                  setMinSyncHostUptime(1800)

       • disableCurlPeerVerification() - Disable checking of peer certificates  in  all  outbound
         HTTPS  connections.   This  is  not  recommended  except  for  debugging  or development
         purposes.  For example:

                  disableCurlPeerVerification()

       • disableCurlHostVerification() - Disable checking of the hostname in the peer certificate
         for  all  outbound  HTTPS  connections.  This is not recommended except for debugging or
         development purposes.

                  disableCurlHostVerification()

       • setCurlCABundleFile(<Path to CA File>) - Gives the location of  a  file  containing  the
         certificate  authorities to use for checking HTTPS server certificates.  Use this if the
         standard installed root certs do not contain the certs you need.  This should be a  file
         containing 1:N certs in PEM format.

                  setCurlCABundleFile("/etc/ca/local_cas.pem")

       • setCurlClientCertAndKey(<Path to Cert File>, <Path to Key File>) - Gives the location of
         the certificate and key files to use for mutual TLS authentication (in PEM format).

                  setCurlClientCertAndKey("/etc/certs/clientcert.pem", "/etc/certs/clientkey.pem")

       • setMetricsNoPassword() - Disable password protection for the /metrics endpoint.

GENERAL FUNCTIONS

       The following functions are available anywhere; either as part  of  the  configuration  or
       within the allow/report/reset functions:

       • getGeoIP2DB(<db  name>)  -  Return an object which can be used to perform GeoIP lookups.
         The database must first be initialised using newGeoIP2DB().  For example:

                  local citydb = getGeoIP2DB("CityDB")

       • GeoIP2DB:lookupCountry(<ComboAddress>) - Returns the two-character country code  of  the
         country  that  the  IP address is located in.  A ComboAddress object can be created with
         the newCA() function.  For example:

                  my_country = countrydb:lookupCountry(newCA("8.8.8.8"))
                  my_country = countrydb:lookupCountry(lt.remote)

       • GeoIP2DB:lookupISP(<ComboAddress>) - Returns the name of the ISP hosting the IP address.
         A ComboAddress object can be created with the newCA() function.  For example:

                  local my_isp = ispdb:lookupISP(newCA("128.243.16.21"))

       • GeoIP2DB:lookupCity(<ComboAddress>)  - Returns a map containing information about the IP
         address, such as the city name and latitude and longitude.  See  GeoIPRecord  below  for
         the full list of fields.  For example:

                  local gip_record = citydb:lookupCity(lt.remote)
                  local my_city = gip_record.city
                  local my_latitude = gip_record.latitude

       • GeoIP2DB:lookupStringValue(<ComboAddress>,  <array of string values>) - Returns a string
         corresponding to the value of the field specified by the array of  string  values.   For
         example:

                  local city_name = citydb:lookupStringValue(newCA(ip_address), {"city", "names", "en"})

       • GeoIP2DB:lookupUIntValue(<ComboAddress>,  <array of string values>) - Returns an integer
         corresponding to the value of the field specified by the array of  string  values.   For
         example:

                  local accuracy = citydb:lookupUIntValue(newCA(ip_address), {"location", "accuracy_radius"})

       • GeoIP2DB:lookupBoolValue(<ComboAddress>,  <array  of string values>) - Returns a boolean
         corresponding to the value of the field specified by the array of  string  values.   For
         example:

                  local eu = citydb:lookupBoolValue(newCA(ip_address), {"country", "is_in_european_union"})

       • GeoIP2DB:lookupDoubleValue(<ComboAddress>, <array of string values>) - Returns the value
         corresponding to the value of the field specified by the array of string  values  (which
         can be either double or float in the MMDB specification).  For example:

                  local city_lat = citydb:lookupDoubleValue(newCA(ip_address), {"location", "latitude"})
                  local city_long = citydb:lookupDoubleValue(newCA(ip_address), {"location", "longitude"})

       • lookupCountry(<ComboAddress>) - (Deprecated - use the new GeoIP2 function).  Returns the
         two-character country code of the  country  that  the  IP  address  is  located  in.   A
         ComboAddress object can be created with the newCA() function.  For example:

                  my_country = lookupCountry(my_ca)

       • lookupISP(<ComboAddress>)  -  (Deprecated  -  use the new GeoIP2 function).  Returns the
         name of the ISP hosting the IP address.  A ComboAddress object can be created  with  the
         newCA() function.  For example:

                  local my_isp = lookupISP(newCA("128.243.16.21"))

       • lookupCity(<ComboAddress>)  - (Deprecated - use the new GeoIP2 function).  Returns a map
         containing information about the IP address, such as the  city  name  and  latitude  and
         longitude.  See GeoIPRecord below for the full list of fields.  For example:

                  local gip_record = lookupCity(lt.remote)
                  local my_city = gip_record.city
                  local my_latitude = gip_record.latitude

       • newCA(<IP[:port]>)  -  Create and return an object representing an IP address (v4 or v6)
         and optional port.  The object is called a ComboAddress.  For example:

                  my_ca = newCA("192.128.12.82")

       • ComboAddress:tostring() - Return a string representing the IP address.  For example:

                  mystr = my_ca:tostring()

       • newNetmask(<IP[/mask]>) - Create and return  an  object  representing  a  Netmask.   For
         example:

                  my_nm = newNetmask("8.0.0.0/8")

       • newNetmaskGroup()  -  Return  a NetmaskGroup object, which is a way to efficiently match
         IPs/subnets against a range.  For example:

                  mynm = newNetmaskGroup()

       • NetmaskGroup:addMask(<cidr>) - Add a mask to the  NetmaskGroup,  in  cidr  format.   For
         example:

                  mynm:addMask("182.22.0.0/16")

       • NetmaskGroup:match(<ip  address>)  - Match an IP address against a NetmaskGroup.  The IP
         address must be a ComboAddress object.  For example:

                  if (mynm.match(lt.remote))
                  then
                      print("ip address matched")
                  end

       • getDNSResolver(<resolver name>) - Return a DNS resolver object corresponding to the name
         specified.  For example:

                  resolv = getDNSResolver("MyResolver")

       • Resolver:addResolver(<ip address>, <port>) - Adds the specified IP address and port as a
         recursive server to use when resolving DNS queries.  For example:

                  resolv = getDNSResolver("MyResolver")
                  resolv:addResolver("8.8.8.8", 53)

       • Resolver:setRequestTimeout(<timeout>) - Sets the timeout in milliseconds.  For example

                  resolv = getDNSResolver("MyResolver")
                  resolv:setRequestTimeout(100)

       • Resolver:setNumContexts(<num contexts>) - Sets the number of  DNS  contexts  to  use  to
         perform  DNS  queries.   Defaults  to  12, but you may want to increase for performance,
         although it should not need to be higher than NumWorkerThreads.  For example:

                  resolv = getDNSResolver("MyResolver")
                  resolv:setNumContexts(20)

       • Resolver:lookupAddrByName(<name>, [<num retries>]) - Performs DNS  A  record  resolution
         for the specified name, returning an array of IP address strings.  Optionally the number
         of retries can be specified.  For example:

                  resolv = getDNSResolver("MyResolver")
                  resolv:lookupAddrByName("google.com")
                  for i, addr in ipairs(dnames) do
                          -- addr contains an IPv4 or IPv6 address
                  end

       • Resolver:lookupNameByAddr(<ComboAddress>, [num  retries])  -  Performs  DNS  PTR  record
         resolution  for  the  specified  address,  returning  an array of names.  Optionally the
         number of retries can be specified.  For example:

                  resolv = getDNSResolver("MyResolver")
                  resolv:lookupNameByAddr(lt.remote)
                  for i, dname in ipairs(dnames) do
                          -- dname is the resolved DNS name
                  end

       • Resolver:lookupRBL(<ComboAddress>, <rbl zone>, [num retries]) - Lookup an IP address  in
         a RBL-formatted zone.  Returns an array of IP address strings.  Optionally the number of
         retries can be specified.  For example:

                  dnames = rblresolv:lookupRBL(lt.remote, "sbl.spamhaus.org")
                  for i, dname in ipairs(dnames) do
                          if (string.match(dname, "127.0.0.2"))
                          then
                              -- the RBL matched
                          end
                  end

       • runCustomWebHook(<custom webhook name>, <webhook data>) - Run  a  previously  configured
         custom  webhook,  using  the  supplied webhook data.  By default the Content-Type of the
         data is “application/json”, however this can be changed using the “content-type”  config
         key  when configuring the custom webhook.  Custom webhooks are run using the same thread
         pool as normal webhooks.  For example:

                  runCustomWebHook(mycustomhook", "{ \"foo\":\"bar\" }")

       • getStringStatsDB(<stats db name>) - Retrieve the StatsDB object specified by  the  name.
         For example:

                  statsdb = getStringStatsDB("OneHourDB")

       • StringStatsDB:twAdd(<key>,  <field  name>,  <value>)  -  For  the specified key, add the
         specified value to the specified field.  Keys can be ComboAddress, strings or  integers.
         Values  can  be  ComboAddress,  strings  or  integers.   Some values only make sense for
         certain field types (e.g. adding a string to an int field type  makes  no  sense).   For
         example:

                  ca = newCA("192.168.1.2")
                  statsdb:twAdd("luser", "diffIPs", ca)
                  statsdb:twAdd(ca, "countLogins", 1)

       • StringStatsDB:twSub(<key>,  <field name>, <value>) - For the specified key, subtract the
         specified value from  the  specified  field.   Keys  can  be  ComboAddress,  strings  or
         integers.  Values can only be integers.  For example:

                  statsdb:twSub(ca, "countLogins", 1)

       • StringStatsDB:twGet(<key>,  <field  name>,  [<value>]) - For the specified key, retrieve
         the value for the specified field.  For fields of type “countmin”, specify the value you
         wish to retrieve.  Return value is summed over all the windows in the db.  For example:

                  numLogins =  statsdb:twGet(lt.login, "countLogins")
                  numUSLogins = statsdb:twGet(lt.login, "countCountries", "US")

       • StringStatsDB:twGetCurrent(<key>,  <field  name>,  [<value>])  -  For the specified key,
         retrieve the value for the specified field for the current (latest)  time  window.   For
         fields of type “countmin”, specify the value you wish to retrieve.  For example:

                      numLogins = statsdb:twGetCurrent(lt.login, "countLogins")

       • StringStatsDB:twGetWindows(<key>,  <field  name>,  [<value>])  -  For the specified key,
         retrieve an array containing all the values for all the windows for the specified field.
         For fields of type “countmin”, specify the value you wish to retrieve.  For example:

                  myarray = statsdb:twGetWindows(lt.login, "countCountries", "AU")

       • StringStatsDB:twGetSize() - Returns the number of keys stored in the db.  For example

                  dbsize = statsdb:twGetSize()

       • StringStatsDB:twReset(<key>)  -  Reset  all  stats  for  all  windows  in the db for the
         specified key.  For example:

                  statsdb:twReset(lt.login)

       • StringStatsDB:twResetField(<key>, <field name>) - Reset all stats for all windows in the
         db for the specified key and field name.  For example:

                  statsdb:twResetField(lt.login, "countLogins")

       • StringStatsDB:twSetExpireSleep(<milliseconds>)  -  Set the sleep interval between checks
         to expire/expunge entries.  Defaults to 250ms.  For example:

                  statsdb:twSetExpireSleep(200)

       • infoLog(<log string>, <key-value map>) - Log at LOG_INFO level  t<he  specified  string,
         adding  “key=value”  strings  to the log for all the kvs specified in the key-value map.
         For example:

                  infoLog("Logging is very important", { logging=1, foo=bar })

       • vinfoLog(<log string>, <key-value map>) - Log at LOG_INFO level  the  specified  string,
         adding  “key=value”  strings  to the log for all the kvs specified in the key-value map,
         but only if wforce was started with the  (undocumented)  -v  flag  (for  verbose).   For
         example:

                  vinfoLog("Logging is very important", { logging=1, foo=bar })

       • warnLog(<log  string>,  <key-value  map>)  - Log at LOG_WARN level the specified string,
         adding “key=value” strings to the log for all the kvs specified in  the  key-value  map.
         For example:

                  warnLog("Logging is very important", { logging=1, foo=bar })

       • errorLog(<log  string>,  <key-value  map>)  - Log at LOG_ERR level the specified string,
         adding “key=value” strings to the log for all the kvs specified in  the  key-value  map.
         For example:

                  errorLog("Logging is very important", { logging=1, foo=bar })

       • debugLog(<log  string>,  <key-value map>) - Log at LOG_DEBUG level the specified string,
         adding “key=value” strings to the log for all the kvs specified in  the  key-value  map,
         but  only  if  wforce  was  started  with the (undocumented) -v flag (for verbose).  For
         example:

                  debugLog("This will only log if wforce is started with -v", { logging=1, foo=bar })

       • getBlacklistIPRetMsg() - Get the message to be returned to clients whose IP  address  is
         blacklisted.  For example:

                  local retmsg = getBlacklistIPRetMsg()

       • getBlacklistLoginRetMsg()  -  Get  the  message to be returned to clients whose login is
         blacklisted.  For example:

                  local retmsg = getBlacklistLoginRetMsg()

       • getBlacklistIPLoginRetMsg() - Get the  message  to  be  returned  to  clients  whose  IP
         address/login is blacklisted.  For example:

                  local retmsg = getBlacklistIPLoginRetMsg()

       • blacklistNetmask(<Netmask>, <expiry>, <reason string>) - Blacklist the specified netmask
         for expiry seconds, with the specified  reason.   Netmask  address  must  be  a  Netmask
         object, e.g. created with newNetmask().  For example:

                  blacklistNetmask(newNetmask("12.32.0.0/16"), 300, "Attempted password brute forcing")

       • blacklistIP(<ip>,  <expiry>,  <reason  string>)  - Blacklist the specified IP for expiry
         seconds, with the specified reason.  IP address must be a ComboAddress.  For example:

                  blacklistIP(lt.remote, 300, "Attempted password brute forcing")

       • blacklistLogin(<login>, <expiry> <reason string>) - Blacklist the  specified  login  for
         expiry seconds, with the specified reason.  For example:

                  blacklistLogin(lt.login, 300, "Potentially compromised account")

       • blacklistIPLogin(<ip>,  <login>,  <expiry>,  <reason  string>) - Blacklist the specified
         IP-Login tuple for expiry seconds, with the specified reason.  Only  when  that  IP  and
         login  are received in the same login tuple will the request be blacklisted.  IP address
         must be a ComboAddress.  For example:

                  blacklistIPLogin(lt.remote, lt.login, 300, "Account and IP are suspicious")

       • unblacklistNetmask(<Netmask>) Remove the blacklist for the specified  netmask.   Netmask
         address must be a Netmask object, e.g. created with newNetmask().  For example:

                  unblacklistNetmask(newNetmask("12.32.0.0/16"))

       • unblacklistIP(<ip>)  -  Remove the blacklist for the specified IP.  IP address must be a
         ComboAddress.  For example:

                  unblacklistIP(lt.remote)

       • unblacklistLogin(<login>) - Remove the blacklist for the specified login.  For example:

                  unblacklistLogin(lt.login)

       • unblacklistIPLogin(<ip>, <login>) - Remove the  blacklist  for  the  specified  IP-Login
         tuple.  IP address must be a ComboAddress.  For example:

                  unblacklistIPLogin(lt.remote, lt.login)

       • checkBlacklistIP(<ip>)  -  Check  if  an  IP  is  blacklisted.  Return true if the IP is
         blacklisted.  IP must be a ComboAddress.  For example:

                  checkBlacklistIP(newCA("192.1.2.3"))

       • checkBlacklistLogin(<login>) - Check if a login is  blacklisted.   Return  true  if  the
         login is blacklisted.  For example:

                  checkBlacklistLogin(lt.login)

       • checkBlacklistIPLogin(<ip>,  <login>) - Check if a IP/login is blacklisted.  Return true
         if the ip/login tuple is blacklisted.  For example:

                  checkBlacklistIPLogin(lt.remote, lt.login)

       • whitelistNetmask(<Netmask>, <expiry>, <reason string>) - Whitelist the specified netmask
         for  expiry  seconds,  with  the  specified  reason.   Netmask address must be a Netmask
         object, e.g. created with newNetmask().  For example:

                  whitelistNetmask(newNetmask("12.32.0.0/16"), 300, "Attempted password brute forcing")

       • whitelistIP(<ip>, <expiry>, <reason string>) - Whitelist the  specified  IP  for  expiry
         seconds, with the specified reason.  IP address must be a ComboAddress.  For example:

                  whitelistIP(lt.remote, 300, "Attempted password brute forcing")

       • whitelistLogin(<login>,  <expiry>  <reason  string>) - Whitelist the specified login for
         expiry seconds, with the specified reason.  For example:

                  whitelistLogin(lt.login, 300, "Potentially compromised account")

       • whitelistIPLogin(<ip>, <login>, <expiry>, <reason string>)  -  Whitelist  the  specified
         IP-Login  tuple  for  expiry  seconds, with the specified reason.  Only when that IP and
         login are received in the same login tuple will the request be whitelisted.  IP  address
         must be a ComboAddress.  For example:

                  whitelistIPLogin(lt.remote, lt.login, 300, "Account and IP are suspicious")

       • unwhitelistNetmask(<Netmask>)  Remove  the whitelist for the specified netmask.  Netmask
         address must be a Netmask object, e.g. created with newNetmask().  For example:

                  unwhitelistNetmask(newNetmask("12.32.0.0/16"))

       • unwhitelistIP(<ip>) - Remove the whitelist for the specified IP.  IP address must  be  a
         ComboAddress.  For example:

                  unwhitelistIP(lt.remote)

       • unwhitelistLogin(<login>) - Remove the whitelist for the specified login.  For example:

                  unwhitelistLogin(lt.login)

       • unwhitelistIPLogin(<ip>,  <login>)  -  Remove  the  whitelist for the specified IP-Login
         tuple.  IP address must be a ComboAddress.  For example:

                  unwhitelistIPLogin(lt.remote, lt.login)

       • checkWhitelistIP(<ip>) - Check if an IP is  whitelisted.   Return  true  if  the  IP  is
         whitelisted.  IP must be a ComboAddress.  For example:

                  checkWhitelistIP(newCA("192.1.2.3"))

       • checkWhitelistLogin(<login>)  -  Check  if  a  login is whitelisted.  Return true if the
         login is whitelisted.  For example:

                  checkWhitelistLogin(lt.login)

       • checkWhitelistIPLogin(<ip>, <login>) - Check if a IP/login is whitelisted.  Return  true
         if the ip/login tuple is whitelisted.  For example:

                  checkWhitelistIPLogin(lt.remote, lt.login)

       • LoginTuple  -  The only parameter to both the allow and report functions is a LoginTuple
         table.  This table contains the following fields:

       • LoginTuple.remote -  An  IP  address  of  type  ComboAddress,  representing  the  system
         performing login.

       • LoginTuple.login - The username of the user performing the login.

       • LoginTuple.pwhash - A hashed representation of the users password

       • LoginTuple.success - Whether the user login was successful.

       • LoginTuple.policy_reject   -  If  the  login  was  not  successful  only  because  of  a
         policy-based reject from wforce (i.e. the username and password were correct).

       • LoginTuple.attrs - Additional array of  (single  valued)  attributes  about  the  login,
         e.g. information about the user from LDAP.  For example:

                   for k, v in pairs(lt.attrs) do
                       if (k == "xxx")
                       then
                           -- do something
                       end
                   end

       • LoginTuple.attrs_mv  -  Additional  array  of (multi-valued) attributes about the login.
         For example:

                   for k, v in pairs(lt.attrs_mv) do
                       for i, vi in ipairs(v) do
                           if ((k == "xxx") and (vi == "yyy"))
                           then
                               -- do something
                           end
                       end
                   end

       • LoginTuple.device_id - An optional string that  represents  the  device  that  the  user
         logged in from.  Also see device_attrs.

       • LoginTuple.device_attrs  -  Additional  array  of  attributes about the device, which is
         parsed from the device_attrs string.  The protocol string is used to  determine  how  to
         parse  device_id,  so  that MUST also be present.  For all protocols, the following keys
         are set wherever possible: os.family,  os.major,  os.minor.   For  http,  the  following
         additional  keys  are  set wherever possible: device.family, device.model, device.brand,
         browser.family, browser.major, browser.minor.  For imap, the following  additional  keys
         are  set  wherever possible: imapc.family, imapc.major, imapc.minor.  For mobileapi, the
         following  additional  keys  are  set:  app.name,   app.brand,   app.major,   app.minor,
         device.family.  For example:

                  if (lt.device_attrs["os.family"] == "Mac OS X")
                  then
                      -- do something special for macOS
                  end

       • LoginTuple.protocol  -  A string representing the protocol that was used to access mail,
         i.e. http, imap, pop3, mobileapi etc.  LoginTuple.protocol MUST be set in order to parse
         device_id  into  device_attrs,  however  currently  only  http,  imap  and mobileapi are
         recognized protocols when parsing device_id.  For example:

                  if (lt.protocol == "http")
                  then
                      -- do something
                  end

       • LoginTuple.tls - A boolean representing whether the login session used TLS or  not.   If
         the client is using TLS offload proxies then it may be set to false.

       • LoginTuple.session_id  -  An  optional string representing the particular session that a
         user used to login.  If this is not supplied by the wforce client, it will be  an  empty
         string.

       • GeoIPRecord - The type returned by the lookupCity() function.  See below for fields:

       • GeoIPRecord.country_code - The two-letter country code e.g. “US”.

       • GeoIPRecord.country_name - The country name, e.g. “United States”

       • GeoIPRecord.region - The region, e.g. “CA”

       • GeoIPRecord.city - The city name, e.g. “Mountain View”

       • GeoIPRecord.postal_code - The postal code, e.g. “93102” or “BA216AS”

       • GeoIPRecord.latitude - The latitude, e.g. 37.386001586914

       • GeoIPRecord.longitude - The longitude, e.g. -122.08380126953

       • CustomFuncArgs - The only parameter to custom functions is a CustomFuncArgs table.  This
         table contains the following fields:

       • CustomFuncArgs.attrs - Array of (single valued) attributes supplied by the caller.   For
         example:

                   for k, v in pairs(args.attrs) do
                       if (k == "xxx")
                       then
                           -- do something
                       end
                   end

       • CustomFuncArgs.attrs_mv  -  Array  of  (multi-valued) attributes supplied by the caller.
         For example:

                   for k, v in pairs(args.attrs_mv) do
                       for i, vi in ipairs(v) do
                           if ((k == "xxx") and (vi == "yyy"))
                           then
                               -- do something
                           end
                       end
                   end

       • incCustomStat(<stat name>) - Increment a custom statistics counter.  The  value  of  the
         counter will be logged every 5 minutes, and then reset.  For example:

                  incCustomStat("custom_stat1")

FILES

       /etc/wforce/wforce.conf

SEE ALSO

       wforce(1) wforce_webhook(5)

AUTHORS

       Open-Xchange.

                                               2018                                WFORCE.CONF(5)