• Stars
    star
    129
  • Rank 279,262 (Top 6 %)
  • Language
    C
  • License
    BSD 2-Clause "Sim...
  • Created over 8 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Small and made-easy HTTP/HTTPS server based on Jef Poskanzer's thttpd

Merecat httpd ∴ Embedded Web Server

License Badge GitHub Status Coverity Status

http://imgur.com/user/SunShot

Merecat started out as a pun at Mongoose, but is now useful for actual web serving purposes. It is however not a real Meerkat, merely yet another copycat, forked from the great thttpd created by Jef Poskanzer.

Merecat httpd expands on the features originally offered by thttpd, but still has a limited feature set:

  • Virtual hosts
  • Basic .htpassd and .htaccess support
  • URL-traffic-based throttling
  • CGI/1.1
  • HTTP/1.1 Keep-alive
  • Built-in gzip deflate using zlib
  • HTTPS support using OpenSSL/LibreSSL, works with Let's Encrypt!
  • Dual server support, both HTTP/HTTPS from one process
  • HTTP redirect, to gently redirect from HTTP server to HTTPS
  • Native PHP support, using php-cgi if enabled in merecat.conf

The resulting footprint (~140 kiB) makes it quick and suitable for small and embedded systems!

Merecat is available as free/open source software under the simplified 2-clause BSD license. For more information, see the manual page merecat(8), or the FAQ.

The rest of this README covers some basic functions and recommendations. For more in-depth use-case examples, see the following HowTos:

Docker

Try out Docker Merecat safely isolated from the rest of the system, with easy deployment.

Authentication

To protect a directory in your ~USERNAME/public_html/, create the file .htpasswd using the included htpasswd tool:

user@example:~/> cd public_html/Downloads
user@example:~/public_html/Downloads/> htpasswd -c .htpasswd friend
Changing password for user friend
New password: *****
Re-type new password: *****

Enable this feature, and user home directories, with the configure script. See more on this in the Features section below.

Virtual Hosts

Setting up virtual hosts on a server can be a bit of a hassle with other web servers. With Merecat you simply create directories for each host in the web server root:

/var/www/
  |-- icons/
  |-- cgi-bin/
  |-- errors/
  |    `-- err404.html
  |-- ftp.example.com/
   `- www.example.com/

Edit /etc/merecat.conf:

virtual-host = true
cgi "/cgi-bin/*|**.cgi" {
    enabled = true
}

Now the web server root, /var/www/, no longer serves files, only virtual host directories do, execpt for the shared files in icons/, cgi-bin/, and errors/.

On Linux bind mounts can be used to set up FTP and web access to the same files. Example /etc/fstab:

/srv/ftp  /var/www/ftp.example.com  none  defaults,bind  0  0

Optimizing Performance

There are many tricks to optimizing the performance of your web server. One of the most important ones is browser caching. Merecat supports both ETag: and Cache-Control:, however to enable the latter you need to define the max-age setting in /etc/merecat.conf:

max-age = 3600        # One hour

The value is completely site dependent. For an embedded system you might want to set it to the maximum value, whereas for other scenarios you will likely want something else. By default this is disabled (0).

Another trick is to employ gzip compression. Merecat has built-in support for serving HTML, CSS, and other text/* files if there is a .gz version of the same file. Here is an example of how to compress relevant files:

root@example:~/> cd /var/www/
root@example:/var/www/> for file in `find . -name '*.html' -o -name '*.css'`; do \
      gzip -c $file > $file.gz; done

This approach is more CPU friendly than letting Merecat "deflate" files on the fly, which it otherwise does.

HTTPS Support

If configure finds OpenSSL installed, HTTPS support is enabled, this can be disabled using --without-ssl. However, to gain access to the SSL/TLS settings you also need support for merecat.conf, so you must install libConfuse. See below for all Build Requirements.

The HTTPS support has SSLv2, SSLv3, and TLSv1 disabled (hard coded) by default. Only TLSv2 and later will be enabled and negotiated on a per client basis.

To set up Merecat for HTTPS the following /etc/merecat.conf settings must be enabled:

server secure {
    port = 443
    ssl {
        certfile = /etc/letsencrypt/live/example.com/fullchain.pem
        keyfile  = /etc/letsencrypt/live/example.com/privkey.pem
        dhfile   = /etc/letsencrypt/live/example.com/dhparam.pem
    }
}

Let's Encrypt

Merecat fully supports Let's Encrypt certificates, including HTTP-01 renewals. Use the server location directive:

server default {
        port = 80
        location "/.well-known/acme-challenge/**" {
                 path = "letsencrypt/.well-known/acme-challenge/"
        }
        redirect "/**" {
                 code = 301
                 location = "https://$host$request_uri$args"
        }
}

The path must be relative to the server root directory. Use bind mounts to get /var/lib/letsencrypt into your server root. This way we can ensure certbot only writes to its own directory and cannot write to any file in the server root.

Then run certbot with the following arguments and then add all virtual hosts you want to support from Merecat:

root@example:/var/www/> certbot certonly --webroot --webroot-path /var/lib/letsencrypt

For a HowTo see:

Self-signed Certificate

To create a self signed certificate and enable perfect forward secrecy, PFS, i.e. Diffie-Helman paramters (optional), use the openssl tool as shown below. Notice the use of a sub-shell with openssl.cnf where most of the certificate settings are, and more importantly notice the use of subjectAltName, or SAN. The latter is required by most browsers today.

root@example:/var/www/> mkdir private certs
root@example:/var/www/> openssl req -x509 -newkey rsa:4096 -nodes    \
            -keyout private/server.key -new -out certs/server.pem    \
            -subj /CN=www.acme.com -reqexts SAN -extensions SAN      \
            -sha256 -days 3650 -config <(cat /etc/ssl/openssl.cnf    \
             <(printf '[SAN]\nsubjectAltName=DNS:www.acme.com'))
root@example:/var/www/> openssl dhparam -out certs/dhparm.pem 4096

HTTP Redirect

For a setup with two servers, the following example can be used to run HTTPS on port 4443, HTTP on port 8080 and redirect to the HTTPS server on any access:

server secure {
    port     = 4443
    ssl {
        certfile = certs/server.pem
        keyfile  = private/server.key
        dhfile   = certs/dhparm.pem
    }
}

server default {
    port = 8080
    redirect "/**" {
        code = 303
        location = "https://$host:4443$request_uri$args"
    }
}

Supported HTTP redirect codes are: 301, 302, 303, and 307.

The location setting supports three nginx style variables as shown in the example. Please note the quotes around the pattern, or the .conf parser will think the pattern is a C-style comment.

Build Requirements

Merecat depends on a few external libraries, if enabled, e.g. OpenSSL, zlib, and libConfuse. On Debian/Ubuntu systems you can install the dependencies with:

user@example:~/> sudo apt install pkg-config libconfuse-dev libssl-dev zlib1g-dev

If you build the deps. from source, they may default to use an install prefix of /usr/local. Non Debian/Ubuntu systems rarely support this GNU standard, so here is how you reference it for the Merecat configure script:

user@example:~/merecat/> PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure

To build Merecat without support for /etc/merecat.conf:

user@example:~/merecat/> ./configure --without-config

If you build from GIT sources and not a released tarball, then remember:

user@example:~/merecat/> ./autogen.sh

To install httpd into /usr/sbin/, default index and icons into /var/www, and config file to /etc/merecat.conf:

user@example:~/merecat/> ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc
user@example:~/merecat/> make
user@example:~/merecat/> sudo make install

Cross compiling Merecat for an another target is possible by setting the --host flag to the configure script. This is well documented in the GNU Documentation. Note: ususally the --build system is automatically detected.

Merecat builds are silent by default. For detailed compiler output, disable silent mode with configure --disable-silent-rules, or build with make V=1.

Features

Merecat consists of a front-end, merecat.c, and a standalone HTTP library, libhttpd.c, which can be tweaked in various ways and used for embedding a web server in another application if needed.

The most common options are available from the merecat command line and the merecat.conf configuration file. Other, less common options, can be enabled using the configure script:

--enable-builtin-icons  Enable built-in icons for dir listings
--enable-htaccess       Enable .htaccess files for access control
--enable-htpasswd       Enable .htpasswd files for authentication
--enable-public-html    Enable $HOME/public_html as ~USERNAME/
--enable-msie-padding   Add padding to error messages for Internet Explorer
--disable-dirlisting    Disable directory listings when no index file is found
--without-config        Disable /etc/merecat.conf support using libConfuse
--without-ssl           Disable HTTPS support, default: enabled
--without-symlinks      Disable httpd and in.httpd symlinks to merecat
--without-zlib          Disable mod_deflate (gzip) using zlib

The source file merecat.h has even more features that can be tweaked, some of those are mentioned in the man page, but the header file has very useful comments as well.

Origin & References

Merecat is a stiched up fork of sthttpd with lots of lost patches found lying around the web. The sthttpd project in turn is a fork from the original thttpd -- the tiny/turbo/throttling HTTP server.

More Repositories

1

inadyn

In-a-Dyn is a dynamic DNS client with multiple SSL/TLS library support
C
782
star
2

finit

Fast init for Linux. Cookies included
C
576
star
3

redir

A TCP port redirector for UNIX
C
349
star
4

mg

Micro (GNU) Emacs-like text editor ❤️ public-domain
C
293
star
5

editline

A small replacement for GNU readline() for UNIX
C
254
star
6

libuev

Lightweight event loop library for Linux epoll() family APIs
C
218
star
7

smcroute

Static multicast routing for UNIX
C
216
star
8

pimd

PIM-SM/SSM multicast routing for UNIX and Linux
C
194
star
9

watchdogd

Advanced system monitor & process supervisor for Linux
C
193
star
10

uftpd

FTP/TFTP server for Linux that just works™
C
162
star
11

mcjoin

Simple multicast testing application
C
130
star
12

tetris

Micro Tetris™, based on the 1989 IOCCC Obfuscated Tetris by John Tromp
C
107
star
13

uredir

A UDP port redirector for UNIX
C
87
star
14

myLinux

myLinux is an embedded operating system based on Buildroot and Finit
Shell
73
star
15

sysklogd

BSD syslog daemon with syslog()/syslogp() API replacement for Linux, RFC3164 + RFC5424
C
71
star
16

mtools

Tools for multicast testing (msend and mreceive). I do however recommend you try out mcjoin(!) or mping instead.
C
69
star
17

mrouted

The original DVMRP (dynamic multicast routing) implementation for UNIX
C
65
star
18

mini-snmpd

A minimal SNMP agent implementation
C
63
star
19

netcalc

Simplified clone of sipcalc with ipcalc looks
C
60
star
20

xplugd

Monitor, keyboard, and mouse plug/unplug helper for X
C
59
star
21

libite

That missing frog DNA you've been looking for
C
58
star
22

ssdp-responder

SSDP responder for UNIX systems that gives you an InternetGatewayDevice icon in Windows :)
C
53
star
23

mdnsd

Jeremie Miller's original mdnsd
C
49
star
24

sntpd

sntpd is a fork of Larry Doolittle's ntpclient with added daemon, syslog, and IPv6 support
C
42
star
25

adventure

Classic Colossal Cave Adventure
C
42
star
26

omping

Open Multicast Ping (omping) is a tool for testing IPv4/IPv6 multicast connectivity on a LAN.
C
33
star
27

snake

Micro Snake, based on Simon Huggins snake game.
C
30
star
28

pok3r-layouts

Vortex POK3R keyboard layouts for Linux, Windows and OS X/macOS. Based on:
28
star
29

rfctl

Linux driver and control tool for 433 MHz communication on Raspberry Pi
C
25
star
30

sun

Simple library and application that shows sunset and sunrise based on your latitude,longitude
C
23
star
31

jush

just give me a unix shell
C
22
star
32

lipify

C API for http://ipify.org
C
19
star
33

pim6sd

PIM for IPv6 sparse mode daemon
C
19
star
34

tinyroot

Small busybox based embedded Linux root file system
Makefile
17
star
35

mping

A simple multicast ping program
C
17
star
36

pimd-dense

Continuation of the original pimd-dense from 1998-1999, gaps filled with frog DNA from pimd
C
14
star
37

pev

Portable Event Library
C
14
star
38

libicmp

Very simple library for sending and receiving ICMP datagrams.
C
13
star
39

backlight

Very simple program to control the backlight brightness of a laptop
C
13
star
40

getty

Minix getty
C
10
star
41

pacman

UNIX pacman game by Dave Nixon, AGS Computers Inc. (1981) with curses support by Mark Horton (1982)
C
10
star
42

uget

Really stupid get-file-over-http program/function
Shell
10
star
43

toolbox

Misc. home brewed code, free to use under GPL/MIT/ISC, see each snippet for license.
C
9
star
44

mrdisc

Stand alone UNIX implementation of RFC4286 Multicast Router Discovery Protocol
C
9
star
45

uemacs

MicroEMACS by Dave Conroy
C
8
star
46

aliens

UNIX aliens game by Jude Miller, Cambridge (1979) with curses support by Mark Horton (1981)
C
7
star
47

nlmon

Simple example of how to use libnl and libev to monitor kernel netlink events
C
7
star
48

quagga

Westermo Quagga. See security/0.99.17 branch for ported CVE fixes and westermo/0.99.17 for patches on top of that. For more information, see the Wiki.
C
7
star
49

keepalived

Health-checking for LVS and high availability
C
6
star
50

ttinfo

Display information about a process, group or tty
C
6
star
51

awesome-config

My awesome window manager configuration
Lua
5
star
52

finit-plugins

Plugin Repository for Finit
C
5
star
53

zoo

public domain zoo archive tool
C
5
star
54

logit

tiny log helper
C
5
star
55

MicroEMACS

MicroEMACS v3.6 by Dave Conroy and Daniel Lawrence from 1986. Free in the public domain.
C
5
star
56

cx

Small wrapper for basic lxc tasks
Shell
5
star
57

awesome-redshift

Ryan Young's small, simple lua library for interfacing the Awesome window manager with redshift
Lua
5
star
58

crobots

CROBOTS is a programming game, for (aspiring) programmers
C
5
star
59

gul

The one true GUL editor!
C
5
star
60

awesome-plain

Plain barebones AwesomeWM setup
Lua
4
star
61

usbctl

A user space tool to operate on USB devices.
C
4
star
62

mctools

Collection of (old) multicast tools
C
4
star
63

deb

Signing key(s) for .deb repository
3
star
64

booz

Zoo Extractor/Lister by Rahul Dhesi
C
3
star
65

sniffer

sniff packets from interface store in db for analysis
C
3
star
66

zroute

Very simple command line client for managing Zebra static routes from the command line. Useful if Zebra is your route manager and you want your DHCP client, or PPPoE client, to set default gateway dynamically via Zebra instead of as kernel routes.
C
3
star
67

libc-chaos

Emit random errors when calling libc functions to emulate an unstable underlying system
C
3
star
68

misc

Misc. helpers, in the public domain
Makefile
2
star
69

alpine-qemu-image

Create bootable Qemu images fro Alpine Linux ISO
Shell
2
star
70

ns

Example of how to use getaddrinfo()
C
2
star
71

awesome-light

Lua library for controlling screen and keyboard brightness from Awesome WM
Lua
2
star
72

plotty

Library for text terminal plotter
C
2
star
73

klish-plugin-sysrepo

Mirror of Serj Kalichev's klish plugins for sysrepo
C
2
star
74

faux

Mirror of Serj Kalichev's auxillary functions library
C
2
star
75

troglobit.github.io

Personal website and blog
CSS
2
star
76

demo

Collection of ASCII art demos
C
1
star
77

ubot

very small and stupid irc bot
C
1
star
78

awesome

My awesome-copycats adaptions
Lua
1
star
79

logrun

An event-based, regexp-triggered, job runner ...
Perl
1
star
80

klish

Mirror of Serj Kalichev's klish
C
1
star
81

br2-finit-demo

Demo of Finit (FastInit) in Buildroot
Makefile
1
star
82

zephyr-uart-test

Playground for the Zephyr UART
C
1
star
83

busybox-builder

busybox defconfig++ binaries
Shell
1
star
84

bridged

Linux bridge helper daemon
C
1
star
85

weatherd

Hackish weather data logger for my homemade Raspberry Pi based weather station
C
1
star