How to add authentication on specific folder on uhttpd?

Hi all,

On our device, we run uhttpd+lua as web service.
We already add simple Lua cgi to response client request, like

# client
curl -v -k "https://172.31.5.204/test/example"

# config on uhttpd, I will ignore global part
config uhttpd 'main'
    list lua_prefix '/test=/usr/lib/lua/test/index.lua'
    list httpauth prefix_user

config httpauth prefix_user
    option prefix '/test'
    option username root
    option password '$p$root'

# response from server
> GET /test/example HTTP/1.1
> Host: 172.31.5.204
> User-Agent: curl/7.68.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Transfer-Encoding: chunked
< Keep-Alive: timeout=20
< Content-Type: application/json
< Content-Length: 18
< 
* Connection #0 to host 172.31.5.204 left intact
{"version":"0.79"}

Questions

  1. Is it possible to add digest authentication? If yes, how?
  2. If I want to have basic authentication on my example, which part is wrong? How to fix it?
    Thanks.

Hi all,

Anyone can help? Please advise. Thanks.

In /etc/config/uhttpd uncomment (and restart afterwards)
option config /etc/httpd.conf

then follow https://openwrt.org/docs/guide-user/services/webserver/uhttpd#basic_authentication_httpdconf ?

Hi Frollic,

Yes, I already follow the guide line you mentioned.
But, you can see the result is not expected.
Can you help out? Thanks.

config uhttpd 'main'
    list lua_prefix '/test=/usr/lib/lua/test/index.lua'
    list httpauth prefix_user

config httpauth prefix_user
    option prefix '/test'
    option username root
    option password '$p$root'

your config tends to disagree with you...

Hi Wulfy23,

Add following code to /etc/httpd.config, still not working.

/test:root:$p$root

Please advise. Thanks.

3rd time lucky... and do us all a favor and share what you have in /etc/httpd.conf if it ain't working...

Hi Wulfy23,

This is what I have. Thanks.

root@OpenWrt:/# cat /etc/httpd.conf 
/test:root:$p$root
root@OpenWrt:/# cat /etc/config/uhttpd 

config uhttpd 'main'
        list listen_http '0.0.0.0:80'
        list listen_http '[::]:80'
        list listen_https '0.0.0.0:443'
        list listen_https '[::]:443'
        option redirect_https '1'
        option home '/www'
        option rfc1918_filter '1'
        option max_requests '3'
        option max_connections '100'
        option cert '/etc/uhttpd.crt'
        option key '/etc/uhttpd.key'
        option cgi_prefix '/cgi-bin'
        list lua_prefix '/cgi-bin/luci=/usr/lib/lua/luci/sgi/uhttpd.lua'
        list lua_prefix '/test=/usr/lib/lua/test/index.lua'
        option script_timeout '60'
        option network_timeout '30'
        option http_keepalive '20'
        option tcp_keepalive '1'
        option ubus_prefix '/ubus'

config cert 'defaults'
        option days '730'
        option key_type 'rsa'
        option bits '2048'
        option ec_curve 'P-256'
        option country 'ZZ'
        option state 'Somewhere'
        option location 'Unknown'
        option commonname 'OpenWrt'

Still not seeing option config /etc/httpd.conf in your /etc/config/uhttpd, like the manual sais you should have.

Hi Frollic,

Please check this. Thanks.

root@OpenWrt:/# curl -v -k "https://172.31.5.204/test/GetAudioSettings"
> GET /test/GetAudioSettings HTTP/1.1
> Host: 172.31.5.204
> User-Agent: curl/7.66.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Transfer-Encoding: chunked
< Keep-Alive: timeout=20
< Content-Type: application/json
< Content-Length: 54
< 
{"micVolume":"90","Error Code":0,"speakerVolume":"90"}
root@OpenWrt:/# cat /etc/httpd.conf 
/test:root:$p$root
root@OpenWrt:/# cat /etc/config/uhttpd 

config uhttpd 'main'
        list listen_http '0.0.0.0:80'
        list listen_http '[::]:80'
        list listen_https '0.0.0.0:443'
        list listen_https '[::]:443'
        option redirect_https '1'
        option home '/www'
        option rfc1918_filter '1'
        option max_requests '3'
        option max_connections '100'
        option cert '/etc/uhttpd.crt'
        option key '/etc/uhttpd.key'
        option cgi_prefix '/cgi-bin'
        list lua_prefix '/cgi-bin/luci=/usr/lib/lua/luci/sgi/uhttpd.lua'
        list lua_prefix '/test=/usr/lib/lua/test/index.lua'
        option script_timeout '60'
        option network_timeout '30'
        option http_keepalive '20'
        option tcp_keepalive '1'
        option ubus_prefix '/ubus'
        option config '/etc/httpd.conf'

config cert 'defaults'
        option days '730'
        option key_type 'rsa'
        option bits '2048'
        option ec_curve 'P-256'
        option country 'ZZ'
        option state 'Somewhere'
        option location 'Unknown'
        option commonname 'OpenWrt'

Works for me.

image

Try adding a trailing / to the path in httpd.conf
/a/:root:$p$root

1 Like

Hi Frollic,

Still not working for me. One question, did the a folder at /www folder?
The test folder on my device is located at /usr/lib/lua.
Thanks.

Yeah, I put it in /www/

Hi Frollic,

I try to reproduce your case on my device, still not working. Could you please check my conf. Thanks.

root@OpenWrt:/www/test# ls
index.html
root@OpenWrt:/www/test# cat /etc/httpd.conf 
/test/:root:$p$root
root@OpenWrt:/www/test# cat /etc/config/uhttpd 

config uhttpd 'main'
        list listen_http '0.0.0.0:80'
        list listen_http '[::]:80'
        list listen_https '0.0.0.0:443'
        list listen_https '[::]:443'
        option redirect_https '1'
        option home '/www'
        option rfc1918_filter '1'
        option max_requests '3'
        option max_connections '100'
        option cert '/etc/uhttpd.crt'
        option key '/etc/uhttpd.key'
        option cgi_prefix '/cgi-bin'
        list lua_prefix '/cgi-bin/luci=/usr/lib/lua/luci/sgi/uhttpd.lua'
        list lua_prefix '/adc-api=/usr/lib/lua/adc-api/index.lua'
        option script_timeout '60'
        option network_timeout '30'
        option http_keepalive '20'
        option tcp_keepalive '1'
        option ubus_prefix '/ubus'
        option config '/etc/httpd.conf'

config cert 'defaults'
        option days '730'
        option key_type 'rsa'
        option bits '2048'
        option ec_curve 'P-256'
        option country 'ZZ'
        option state 'Somewhere'
        option location 'Unknown'
        option commonname 'OpenWrt'

root@OpenWrt:/www/test# curl -v -k "https://127.0.0.1/test/"
> GET /test/ HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.66.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Keep-Alive: timeout=20
< ETag: "44e-1-5f61bcdf"
< Last-Modified: Wed, 16 Sep 2020 07:21:03 GMT
< Date: Wed, 16 Sep 2020 07:23:54 GMT
< Content-Type: text/html
< Content-Length: 1
< 

Anything I missed? If not, what is your uhttpd version? The version is uhttpd-2020-03-13-975dce23.tar.xz on my device. Thanks.

Mine came with OpenWrt 19.07.3 - 2020-03-13-975dce23-1,
seems to be the same as yours.

I only did one thing in the original /etc/config/uhttpd, uncommented the httpd.conf line,
and created the httpd.conf file in /etc. Then restarted uhttpd for the config to kick in.

Hi Frollic,

Any specific options at openwrt did you enable to have Basic Auth feature?
I have no idea how to trace it now. Thanks.

Hi Frollic,

Remove whole overlay and reboot device, /test is working with basic auth now. Next question is how to add basic auth to luci folder? The location of luci folder is /usr/lib/lua/test. Thanks.

If you can't move your stuff to /www/test

You could try a sym link, uhttpd seems to support it (at least there's a no_symlinks option in the config).

Or if it doesn't work, set up an additional site on a different port, pointing towards where
ever you'd like it to be.

config 'uhttpd' 'test'
        option 'listen_http' '81'
        option 'home'        '/usr/lib/lua/test'

https://openwrt.org/docs/guide-user/services/webserver/uhttpd

What are you actually trying to achieve, besides working authentication, that is ?

But I see no reason why pointing towards /usr/lib/lua/test in httpd.conf wouldn't work,
except perhaps the path is being rewritten in the process.

1 Like

Hi Frollic,

Look deeply into the source code of uhttpd. It would not handle auth when it find the script to run.

      req->redirect_status = 200;
      d = dispatch_find(url, NULL);
      if (d)
          return uh_invoke_handler(cl, d, url, NULL);
  
      if (__handle_file_request(cl, url))
          return;

I add some changes, it works with /etc/httpd.conf and lua path.
But, it did not support digest auth, so we need to switch to another web server.
Anyway, thanks for your help. Have a good day. ^^