<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="generator" content="Osso Notes">
    <title></title></head>
<body>
<p>----- Original message -----
<br>&gt; Hi!
<br>&gt; 
<br>&gt; Csaba Major &lt;<a href="mailto:csaba.major@balabit.com">csaba.major@balabit.com</a>&gt; writes:
<br>&gt; 
<br>&gt; &gt; I have a system where I have a lot of logs with IP addresses
<br>&gt; &gt; (typically firewall logs), and the requirement was to also include the
<br>&gt; &gt; country name in the logs. I found that a geoip based template function
<br>&gt; &gt; would be an easy way for this, so I created a PoC for that.
<br>&gt; 
<br>&gt; This sounds very interesting, thanks for the PoC!
<br>
<br>indeed, it is.
<br>
<br>&gt; 
<br>&gt; &gt; The created patch is attached (based on 3.3.5), some may find it
<br>&gt; &gt; useful :) (It requires libgeoip, and a geoip database, of course)
<br>&gt; 
<br>&gt; See my comments below. The idea is wonderful, and I'll prep up an
<br>&gt; improved version for 3.4. Since you want it for 3.3, I'll also create a
<br>&gt; patch for that branch too, but it's 3.4 where it can be merged, if Bazsi
<br>&gt; likes the idea too.
<br>&gt; 
<br>&gt; &gt; --- /dev/null
<br>&gt; &gt; +++ b/modules/tfgeoip/Makefile.am
<br>&gt; &gt; @@ -0,0 +1,11 @@
<br>&gt; &gt; +moduledir = @moduledir@
<br>&gt; &gt; +export top_srcdir
<br>&gt; &gt; +
<br>&gt; &gt; +#if ENABLE_UUID
<br>&gt; &gt; +AM_CPPFLAGS = -I$(top_srcdir)/lib -I../../lib $(GEOIP_CFLAGS)
<br>&gt; &gt; +module_LTLIBRARIES = libtfgeoip.la
<br>&gt; &gt; +
<br>&gt; &gt; +libtfgeoip_la_SOURCES = tfgeoip.c
<br>&gt; &gt; +libtfgeoip_la_LIBADD = $(MODULE_DEPS_LIBS) $(GEOIP_LIBS)
<br>&gt; &gt; +libtfgeoip_la_LDFLAGS = $(MODULE_LDFLAGS)
<br>&gt; &gt; +#endif
<br>&gt; 
<br>&gt; I assume s/UUID/GEOIP/ :)
<br>&gt; 
<br>&gt; &gt; diff --git a/modules/tfgeoip/tfgeoip.c b/modules/tfgeoip/tfgeoip.c
<br>&gt; &gt; new file mode 100644
<br>&gt; &gt; index 0000000..eeea330
<br>&gt; &gt; --- /dev/null
<br>&gt; &gt; +++ b/modules/tfgeoip/tfgeoip.c
<br>&gt; [...]
<br>&gt; &gt; +static void
<br>&gt; &gt; +tf_geoip(LogMessage *msg, gint argc, GString *argv[], GString *result)
<br>&gt; &gt; +{
<br>&gt; &gt; +&nbsp; &#32;GeoIP * gi;
<br>&gt; &gt; +&nbsp; &#32;const char * returnedCountry;
<br>&gt; &gt; +
<br>&gt; &gt; +&nbsp; &#32;if (argc != 1)
<br>&gt; &gt; +&nbsp; &nbsp; &nbsp; &#32;return;
<br>&gt; &gt; +&nbsp; &#32;gi = GeoIP_open("/usr/share/GeoIP/GeoIP.dat", GEOIP_STANDARD);
<br>
<br>probably some caching would make sense here. perhaps even enhancing the dns cache code with the ability to store such information. template functions can be invoked for every message, opening and parsing the geoip database is probably very expensive.
<br>
<br>&gt; &gt; +
<br>&gt; &gt; +&nbsp; &#32;returnedCountry = GeoIP_country_code_by_addr(gi, argv[0]-&gt;str);
<br>&gt; &gt; +&nbsp; &#32;g_string_append_printf (result, "%s", returnedCountry);
<br>&gt; &gt; +}
<br>&gt; 
<br>&gt; As you mentioned in person, it would be nice if the template function
<br>&gt; could be configured, preferably globally, so that one wouldn't have to
<br>&gt; repeat the same parameters over and over again in every template where
<br>&gt; it would be used.
<br>
<br>I'm not sure, templates can be declared as objects, referenced from multiple locations in the config. it is true though that this would probably be used in the naming of files which can't be declared in advance. what kind of settings would this be about?
<br>
<br>&gt; 
<br>&gt; Things like returning country vs country code, the location of the
<br>&gt; database and so on and so forth should be configurable.
<br>&gt; 
<br>
<br>hmmm. isn't the database location fixed?
<br>
<br>I think when naming files, the country code should be enough.
<br>
<br>what about using global @define based variables for this purpose? that would probably be simple to access from within the template function and is global.
<br>
<br>the con of this is that nothing else uses @define yet.
<br>
<br>&gt; The best would be to have a geoip() option in the global option space,
<br>&gt; but I'm not sure a plugin can hook into that.
<br>&gt; 
<br>
<br>The syslog-ng team added some mechanisms to hook into the global options block though, but last time I looked I wasn't very happy about the implementation.
<br>
<br>let's talk about this the coming monday.
<br>
<br>&gt; I suppose the first thing would be to add commandline handling to
<br>&gt; tf_geoip first, so at least it's configurable. Then figure out a way to
<br>&gt; make global configuration possible. I have no idea whether this latter
<br>&gt; is possible with current syslog-ng 3.4, but this is a great opportunity
<br>&gt; to make it possible to do this.
<br>&gt; 
<br>&gt; Unless you want to work on this yourself further, I'll spice it up with
<br>&gt; error handling and basic configurability in the next few days.
<br>&gt; 
<br>&gt; Come to think of it, perhaps it would make sense to introduce a new
<br>&gt; rewrite command, something along the lines of:
<br>&gt; 
<br>&gt; rewrite r_geoip {
<br>&gt;&nbsp; &nbsp; &#32;apply(geoip("SRCIP"), "GEOIP");
<br>&gt; };
<br>&gt; 
<br>&gt; This would apply the "geoip" function to the value of the "SRCIP" key,
<br>&gt; and place the result in ${GEOIP}. The advantage of this is that it's
<br>&gt; perhaps faster to do this than parsing a template function and using
<br>&gt; g_string_append_printf to reassemble another string.
<br>&gt; 
<br>
<br>I'm not sure why this would be faster than the set() rewrite op.
<br>
<br>&gt; Similarly, this same apply() thing could be used to permanently modify
<br>&gt; the name-value pairs: similar to what value-pairs() does, but instead of
<br>&gt; returning a different, entirely independent set of name-value pairs, we
<br>&gt; could apply the same transformations and filtering within a rewrite
<br>&gt; rule:
<br>&gt; 
<br>&gt; rewrite r_vp {
<br>&gt;&nbsp; &nbsp; &#32;apply(value-pairs("*" rekey(subst(".", "_"))));
<br>&gt; };
<br>&gt; 
<br>&gt; This would take all keys, and replace leading dots in key names with an
<br>&gt; underscore instead, and it would modify the stuff in-place, so that
<br>&gt; anything that works with the message from this point onward, would see
<br>&gt; the rewritten names.
<br>
<br>this is a more interesting use-case.
<br>
<br>&gt; 
<br>&gt; In essence, apply() would have a syntax like
<br>&gt;&nbsp; &#32;apply(FUNCTION(...)[, OUTPUT_VARIABLE])
<br>&gt; 
<br>&gt; The function could either modify the LogMessage object itself, or return
<br>&gt; a value. Functions would need to signal which one they do, and the
<br>&gt; config parser would not allow using a function with an output value
<br>&gt; without specifying a destination, etc.
<br>&gt; 
<br>&gt; ...but I guess I'll draft up an RFC about this instead with a few more
<br>&gt; possible use cases, advantages &amp; disadvantages and the rest.
<br>&gt; 
<br>
<br>good ideas, but I would be careful to introduce another programmable mechanism in this syntax. so the usecases are interesting, I'm not sure about the proposed solutions.</p>
</body>
</html>