Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | OpenBSD server docs: Add instructions to make fossil.log owned by 'www' user, and repository directory group writeable; remove unnecessary 'directory index' option in httpd.conf; and fix redundant double backticks. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
8ce8828d0c1d38d518c6857267023040 |
User & Date: | jamsek 2020-06-27 12:45:32.840 |
Context
2020-06-27
| ||
14:48 | Add the obscure() shell function. Corresponding unobscure() is not provided. ... (check-in: f7e572b0 user: drh tags: trunk) | |
12:45 | OpenBSD server docs: Add instructions to make fossil.log owned by 'www' user, and repository directory group writeable; remove unnecessary 'directory index' option in httpd.conf; and fix redundant double backticks. ... (check-in: 8ce8828d user: jamsek tags: trunk) | |
10:48 | Attempt to fix broken link on the documentation index. ... (check-in: 02a7c72b user: drh tags: trunk) | |
Changes
Changes to www/server/openbsd/httpd.md.
1 2 3 4 5 6 7 8 | # Serving via httpd on OpenBSD [`httpd`][httpd] is the default web server that is included in the base install on OpenBSD. It's minimal and lightweight but secure and capable, and provides a clean interface for setting up a Fossil server using FastCGI. This article will detail the steps required to setup a TLS-enabled | | | | | | | | | | | | | > | > | | | | | | | | | | | > | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | # Serving via httpd on OpenBSD [`httpd`][httpd] is the default web server that is included in the base install on OpenBSD. It's minimal and lightweight but secure and capable, and provides a clean interface for setting up a Fossil server using FastCGI. This article will detail the steps required to setup a TLS-enabled `httpd` configuration that serves multiple Fossil repositories out of a single directory within a chroot, and allow `ssh` access to create new repositories remotely. **NOTE:** The following instructions assume an OpenBSD 6.7 installation. [httpd]: https://www.openbsd.org/papers/httpd-asiabsdcon2015.pdf ## <a name="fslinstall"></a>Install Fossil Use the OpenBSD package manager `pkg_add` to install Fossil, making sure to select the statically linked binary. ```console $ doas pkg_add fossil quirks-3.325 signed on 2020-06-12T06:24:53Z Ambiguous: choose package for fossil 0: <None> 1: fossil-2.10v0 2: fossil-2.10v0-static Your choice: 2 fossil-2.10v0-static: ok ``` This installs Fossil into the chroot. To facilitate local use, create a symbolic link of the fossil executable into `/usr/local/bin`. ```console $ doas ln -s /var/www/bin/fossil /usr/local/bin/fossil ``` As a privileged user, create the file `/var/www/cgi-bin/scm` with the following contents to make the CGI script that `httpd` will execute in response to `fsl.domain.tld` requests; all paths are relative to the `/var/www` chroot. ```sh #!/bin/fossil directory: /htdocs/fsl.domain.tld notfound: https://domain.tld repolist errorlog: /logs/fossil.log ``` The `directory` directive instructs Fossil to serve all repositories found in `/var/www/htdocs/fsl.domain.tld`, while `errorlog` sets logging to be saved to `/var/www/logs/fossil.log`; create the repository directory and log file—making the latter owned by the `www` user, and the script executable. ```console $ doas mkdir /var/www/htdocs/fsl.domain.tld $ doas touch /var/www/logs/fossil.log $ doas chown www /var/www/logs/fossil.log $ doas chmod 755 /var/www/cgi-bin/scm ``` ## <a name="chroot"></a>Setup chroot Fossil needs both `/dev/random` and `/dev/null`, which aren't accessible from within the chroot, so need to be constructed; `/var`, however, is mounted with the `nodev` option. Rather than removing this default setting, create a small memory filesystem with [`mount_mfs(8)`][mfs] upon which `/var/www/dev` will be mounted so that the `random` and `null` device files can be created. ```console $ doas mkdir /var/www/dev $ doas mount_mfs -s 1M /dev/sd0b /var/www/dev $ doas cd /var/www/dev $ doas /dev/MAKEDEV urandom $ doas mknod -m 666 null c 2 2 $ ls -l total 0 crw-rw-rw- 1 root daemon 2, 2 Jun 20 08:56 null lrwxr-xr-x 1 root daemon 7 Jun 18 06:30 random@ -> urandom crw-r--r-- 1 root wheel 45, 0 Jun 18 06:30 urandom ``` [mfs]: https://man.openbsd.org/mount_mfs.8 To make the mountable memory filesystem permanent, open `/etc/fstab` as a privileged user and add the following line to automate creation of the filesystem at startup: ```console swap /var/www/dev mfs rw,-s=1048576 0 0 ``` The same user that executes the fossil binary must have writable access to the repository directory that resides within the chroot; on OpenBSD this is `www`. In addition, grant repository directory ownership to the user who will push to, pull from, and create repositories. ```console $ doas chown -R user:www /var/www/htdocs/fsl.domain.tld $ doas chmod 775 /var/www/htdocs/fsl.domain.tld ``` ## <a name="httpdconfig"></a>Configure httpd On OpenBSD, [httpd.conf(5)][httpd] is the configuration file for `httpd`. To setup the server to serve all Fossil repositores within the directory specified in the CGI script, and automatically redirect standard HTTP requests to HTTPS—apart from [Let's Encrypt][LE] challenges issued in response to [acme-client(1)][acme] certificate requests—create `/etc/httpd.conf` as a privileged user with the following contents. [LE]: https://letsencrypt.org [acme]: https://man.openbsd.org/acme-client.1 [httpd.conf(5)]: https://man.openbsd.org/httpd.conf.5 ```apache |
︙ | ︙ | |||
141 142 143 144 145 146 147 | } hsts { max-age 15768000 preload subdomains } connection max request body 104857600 | < | | | | | | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | } hsts { max-age 15768000 preload subdomains } connection max request body 104857600 location "/*" { fastcgi { param SCRIPT_FILENAME "/cgi-bin/scm" } } location "/.well-known/acme-challenge/*" { root "/acme" request strip 2 } } ``` **NOTE:** If not already in possession of a HTTPS certificate, comment out the `https` server block and proceed to securing a free [Let's Encrypt Certificate](#letsencrypt); otherwise skip to [Start `httpd`](#starthttpd). ## <a name="letsencrypt"></a>Let's Encrypt Certificate In order for `httpd` to serve HTTPS, secure a free certificate from Let's Encrypt using `acme-client`. Before issuing the request, however, ensure you have a zone record for the subdomain with your registrar or nameserver. Then open `/etc/acme-client.conf` as a privileged user to configure the request. ```dosini authority letsencrypt { api url "https://acme-v02.api.letsencrypt.org/directory" account key "/etc/acme/letsencrypt-privkey.pem" } |
︙ | ︙ | |||
185 186 187 188 189 190 191 | domain key "/etc/ssl/private/domain.tld.key" domain certificate "/etc/ssl/domain.tld.crt" domain full chain certificate "/etc/ssl/domain.tld.fullchain.pem" sign with letsencrypt } ``` | > | > | | | | | | | | | | | | < | | | | | | | | | | | | | | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | domain key "/etc/ssl/private/domain.tld.key" domain certificate "/etc/ssl/domain.tld.crt" domain full chain certificate "/etc/ssl/domain.tld.fullchain.pem" sign with letsencrypt } ``` Start `httpd` with the new configuration file, and issue the certificate request. ```console $ doas rcctl start httpd $ doas acme-client -vv domain.tld acme-client: /etc/acme/letsencrypt-privkey.pem: account key exists (not creating) acme-client: /etc/acme/letsencrypt-privkey.pem: loaded RSA account key acme-client: /etc/ssl/private/domain.tld.key: generated RSA domain key acme-client: https://acme-v01.api.letsencrypt.org/directory: directories acme-client: acme-v01.api.letsencrypt.org: DNS: 172.65.32.248 ... N(Q????Z???j?j?>W#????b???? H????eb??T??*? DNosz(???n{L}???D???4[?B] (1174 bytes) acme-client: /etc/ssl/domain.tld.crt: created acme-client: /etc/ssl/domain.tld.fullchain.pem: created ``` A successful result will output the public certificate, full chain of trust, and private key into the `/etc/ssl` directory as specified in `acme-client.conf`. ```console $ doas ls -lR /etc/ssl -r--r--r-- 1 root wheel 2.3K Mar 2 01:31:03 2018 domain.tld.crt -r--r--r-- 1 root wheel 3.9K Mar 2 01:31:03 2018 domain.tld.fullchain.pem /etc/ssl/private: -r-------- 1 root wheel 3.2K Mar 2 01:31:03 2018 domain.tld.key ``` Make sure to reopen `/etc/httpd.conf` to uncomment the second server block responsible for serving HTTPS requests before proceeding. ## <a name="starthttpd"></a>Start `httpd` With `httpd` configured to serve Fossil repositories out of `/var/www/htdocs/fsl.domain.tld`, and the certificates and key in place, enable and start `slowcgi`—OpenBSD's FastCGI wrapper server that will execute the above Fossil CGI script—before checking that the syntax of the `httpd.conf` configuration file is correct, and (re)starting the server (if still running from requesting a Let's Encrypt certificate). ```console $ doas rcctl enable slowcgi $ doas rcctl start slowcgi slowcgi(ok) $ doas httpd -vnf /etc/httpd.conf configuration OK $ doas rcctl start httpd httpd(ok) ``` ## <a name="clientconfig"></a>Configure Client To facilitate creating new repositories and pushing them to the server, add the following function to your `~/.cshrc` or `~/.zprofile` or the config file for whichever shell you are using on your development box. ```sh finit() { fossil init $1.fossil && \ chmod 664 $1.fossil && \ fossil open $1.fossil && \ fossil user password $USER $PASSWD && \ fossil remote-url https://$USER:$PASSWD@fsl.domain.tld/$1 && \ rsync --perms $1.fossil $USER@fsl.domain.tld:/var/www/htdocs/fsl.domain.tld/ >/dev/null && \ chmod 644 $1.fossil && \ fossil ui } ``` This enables a new repository to be made with `finit repo`, which will create the fossil repository file `repo.fossil` in the current working directory; by default, the repository user is set to the environment variable `$USER`. It then opens the repository and sets the user password to the `$PASSWD` environment variable (which you can either set with `export PASSWD 'password'` on the command line or add to a *secured* shell environment file), and the `remote-url` to `https://fsl.domain.tld/repo` with the credentials of `$USER` who is authenticated with `$PASSWD`. Finally, it `rsync`'s the file to the server before opening the local repository in your browser where you can adjust settings such as anonymous user access, and set pertinent repository details. Thereafter, you can add files with `fossil add`, and commit with `fossil ci -m 'commit message'` where Fossil, by default, will push to the `remote-url`. It's suggested you read the [Fossil documentation][documentation]; with a sane and consistent development model, the system is much more efficient and cohesive than `git`—so the learning curve is not steep at all. [documentation]: https://fossil-scm.org/home/doc/trunk/www/permutedindex.html *[Return to the top-level Fossil server article.](../)* |