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