summaryrefslogblamecommitdiffstats
path: root/computer/harry_potter_and_jabber_spam.rst
blob: 580de0bd8c9ffb139a43b4eea3621a13f59de5f2 (plain) (tree)



































                                                                 
                                                        




























































































































































                                                                        
Harry Potter and The Jabber Spam
################################

:date: 2017-01-13T16:21:16
:category: computer
:tags: xmpp

After many many years of happy using :abbr:`XMPP (Jabber)` we
were finally awarded with the respect of spammers and suddenly
some of us (especially those who have their :abbr:`JID (Jabber
ID)` in their email signature) are getting a lot of :abbr:`spim
(IM Spam)`.

Fortunately, the world of Jabber is not so defenceless, thanks to
`XEP-0016`_ (Privacy Lists). Not only it is possible to set up
list of known spammers (not only by their complete JIDs, but also
by whole domains), but it is also possible to build a more
complicated constructs.

Usually these constructs are not very well supported by GUI so
most of the work must be done by sending plain XML stanzas to the
XMPP stream. For example with pidgin_ one can open XMPP Console
by going to Tools/XMPP Console and selecting appropriate account
for which the privacy lists are supposed to be edited.

Whole system of ACLs consists from multiple lists. To get a list
of all those privacy lists for the particular server, we need to
send this XMPP stanza:

.. code-block:: xml

    <iq type='get' id='getlist1'>
            <query xmlns='jabber:iq:privacy'/>

    </iq>

If the stanza is sent correctly and your server supports
XEP-0016, then the server replies with the list of all privacy
lists:

.. code-block:: xml

    <iq id='getlist1' type='result'>
            <query xmlns='jabber:iq:privacy'>
                    <default name='urn:xmpp:blocking'/>
                    <list name='invisible'/>
                    <list name='urn:xmpp:blocking'/>
            </query>
    </iq>

To get a content of one particular list we need to send this
stanza:

.. code-block:: xml

    <iq type='get' id='getlist2'>
        <query xmlns='jabber:iq:privacy'>
            <list name='urn:xmpp:blocking'/>
        </query>
    </iq>

And again the server replies with this list:

.. code-block:: xml

    <iq id='getlist2' type='result'>
        <query xmlns='jabber:iq:privacy'>
            <list name='urn:xmpp:blocking'>
                <item order='0' action='deny'
                    value='talk.mipt.ru' type='jid'/>
                <item order='0' action='deny'
                    value='im.flosoft.biz' type='jid'/>
                <item order='0' action='deny'
                    value='nius.net' type='jid'/>
                <item order='0' action='deny'
                    value='jabber.me' type='jid'/>
                <item order='0' action='deny'
                    value='tigase.im' type='jid'/>
                <item order='0' action='deny'
                    value='pisem.net' type='jid'/>
                <item order='0' action='deny'
                    value='qip.ru' type='jid'/>
                <item order='0' action='deny'
                    value='crypt.mn' type='jid'/>
                <item order='0' action='deny'
                    value='atteq.com' type='jid'/>
                <item order='0' action='deny'
                    value='j3ws.biz' type='jid'/>
                <item order='0' action='deny'
                    value='jabber.dol.ru' type='jid'/>
                <item order='0' action='deny'
                    value='vpsfree.cz' type='jid'/>
                <item order='0' action='deny'
                    value='buckthorn.ws' type='jid'/>
                <item order='0' action='deny'
                    value='pandion.im' type='jid'/>
            </list>
        </query>
    </iq>

Server goes through every item in the list and decides based on
the value of ``action`` attribute. If the actual considered
stanza does not match any item in the list, the whole system
defaults to ``allow``.

I was building a blocking list like this for some time (I have
even authored `a simple Python script`_ for adding new JID to the
list), but it seems to be road to nowhere. Spammers are just
generating new and new domains. The only workable solution seems
to me to be white-list. Some domains are allowed, but everything
else is blocked.

See this list stanza sent to the server (answer should be simple
one line empty XML element):

.. code-block:: xml

    <iq type='set' id='setwl1'>
        <query xmlns='jabber:iq:privacy'>
            <list name='urn:xmpp:whitelist'>
                <item type='jid' value='amessage.de'
                      action='allow' order='1'/>
                <item type='jid' value='ceplovi.cz'
                      action='allow' order='2'/>
                <item type='jid' value='cepl.eu'
                      action='allow' order='3'/>
                <item type='jid' value='dukgo.com'
                      action='allow' order='4'/>
                <item type='jid' value='eischmann.cz'
                      action='allow' order='5'/>
                <item type='jid' value='gmail.com'
                      action='allow' order='7'/>
                <item type='jid' value='gtalk2voip.com'
                      action='allow' order='8'/>
                <item type='jid' value='jabber.at'
                      action='allow' order='9'/>
                <item type='jid' value='jabber.cz'
                      action='allow' order='10'/>
                <item type='jid' value='jabber.fr'
                      action='allow' order='11'/>
                <item type='jid' value='jabber.org'
                      action='allow' order='12'/>
                <item type='jid' value='jabber.ru'
                      action='allow' order='13'/>
                <item type='jid' value='jabbim.cz'
                      action='allow' order='14'/>
                <item type='jid' value='jankratochvil.net'
                      action='allow' order='15'/>
                <item type='jid' value='kde.org'
                      action='allow' order='16'/>
                <item type='jid' value='loqui.im'
                      action='allow' order='17'/>
                <item type='jid' value='mac.com'
                      action='allow' order='18'/>
                <item type='jid' value='metajack.im'
                      action='allow' order='19'/>
                <item type='jid' value='njs.netlab.cz'
                      action='allow' order='20'/>
                <item type='jid' value='stpeter.im'
                      action='allow' order='21'/>
                <item type='jid' value='ucw.cz'
                      action='allow' order='22'/>
                <item action='deny' order='23'/>
            </list>
        </query>
    </iq>

Server goes in order through all items on the list, and if it
doesn’t match on any item, it hits the last item in the list,
which denies the access.

It is also useful to make sure the list which have actually
created be default:

.. code-block:: xml

    <iq type='set' id='default1'>
        <query xmlns='jabber:iq:privacy'>
            <default name='urn:xmpp:whitelist'/>
        </query>
    </iq>

So, now I am in the state of testing, how it works (using as
server jabberd2 version 2.4.0 from the RHEL-6/EPEL package).

.. _`XEP-0016`:
    http://xmpp.org/extensions/xep-0016.html

.. _pidgin:
    http://pidgin.im/

.. _`a simple Python script`:
    https://github.com/horazont/aioxmpp/blob/devel/examples/block_jid.py