Philipp Schafft
2018-Nov-09 11:10 UTC
[Icecast] Micro Guide to Understanding Icecast 2.5.x authentication (For Icecast 2.5 beta 3)
Good morning, as there has been some confusion I thought it might be best to write some little "Micro Guide" for Icecast 2.5.x's authentication subsystem. This E-Mail refers to not yet released version 2.5 beta 3 (to be released soon). !!! /!\ !!! If you run Icecast 2.4.x (stable) this E-Mail is not relevant to you! !!! /!\ !!! Overview Icecast 2.5.x changed the authentication system very much since Icecast 2.4.x. But good news first: Icecast 2.5.x can read Icecast 2.4.x config files and will behave correctly. The new system works by a set of rules. Rules are tried from top to bottom. The first one that matches wins. When a rule matches a set of access control parameters are set. Rules can be defined by (and tried in this order): * listen sockets (<listen-socket>), * normal mounts (<mount type="normal">), * default mounts (<mount type="default">), * the global list (<icecast>). Each of those blocks can contain a <authentication> subtag. (Note: It must not set a type="", otherwise it will be interpreted as Icecast 2.4.x config). Each such <authentication> can contain a number of <role> tags. Each <role> tag defines a rule. A <role> tag can include <option>, and <http-headers> tags. <option> tags are used to define additional options for the used backend the same way as they did in 2.4.x. Examples can be found at the end of this E-Mail. Defining a role A <role> represents a rule in the system. The servers will try all related <role>s when a client connects in from top to bottom. A role may contain filters on parameters of the client. Such as the request method. By default no filters are used. When the role's filters match the request (or no filters are set) the configured backend is asked. Such backends include static username/password sets or more empowered backends such as the URL auth backend. The will report a positive (success) or negative match (access deny) or no-match (the next rule is tried). When a role returned a negative match access to the requested resource is denied. When a positive match is returned the given access control rules are applied. Defining access control rules Access control rules can be defined as part of the <role> tag. There currently are the following access parameters that can be set: * which HTTP methods are allowed (such as GET or PUT) (allow-method, deny-method; default: allow only GET and OPTIONS), * which admin/ commands are allowed (allow-admin, deny-admin; default: allow only buildm3u (playlist generation)), * if web/ access (that is the status page and the actual streams) is allowed (allow-web, deny-web; default: allow web access), * how many simultaneous connections can be made by a user (connections-per-user; default: unlimited connections), * how long a listener might listen to a stream before being automatically disconnected (connection-duration; default: unlimited time). Examples: Consider the following global <authentication> block: <authentication> <role type="static" allow-all="*" > <option name="username" value="admin" /> <option name="password" value="hackme" /> </role> <role type="static" allow-web="*" deny-admin="*" > <option name="username" value="listener" /> <option name="password" value="salad" /> </role> <role type="anonymous" deny-all="*" /> </authentication> This first checks for a user with the username "admin" and the password "hackme". If the client sent those credentials it allowd to have full access (allow-all="*"). Then the server checks for the user with username "listener" and password "salad". If the client sent those credentials to the server it is allowed web access (and listening to streams) (allow-web="*") but no admin access (deny-admin="*"). If no of the above rules match the last rule matches and forbids all access (deny-all="*"). Now let's consider the following additional block: <mount type="normal"> <mount-name>/example1.ogg</mount-name> <authentication> <role type="static" allow-web="*"> <option name="username" value="friend" /> <option name="password" value="wine" /> </role> </authentication> </mount> This <mount> block configures the mountpoint "/example1.ogg". It contains a <authentication> with a single <role>. Let's see what happens: Now if a client connects to this specific mount point it is first checked if it's our friend "friend" with the password "wine". If it's our friend we allow listen him to listen to the stream as well. Here no rule for admin access has been defined, so the default value is used: Allow playlist generation only. If the client is not our friend, the rules from the global section are tried. Our last example will disable admin access on a given listen socket (e.g. for restricting it to an internal interface). We do this by applying a filter. Consider the following block: <listen-socket> <bind-address>192.0.2.137</bind-address> <port>8000</port> <authentication> <role type="anonymous" match-admin="*" nomatch-web="*" deny-all="*" /> </authentication> </listen-socket> In this example all clients that request admin any admin commands (match-admin="*") but no clients requesting web/ resources (nomatch-web="*") are rejected (deny-all="*"). Conclusion and looking forward The new authentication subsystem is very powerful and can be used for complex setups. However it requires more understanding of rule based access control. The new and the old style configs can freely be mixed to enable both a smooth transition as well as make simple setups keep simple (e.g. by using the old style <source-password> tag). We currently work on ways to make the config a bit simpler and also to document things better. This E-Mail is a first part of this. There are a lot more options that have not been covered in this E-Mail such as more complex matching setups or backend based client rewrites. There are also some more ideas for the future features such as better integration of <resource>[0][1] or optimizations to keep load off the actual backend by handling challenge requests internally. I'm happy to answer all questions and looking forward to any feedback! With best regards, [0] Previously known as <alias>. Has been improved a lot! [1] Maybe worth another E-Mail? Let me know if there is interest. -- Philipp Schafft (CEO/Geschäftsführer) Telephon: +49.3535 490 17 92 Löwenfelsen UG (haftungsbeschränkt) Registration number: Bickinger Straße 21 HRB 12308 CB 04916 Herzberg (Elster) VATIN/USt-ID: Germany DE305133015 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 490 bytes Desc: This is a digitally signed message part URL: <http://lists.xiph.org/pipermail/icecast/attachments/20181109/8a35ec55/attachment.sig>