How to (safely) enable HTTPS LuCi with HTTPS authentication?

I have two major objectives:

  1. HTTPS-only web UI and
  2. Get the HTTP(S) authentication the the connection instead of a login page.

From the OpenWRT wiki I have got these directions for HTTPS

opkg install luci-ssl
/etc/init.d/uhttpd stop
mv /etc/config/uhttpd /etc/config/uhttpd.old
WEBUIPORT=880
config uhttpd 'main'
        list listen_https '0.0.0.0:$WEBUIPORT' #IPv4 TCP PORT HERE!
        list listen_https '[::]:$WEBUIPORT'    # IPv6 TCP PORT HERE!
        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'
        option script_timeout '60'
        option network_timeout '30'
        option http_keepalive '20'
        option tcp_keepalive '1'
        option ubus_prefix '/ubus'
        option realm 'My Realm'

config cert 'px5g'
        option days '730' # <== TWO YEARS
        option bits '1024'
        option country 'IT' # <== YOUR COUNTRY ISO CODE
        option state 'Caserta' # <== YOUR Province/County NAME
        option location 'San Nicola la Strada' # <== YOUR CITY
        option commonname 'My Office Router' # <== YOUR DEVICE
EOF
/etc/init.d/uhttpd start

After the last start command crypto certificates will be created on the fly.

For the HTTP(S) AUTH request I have these directions:

/etc/init.d/uhttpd stop
echo '/:root:$p$root' >> /etc/httpd.conf
uci set uhttpd.main.realm="My Realm" # <== YOUR DEVICE NAME HERE!
uci commit uhttpd
sed -i -e 's/\.sysauth = .*/.sysauth = nil/g' /usr/lib/lua/luci/controller/admin/*.lua
/etc/init.d/uhttpd start

Both are quite old and, more importan, are related to OpenWRT 14.07, so they could not fit current LEDE stuff.
In my opinion the HTTPS stuff should be OK.
I wouldn't bet on the HTTP AUTH request stuff as I don't know very well the LUA language.

Is there any one that can confirm or give me some hints?

Use this as a template:

# Server configuration
config uhttpd main

	# HTTP listen addresses, multiple allowed
	list listen_http	0.0.0.0:80
	list listen_http	[::]:80

	# HTTPS listen addresses, multiple allowed
	list listen_https	0.0.0.0:443
	list listen_https	[::]:443

	# Redirect HTTP requests to HTTPS if possible
	option redirect_https	1

	# Server document root
	option home		/www

	# Reject requests from RFC1918 IP addresses
	# directed to the servers public IP(s).
	# This is a DNS rebinding countermeasure.
	option rfc1918_filter 1

	# Maximum number of concurrent requests.
	# If this number is exceeded, further requests are
	# queued until the number of running requests drops
	# below the limit again.
	option max_requests 3

	# Maximum number of concurrent connections.
	# If this number is exceeded, further TCP connection
	# attempts are queued until the number of active
	# connections drops below the limit again.
	option max_connections 100

	# Certificate and private key for HTTPS.
	# If no listen_https addresses are given,
	# the key options are ignored.
	option cert		/etc/uhttpd.crt
	option key		/etc/uhttpd.key

	# CGI url prefix, will be searched in docroot.
	# Default is /cgi-bin
	option cgi_prefix	/cgi-bin

	# List of extension->interpreter mappings.
	# Files with an associated interpreter can
	# be called outside of the CGI prefix and do
	# not need to be executable.
#	list interpreter	".php=/usr/bin/php-cgi"
#	list interpreter	".cgi=/usr/bin/perl"

	# Lua url prefix and handler script.
	# Lua support is disabled if no prefix given.
#	option lua_prefix	/luci
#	option lua_handler	/usr/lib/lua/luci/sgi/uhttpd.lua

	# Specify the ubus-rpc prefix and socket path.
#	option ubus_prefix	/ubus
#	option ubus_socket	/var/run/ubus.sock

	# CGI/Lua timeout, if the called script does not
	# write data within the given amount of seconds,
	# the server will terminate the request with
	# 504 Gateway Timeout response.
	option script_timeout	60

	# Network timeout, if the current connection is
	# blocked for the specified amount of seconds,
	# the server will terminate the associated
	# request process.
	option network_timeout	30

	# HTTP Keep-Alive, specifies the timeout for persistent
	# HTTP/1.1 connections. Setting this to 0 will disable
	# persistent HTTP connections.
	option http_keepalive	20

	# TCP Keep-Alive, send periodic keep-alive probes
	# over established connections to detect dead peers.
	# The value is given in seconds to specify the
	# interval between subsequent probes.
	# Setting this to 0 will disable TCP keep-alive.
	option tcp_keepalive	1

	# Basic auth realm, defaults to local hostname
#	option realm	Lede

	# Configuration file in busybox httpd format
#	option config	/etc/httpd.conf

	# Do not follow symlinks that point outside of the
	# home directory.
#	option no_symlinks	0

	# Do not produce directory listings but send 403
	# instead if a client requests an url pointing to
	# a directory without any index file.
#	option no_dirlists	0

	# Do not authenticate any ubus-rpc requests against
	# the ubus session/access procedure.
	# This is dangerous and should be always left off
	# except for development and debug purposes!
#	option no_ubusauth	0

	# For this instance of uhttpd use the listed httpauth
	# sections to require Basic auth to the specified
	# resources.
#	list httpauth prefix_user


# Defaults for automatic certificate and key generation
config cert defaults

	# Validity time
	option days		730

	# RSA key size
	option bits		2048

	# Location
	option country		ZZ
	option state		Somewhere
	option location		Unknown

	# Common name
	option commonname	'LEDE'

# config httpauth prefix_user
#	option prefix /protected/url/path
#	option username user
#	option password 'plaintext_or_md5_or_$p$user_for_system_user'
1 Like

Hi.
The HTTPS part is OK.
The httpauth part you suggest isn't clear at all. My fault, surely.

First, the "option prefix" is related to the web URL (thus it should be "/") or to the underlying file system (thus /www)?

Second, cannot I use the local user(s) I am using with normal local password(s)?
Third, where did you get these infos from? I can see it on GitHub, but I need more details to understand.

TALIA!

UPDATE!
I have found some details, very scarce indeed, here. I am still missing the stuff about user authentication, though.

@Uqbar

Hi,

here's an example config I'm using to auth uhttpd:

config uhttpd 'main'
    list listen_https '0.0.0.0:443'
    list listen_https '[::]:443'
    option home '/www'
    option rfc1918_filter '1'
    option max_requests '3'
    option max_connections '100'
    option cgi_prefix '/cgi-bin'
    option script_timeout '60'
    option network_timeout '30'
    option http_keepalive '20'
    option tcp_keepalive '1'
    option cert '/etc/uhttpd.crt'
    option key '/etc/uhttpd.key'
    option redirect_https '1'
    list httpauth 'prefix_user'

config cert 'defaults'
    option days '730'
    option bits '2048'
    option country 'ZZ'
    option state 'Somewhere'
    option location 'Unknown'
    option commonname 'LEDE'

config httpauth 'prefix_user'
    option prefix '/'
    option username 'pippo'
    option password '34akjn3@p@#'

@cga Thanks. But my point is to use the very same authentication method I have for key-less SSH.
That is, the passwords that are in /etc/shadow. It would be complex to keep those two passwords aligned...

Anyway, grazie!

Use the $p$... password notation:

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

The $p$root token will cause uhttpd to compare the provided password against the hash for root in /etc/shadow

1 Like

Thanks a lot @jow .
But it seems not to work.
I have used the configuration seen here in this very thread with your suggestion.
But I still get the normal authentication page instead of an HTTPAUTH request straight from the browser.

@Uqbar

I can confirm that it works with

config httpauth 'prefix_user'
    option prefix '/'
    option username 'pippo'
    option password '$p$pippo' 

in fact I'm actually using it!

Nope!
I reinstalled v17.01.2 plus HTTPS package but I still cannot get the HTTPAUTH request.
Whenever I point my browser to the LEDE box I get the security alert page (because of the selfsigned certificate) and then the login page.
Please, which version of LEDE are you using, @cga?
I see you have HTTPS enabled as well, that shouldn't be the point.
I am reinstalling once again with the -factory image insted of -sysupgrade, though.

Dumb question here: did you try to clear your browser's history ?

Nope. If a browser history can defy an HTTPAUTH request, then we are done!
:slight_smile:
Jokes, aside, the HTTPAUTH request should:

  1. be sent back to the browser for any (virtual) path below /, even those in the history and
  2. land you after the the login page, as it's a login in its own.

You can try the non-uci variant below which is a bit simpler to setup:

echo '/:root:$p$root' > /etc/httpd.conf && /etc/init.d/uhttpd restart

This should enable badic auth and allow you to login with user root and the password from /etc/shadow.

@jow This is what I mentioned in the very first post.
Is this "alternative" to what has been suggested for the /etc/config/uhttp file change?

My point here is that I am gathering details from here and there with no central documentation.
I can also volunteer, but still need some starting point.

I think that an HTTPAUTH request would be better than the current login page as it doesn't provide any easy way to gather information from a LEDE box. In my opinion.
At the moment my box says to everyone its name and stuff like:

Powered by LuCI lede-17.01 branch (git-17.152.82987-7f6fc16) / LEDE Reboot 17.01.2 r3435-65eec8bd5f

It could be even made an option as seen in dd-wrt.

Yes it is an alternative to the proposed uci config. I tried both at home with uhttpd and they work.

@jow What I get is HTTP AUTH request enabled, but the login page is still presented so you have to enter credentials twice!

I wasn't willing to reinstall everything and do tests (this is why I asked in the OP about confirmation).
Nonetheless I ended up doing it.
So I do confirm: the recipe I wrote about in the OP DOESN'T work also for LEDE v17.01.2:

 # turn the web server off
/etc/init.d/uhttpd stop

# Enable HTTP AUTH for all pages
echo '/:root:$p$root' >> /etc/httpd.conf

# Disable normal login for all pages
sed -i -e 's/\.sysauth = .*/.sysauth = nil/g' /usr/lib/lua/luci/controller/admin/*.lua

# Turn the web server back on
/etc/init.d/uhttpd start

The proposed change in the /etc/config/uhttpd hasn't proved to be effective, though.

Along with the default LEDE uhttpd configuration I was expecting to get:

  1. HTTP to HTTPS redirect before any authentication is done
  2. HTTP AUTH enabled for any page in the web UI
  3. rid of the login page

It almost works.
The only problem is that now I get errors for a number of submissions:

The submitted security token is invalid or already expired!

In order to prevent unauthorized access to the system, your request has been blocked. Click "Continue »" below to return to the previous page.

Continue »

So I go back to normal authentication until there will be some more detailed information!
Sigh! :cry:

@Uqbar

I'm on LEDE stable too:

root@lede-wyn:~# cat /etc/os-release
NAME="LEDE"
VERSION="17.01.2, Reboot"
ID="lede"
ID_LIKE="lede openwrt"
PRETTY_NAME="LEDE Reboot 17.01.2"
VERSION_ID="17.01.2"
HOME_URL="http://lede-project.org/"
BUG_URL="http://bugs.lede-project.org/"
SUPPORT_URL="http://forum.openwrt.org/"
BUILD_ID="r3435-65eec8bd5f"
LEDE_BOARD="mvebu/generic"
LEDE_ARCH="arm_cortex-a9_vfpv3"
LEDE_TAINTS="no-all"
LEDE_DEVICE_MANUFACTURER="LEDE"
LEDE_DEVICE_MANUFACTURER_URL="http://lede-project.org/"
LEDE_DEVICE_PRODUCT="Generic"
LEDE_DEVICE_REVISION="v0"
LEDE_RELEASE="LEDE Reboot 17.01.2 r3435-65eec8bd5f" 

However I'm NOT using the OP method. Changing scripts is NOT necessary. All I have is what I have shared and it does work. Besides, you do NOT need /etc/httpd.conf if you use the httpdauth in /etc/config/uhttpd.

I don't know what to say more than this...

No way!
Reverted back to stock stuff (reinstalled once again the -factory image).
This is what I have now:

root@N0A-G0:~# cat /etc/os-release 
NAME="LEDE"
VERSION="17.01.2, Reboot"
ID="lede"
ID_LIKE="lede openwrt"
PRETTY_NAME="LEDE Reboot 17.01.2"
VERSION_ID="17.01.2"
HOME_URL="http://lede-project.org/"
BUG_URL="http://bugs.lede-project.org/"
SUPPORT_URL="http://forum.openwrt.org/"
BUILD_ID="r3435-65eec8bd5f"
LEDE_BOARD="ar71xx/generic"
LEDE_ARCH="mips_24kc"
LEDE_TAINTS="no-all"
LEDE_DEVICE_MANUFACTURER="LEDE"
LEDE_DEVICE_MANUFACTURER_URL="http://lede-project.org/"
LEDE_DEVICE_PRODUCT="Generic"
LEDE_DEVICE_REVISION="v0"
LEDE_RELEASE="LEDE Reboot 17.01.2 r3435-65eec8bd5f"
root@N0A-G0:~# 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:880'
        list listen_https '[::]:880'
        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'
        option script_timeout '60'
        option network_timeout '30'
        option http_keepalive '20'
        option tcp_keepalive '1'
        option ubus_prefix '/ubus'
        option realm 'N0A-G0'

config cert 'defaults'
        option days '3650'
        option bits '2048'
        option country 'IT'
        option state 'Caserta'
        option location 'San Nicola la Strada'
        option commonname 'N0A-G0'

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

Nonetheless I still get to the login page.
I installed a brand new browser (rekonq v2.4.2) where I can be sure I delete any cached bit of information, passwords included.
I still get to the login page after being redirected from HTTP:80 to HTTPS:880.
Now, either this stuff doesn't work or I am missing some important bit I am not aware of.
How can I troubleshoot this situation?
Is there any debug flag I can use with uhttpd?

Your config uhttpd main section lacks list httpauth 'prefix_user' to actually use the defined auth realm.

1 Like

Correct! My bad! :scream:
Now I get the HTTP AUTH request, but then I land to the login page.
This is why the edits to the LUA pages were needed, as far as I understood.

I took a look now and the facility got broken while rewriting uhttpd to uhttpd2. LuCI auto-logins the user if credentials are available via basic auth, but uhttpd2 fails to expose HTTP_AUTH_USER and HTTP_AUTH_PASS environment variables anymore.

I'll fix this in uhttpd along with the auth-before-redirect issue.

2 Likes