Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revisionBoth sides next revision
docs:guide-user:services:webserver:uhttpd [2018/10/26 21:15] – [Server Settings] stokitodocs:guide-user:services:webserver:uhttpd [2024/05/25 18:59] – [Securing uHTTPd] stokito
Line 1: Line 1:
-====== Web Server Configuration (uHTTPd) ====== +====== uHTTPd Web Server Configuration ====== 
- +The ''/etc/config/uhttpd'' configuration is provided by the [[docs:guide-user:services:webserver:http.uhttpd|uhttpd]] web server package. 
-The ''/etc/config/uhttpd'' configuration is provided by the [[docs:guide-user:services:webserver:http.uhttpd|uhttpd]] web server package used since OpenWrt 10.03 (Backfire)+This file defines the behavior of the server and default values for certificates generated for SSL operation. uhttpd supports multiple instances (i.e. multiple listen ports, each with its own document root and other features) as well as cgi, php7, perl and lua.
-This file defines the behaviour of the server and default values for certificates generated for SSL operation. uhttpd supports multiple instances (i.e. multiple listen ports, each with its own document root and other features) as well as cgi, php5, perl and lua.+
  
 ===== Sections ===== ===== Sections =====
 +There are two sections defined, the section of type ''uhttpd'' contains general server settings while the ''cert'' one defines the default values for SSL certificates.
 +
 +For information on sections and UCI configuration see [[docs:guide-user:base-system:uci|The UCI System]]
  
-There are two sections defined, the section of type //uhttpd// contains general server settings while the //cert// one defines the default values for SSL certificates. 
 ==== Server Settings ==== ==== Server Settings ====
- 
 A minimal ''uhttpd'' config section must consist of at least the document root and HTTP listen options: A minimal ''uhttpd'' config section must consist of at least the document root and HTTP listen options:
  
-<code>+<code bash>
 config 'uhttpd' 'main' config 'uhttpd' 'main'
         option 'listen_http' '80'         option 'listen_http' '80'
Line 20: Line 20:
  
 ^ Name ^ Type ^ Required ^ Default ^ Description ^ ^ Name ^ Type ^ Required ^ Default ^ Description ^
-| ''listen_http'' | list of port numbers or address:port pairs | yes, if '''listen_https''' is not given  | //(none)// | Specifies the ports and addresses to listen on for plain HTTP access. If only a port number is given, the server will attempt to serve both IPv4 and IPv6 requests. Use ''0.0.0.0:80'' to bind at port 80 only on IPv4 interfaces or ''[::]:80'' to serve only IPv6. To run on multiple addresses, specifying each, you can list one address (or address:port) per line. | +| ''listen_http'' | list of port or address:port pairs | yes, if '''listen_https''' is not given  | //(none)// | Specifies the ports and addresses to listen on for plain HTTP access. If only a port number is given, the server will attempt to serve both IPv4 and IPv6 requests. Use ''0.0.0.0:80'' to bind at port 80 only on IPv4 interfaces or ''[::]:80'' to serve only IPv6. To run on multiple addresses, specifying each, you can list one address (or address:port) per line. You can use DNS or even [[docs:guide-user:services:ddns:client|DynDNS]] domain instead of IP but note that this is not any kind of virtual hosting 
-| ''listen_https'' | list of port numbers or address:port pairs | yes, if '''listen_http''' is not given | //(none)// | Specifies the ports and addresses to listen on for encrypted HTTPS access. The format is the same as for ''listen_http''. ** Read below for extra details** |+| ''listen_https'' | list of port or address:port pairs | yes, if '''listen_http''' is not given | //(none)// | Specifies the ports and addresses to listen on for encrypted HTTPS access. The format is the same as for ''listen_http''. ** Read below for extra details** |
 | ''home'' | directory path | yes | ''/www'' | Defines the server document root | | ''home'' | directory path | yes | ''/www'' | Defines the server document root |
-| ''cert'' | file path | yes if ''listen_https'' is given, else no | ''/etc/uhttpd.crt'' | ASN.1/DER certificate used to serve HTTPS connections | +| ''cert'' | file path | yes if ''listen_https'' is given, else no | ''/etc/uhttpd.crt'' | ASN.1/DER or PEM certificate used to serve HTTPS connections. If you want to you use an intermediate certificate you concatenate it to one file (PEM only!). Some PEM formats may require the luci-ssl-openssl package. 
-| ''key'' | file path | yes if ''listen_https'' is given, else no | ''/etc/uhttpd.key'' | ASN.1/DER private key used to serve HTTPS connections |+| ''key'' | file path | yes if ''listen_https'' is given, else no | ''/etc/uhttpd.key'' | ASN.1/DER or PEM private key used to serve HTTPS connections. Some PEM formats may require the luci-ssl-openssl package. |
 | ''cgi_prefix'' | string | no | ''/cgi-bin'' | Defines the prefix for CGI scripts, relative to the document root. CGI support is disabled if this option is missing | | ''cgi_prefix'' | string | no | ''/cgi-bin'' | Defines the prefix for CGI scripts, relative to the document root. CGI support is disabled if this option is missing |
 | ''lua_prefix'' | string | no | //(none)// | Defines the prefix for dispatching requests to the embedded Lua interpreter, relative to the document root. Lua support is disabled if this option is missing | | ''lua_prefix'' | string | no | //(none)// | Defines the prefix for dispatching requests to the embedded Lua interpreter, relative to the document root. Lua support is disabled if this option is missing |
Line 32: Line 32:
 | ''realm'' | string | no | //local hostname// | Basic authentication realm when prompting the client for credentials (HTTP 400) | | ''realm'' | string | no | //local hostname// | Basic authentication realm when prompting the client for credentials (HTTP 400) |
 | ''config'' | file path | no | ''/etc/httpd.conf'' | Config file in Busybox httpd format for additional settings (currently only used to specify Basic Auth areas) | | ''config'' | file path | no | ''/etc/httpd.conf'' | Config file in Busybox httpd format for additional settings (currently only used to specify Basic Auth areas) |
-| ''index_file'' | file name | no | ''index.html, index.htm,'' ''default.html, default.htm'' | Index file to use for directories, e.g. add index.php when using php |+| ''index_file'' | file name | no | ''index.html''''index.htm,'' ''default.html''''default.htm'' | Index file to use for directories, e.g. add index.php when using php |
 | ''index_page'' | file name | no | ''index.html'' | Index file to use for directories, e.g. add index.php when using php (last, 20131015, replace index_file ?) should be noted: list index_page "index.html index.htm default.html default.htm index.php" | | ''index_page'' | file name | no | ''index.html'' | Index file to use for directories, e.g. add index.php when using php (last, 20131015, replace index_file ?) should be noted: list index_page "index.html index.htm default.html default.htm index.php" |
 | ''error_page'' | string | no | //(none)// | Virtual URL of file or CGI script to handle 404 request.  Must begin with '/' | | ''error_page'' | string | no | //(none)// | Virtual URL of file or CGI script to handle 404 request.  Must begin with '/' |
 | ''no_symlinks'' | boolean | no | ''0'' | Do not follow symbolic links if enabled | | ''no_symlinks'' | boolean | no | ''0'' | Do not follow symbolic links if enabled |
 | ''no_dirlists'' | boolean | no | ''0'' | Do not generate directory listings if enabled | | ''no_dirlists'' | boolean | no | ''0'' | Do not generate directory listings if enabled |
-| ''http_keepalive'' | integer | no | ''20'' | connection reuse.  Some bugs have been seen, you //may// wish to disable this by setting to ''0'' (BB or later only) |+| ''rfc1918_filter'' | boolean | no | ''1'' | Reject requests from [[https://en.wikipedia.org/wiki/Private_network|RFC1918]] IP addresses directed to the servers public IPs. This is a DNS rebinding countermeasure. | 
 +| ''http_keepalive'' | integer | no | ''20'' | connection reuse.  Some bugs have been seen, you //may// wish to disable this by setting to ''0'' (BB or later only) |
 | ''max_requests'' | integer | no | ''3'' | 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. | | ''max_requests'' | integer | no | ''3'' | 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. |
-| ''max_connections'' | integer | no | ''100'' | Maximum number of concurrent connections. If this number is exceeded, further TCP connection attempts are queued until the number of active connections drops |+| ''max_connections'' | integer | no | ''100'' | 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. |
 | ''ubus_prefix'' | string | no | //(none)//  | URL prefix for [[docs:techref:ubus#access_to_ubus_over_http|UBUS via JSON-RPC handler]] e.g. ''/ubus''. If not specified then UBUS is not enabled. | | ''ubus_prefix'' | string | no | //(none)//  | URL prefix for [[docs:techref:ubus#access_to_ubus_over_http|UBUS via JSON-RPC handler]] e.g. ''/ubus''. If not specified then UBUS is not enabled. |
 | ''ubus_socket'' | file | no | //(none)//  | Override ubus socket path | | ''ubus_socket'' | file | no | //(none)//  | Override ubus socket path |
Line 46: Line 47:
  
  
-Multiple sections if the type //uhttpd// may exist - the init script will launch one webserver instance per section.+Multiple sections if the type ''uhttpd'' may exist - the init script will launch one webserver instance per section.  
 + 
 +As specified in the [[docs:guide-user:base-system:uci|The UCI System]] documentation, each of the ''uhttpd'' sections must be named differently. 
 + 
 +<code bash> 
 +config 'uhttpd' 'main' 
 +        option 'listen_http' '80' 
 +        option 'home'        '/www' 
 +         
 +config 'uhttpd' 'other' 
 +        option 'listen_http' '8080' 
 +        option 'home'        '/www/other' 
 +</code>
  
  
 ==== HTTPS Enable and Certificate Settings and Creation ==== ==== HTTPS Enable and Certificate Settings and Creation ====
-**First of all**you need to install the ''uhttpd-mod-tls'' package in order to pull into the system the '//TLS plugin which adds HTTPS support to uHTTPd//'.+In order to speak HTTPS/TLS, uhttpd needs one of several [[:docs:guide-user:services:tls:libs|cryptographic libraries]]. Such ''libuhttpd-...'' packages can be installed via opkge.g. ''libuhttpd-mbedtls'', ''libuhttpd-openssl'' or ''libuhttpd-wolfssl''
 + 
 +In the server configuration, the ''listen_https'' option needs to be defined as explained above. 
 + 
 +uhttpd requires an X.509 certificate and a private key. You can create and copy them manually to the place specified in the configuration.
  
-Then if ''listen_https'' is defined in the server configuration, the certificate and private key is missing. In this case (as of 10.03.1) you'll need to install the ''luci-ssl'' meta-package which in turn will pull also the ''px5g'' script. With this utility the init script will generate the appropriate certifcate and key files when the server is started for the first time, either by reboot or by manual restart.+There is an alternative: In this case (as of 10.03.1) you'll need to install the ''luci-ssl'' meta-package which in turn will pull also the ''px5g'' script. With this utility the init script will generate the appropriate self signed certificate and key files when the server is started for the first time, either by reboot or by manual restart.
  
 The ''/etc/config/uhttpd'' file contains in the end a section detailing the certificate and key files creation parameters: The ''/etc/config/uhttpd'' file contains in the end a section detailing the certificate and key files creation parameters:
Line 58: Line 75:
 ^ Name ^ Type ^ Required ^ Default ^ Description ^ ^ Name ^ Type ^ Required ^ Default ^ Description ^
 | ''days'' | integer | no | ''730'' | Validity time of the generated certificates in days | | ''days'' | integer | no | ''730'' | Validity time of the generated certificates in days |
-| ''bits'' | integer | no | ''1024'' | Size of the generated RSA key in bits | +| ''bits'' | integer | no | ''2048'' | Size of the generated RSA key in bits | 
-| ''country'' | string | no | ''DE'' | ISO country code of the certificate issuer | +| ''country'' | string | no | ''ZZ'' | ISO country code of the certificate issuer | 
-| ''state'' | string | no | ''Berlin'' | State of the certificate issuer | +| ''state'' | string | no | ''Somewhere'' | State of the certificate issuer | 
-| ''location'' | string | no | ''Berlin'' | Location/city of the certificate issuer |+| ''location'' | string | no | ''Unknown'' | Location/city of the certificate issuer |
 | ''commonname'' | string | no | ''OpenWrt'' | Common name covered by the certificate | | ''commonname'' | string | no | ''OpenWrt'' | Common name covered by the certificate |
  
 Those will be needed only once, at the next restart. Those will be needed only once, at the next restart.
 +
 +If you are hosting the website to internet you may want to [[:docs:guide-user:services:tls:certs|obtain LetsEncrypt certificates]].
  
 ===== Basic Authentication (httpd.conf) ===== ===== Basic Authentication (httpd.conf) =====
Line 76: Line 95:
   * ''password'' defines the secret password required to authenticate   * ''password'' defines the secret password required to authenticate
  
-The password can be either in plain text format, MD5 encoded or in the form ''$p$user'' where ''user'' refers to an account in ''/etc/shadow'' or ''/etc/passwd''.+The password can be either in plain text format, [[https://en.wikipedia.org/wiki/Crypt_(Unix)|crypt(1) MD5]] encoded or in the form ''$p$user'' where ''user'' refers to an account in ''/etc/shadow'' or ''/etc/passwd''.
  
 A plain text password can be converted to MD5 encoding by using the ''-m'' switch of the //uhttpd// executable: A plain text password can be converted to MD5 encoding by using the ''-m'' switch of the //uhttpd// executable:
  
-<code>root@OpenWrt:~# uhttpd -m secret +<code bash> 
-$1$$ysVNzQc4CTMkp5daOdZ.3/</code>+# uhttpd -m secret 
 +$1$$ysVNzQc4CTMkp5daOdZ.3/ 
 +</code>
  
 If the ''$p$...'' format is used, //uhttpd// will compare the client provided password against the one stored in the ''shadow'' or ''passwd'' database. If the ''$p$...'' format is used, //uhttpd// will compare the client provided password against the one stored in the ''shadow'' or ''passwd'' database.
  
-===== URL decoding =====+Example: 
 +<code - /etc/httpd.conf> 
 +/dashboard/:admin:$1$$ysVNzQc4CTMkp5daOdZ.3/ 
 +/:root:$p$root 
 +/:alice:P@$$w0rd 
 +</code>
  
 +  * Here the ''/dashboard/'' path is protected but allowed for user ''admin'' with the password ''secret'' that is hashed with crypt(1) MD5.
 +  * The root path ''/'' is allowd to the user ''root'' and it's password will be taken from ''/etc/passwd''
 +  * Also the ''/'' path is allowed for the user ''alice'' and shes password is ''P@$$w0rd'' which is not hashed and stored in clear text.
 +
 +===== URL decoding =====
 Like //Busybox HTTPd//, the URL decoding of strings on the command line is supported through the ''-d'' switch: Like //Busybox HTTPd//, the URL decoding of strings on the command line is supported through the ''-d'' switch:
  
-<code>root@OpenWrt:/# uhttpd -d "An%20URL%20encoded%20String%21%0a" +<code bash> 
-An URL encoded String!</code> +root@OpenWrt:/# uhttpd -d "An%20URL%20encoded%20String%21%0a" 
- +An URL encoded String! 
-===== Using PHP5 =====+</code>
  
-A minimal php5 installation includes  +===== Using PHP7 ===== 
-  * php5 +A minimal php7 installation includes: 
-  * php5-cgi+  * php7 
 +  * php7-cgi
  
-In /etc/php.ini ensure that the doc_root is empty if you are using multiple uhttpd instances (each on its own port). This enables the uhttpd 'home' variable to work for you.+In ''/etc/php.ini'' ensure that the doc_root is empty if you are using multiple uhttpd instances (each on its own port). This enables the uhttpd ''home'' variable to work for you.
  
 Ensure that you uncomment the extension interpreter line for PHP in the main section of the uHTTPd config file: Ensure that you uncomment the extension interpreter line for PHP in the main section of the uHTTPd config file:
-|'' list interpreter ".php=/usr/bin/php-cgi"''|+ 
 +<code bash> 
 +list interpreter ".php=/usr/bin/php-cgi" 
 +</code>
  
 ===== Securing uHTTPd ===== ===== Securing uHTTPd =====
 +See [[:docs:guide-user:luci:luci.secure]] for more details.
  
-By default, uHTTPd is bind to 0.0.0.0 which also includes the WAN port of your router. To bind uHTTPd to the LAN port only you have to change the listen_http and listen_https options to your LAN IP address.+By default, uHTTPd is bind to ''0.0.0.0'' which also includes the WAN port of your router. To bind uHTTPd to the LAN port only you have to change the ''listen_http'' and ''listen_https'' options to your LAN IP address.
  
 To get your current LAN IP address run this command: To get your current LAN IP address run this command:
-<code> + 
-uci get network.lan.ipaddr+<code bash
 +uci get network.lan.ipaddr 
 +192.168.1.1
 </code> </code>
  
-|'' +Then edit ''/etc/config/uhttpd'' and bind ''listen_http'' to specific ''192.168.1.1'' IP instead of ''0.0.0.0'' and comment out IPv6 bindings:
-config uhttpd main+
  
 +<code bash>
 +config uhttpd main
         # HTTP listen addresses, multiple allowed         # HTTP listen addresses, multiple allowed
-        list listen_http        **192.168.1.1:80**+        list listen_http        192.168.1.1:80
 #       list listen_http        [::]:80 #       list listen_http        [::]:80
  
         # HTTPS listen addresses, multiple allowed         # HTTPS listen addresses, multiple allowed
-        list listen_https       **192.168.1.1:443**+        list listen_https       192.168.1.1:443
 #       list listen_https       [::]:443 #       list listen_https       [::]:443
-''|+</code>
  
 ===== Embedded Lua ===== ===== Embedded Lua =====
 +uHTTPd supports running Lua in-process, which can speed up Lua CGI scripts. Also LuCI works fine with the embedded Lua interpreter. See the next subsection for instructions on how to set it up.
  
-uHTTPd supports running Lua in-process, which can speed up Lua CGI scripts. <del>It is unclear whether LuCI supports running in this embedded interpreter.</del> LuCI seems to work fine (if not better) with the embedded Lua interpreter. See the next subsection for instructions on how to set it up.+Here is an example using a test file ''test.lua'' to show it works:
  
-Here is an example using a test file test.lua to show it works: +<code bash
-<code> +# opkg install uhttpd-mod-lua
-root@OpenWrt:~# opkg install uhttpd-mod-lua+
 Installing uhttpd-mod-lua (18) to root... Installing uhttpd-mod-lua (18) to root...
 Downloading http://downloads.openwrt.org/snapshots/trunk/ar71xx/packages/uhttpd-mod-lua_18_ar71xx.ipk. Downloading http://downloads.openwrt.org/snapshots/trunk/ar71xx/packages/uhttpd-mod-lua_18_ar71xx.ipk.
 Configuring uhttpd-mod-lua. Configuring uhttpd-mod-lua.
-root@OpenWrt:~# uci set uhttpd.main.lua_prefix=/lua +# uci set uhttpd.main.lua_prefix=/lua 
-root@OpenWrt:~# uci set uhttpd.main.lua_handler=/root/test.lua +# uci set uhttpd.main.lua_handler=/root/test.lua 
-root@OpenWrt:~# cat /root/test.lua+# cat /root/test.lua
 function handle_request(env) function handle_request(env)
         uhttpd.send("Status: 200 OK\r\n")         uhttpd.send("Status: 200 OK\r\n")
Line 142: Line 181:
         uhttpd.send("Hello world.\n")         uhttpd.send("Hello world.\n")
 end end
-root@OpenWrt:~# /etc/init.d/uhttpd restart +# /etc/init.d/uhttpd restart 
-root@OpenWrt:~# wget -qO- http://127.0.0.1/lua/+# wget -qO- http://127.0.0.1/lua/
 Hello world. Hello world.
-root@OpenWrt:~# 
 </code> </code>
  
Line 152: Line 190:
  
 ==== LuCI with embedded Lua interpreter ==== ==== LuCI with embedded Lua interpreter ====
- 
 You need to install ''uhttpd-mod-lua'' and ''luci-sgi-uhttpd'' to get it to work: You need to install ''uhttpd-mod-lua'' and ''luci-sgi-uhttpd'' to get it to work:
-<code>root@OpenWrt:~# opkg install uhttpd-mod-lua luci-sgi-uhttpd</code>+ 
 +<code bash> 
 +opkg install uhttpd-mod-lua luci-sgi-uhttpd 
 +</code>
  
 In Chaos Calmer 15.05, the ''luci-sgi-uhttpd'' package is not needed. The appropriate files are included in ''luci-base''. In Chaos Calmer 15.05, the ''luci-sgi-uhttpd'' package is not needed. The appropriate files are included in ''luci-base''.
  
 Then uncomment the following lines in ''/etc/config/uhttpd'' (or add them if you don't have them): Then uncomment the following lines in ''/etc/config/uhttpd'' (or add them if you don't have them):
-<code>+ 
 +<code bash>
         option lua_prefix       /luci         option lua_prefix       /luci
         option lua_handler      /usr/lib/lua/luci/sgi/uhttpd.lua         option lua_handler      /usr/lib/lua/luci/sgi/uhttpd.lua
Line 165: Line 206:
  
 Then restart the server: Then restart the server:
-<code>root@OpenWrt:~# /etc/init.d/uhttpd restart</code>+ 
 +<code bash> 
 +/etc/init.d/uhttpd restart 
 +</code>
  
 One thing remains to be done. By default ''/www/index.html'' redirects you to ''/cgi-bin/luci'' which is the default CGI gateway for LuCI. The config above puts LuCI through embedded interpreter under ''/luci'' (''lua_prefix'' is what causes it) so you have to change that in ''/www/index.html''. The path appears there twice (one for the ''meta'' tag which does the redirect and one for the anchor). You can also copy/paste the code below if you don't want to meddle with it on your own. One thing remains to be done. By default ''/www/index.html'' redirects you to ''/cgi-bin/luci'' which is the default CGI gateway for LuCI. The config above puts LuCI through embedded interpreter under ''/luci'' (''lua_prefix'' is what causes it) so you have to change that in ''/www/index.html''. The path appears there twice (one for the ''meta'' tag which does the redirect and one for the anchor). You can also copy/paste the code below if you don't want to meddle with it on your own.
-<code>+<code html>
 <?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  • Last modified: 2024/12/16 09:26
  • by stokito