diff --git a/utils/httpd/Makefile b/utils/httpd/Makefile
new file mode 100644
index 0000000..73ff5ec
--- /dev/null
+++ b/utils/httpd/Makefile
@@ -0,0 +1,58 @@
+# httpd-utils
+# Written in 2020 by Lucas
+# CC0 1.0 Universal/Public domain - No rights reserved
+#
+# To the extent possible under law, the author(s) have dedicated all
+# copyright and related and neighboring rights to this software to the
+# public domain worldwide. This software is distributed without any
+# warranty. You should have received a copy of the CC0 Public Domain
+# Dedication along with this software. If not, see
+# .
+.POSIX:
+.SUFFIXES:
+.SUFFIXES: .c
+
+P = httpd-utils
+V = 1
+
+DOMAIN = example.net
+DOMAIN_V4 = 4.${DOMAIN}
+DOMAIN_V6 = 6.${DOMAIN}
+IPV4 = 192.0.2.1
+IPV6 = 2001:db8::2
+PREFIX = /var/www/htdocs/${DOMAIN}
+
+CGI = ip
+SRC = ip.c gen-config.sh gen-index.sh
+TXT = codes.txt
+
+.c:
+ ${CC} ${CFLAGS} ${LDFLAGS} -static -o $@ $<
+
+all: ${DOMAIN}.httpd.conf index.html ${CGI}
+
+${DOMAIN}.httpd.conf: gen-config.sh codes.txt
+ sh gen-config.sh ${DOMAIN} ${DOMAIN_V4} ${IPV4} ${DOMAIN_V6} ${IPV6} >$@
+
+index.html: gen-index.sh codes.txt
+ sh gen-index.sh ${DOMAIN} ${DOMAIN_V4} ${DOMAIN_V6} >$@
+
+clean:
+ rm -f ${DOMAIN}.httpd.conf index.html ${CGI} ${P}-${V}.tgz
+
+dist: clean
+ pax -ws ',^,${P}-${V}/,' Makefile ${SRC} ${TXT} | gzip >${P}-${V}.tgz
+
+install: all
+ cp -f ${DOMAIN}.httpd.conf /etc
+ mkdir -p ${PREFIX}
+ cp -f ${CGI} ${PREFIX}
+ cd ${PREFIX} && chmod 555 ${CGI}
+ cd ${PREFIX} && chown www:www ${CGI}
+ cp -f index.html ${PREFIX}
+ cd ${PREFIX} && chmod 444 index.html
+ cd ${PREFIX} && chown www:www index.html
+
+uninstall:
+ rm -f /etc/${DOMAIN}.httpd.conf
+ cd ${PREFIX} && rm -f ${CGI} index.html
diff --git a/utils/httpd/codes.txt b/utils/httpd/codes.txt
new file mode 100644
index 0000000..b8a67f5
--- /dev/null
+++ b/utils/httpd/codes.txt
@@ -0,0 +1,70 @@
+# Informational 1xx
+100
+101
+102
+
+# Successful 2xx
+200
+201
+202
+203
+204
+205
+206
+207
+208
+226
+
+# Redirection 3xx
+300
+301
+302
+303
+304
+305
+306
+307
+308
+
+# Client Error 4xx
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+420
+422
+423
+424
+426
+428
+429
+431
+451
+
+# Server Error 5xx
+500
+501
+502
+503
+504
+505
+506
+507
+508
+510
+511
diff --git a/utils/httpd/gen-config.sh b/utils/httpd/gen-config.sh
new file mode 100644
index 0000000..c355e2f
--- /dev/null
+++ b/utils/httpd/gen-config.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+# httpd-utils
+# Written in 2020 by Lucas
+# CC0 1.0 Universal/Public domain - No rights reserved
+#
+# To the extent possible under law, the author(s) have dedicated all
+# copyright and related and neighboring rights to this software to the
+# public domain worldwide. This software is distributed without any
+# warranty. You should have received a copy of the CC0 Public Domain
+# Dedication along with this software. If not, see
+# .
+
+usage()
+{
+ printf "Usage: %s domain domain_v4 ipv4 domain_v6 ipv6\n" "${0##*/}" >&2
+ exit 1
+}
+
+list_codes()
+{
+ case $1 in
+ 1xx) q='1[0-9][0-9]' ;;
+ 2xx) q='2[0-9][0-9]' ;;
+ 3xx) q='3[0-9][0-9]' ;;
+ 4xx) q='4[0-9][0-9]' ;;
+ 5xx) q='5[0-9][0-9]' ;;
+ *) q=X ;;
+ esac
+ grep -x -- "$q" codes.txt
+}
+
+print_block_return()
+{
+ _c=$1 _l=${2:-}
+
+ _fmt='\tlocation "/c/%u" { block return %u'${_l:+' "%s"'}' }\n'
+ printf "$_fmt" $_c $_c $_l
+}
+
+[ $# -eq 5 ] || usage
+domain=$1 domain_v4=$2 ipv4=$3 domain_v6=$4 ipv6=$5
+
+cat - <.
+
+usage()
+{
+ printf "Usage: %s domain domain_v4 domain_v6\n" "${0##*/}" >&2
+ exit 1
+}
+
+list_codes()
+{
+ case $1 in
+ 1xx) q='1[0-9][0-9]' ;;
+ 2xx) q='2[0-9][0-9]' ;;
+ 3xx) q='3[0-9][0-9]' ;;
+ 4xx) q='4[0-9][0-9]' ;;
+ 5xx) q='5[0-9][0-9]' ;;
+ *) q=X ;;
+ esac
+ grep -x -- "$q" codes.txt
+}
+
+show_category()
+{
+ _t=$1 _cc=$2
+ cat - <
+ $_t $_cc
+EOF
+
+ for _c in $(list_codes "$_cc"); do
+ printf '\t\t\t%u\n' "$_c" "$_c"
+ done
+ printf "\t\t\n"
+}
+
+[ $# -eq 3 ] || usage
+domain=$1 domain_v4=$2 domain_v6=$3
+
+cat - <
+
+
+
+ $domain
+
+
+
+ $domain
+
+ Utilities
+
+ - /ip
+ - shows client IP.
+ - $domain_v4/ip
+ - shows client IP, only listens on a IPv4 address.
+ - $domain_v6/ip
+ - shows client IP, only listens on a IPv6 address.
+
+
+ HTTP status codes
+EOF
+
+show_category "Informational" 1xx
+show_category "Successful" 2xx
+show_category "Redirection" 3xx
+show_category "Client Error" 4xx
+show_category "Server Error" 5xx
+
+cat - <
+
+EOF
diff --git a/utils/httpd/ip.c b/utils/httpd/ip.c
new file mode 100644
index 0000000..e4bdc8f
--- /dev/null
+++ b/utils/httpd/ip.c
@@ -0,0 +1,31 @@
+/*
+ * httpd-utils
+ * Written in 2020 by Lucas
+ * CC0 1.0 Universal/Public domain - No rights reserved
+ *
+ * To the extent possible under law, the author(s) have dedicated all
+ * copyright and related and neighboring rights to this software to the
+ * public domain worldwide. This software is distributed without any
+ * warranty. You should have received a copy of the CC0 Public Domain
+ * Dedication along with this software. If not, see
+ * .
+ */
+
+#include
+#include
+
+int
+main(void)
+{
+ char *ip;
+
+ ip = getenv("HTTP_X_FORWARDED_FOR");
+ if (ip == NULL)
+ ip = getenv("REMOTE_ADDR");
+ if (ip == NULL)
+ ip = "unknown";
+
+ printf("Content-type: text/plain\n\n%s\n", ip);
+
+ return 0;
+}