====== Creating a folder tree ======

Create a new folder tree for hosting web server resources and additional services.

<code> doas mkdir -p /home/www/acme doas mkdir -p /home/www/bin doas mkdir -p /home/www/cache doas mkdir -p /home/www/cgi-bin doas mkdir -p /home/www/conf doas mkdir -p /home/www/htdocs doas mkdir -p /home/www/logs doas mkdir -p /home/www/run doas mkdir -p /home/www/tmp doas mkdir -p /home/www/usr </code>

====== Setting directory owners ======

Next, you need to set the correct owners for the new folder tree.

<code> doas chown root:daemon /home/www/acme doas chown root:daemon /home/www/bin doas chown www:daemon /home/www/cache doas chown root:daemon /home/www/cgi-bin doas chown root:daemon /home/www/conf doas chown root:daemon /home/www/htdocs doas chown root:daemon /home/www/logs doas chown root:daemon /home/www/run doas chown www:www /home/www/tmp doas chown root:daemon /home/www/usr </code>

====== Copying service files ======

The next step is to copy the old files into the new folder tree.

<code> doas cp /var/www/bin/* /home/www/bin/ doas chown root:bin /home/www/bin/* doas cp /var/www/cgi-bin/* /home/www/cgi-bin/ doas chown root:bin /home/www/cgi-bin/* doas cp /var/www/conf/* /home/www/conf/ doas chown root:wheel /home/www/conf/* doas mkdir -p /home/www/usr/sbin doas chown root:daemon /home/www/usr/sbin doas cp /var/www/usr/sbin/sendmail /home/www/usr/sbin/sendmail doas chown root:daemon /home/www/usr/sbin/sendmail </code>

====== Stopping services ======

You need to stop the web server and its additional services.

<code> doas rcctl -d stop httpd doas rcctl -d stop php73_fpm </code>

====== Making changes to the configuration ======

The next step is to make changes to the configuration files of the web server and its services.

/etc/httpd.conf: <code> chroot "/home/www" </code>

/etc/php-fpm.conf: <code> listen = /home/www/run/php-fpm.sock chroot = /home/www </code>

====== Email security settings ====== Setting the minimum rights for the mail system <code> doas chmod 640 /etc/mail/domains doas chmod 640 /etc/mail/vusers doas chmod 640 /etc/mail/hosts doas chmod 640 /etc/mail/passwd doas chmod 640 /etc/mail/vusers doas chmod 640 /etc/mail/smtpd.conf doas chown _dovecot:_dovecot /etc/dovecot/dovecot.conf doas chown _dovecot:_dovecot /etc/dovecot/users.txt doas chmod 640 /etc/dovecot/dovecot.conf doas chmod 640 /etc/dovecot/users.txt </code>

First make sure to set quotas

Second, make sure to change file permissions for


We symlinked /htdocs inside each user's home folder to /var/www/htdocs/<username>

We installed

Inside /etc/httpd.conf:


        location "/~username/*" {
                root "/htdocs/username"
                request strip 1


Update: hiding logs was causing problems

We also hide logs in /var/logs and /var/www/logs

Packages installed

Packages installed:

<code> ImageMagick- image processing tools alpine-2.21p3 UW e-mail client anthy-9100hp2 japanese input method antiword-0.37p0 converts MSWord Documents to ASCII Text and PostScript apr-1.6.5p0 Apache Portable Runtime apr-util-1.6.1p2 companion library to APR argon2-20171227 C implementation of Argon2 - password hashing function aspell- spell checker designed to eventually replace Ispell bash-5.0.11 GNU Bourne Again Shell boehm-gc-7.6.0p3 garbage collection and memory leak detection for C and C++ boost-1.66.0p7 free peer-reviewed portable C++ source libraries bzip2-1.0.8 block-sorting file compressor, unencumbered cmake-3.15.3v0 portable build system coreutils-8.31p1 file, shell and text manipulation utilities curl-7.66.0 get files from FTP, Gopher, HTTP or HTTPS servers cvsps-2.1p2 generate patchsets from CVS repositories cyrus-sasl-2.1.27p1 RFC 2222 SASL (Simple Authentication and Security Layer) db-4.6.21p7v0 Berkeley DB package, revision 4 desktop-file-utils-0.24p0 utilities for dot.desktop entries djvulibre-3.5.27p6 view, decode and encode DjVu files docx2txt-1.4p0 command line converter from Microsoft docx to ASCII text elvis-2.2.0p5-no_x11 clone of the ex/vi text editor emacs-26.3-no_x11 GNU editor: extensible, customizable, self-documenting fdm-2.0 fetch, filter and deliver mail fetchmail-6.3.26p3 mail retrieval utility for POP2, POP3, KPOP, IMAP and more fftw3-3.3.8p1 C routines for computing the Discrete Fourier Transform fftw3-common-3.3.8p1 common files for the fftw3 packages figlet-2.2.5 generates ASCII banner art gawk-5.0.0p0 GNU awk gdk-pixbuf-2.38.2 graphic library for gtk+2 geomyidae-0.34 Gopher protocol daemon gettext-runtime-0.20.1p0 GNU gettext runtime libraries and programs giflib-5.1.6 tools and library routines for working with GIF images git-2.23.0 GIT - Tree History Storage Tool glib2-2.60.7 general-purpose utility library gmake-4.2.1p4 GNU make gnupg-1.4.23p3 GNU privacy guard - a free PGP replacement gnupg-2.2.12p0 GNU privacy guard - a free PGP replacement got-0.17 game of trees version control system groff-1.22.4p0 GNU troff typesetter gtk-update-icon-cache-3.24.12 gtk+ icon theme caching utility hicolor-icon-theme-0.17 fallback theme of the icon theme specification icu4c-64.2p0 International Components for Unicode ii-1.7p3 minimalist IRC client irssi-1.2.2 modular IRC client with many features jasper-2.0.14 reference implementation of JPEG-2000 jbigkit-2.1 lossless image compression library, with lightweight version jpeg-2.0.3v0 SIMD-accelerated JPEG codec replacement of libjpeg jq-1.6p0 lightweight and flexible command-line JSON processor jsoncpp-1.8.4p2 JSON parsing C++ API lcms2-2.9p0 color management library ledger-3.1.1p4 command line double-entry accounting ledger libarchive-3.4.0 multi-format archive and compression library libb2-0.98.1v0 library providing BLAKE2b, BLAKE2s, BLAKE2bp, BLAKE2sp libffi-3.2.1p5 Foreign Function Interface libiconv-1.16p0 character set conversion library libidn2-2.3.0 implementation of IDNA2008 internationalized domain names libraw-0.19.5 library for reading RAW files libtasn1-4.14 Abstract Syntax Notation One structure parser library libunbound-1.9.4 validating DNS resolver library libunistring-0.9.7 manipulate Unicode strings libuv-1.30.1 multi-platform library for asynchronous I/O libwebp-1.0.3 Google WebP image format conversion tool libxml-2.9.9 XML parsing library links-1.03p0 text browser, displays while downloading lua-5.3.5 powerful, light-weight programming language (version 5.3.5) lynx-2.8.9rel1p0 text web browser lz4-1.9.2 fast BSD-licensed data compression mariadb-client-10.3.20v1 multithreaded SQL database (client) mariadb-server-10.3.20v1 multithreaded SQL database (server) mawk- fast POSIX-compliant awk mcabber-1.1.0p4 console jabber client mercurial-5.0.2 fast, lightweight source control management multitail-6.4.2p0 multi-window tail(1) utility mutt-1.12.2v3-sasl tty-based e-mail client nano-4.4 simple editor, inspired by Pico neovim-0.3.8 continuation and extension of Vim newsboat-2.15p0 RSS/Atom feed reader for text terminals nghttp2-1.39.2 library for HTTP/2 ngircd-25 lightweight irc server node-10.16.3 V8 JavaScript for clients and servers nvi-2.1.3p2 ex/vi text editor with wide character support oath-toolkit-2.6.2p1 toolkit for OATH/HOTP and TOTP openjp2-2.3.1 open-source JPEG 2000 codec library p11-kit- library for loading and enumerating PKCS#11 modules pcre-8.41p2 perl-compatible regular expression library php-7.3.12 server-side HTML-embedded scripting language pico-5.09p20 UW text editor pkglocatedb-1.5 database of packages for use with locate(1) png-1.6.37 library for manipulating PNG images profanity-0.7.1 console based XMPP client py-pip-19.1.1 tool for installing Python packages py3-neovim-0.3.2p0 Python plugin support for Neovim py3-pip-19.1.1 tool for installing Python packages python-2.7.16p1 interpreted object-oriented programming language python-3.7.4 interpreted object-oriented programming language quirks-3.182 exceptions to pkg_add rules rhash-1.3.5p0 utility and library for computing hash sums rsync-3.1.3 mirroring/synchronization over low bandwidth links ruby-2.6.5 object oriented script language with threads rust-1.38.0 compiler for Rust Language sacc-1.00 simple console gopher client screen-4.6.2 multi-screen window manager shared-mime-info-1.10p5 shared mime database for desktops sic-1.2p1 simple irc client slrn-1.0.2p2 SLang-based newsreader sqlite3-3.29.0 embedded SQL implementation subversion-1.12.2 subversion revision control system tcsh-6.20.00p1 extended C-shell with many useful features tiff-4.0.10 tools and library routines for working with TIFF images tree-0.62 print ascii formatted tree of a directory structure trn-4.0.77p2 threaded newsreader uim-1.8.8p0 multilingual input method library uim-chewing-0.1.0p2 chewing input method for uim unzip-6.0p12 extract, list & test files in a ZIP archive vim-8.1.2061-no_x11 vi clone, many additional features w3m-0.5.3p8 pager/text-based web browser weechat-2.6 fast, light and extensible chat client wget-1.20.3p1 retrieve files from the web via HTTP, HTTPS and FTP xlsx2csv-20150318p1 convert XLSX files to CSV xz-5.2.4 LZMA compression and decompression tools zh-fonts-kc-1.05p2 extra chinese fonts zh-libchewing-0.5.1p0 intelligent phonetic input method library zip-3.0p1 create/update ZIP files compatible with PKZip(tm) zstd-1.4.3 zstandard fast real-time compression algorithm </code>

To set the user's default prompt to "username$ ", stick this into /etc/profile:

<code> export PS1="`whoami`$ " </code>


             # chmod -R o-rx /var/log
             # chmod o-rx /var/run/utmp
             # chmod o-r /var/log/wtmp*


Seems like there is no way to hide processes from users:


  1. chmod 750 /var/www/logs/
  2. chmod 640 /var/www/logs/*
  3. chmod 750 /var/log
  4. chmod o-rx /var/log/*
  5. chmod -R o-rx /etc/mail


to turn accounting on.. only users love making use of it too

add login.conf rules

For each new user:


  1. adduser
  2. chmod 700 /home/username /home/username/.ssh
  3. chmod 600 /home/username/{.Xdefaults,.cshrc,.cvsrc,.login,.mailrc,.profile}
  4. mkdir /var/www/htdocs/username
  5. ln -s /var/www/htdocs/username /home/username/htdocs
  6. chown username:username /var/www/htdocs/username /home/username/htdocs
  7. edquota username


In /etc/httpd.conf:


        location "/~username/*" {
                root "/htdocs/username"
                request strip 1 


In nsd zone files, create 1 subdomain per user so users get:

any new suid binary's with <code>

             # find / -perm -4000


Check /etc/groups to make sure that no user is a member of wheel. This will prevent them from su to root even if they know the password.

In /etc/ssh/sshd_config, turn off X11 forwarding

Create symlinks for users so they don't complain:

<code> ln -s /usr/local/bin/tclsh8.6 /usr/local/bin/tclsh ln -s /usr/local/bin/python3.7 /usr/local/bin/python </code>

You will want to have /var/www/etc/resolv.conf to allow DNS lookup inside the chroot:


  1. mkdir /var/www/etc/
  2. cp /etc/resolv.conf /var/www/etc/
  3. chown -R www:daemon /var/www/etc