-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathuser-authentication.xml
342 lines (285 loc) · 15.2 KB
/
user-authentication.xml
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="user-authentication">
<title>User and credential storage</title>
<para>Most of the products described in this document, including
SIP proxy servers, XMPP servers, TURN servers and soft PBXes offer a range
of choices for maintaining a user database and storing user
credentials.</para>
<sect1 xml:id="user-authentication-credentials">
<title>Credentials</title>
<sect2 xml:id="user-authentication-usernames">
<title>Personal account names or extension numbers</title>
<para>An issue that arises early in many discussions about this
topic is whether to use email addresses of the form
<literal>username@example.org</literal> or to use extension
numbers as the account identifiers.</para>
<para>In most cases, users still need to be able to be contactable
using either type of address, but the question remains: should
their phone login to the system using a named username or using an
extension number?</para>
<para>Extension numbers are the standard in many traditional phone
systems and some people have simply tried to replicate this model
when moving to IP-based RTC.</para>
<para>There are three big reasons why numbers are popular:
numbers can be dialed from anywhere else in the PSTN,
numbers are easier to dial for people who are not calling from a
computer (phones only have 12 buttons) and there is not always
a one-to-one mapping between people and phones. One additional
feature of numbers is that they are slightly less personal,
somebody does not know exactly who will answer when they
call a landline in a house shared by a large family and when
somebody leaves a job, their phone number can be assigned to
their successor.</para>
<para>Mobile telephones and smartphones in particular have
dramatically reduced the significance of these factors that encouraged
the continued use of numbers. For example, the inconvenience of manually
dialing a SIP or XMPP address is not such a big factor because people are
more likely to have these details in their address books.</para>
<para>Phone numbers also have disadvantages. One of these is the
dependency on phone companies, the ITU and government bureaucracies
who administer the numbering system. Users can be forced to change
their phone number when changing provider. Dialing codes change,
making it necessary to update old records in an address book.
Each group of numbers is tightly bound to the infrastructure of a
specific the telephone exchange, leading to inflexibility when relocating
or when a local service outage occurs.</para>
<sect3>
<title>Recommendation</title>
<para>Use alphabetic usernames rather than extension numbers
internally. SIP, XMPP and email each support a slightly different
set of characters in usernames so only use the set of characters
supported for all protocols. Wherever a device is being used with
named accounts, such as a desktop PC where users login and have
access to their own company email account, or a smartphone that
is only used by one person and has been configured to access
a named email account, provision the same personalized SIP/XMPP
address on that device. Where a device is shared, such as a
conference room phone, create a named account for that purpose.</para>
<para>It is generally helpful if the same username is used for
login, email address, SIP and XMPP addresses. If the login names
are not the same as email addresses, use the email addresses as
the SIP and XMPP addresses.</para>
<para>To give users the convenience of dialing extension numbers
from regular phones, create mappings from the extension numbers
to the usernames.</para>
<para>This strategy offers significantly more potential for
the future as more and more services will rely on usernames and
fewer services will place emphasis on phone numbers.</para>
<para>When using this strategy, it is necessary to implement
mappings from phone numbers to usernames as part of the
<emphasis>ingress</emphasis> processing and for calls that go
out to the PSTN over SIP or ISDN trunks, it is necessary to
implement the reverse mapping, ensuring that the caller ID of each
outgoing call is personalized based on the internal username.</para>
</sect3>
</sect2>
<sect2>
<title>Password encryption</title>
<para>It is not strictly necessary to use passwords for SIP, XMPP
and TURN, you can use certificate authentication instead.
Nonetheless, many people find that some of their users can only
support password authentication or they don't want the complexity
of managing public key infrastructure (PKI).</para>
<para>XMPP transmits passwords in cleartext, so all XMPP
connections should be secured with TLS to avoid eavesdropping.
The benefit of this approach is that XMPP users can be
authenticated against any type of pre-hashed passwords or using
a method such as LDAP bind to verify the supplied credential.</para>
<para>SIP and TURN use a DIGEST algorithm very similar to
HTTP DIGEST. The DIGEST algorithm requires the server to have
either an unencrypted copy of the password, a password encrypted
with the HA1 algorithm or a service (such as RADIUS) that can
perform delegated DIGEST authentication.</para>
<para>If unencrypted passwords are available, then the SIP and
TURN servers can use them to construct the HA1 hash value or
you can precompute the HA1 values and store them in a database.</para>
<warning>
<para>HA1 hash values should be considered as sensitive as
unencrypted passwords. Even though the plaintext password can't
be recovered in a simple manner, anybody in possession of the
HA1 value is able to use it to construct a response to a HTTP
or SIP DIGEST challenge, thereby impersonating the user who
owns that password. Therefore, do not keep HA1 hash values in
world-readable configuration files or publicly accessible in
LDAP.</para>
</warning>
</sect2>
<sect2>
<title>HA1 in detail</title>
<para>The HA1 hash includes the username, the password and the realm.
A HA1 hash can be easily constructed at the UNIX command line
as demonstrated in <xref linkend="auth-make-ha1"/>.</para>
<example xml:id="auth-make-ha1">
<title>Computing HA1</title>
<programlisting format="linespecific">$ echo -n "alice:example.org:secret" | md5sum
543e1aec5d3614f03141652d6ada51b2 -
$ echo -n "alice@example.org:example.org:secret" | md5sum
1441a999b257bcd0cf5166930039876a -</programlisting>
</example>
<para>In both examples, the realm is <code>example.org</code>.</para>
<para>In the first case, the user authenticates using the
username <code>alice</code>. In the second case, the user
authenticates using the username <code>alice@example.org</code>.
This second permutation is referred to by some products as
<emphasis>HA1B</emphasis>. Some people prefer to use the full
<emphasis>user@domain</emphasis> syntax to support virtual hosting
with a single <emphasis>realm</emphasis> value on a single SIP
proxy or TURN server.</para>
</sect2>
</sect1>
<sect1 xml:id="user-authentication-databases">
<title>Databases</title>
<sect2>
<title>RADIUS</title>
<para>IETF <code>draft-sterman-aaa-sip-04</code> describes a
mechanism for RADIUS servers to participate in a SIP DIGEST
challenge/response without the SIP proxy having a copy of the
password or HA1 value at all. This is implemented by the
<emphasis>FreeRADIUS</emphasis> project in the module
<link xlink:href="http://wiki.freeradius.org/modules/Rlm_digest">
<code>rlm_digest</code></link> and supported by all the major
SIP proxy servers.</para>
<para>At the time of writing, work is in progress to enable RADIUS
to participate in TURN authentication in the same way.</para>
</sect2>
<sect2>
<title>LDAP</title>
<para>If LDAP is in use, you may wish to consider storing the
HA1 values in the LDAP directory. Each time a user is created
or a user changes their password, the LDAP server will need to
update the HA1 hash as well as updating any other copies of the
password hashed with other algorithms.</para>
<para>For example, the <emphasis>OpenLDAP</emphasis> server
allows such logic to be implemented in an overlay, this is
already demonstrated in the <emphasis>smbk5pwd</emphasis> module
for hashing copies of the user's password in various algorithms
used by Windows.</para>
<para>Due to the sensitive nature of the HA1 values, they
should be stored in an attribute that is not readable to any
other user or anonymous access. <xref linkend="openldap-acl-ha1"/>
demonstrates how to protect the <code>ha1Password</code> so it can
only be read by a user
<code>cn=sip-proxy,dc=example,dc=org</code>.</para>
<example xml:id="openldap-acl-ha1">
<title><emphasis>OpenLDAP</emphasis> ACL for protecting
<code>ha1Password</code></title>
<programlisting format="linespecific"> access to attr=ha1Password
by self =xw
by dn="cn=sip-proxy,dc=example,dc=org" read
by anonymous auth
by * none </programlisting>
</example>
<para>LDAP can also be used to assist in routing as described in
<xref linkend="enum"/>.</para>
</sect2>
<sect2 xml:id="user-authentication-sql">
<title>SQL databases</title>
<para>Many RTC products have some capability to interact with an
SQL database to obtain user credentials, configuration settings
and routing information. <xref linkend="postgresql-users-repro"/>
demonstrates a typical schema.</para>
<example xml:id="postgresql-users-repro">
<title>SQL table for repro users</title>
<programlisting format="linespecific">CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(64) NOT NULL,
domain VARCHAR(253),
realm VARCHAR(253),
passwordHash VARCHAR(32),
passwordHashAlt VARCHAR(32),
name VARCHAR(256),
email VARCHAR(256),
forwardAddress VARCHAR(256)
);</programlisting>
</example>
<para>Each product has a different schema, however, it is possible
to create a user list table that aggregates all the columns
required to satisfy multiple processes and then create SQL views to
present the data with the column names required by the individual
applications. For example, a single user list table can be created
for use by Asterisk (the <literal>sippeers</literal> table) and used
by repro (using a view instead of a real <literal>users</literal> table)
as demonstrated in <xref linkend="postgresql-view-repro-asterisk"/>.
repro simply doesn't require many of the columns used by Asterisk.
Notice that Asterisk's <literal>sippeers</literal> table doesn't
contain a domain or realm column for each user, these are stored
elsewhere in the <literal>sip.conf</literal> file, so for repro, they
are specified as constant values in the <literal>SELECT</literal> query.
</para>
<example xml:id="postgresql-view-repro-asterisk">
<title>SQL view presenting Asterisk users to repro</title>
<programlisting format="linespecific">CREATE VIEW users AS
SELECT
id,
name AS username,
'my_domain' AS domain,
'my_realm' AS realm,
md5secret AS passwordHash,
NULL As passwordHashAlt,
NULL AS name,
NULL AS email,
NULL AS forwardAddress
FROM sippeers;</programlisting>
</example>
<sect3 xml:id="user-authentication-sql-setup-postgresql">
<title>Setting up PostgreSQL for SIP users</title>
<para>The packages for the <emphasis>repro</emphasis> SIP proxy
include SQL schema files for creating tables.
<xref linkend="postgresql-install-debian"/> demonstrates how
to install the <emphasis>PostgreSQL</emphasis> server package.
<xref linkend="postgresql-setup-debian"/> demonstrates how
to use the <code>createdb</code> command to create a database
called <code>repro</code> and use the <code>psql</code>
command to log in as the <emphasis>DBA</emphasis> and
create a user called <code>repro</code> for the SIP proxy.
The final <code>psql</code> command uses the schema file
to create the tables.</para>
<example xml:id="postgresql-install-debian">
<title>Install <emphasis>PostgreSQL</emphasis> on Debian or Ubuntu</title>
<programlisting format="linespecific">$ sudo apt-get install postgresql postgresql-client</programlisting>
</example>
<example xml:id="postgresql-setup-debian">
<title>Configure PostgreSQL and load schema</title>
<programlisting format="linespecific">$ sudo su - postgres
postgres$ createdb repro
postgres$ psql
postgres=# create user repro password 'abc';
postgres=# \q
postgres$ exit
$ su vi /etc/postgresql/9.4/main/pg_hba.conf
$ su systemctl restart postgresql
$ psql -U repro -W repro < /usr/share/doc/repro/create_postgresql_reprodb.sql</programlisting>
</example>
</sect3>
</sect2>
<sect2>
<title>Product-specific file formats</title>
<para>Each product also supports some native file formats.
For example, <emphasis>repro</emphasis> can store user data in
<emphasis>Berkeley DB</emphasis> files while
<emphasis>Asterisk</emphasis> can store users in the
<code>sip.conf</code> text file. The <emphasis>Prosody</emphasis>
XMPP server can store its data in JSON files. In some cases, the
files are maintained by the administrator using a text editor and
in other cases they are updated at runtime by the application.</para>
<para>To eliminate the risk of runtime dependencies on databases,
it is relatively straightforward to create a script that
periodically extracts user data from a database and creates files
for the relevant processes to consume. If one of the processes has
to start up or continue operating during a database outage, it will
be able to do so using the last copy of the file.</para>
</sect2>
</sect1>
<sect1 xml:id="user-authentication-conclusion">
<title>Conclusion</title>
<para>A guide like this can't proscribe the correct solution for
every scenario. This chapter simply aims to raise awareness of all
the options for storing usernames and credentials and making them
accessible to RTC processes. System administrators and developers
will need to consider the infrastructure that is already present
when deciding which of these options are most relevant for a given
site.</para>
</sect1>
</chapter>