matsumotory / ngx_mruby

ngx_mruby - A Fast and Memory-Efficient Web Server Extension Mechanism Using Scripting Language mruby for nginx
https://ngx.mruby.org/
987 stars 112 forks source link

Nginx::SSL limitations? #339

Open yyamano opened 6 years ago

yyamano commented 6 years ago

Nginx::SSL#servername doesn't work in content handler. Not sure if it's a bug or unexpected usage. Other SSL methods might have similar issue.

I get SIGSEGV without ssl handshake handler. With the handler, Nginx::SSL#servername returns empty string.

        location /ssl_in_content_handler {
          mruby_content_handler_code '
            ssl = Nginx::SSL.new
            Nginx.rputs "servername: #{ssl.servername}"
          ';
        }
Program received signal SIGSEGV, Segmentation fault.
0x000000000055ac31 in ngx_mrb_ssl_get_servername (mrb=0xbfeec0, self=...)
    at /home/vagrant/ngx_mruby/src/http/ngx_http_mruby_ssl.c:88
88    return mrb_str_new(mrb, (char *)mscf->servername->data, mscf->servername->len);
Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.6.x86_64 nss-softokn-freebl-3.16.2.3-13.el7_1.x86_64 openssl-libs-1.0.1e-51.el7_2.5.x86_64 pcre-8.32-15.el7_2.1.x86_64 zlib-1.2.7-15.el7.x86_64
(gdb) bt
#0  0x000000000055ac31 in ngx_mrb_ssl_get_servername (mrb=0xbfeec0, self=...)
    at /home/vagrant/ngx_mruby/src/http/ngx_http_mruby_ssl.c:88
#1  0x000000000058383d in mrb_vm_exec (mrb=0xbfeec0, proc=0xcd5930, pc=0xd7018c) at /home/vagrant/ngx_mruby/mruby/src/vm.c:1461
#2  0x00000000005815f0 in mrb_vm_run (mrb=0xbfeec0, proc=0xcd5930, self=..., stack_keep=2)
    at /home/vagrant/ngx_mruby/mruby/src/vm.c:935
#3  0x000000000058aba3 in mrb_run (mrb=0xbfeec0, proc=0xcd5930, self=...) at /home/vagrant/ngx_mruby/mruby/src/vm.c:2982
#4  0x000000000054ead8 in ngx_mrb_run (r=0xbfd4e0, state=0xbf8258, code=0xd64cb0, cached=1, result=0x0)
    at /home/vagrant/ngx_mruby/src/http/ngx_http_mruby_module.c:843
#5  0x00000000005512f0 in ngx_http_mruby_content_inline_handler (r=0xbfd4e0)
    at /home/vagrant/ngx_mruby/src/http/ngx_http_mruby_module.c:1586
#6  0x00000000004af074 in ngx_http_core_content_phase (r=0xbfd4e0, ph=0xd85858) at src/http/ngx_http_core_module.c:1169
#7  0x00000000004ae3f7 in ngx_http_core_run_phases (r=0xbfd4e0) at src/http/ngx_http_core_module.c:851
#8  0x00000000004ae365 in ngx_http_handler (r=0xbfd4e0) at src/http/ngx_http_core_module.c:834
#9  0x00000000004bd3e6 in ngx_http_process_request (r=0xbfd4e0) at src/http/ngx_http_request.c:1948
#10 0x00000000004bbd6f in ngx_http_process_request_headers (rev=0xbebb80) at src/http/ngx_http_request.c:1375
#11 0x00000000004bb135 in ngx_http_process_request_line (rev=0xbebb80) at src/http/ngx_http_request.c:1048
#12 0x00000000004b9cf5 in ngx_http_wait_request_handler (rev=0xbebb80) at src/http/ngx_http_request.c:506
#13 0x000000000049d333 in ngx_epoll_process_events (cycle=0xbe74a0, timer=60000, flags=1)
    at src/event/modules/ngx_epoll_module.c:902
#14 0x000000000048bf15 in ngx_process_events_and_timers (cycle=0xbe74a0) at src/event/ngx_event.c:242
#15 0x0000000000499689 in ngx_single_process_cycle (cycle=0xbe74a0) at src/os/unix/ngx_process_cycle.c:310
#16 0x0000000000457bdb in main (argc=1, argv=0x7fffffffe408) at src/core/nginx.c:379
(gdb) l
83  
84  static mrb_value ngx_mrb_ssl_get_servername(mrb_state *mrb, mrb_value self)
85  {
86    ngx_http_mruby_srv_conf_t *mscf = mrb->ud;
87  
88    return mrb_str_new(mrb, (char *)mscf->servername->data, mscf->servername->len);
89  }
90  
91  static in_port_t get_in_port(struct sockaddr *sa)
92  {
(gdb) p *mscf
$1 = {state = 0xbf8258, ssl_handshake_code = 0xffffffffffffffff, ssl_handshake_inline_code = 0xffffffffffffffff, 
  server_config_inline_code = 0xc9d558, cf = 0x7fffffffdf50, cscf = 0xc98630, servername = 0x0, cert_path = {len = 0, 
    data = 0x0}, cert_key_path = {len = 0, data = 0x0}, cert_data = {len = 0, data = 0x0}, cert_key_data = {len = 0, 
    data = 0x0}, connection = 0x0}
matsumotory commented 6 years ago

The specification of the SSL class is that it can not be used in hook of HTTP request processing. I would like to be able to handle errors by using flags related to phases at run time inside classes and methods.

matsumotory commented 6 years ago

In the implementation of trusterd, the request structure has information on each phase, and each method itself determines whether it is a phase that can be executed.

ref: https://github.com/matsumotory/mruby-http2/blob/master/src/mrb_http2_request.h#L21

yyamano commented 6 years ago

@matsumotory I just want to make sure that Nginx::SSL works only in the handshake and the verify client handler.

matsumotory commented 6 years ago

Nginx::SSL class only works in ssl_handshake_handle for now. I do not assume that methods of SSL class except accept_client and reject_client work in verify client handler.

yyamano commented 6 years ago

Will take care of it. We need to add the limitations to doc too.

yyamano commented 5 years ago

I added the limitation to docs/class_and_method/README.md#nginxssl-class.

Nginx::SSL class is designed to be used in the ssl handshake handlers. It doesn't work in other handlers like mruby_content_handler_code.

matsumotory commented 5 years ago

lgtm!