You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
13 KiB

  1. #!/bin/sh
  2. # This is a template copy it by: ./README.sh | xclip -selection c
  3. # to https://openwrt.org/docs/guide-user/services/webserver/nginx#configuration
  4. NGINX_UTIL="/usr/bin/nginx-util"
  5. EXAMPLE_COM="example.com"
  6. MSG="
  7. /* Created by the following bash script that includes the source of some files:
  8. * https://github.com/openwrt/packages/net/nginx/files/README.sh
  9. */"
  10. eval $("${NGINX_UTIL}" get_env)
  11. code() { printf "<file nginx %s>\n%s</file>" "$1" "$(cat "$(basename $1)")"; }
  12. ifConfEcho() { sed -nE "s/^\s*$1=\s*(\S*)\s*\\\\$/\n$2 \"\1\";/p" ../Makefile;}
  13. cat <<EOF
  14. ===== Configuration =====${MSG}
  15. The official Documentation contains a
  16. [[https://docs.nginx.com/nginx/admin-guide/|Admin Guide]].
  17. Here we will look at some often used configuration parts and how we handle them
  18. at OpenWrt.
  19. At different places there are references to the official
  20. [[https://docs.nginx.com/nginx/technical-specs/|Technical Specs]]
  21. for further reading.
  22. **tl;dr:** The main configuration is a minimal configuration enabling the
  23. ''${CONF_DIR}'' directory:
  24. * There is a ''${LAN_NAME}.conf'' containing a default server for the LAN, \
  25. which includes all ''*.locations''.
  26. * We can disable parts of the configuration by renaming them.
  27. * If we want to install other HTTPS servers that are also reachable locally, \
  28. we can include the ''${LAN_SSL_LISTEN}'' file.
  29. * We have a server in ''_redirect2ssl.conf'' that redirects inexistent URLs \
  30. to HTTPS, too.
  31. * We can create a self-signed certificate and add corresponding directives \
  32. to e.g. ''${EXAMPLE_COM}.conf'' by invoking \
  33. <code>$(basename ${NGINX_UTIL}) ${ADD_SSL_FCT} ${EXAMPLE_COM}</code>
  34. ==== Basic ====${MSG}
  35. We modify the configuration by creating different configuration files in the
  36. ''${CONF_DIR}'' directory.
  37. The configuration files use the file extensions ''.locations'' and
  38. ''.conf'' plus ''.crt'' and ''.key'' for SSL certificates and keys.
  39. We can disable single configuration parts by giving them another extension,
  40. e.g., by adding ''.disabled''.
  41. For the new configuration to take effect, we must reload it by:
  42. <code>service nginx reload</code>
  43. For OpenWrt we use a special initial configuration, which is explained below in
  44. the section [[#openwrt_s_defaults|OpenWrt’s Defaults]].
  45. So, we can make a site available at a specific URL in the **LAN** by creating a
  46. ''.locations'' file in the directory ''${CONF_DIR}''.
  47. Such a file consists just of some
  48. [[https://nginx.org/en/docs/http/ngx_http_core_module.html#location|
  49. location blocks]].
  50. Under the latter link, you can find also the official documentation for all
  51. available directives of the HTTP core of Nginx.
  52. Look for //location// in the Context list.
  53. The following example provides a simple template, see at the end for
  54. different [[#locations_for_apps|Locations for Apps]] and look for
  55. [[https://github.com/search?utf8=%E2%9C%93&q=repo%3Aopenwrt%2Fpackages
  56. +extension%3Alocations&type=Code&ref=advsearch&l=&l=|
  57. other packages using a .locations file]], too:
  58. <code nginx ${CONF_DIR}example.locations>
  59. location /ex/am/ple {
  60. access_log off; # default: not logging accesses.
  61. # access_log /proc/self/fd/1 openwrt; # use logd (init forwards stdout).
  62. # error_log stderr; # default: logging to logd (init forwards stderr).
  63. error_log /dev/null; # disable error logging after config file is read.
  64. # (state path of a file for access_log/error_log to the file instead.)
  65. index index.html;
  66. }
  67. # location /eg/static { … }
  68. </code>
  69. All location blocks in all ''.locations'' files must use different URLs,
  70. since they are all included in the ''${LAN_NAME}.conf'' that is part of the
  71. [[#openwrt_s_defaults|OpenWrt’s Defaults]].
  72. We reserve the ''location /'' for making LuCI available under the root URL,
  73. e.g. [[https://192.168.1.1/|192.168.1.1/]].
  74. All other sites shouldn’t use the root ''location /'' without suffix.
  75. We can make other sites available on the root URL of other domain names, e.g.
  76. on www.example.com/.
  77. In order to do that, we create a ''.conf'' file for every domain name:
  78. see the next section [[#new_server_parts|New Server Parts]].
  79. We can also activate SSL there, as described below in the section
  80. [[#ssl_server_parts|SSL Server Parts]].
  81. We use such server parts also for publishing sites to the internet (WAN)
  82. instead of making them available just in the LAN.
  83. Via ''.conf'' files we can also add directives to the //http// part of the
  84. configuration. The difference to editing the main ''${NGINX_CONF}''
  85. file instead is the following: If the package’s ''nginx.conf'' file is updated
  86. it will only be installed if the old file has not been changed.
  87. ==== New Server Parts ====${MSG}
  88. For making the router reachable from the WAN at a registered domain name,
  89. it is not enough to give the name server the internet IP address of the router
  90. (maybe updated automatically by a
  91. [[docs:guide-user:services:ddns:client|DDNS Client]]).
  92. We also need to set up virtual hosting for this domain name by creating an
  93. appropriate server part in a ''${CONF_DIR}*.conf'' file.
  94. All such files are included at the start of Nginx by the default main
  95. configuration of OpenWrt ''${NGINX_CONF}'' as depicted in
  96. [[#openwrt_s_defaults|OpenWrt’s Defaults]].
  97. In the server part, we state the domain as
  98. [[https://nginx.org/en/docs/http/ngx_http_core_module.html#server_name|
  99. server_name]].
  100. The link points to the same document as for the location blocks in the
  101. [[#basic|Basic Configuration]]: the official documentation for all available
  102. directives of the HTTP core of Nginx.
  103. This time look for //server// in the Context list, too.
  104. The server part should also contain similar location blocks as before.
  105. We can re-include a ''.locations'' file that is included in the server part for
  106. the LAN by default.
  107. Then the site is reachable under the same path at both domains, e.g., by
  108. http://192.168.1.1/ex/am/ple as well as by http://example.com/ex/am/ple.
  109. The following example is a simple template:
  110. <code nginx ${CONF_DIR}${EXAMPLE_COM}.conf>
  111. server {
  112. listen 80;
  113. listen [::]:80;
  114. server_name ${EXAMPLE_COM};
  115. # location / { … } # root location for this server.
  116. include '${CONF_DIR}${EXAMPLE_COM}.locations';
  117. }
  118. </code>
  119. ==== SSL Server Parts ====${MSG}
  120. We can enable HTTPS for a domain if Nginx is installed with SSL support.
  121. We need a SSL certificate as well as its key and add them by the directives
  122. //ssl_certificate// respective //ssl_certificate_key// to the server part of the
  123. domain.
  124. The rest of the configuration is similar as described in the previous section
  125. [[#new_server_parts|New Server Parts]],
  126. we only have to adjust the listen directives by adding the //ssl// parameter,
  127. see the official documentation for
  128. [[https://nginx.org/en/docs/http/configuring_https_servers.html|
  129. configuring HTTPS servers]], too.
  130. The [[#openwrt_s_defaults|OpenWrt’s Defaults]] include a ''${LAN_NAME}.conf''
  131. file containing a server part that listens on the LAN address(es) and acts as
  132. //default_server// with ssl on port 443.
  133. For making the domain name accessible in the LAN, too, the corresponding
  134. server part must listen **explicitly** on the local IP address(es), cf. the
  135. official documentation on
  136. [[https://nginx.org/en/docs/http/request_processing.html|request_processing]].
  137. We can include the file ''${LAN_SSL_LISTEN}'' that contains the listen
  138. directives with ssl parameter for all LAN addresses on the HTTP port 443 and is
  139. updated automatically.
  140. The official documentation of the SSL module contains an
  141. [[https://nginx.org/en/docs/http/ngx_http_ssl_module.html#example|
  142. example]],
  143. which includes some optimizations.
  144. The following template is extended similarly:
  145. <code nginx ${CONF_DIR}${EXAMPLE_COM}>
  146. server {
  147. listen 443 ssl;
  148. listen [::]:443 ssl;
  149. include '${LAN_SSL_LISTEN}';
  150. server_name ${EXAMPLE_COM};
  151. ssl_certificate '${CONF_DIR}${EXAMPLE_COM}.crt';
  152. ssl_certificate_key '${CONF_DIR}${EXAMPLE_COM}.key';
  153. ssl_session_cache ${SSL_SESSION_CACHE_ARG};
  154. ssl_session_timeout ${SSL_SESSION_TIMEOUT_ARG};
  155. # location / { … } # root location for this server.
  156. include '${CONF_DIR}${EXAMPLE_COM}.locations';
  157. }
  158. </code>
  159. For creating a certificate (and its key) we can use Let’s Encrypt by installing
  160. [[https://github.com/Neilpang/acme.sh|ACME Shell Script]]:
  161. <code>opkg update && opkg install acme # and for LuCI: luci-app-acme</code>
  162. For the LAN server in the ''${LAN_NAME}.conf'' file, the init script
  163. ''/etc/init.d/nginx'' script installs automatically a self-signed certificate.
  164. We can use this mechanism also for other sites by issuing, e.g.:
  165. <code>$(basename ${NGINX_UTIL}) ${ADD_SSL_FCT} ${EXAMPLE_COM}</code>
  166. - It adds SSL directives to the server part of \
  167. ''${CONF_DIR}${EXAMPLE_COM}.conf'' like in the example above.
  168. - Then, it checks if there is a certificate and key for the given domain name\
  169. that is valid for at least 13 months or tries to create a self-signed one.
  170. - When cron is activated, it installs a cron job for renewing the self-signed\
  171. certificate every year if needed, too. We can activate cron by: \
  172. <code>service cron enable && service cron start</code>
  173. Beside the ''${LAN_NAME}.conf'' file, the
  174. [[#openwrt_s_defaults|OpenWrt’s Defaults]] include also the
  175. ''_redirect2ssl.conf'' file containing a server part that redirects all HTTP
  176. request for inexistent URIs to HTTPS.
  177. ==== OpenWrt’s Defaults ====${MSG}
  178. The default main configuration file is:
  179. $(code ${NGINX_CONF})
  180. We can pretend the main configuration contains also the following presets,
  181. since Nginx is configured with them:
  182. <code nginx>$(ifConfEcho --pid-path pid)\
  183. $(ifConfEcho --lock-path lock_file)\
  184. $(ifConfEcho --error-log-path error_log)\
  185. $(false && ifConfEcho --http-log-path access_log)\
  186. $(ifConfEcho --http-proxy-temp-path proxy_temp_path)\
  187. $(ifConfEcho --http-client-body-temp-path client_body_temp_path)\
  188. $(ifConfEcho --http-fastcgi-temp-path fastcgi_temp_path)\
  189. </code>
  190. So, the access log is turned off by default and we can look at the error log
  191. by ''logread'', as Nginx’s init file forwards stderr and stdout to the
  192. [[docs:guide-user:base-system:log.essentials|logd]].
  193. We can set the //error_log// and //access_log// to files where the log
  194. messages are forwarded to instead (after the configuration is read).
  195. And for redirecting the access log of a //server// or //location// to the logd,
  196. too, we insert the following directive in the corresponding block:
  197. <code nginx>
  198. access_log /proc/self/fd/1 openwrt;
  199. </code>
  200. At the end, the main configuration pulls in all ''.conf'' files from the
  201. directory ''${CONF_DIR}'' into the http block, especially the following
  202. server part for the LAN:
  203. $(code ${CONF_DIR}${LAN_NAME}.conf)
  204. It pulls in all ''.locations'' files from the directory ''${CONF_DIR}''.
  205. We can install the location parts of different sites there (see above in the
  206. [[#basic|Basic Configuration]]) and re-include them in server parts of other
  207. ''${CONF_DIR}*.conf'' files.
  208. This is needed especially for making them available to the WAN as described
  209. above in the section [[#new_server_parts|New Server Parts]].
  210. All ''.locations'' become available on the LAN through the file
  211. ''$(basename ${LAN_SSL_LISTEN}).default'', which contains one of the following
  212. directives for every local IP address:
  213. <code nginx>
  214. listen IPv4:443 ssl default_server;
  215. listen [IPv6]:443 ssl default_server;
  216. </code>
  217. The ''${LAN_SSL_LISTEN}'' file contains the same directives without the
  218. parameter ''default_server''.
  219. We can include this file in other server parts that should be reachable in the
  220. LAN through their //server_name//.
  221. Both files ''${LAN_SSL_LISTEN}{,.default}'' are (re-)created if Nginx starts
  222. through its init for OpenWrt or the LAN interface changes.
  223. There is also the following server part that redirects requests for an
  224. inexistent ''server_name'' from HTTP to HTTPS (using an invalid name, more in
  225. the official documentation on
  226. [[https://nginx.org/en/docs/http/request_processing.html|request_processing]]):
  227. $(code ${CONF_DIR}_redirect2ssl.conf)
  228. Nginx’s init file for OpenWrt installs automatically a self-signed certificate
  229. for the LAN server part if needed and possible:
  230. - Everytime Nginx starts, we check if the LAN is set up for SSL.
  231. - We add //ssl*// directives (like in the example of the previous section \
  232. [[#ssl_server_parts|SSL Server Parts]]) to the configuration file \
  233. ''${CONF_DIR}${LAN_NAME}.conf'' if needed and if it looks “normal”, i.e., \
  234. it has a ''server_name ${LAN_NAME};'' part.
  235. - If there is no corresponding certificate that is valid for more than 13 \
  236. months at ''${CONF_DIR}${LAN_NAME}.{crt,key}'', we create a self-signed one.
  237. - We activate SSL by including the ssl listen directives from \
  238. ''${LAN_SSL_LISTEN}.default'' and it becomes available by the default \
  239. redirect from ''listen *:80;'' in ''${CONF_DIR}_redirect2ssl.conf''
  240. - If cron is available, i.e., its status is not ''inactive'', we use it \
  241. to check the certificate for validity once a year and renew it if there \
  242. are only about 13 months of the more than 3 years life time left.
  243. The points 2, 3 and 5 can be used for other domains, too:
  244. As described in the section [[#new_server_parts|New Server Parts]] above, we
  245. create a server part in ''${CONF_DIR}www.example.com.conf'' with
  246. a corresponding ''server_name www.example.com;'' directive and call
  247. <code>$(basename ${NGINX_UTIL}) ${ADD_SSL_FCT} www.example.com</code>
  248. EOF