Hello!
Here are patches for OCSP stapling support. Testing and
review appreciated.
New directives:
ssl_trusted_certificate /path/to/file;
Specifies a file with CA certificates in the PEM format used for
certificate verification. In contrast to ssl_client_certificate, DNs
of these certificates aren't sent to a client in CertificateRequest.
ssl_stapling on|off;
Activates OCSP stapling.
ssl_stapling_file /path/to/file;
Use predefined OCSP response for stapling, do not query responder.
Assumes OCSP response in DER format as produced by "openssl ocsp".
ssl_stapling_responder URL;
Use specified OCSP responder instead of one found in AIA certificate
extension.
Example configuration:
server {
listen 443 ssl;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_stapling on;
ssl_trusted_certificate /path/to/ca.pem;
resolver 8.8.8.8;
}
Known limitations:
- Unless externally set OCSP response is used (via the "ssl_stapling_file"
directive), stapled response won't be sent in a first connection. This
is due to the fact that OCSP responders are currently queried by nginx
once it receives connection with certificate_status extension in ClientHello,
and due to limitations in OpenSSL API (certificate status callback is
blocking).
- Cached OCSP responses are currently stored in local process memory (thus
each worker process will query OCSP responders independently). This
shouldn't be a problem as typical number of worker processes is low, usually
set match number of CPUs.
- Various timeouts are hardcoded (connect/read/write timeouts are 60s,
response is considered to be valid for 1h after loading). Adding
configuration directives to control these would be trivial, but it may
be a better idea to actually omit them for simplicity.
- Only "http://" OCSP responders are recognized.
Patch can be found here:
http://nginx.org/patches/ocsp-stapling/
Thanks to Comodo, DigiCert and GlobalSign for sponsoring this work.
Maxim Dounin
Hello,
I have written a module to implement sFlow in nginx (nginx-sflow-module.googlecode.com). I'm simulating a 1-second timer-tick by assuming that the request handler will be called at least once per second. That's probably a safe assumption for any server that would care about sFlow monitoring, but I expect there's a better way...
I tried asking for a timer callback like this:
ngx_event_t *ev = ngx_pcalloc(pool, sizeof(ngx_event_t));
ev->hander = ngx_http_sflow_tick_event_hander;
ngx_add_timer(ev, 1000);
but (like most russian girls) the event never called me back. It looks like I might have to hang this on a file-descriptor somehow, but that's where I'm getting lost. Any pointers would be most appreciated.
Neil
Hello!
According to the current implementation of ngx_http_upstream, there is
almost no way for 3rd-party output body filters and "post_subrequest"
handlers (in the subrequest context) to know if there's any errors
while ngx_http_upstream is processing the upstream response body after
the response header is sent out (in both the buffered and non-buffered
modes).
For example, if
1. a read-timeout happens in the middle of the process of reading the
upstream response body,
2. or the upstream connection is closed prematurely in the same situation,
then ngx_http_upstream will just happily finalize the current request
with the status code 0 (i.e., NGX_OK). This issue already affects at
least our ngx_srcache and ngx_lua modules (originally reported by
Bryan Alger).
Here attaches a patch that makes ngx_http_upstream set
r->headers_out.status to a new error status code to notify the outside
world if there is a problem. Comments will be highly appreciated as
always :)
Thanks!
-agentzh
--- nginx-1.2.3/src/http/ngx_http_upstream.c 2012-08-06 10:34:08.000000000 -0700
+++ nginx-1.2.3-patched/src/http/ngx_http_upstream.c 2012-09-09
21:58:04.727761891 -0700
@@ -2383,7 +2383,7 @@
if (c->read->timedout) {
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
- ngx_http_upstream_finalize_request(r, u, 0);
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
return;
}
@@ -2430,13 +2430,17 @@
if (u->busy_bufs == NULL) {
if (u->length == 0
- || upstream->read->eof
- || upstream->read->error)
+ || (upstream->read->eof &&
u->headers_in.content_length_n == -1))
{
ngx_http_upstream_finalize_request(r, u, 0);
return;
}
+ if (upstream->read->eof || upstream->read->error) {
+ ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_BAD_GATEWAY);
+ return;
+ }
+
b->pos = b->start;
b->last = b->start;
}
@@ -2710,7 +2714,16 @@
#if 0
ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
#endif
- ngx_http_upstream_finalize_request(r, u, 0);
+
+ if (p->upstream_done
+ || (p->upstream_eof && u->headers_in.content_length_n == -1))
+ {
+ ngx_http_upstream_finalize_request(r, u, 0);
+
+ } else {
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
+ }
+
return;
}
}
@@ -3073,6 +3086,13 @@
&& rc != NGX_HTTP_REQUEST_TIME_OUT
&& (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE))
{
+ if (rc == NGX_ERROR) {
+ r->headers_out.status = NGX_HTTP_INTERNAL_SERVER_ERROR;
+
+ } else {
+ r->headers_out.status = rc;
+ }
+
rc = 0;
}
Based on Apache HTTPD autoindex docs[1]. Supported:
- C=N sorts the directory by file name
- C=M sorts the directory by last-modified date, then file name
- C=S sorts the directory by size, then file name
- O=A sorts the listing in Ascending Order
- O=D sorts the listing in Descending Order
Not supported (does not make sense for nginx):
- C=D sorts the directory by description, then file name
- All F= (FancyIndex) related arguments
- Version sorting for file names (V=)
- Pattern filter (P=)
Argument processing stops when the query string does not exactly match the
options allowed by nginx, invalid values (like "C=m", "C=x" or "C=foo") are
ignored and cause further processing to stop.
C and O are the most useful options and can commonly be found in my old Apache
logs (also outputted in header links). This patch is made for these cases, not
for some exotic use of Apache-specific properties.
[1]: http://httpd.apache.org/docs/2.4/mod/mod_autoindex.html
---
(this patch is also available at http://lekensteyn.nl/files/nginx/)
RFC: this patch only adds support for URL parameters. Before implementing the
actual clickable headers I would like to have some feedback. Do you actually
want to add such a sorting feature to the standard autoindex module? Sorting
has also been requested on http://forum.nginx.org/read.php?10,211728
I am aware of FancyIndex[2] (which does not support sorting either), but having
two separate modules to do the exact same thing seems a bit useless.
About the implementation, I considered using the non-standard qsort_r
(different prototypes on BSD and Linux, qsort_s on Windows) for adding the sort
options. Because these prototypes and their compare functions are incompatible
I dropped that idea. Next was augmenting the directory entries struct to make
the options available, this is currently the way how it is implemented.
Parsing URL parameters is done in a separate function which is currently
non-void. Since the return value is not used at the moment, it can also be make
void. Thoughts?
[2]: http://wiki.nginx.org/NgxFancyIndex
---
src/http/modules/ngx_http_autoindex_module.c | 93 +++++++++++++++++++++++++++-
1 file changed, 92 insertions(+), 1 deletion(-)
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index 450a48e..aa1be25 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -24,6 +24,16 @@ typedef struct {
typedef struct {
+ u_char sort_key;
+ unsigned order_desc:1;
+} ngx_http_autoindex_opts_t;
+
+#define NGX_AUTOINDEX_SORT_NAME 'N'
+#define NGX_AUTOINDEX_SORT_MTIME 'M'
+#define NGX_AUTOINDEX_SORT_SIZE 'S'
+
+
+typedef struct {
ngx_str_t name;
size_t utf_len;
size_t escape;
@@ -33,6 +43,8 @@ typedef struct {
time_t mtime;
off_t size;
+
+ ngx_http_autoindex_opts_t *sort_opts;
} ngx_http_autoindex_entry_t;
@@ -50,6 +62,8 @@ typedef struct {
static int ngx_libc_cdecl ngx_http_autoindex_cmp_entries(const void *one,
const void *two);
+static ngx_int_t ngx_http_autoindex_get_opts(ngx_http_request_t *r,
+ ngx_http_autoindex_opts_t *opts);
static ngx_int_t ngx_http_autoindex_error(ngx_http_request_t *r,
ngx_dir_t *dir, ngx_str_t *name);
static ngx_int_t ngx_http_autoindex_init(ngx_conf_t *cf);
@@ -153,6 +167,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
ngx_array_t entries;
ngx_http_autoindex_entry_t *entry;
ngx_http_autoindex_loc_conf_t *alcf;
+ ngx_http_autoindex_opts_t opts;
static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
@@ -214,6 +229,8 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
return rc;
}
+ ngx_http_autoindex_get_opts(r, &opts);
+
#if (NGX_SUPPRESS_WARN)
/* MSVC thinks 'entries' may be used without having been initialized */
@@ -353,6 +370,8 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
entry->dir = ngx_de_is_dir(&dir);
entry->mtime = ngx_de_mtime(&dir);
entry->size = ngx_de_size(&dir);
+
+ entry->sort_opts = &opts;
}
if (ngx_close_dir(&dir) == NGX_ERROR) {
@@ -580,11 +599,67 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
}
+static ngx_int_t
+ngx_http_autoindex_get_opts(ngx_http_request_t *r,
+ ngx_http_autoindex_opts_t *opts)
+{
+ u_char *p, *last, key, val;
+
+ opts->sort_key = NGX_AUTOINDEX_SORT_NAME;
+ opts->order_desc = 0;
+
+ p = r->args.data;
+ last = p + r->args.len;
+
+ for ( /* void */; p < last; p++) {
+
+ key = *p++;
+
+ if (*p++ != '=') {
+ return NGX_DECLINED;
+ }
+
+ val = *p++;
+
+ /* assume one-letter value and expect separator */
+ if (p < last && *p != '&' && *p != ';') {
+ return NGX_DECLINED;
+ }
+
+ if (key == 'C') {
+ switch (val) {
+ case NGX_AUTOINDEX_SORT_NAME:
+ case NGX_AUTOINDEX_SORT_MTIME:
+ case NGX_AUTOINDEX_SORT_SIZE:
+ opts->sort_key = val;
+ break;
+ default:
+ return NGX_DECLINED;
+ }
+ } else if (key == 'O') {
+ if (val == 'D') {
+ opts->order_desc = 1;
+ } else if (val == 'A') {
+ opts->order_desc = 0;
+ } else {
+ return NGX_DECLINED;
+ }
+ } else {
+ return NGX_DECLINED;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
static int ngx_libc_cdecl
ngx_http_autoindex_cmp_entries(const void *one, const void *two)
{
ngx_http_autoindex_entry_t *first = (ngx_http_autoindex_entry_t *) one;
ngx_http_autoindex_entry_t *second = (ngx_http_autoindex_entry_t *) two;
+ ngx_http_autoindex_opts_t *opts = first->sort_opts;
+ int r;
if (first->dir && !second->dir) {
/* move the directories to the start */
@@ -596,7 +671,23 @@ ngx_http_autoindex_cmp_entries(const void *one, const void *two)
return 1;
}
- return (int) ngx_strcmp(first->name.data, second->name.data);
+ switch (opts->sort_key) {
+ case NGX_AUTOINDEX_SORT_MTIME:
+ r = first->mtime - second->mtime;
+ break;
+ case NGX_AUTOINDEX_SORT_SIZE:
+ r = first->size - second->size;
+ break;
+ default: /* includes NGX_AUTOINDEX_SORT_NAME */
+ r = 0;
+ break;
+ }
+
+ if (r == 0) {
+ r = ngx_strcmp(first->name.data, second->name.data);
+ }
+
+ return opts->order_desc ? -r : r;
}
--
1.8.1.1
Hello,
I've not yet ventured into Nginx C module coding, but I would like to
know if changing the current SSL module directives:
ssl_certificate and ssl_certificate_key, so that instead of strings
they can be variables (complex values) is feasible, or due to the fact
that SSL happens below the protocol layer, is much more difficult, than,
for instance, the recent transformation in variables of the auth_basic
module directives?
Thank you,
--- appa
Ive been working on my first nginx module (well more specifically, a fork
of an existing module with permission).
Pretty close to done however found one thing thats lacking in the nginx
core (as far as I can tell). UDP Listening.
There is support for UDP sockets, so sending of UDP data is fine. Howeaver
binding and listening seems to be full of hardcoded TCP related stuff.
Is this correct or am I just doing it wrong?.
Hi Guys,
I made a patch for exporting all log only variable as common nginx variables. I am wandering how can I submit the patch to the official nginx devs. I am attaching the patch in this email. If I have to do something more please write me back. Patch was made for nginx 1.3.10 which is the newest development nginx release.
Regards,
Kiril
Found a segfault in the ngx_http_syslog module.
I dont have the contact details for any of the ngsru team that developed it
so I am posting it in the mailing list in the hope a few are members.
Occurs when error_page is used, tested on a 504 error with config similar to
@e504 {
proxy_pass ...;
}
error_page 504 @e504;
Backtrace:
#0 0x080f2ac7 in ngx_http_syslog_error_handler (log=0x8cf4608,
p=0xbfbae8b8 "\b\353\272\277L<\265\b\346", p_len=1960)
at /var/x4b/nginx-syslog-module/ngx_http_syslog_module.c:489
489 ngx_http_syslog_common_handler(
(gdb) backtrace full
#0 0x080f2ac7 in ngx_http_syslog_error_handler (log=0x8cf4608,
p=0xbfbae8b8 "\b\353\272\277L<\265\b\346", p_len=1960)
at /var/x4b/nginx-syslog-module/ngx_http_syslog_module.c:489
No locals.
#1 0x080f2aea in ngx_http_syslog_error_handler (log=0x0, p=0xa <Address
0xa out of bounds>,
p_len=3206221928) at
/var/x4b/nginx-syslog-module/ngx_http_syslog_module.c:494
No locals.
#2 0x080f2aea in ngx_http_syslog_error_handler (log=0xb7bc7380,
p=0xb7bc6ff4 "|-\024",
p_len=3206222780) at
/var/x4b/nginx-syslog-module/ngx_http_syslog_module.c:494
No locals.
#3 0x00000000 in ?? ()