<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Hi Andrey,<div><div><br><blockquote type="cite"><div>On 11 Apr 2024, at 3:27 AM, Andrey Kulikov <amdeich@gmail.com> wrote:</div><br class="Apple-interchange-newline"><div><div dir="ltr"><div>Hello,</div><div><br></div><div>Consider the following test-case:</div><div>I, as admin, would like to limit access to certain resources, based on Client TLS certificate content, fields, etc...</div><div><br></div><div>Solution for HTTP: Easy!</div><div>There is 
<code>NGX_HTTP_ACCESS_PHASE</code> phase, where connections have been already accepted, and I have access to all $ssl_client_* variables.</div><div>And I control whatever I want, either using the if directive, or by implementing arbitrary sophisticated logic with some custom module.</div><div><br></div><div>
Solution for Stream: Simply impossible!</div><div>On NGX_STREAM_ACCESS_PHASE only IP-addresses can be checked, as TLS has not taken place yet.</div><div>NGX_STREAM_SSL_PHASE seems to be intended to specify certificates/keys for performing TLS handshake.</div><div>On NGX_STREAM_PREREAD_PHASE no 
$ssl_client_* variables available, as TLS handshake has not finished yet.</div><div>On NGX_STREAM_CONTENT_PHASE it is too late to do anything, as connection to the destination server was already established.</div><div>Hard way: implement a custom stream filter module, 
which checks access criteria on 
NGX_STREAM_CONTENT_PHASE. But it looks overcomplicated... 

</div><div><br></div><div>Proposal:</div><div>Extend list of Stream phases at least to following:</div><div><br></div><div>typedef enum {<br>    NGX_STREAM_POST_ACCEPT_PHASE = 0,<br>    NGX_STREAM_PREACCESS_PHASE,<br>    NGX_STREAM_ACCESS_PHASE,<br>    NGX_STREAM_SSL_PHASE,<br>    NGX_STREAM_PREREAD_PHASE,</div><div>+  NGX_STREAM_PRE_CONTENT_PHASE, // Change name to whatever seems suitable.<br></div><div>    NGX_STREAM_CONTENT_PHASE,<br>    NGX_STREAM_LOG_PHASE<br>} ngx_stream_phases;<br></div><div><br></div><div>Questions:</div><div>Does it look feasible?</div><div>Are there any objectives NOT to do anything like this? (binary compatibility, etc...)<br></div><div>If I implement a trivial patch to extend the number of phases, will it be considered for review?<br></div></div></div></blockquote><div><br></div><div>While the problem does exist, precontent phase is not the right place for access control anyway.</div><div><br></div><div>There's another solution. With the introduction of ngx_stream_pass_module, you can terminate TLS in one server and then switch to another server for access control.</div><div><br></div><div>server {</div><div>    listen 9000 ssl;</div><div>    ...</div><div>    pass 127.0.0.1:9001;</div><div>}</div><div><br></div><div>server {</div><div>    listen 127.0.0.1:9001;</div><div>    # access control in access phase</div><div>    ...</div><div>}</div></div><br><div>
<div dir="auto" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div>----</div><div>Roman Arutyunyan</div><div>arut@nginx.com</div><div><br></div></div><br class="Apple-interchange-newline"><br class="Apple-interchange-newline">

</div>
<br></div></body></html>