18

I am trying to retrieve a page on my SSL enabled server with a lua script. Important to note that the server has a self-signed certificate. No problem with certificate issued by a trusted CA.

local https = require("socket.http")
local resp = {}
local r, c, h, s = https.request{
    url = "https://my-server:443/example.php",
    sink = ltn12.sink.table(resp),
    protocol = "tlsv1"
}

The server returns:

Bad Request Your browser sent a request that this server could not understand. Reason: You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please.

And on the server side, that request produce this entry in the Apache ssl_access.log

192.168.0.150 - - [27/Nov/2011:16:32:07 +0100] "GET /" 400 529 "-" "-"

Furthermore, tcpdump shows that after the SYN-ACK handshake, no SSL 257 Client Hello is sent. Using the same URL from my browser or with wget works ok.

greatwolf
  • 20,287
  • 13
  • 71
  • 105
ripat
  • 3,076
  • 6
  • 26
  • 38

4 Answers4

15

As Doug Currie said, you should use luasec. In order to enable https.request, you have to require the ssl.https module:

local https = require 'ssl.https'
local r, c, h, s = https.request{
    url = "https://my-server:443/example.php",
    sink = ltn12.sink.table(resp),
    protocol = "tlsv1"
}
Michal Kottman
  • 16,375
  • 3
  • 47
  • 62
  • As I said above, that lua script will be executed on a rather cramped router that has no room left for the LuaSec package. I believe I'll have to find a workaround. Thanks for your help anyway. And BTW I tried your snippet in a LuaSec aware box and it doesn't seem to find the 'ssl.https' module. – ripat Nov 28 '11 at 06:35
  • Which version of LuaSec did you use? The [version 0.4.1](http://www.inf.puc-rio.br/~brunoos/luasec/download/luasec-0.4.1.tar.gz), which is available on the main site, contains ssl/https.lua that should be installed into the Lua package path. – Michal Kottman Nov 28 '11 at 14:02
  • Version 4.0. I had a look into the https.lua module and it seems to create a module `ssl.module`. Why can't I simply use the https.lua module like I tried to do in my first post? That module is derived from LuaSec I believe. – ripat Nov 29 '11 at 07:42
  • 1
    Because you are importing `socket.http` module, which does not know anything about HTTPS ([discussion here](http://thread.gmane.org/gmane.comp.lang.lua.general/85762/focus=85899)). That is why you need to load the custom module. Of course, you can put it wherever you like, for example in $LUA_PATH/socket/https.lua, then you can call it as `require 'socket.https'`. – Michal Kottman Nov 29 '11 at 10:23
  • link to luasec is broken. But maybe [this link could replace the old one](https://github.com/brunoos/luasec/wiki) – yair Feb 19 '15 at 23:11
7

See this lua-l thread describing how to add support for luasocket https client using luasec.

Doug Currie
  • 40,708
  • 1
  • 95
  • 119
  • I saw that thread but I was hoping to find something simpler. Like in [this example](http://www.inf.puc-rio.br/~brunoos/luasec/reference.html#request) from the LuaSec documentation. That method works all right with certificates issued by trusted CA but not on self-signed ones. – ripat Nov 27 '11 at 17:12
  • 1
    Another bad news is that I don't have enough memory on my router to install the LuaSec package. – ripat Nov 27 '11 at 19:52
4

like this

local https = require("ssl.https")
local one, code, headers, status = https.request{
       url = "https://www.test.com",
       key = "/root/client.key",
       certificate="/root/client.crt",
       cafile="/root/ca.crt"
}
cclient
  • 847
  • 7
  • 5
1

A more modern solution is to use lua-http: https://github.com/daurnimator/lua-http

It comes with a luasocket/luasec compatible interface.

daurnimator
  • 4,091
  • 18
  • 34