summaryrefslogtreecommitdiffstats
path: root/computer/harry_potter_and_jabber_spam.rst
blob: 580de0bd8c9ffb139a43b4eea3621a13f59de5f2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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