https://github.com/alphaone1/sonicweb
Lightweight static file webserver
https://github.com/alphaone1/sonicweb
lightweight static-site webapplicationfirewall webserver
Last synced: 25 days ago
JSON representation
Lightweight static file webserver
- Host: GitHub
- URL: https://github.com/alphaone1/sonicweb
- Owner: AlphaOne1
- License: mpl-2.0
- Created: 2024-06-02T08:27:08.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2025-08-18T16:10:02.000Z (10 months ago)
- Last Synced: 2025-08-18T17:42:05.371Z (10 months ago)
- Topics: lightweight, static-site, webapplicationfirewall, webserver
- Language: Go
- Homepage:
- Size: 454 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
- Authors: AUTHORS.md
Awesome Lists containing this project
README
*SonicWeb* is a lightweight, easy-to-use web server for static content.
Features
--------
* statically linked, suitable for use in scratch containers (~13MB)
* focused purpose, thus little attack surface
* integrates OWASP [Coraza](https://github.com/corazawaf/coraza) middleware
to follow security best practices
* HTTPS using [Let's Encrypt](https://letsencrypt.org) certificates
* easy integration with monitoring and observability tools via OpenTelemetry,
for example, [Prometheus](https://prometheus.io) and [Jaeger Tracing](https://jaegertracing.io)
* no need for complicated configuration files
Installation
------------
*SonicWeb* provides prebuilt binaries and installation packages for Debian and RPM-based distributions.
Builds are secured with SLSA Level 3 provenance via slsa-framework/slsa-github-generator.
The downloaded archive together with the provenance file `multiple.intoto.jsonl`
can be verified using the [slsa-verifier](https://github.com/slsa-framework/slsa-verifier/)
(replace the `` with the one you actually downloaded, e.g., `v1.9.0`):
```bash
$ slsa-verifier verify-artifact SonicWeb-linux-amd64-.deb \
--provenance-path multiple.intoto.jsonl \
--source-uri github.com/AlphaOne1/sonicweb \
--source-tag
```
If a source build is necessary, one could use the following command:
```bash
go install -ldflags "-s -w -X main.buildInfoTag=latest" github.com/AlphaOne1/sonicweb@latest
```
Getting Started
---------------
*SonicWeb* is controlled solely by command line arguments. They are as follows:
| Parameter | Description | Default | Multiple |
|------------------------------|----------------------------------------------------|-------------------|----------|
| -root \ | root directory of content | `/www` | |
| -base \ | base path to publish the content | `/` | |
| -port \ | port to listen on for web requests | `8080` | |
| -address \
| address to listen on for web requests | all | |
| -tlscert \ | TLS certificate file | n/a | |
| -tlskey \ | TLS key file | n/a | |
| -clientca \ | client certificate authority for mTLS | n/a | ✓ |
| -acmedomain \ | allowed domain for automatic certificate retrieval | n/a | ✓ |
| -certcache \ | directory for certificate cache | os temp directory | |
| -acmeendpoint \ | endpoint for automatic certificate retrieval | n/a | |
| -index {true,false} | enable directory listing | true | |
| -header \ | additional header | n/a | ✓ |
| -headerfile \ | file containing additional headers | n/a | ✓ |
| -tryfile \ | always try to load file expression first | n/a | ✓ |
| -wafcfg \ | configuration for Web Application Firewall | n/a | ✓ |
| -iport \ | port to listen on for telemetry requests | `8081` | |
| -iaddress \ | address to listen on for telemetry requests | all | |
| -telemetry {true,false} | enable/disable telemetry support | `true` | |
| -trace-endpoint {address} | deprecated, use OTEL_EXPORTER_OTLP_TRACES_ENDPOINT environment instead | `""`| |
| -pprof {true,false} | enable/disable pprof support | `false` | |
| -log \ | log level (debug, info, warn, error) | `info` | |
| -logstyle \ | log style (auto, text, json) | `auto` | |
| -help | print the argument overview and exit | n/a | |
| -version | print just version information and exit | n/a | |
Example call, to serve the content of `testroot/` on the standard base path `/`:
```text
$ ./sonicweb-linux-amd64 -root testroot/
|\
||\
_________||\\
\ \ /|
\ ___ \ / |
/ /.-.\ _V__| _ _ __ __
/ // \ / ___/____ ____ (_)___| | / /__ / /_
/___ // _ | \__ \/ __ \/ __ \/ / ___/ | /| / / _ \/ __ \
| \(_)/ ___/ / /_/ / / / / / /__ | |/ |/ / __/ /_/ /
| , \_/ /____/\____/_/ /_/_/\___/ |__/|__/\___/_.___/
| / \ \
|/ \ _______\ Version: v1.9.0
\ | of: 2026-05-03T10:54:31Z
\ | using: go1.26.2
\|
time=2026-05-05T14:05:46.705556+02:00 level=INFO msg=logging level=info
time=2026-05-05T14:05:46.705997+02:00 level=INFO msg="using root directory" root=testroot
time=2026-05-05T14:05:46.706067+02:00 level=INFO msg="using base path" path=/
time=2026-05-05T14:05:46.710485+02:00 level=INFO msg="telemetry initialized"
time=2026-05-05T14:05:46.710514+02:00 level=INFO msg="registering handlers for FileServer"
time=2026-05-05T14:05:46.712723+02:00 level=INFO msg="started server" address=:8080 t_init=9.1591ms
time=2026-05-05T14:05:46.712893+02:00 level=INFO msg="waiting for servers to shutdown"
time=2026-05-05T14:05:46.713104+02:00 level=INFO msg="server started" name=SonicWeb addr=[::]:8080
```
HTTPS
---
*SonicWeb* supports serving HTTPS via TLS. There are two options to enable HTTPS:
1. Manually provide a certificate and a key
2. Enable automatic certificate retrieval via [Let's Encrypt](https://letsencrypt.org)
### Manual Configuration
To use a certificate and key pair, you simply start *SonicWeb* as follows:
```sh
./sonicweb-linux-amd64 -root testroot/ -tlscert cert.pem -tlskey key.pem
```
The Makefile provides a straightforward way to generate certificates for testing purposes.
For serious use, an official certificate signed by a certificate authority should be considered.
### Manual Configuration with Client Certificate Authentication
To use the client certificate authentication, you simply start *SonicWeb* as follows:
```sh
./sonicweb-linux-amd64 -root testroot/ -tlscert cert.pem -tlskey key.pem -clientca clientca0.pem
```
### Automatic Certificate Retrieval
Let's Encrypt offers to automatically obtain certificates. For this to work, *SonicWeb* holds a list of valid domains,
for which certificate retrieval is allowed. When a client connects to one of these, and no certificate is available,
*SonicWeb* sends a certificate request to Let's Encrypt. The valid domains can be specified via the `-acmedomain`
parameter. Only exact domains match, so subdomains must be provided with repeated calls.
Once a certificate is obtained, it is stored in a certificate cache. By default, this cache is in the
operating system's default temporary directory. It can be changed using the `-certcache` parameter.
To start *SonicWeb* using automatic certificate retrieval, use the following command:
```sh
./sonicweb-linux-amd64 -root testroot/ -acmedomain example.com -acmedomain www.example.com
```
Other acme endpoints can be used, specifying the `-acmeendpoint` parameter. If nothing is specified, the production
endpoint of Let's Encrypt is used. Use the following command for testing:
```sh
./sonicweb-linux-amd64 -root testroot/ \
-acmedomain example.com \
-acmedomain www.example.com \
-acmeendpoint "https://acme-staging-v02.api.letsencrypt.org/directory"
```
Directory Listing
-----------------
When serving files from a directory, it might be useful to enable directory listing.
*SonicWeb* supports this via the `-index` parameter. It is enabled by default. When enabled, *SonicWeb* will
respond to directory requests with a generated page that contains the entries of the requested directory,
including:
- file or directory name
- size (in bytes)
- last modified time
When disabled, attempting to list a directory's contents will result in a 403 Forbidden response.
Additional Headers
------------------
In some situations, it is necessary to add HTTP headers to the response.
*SonicWeb* provides the `-header` parameter to facilitate this.
```sh
./sonicweb-linux-amd64 -root testroot/ -header "Environment: production"
```
To add a huge number of headers, the `-headerfile` parameter can be used:
```sh
./sonicweb-linux-amd64 -root testroot/ -headerfile additional_headers.conf
```
The file should be formatted as follows:
```text
<HeaderKey>: <HeaderValue>
<nextLine, if multi-line, starts with space>
```
Headers can be specified multiple times, with the last entry taking precedence.
*SonicWeb* sets the `Server` header to its name and version.
By providing a custom `Server` header, it can be replaced, e.g., to mislead potential attackers.
Try Files
---------
The `-tryfile` option is specially aimed at single-page applications that use URIs to encode functionality.
When used, *SonicWeb* tries the given file expressions in order. There is a special value that can be used:
| Value | Description |
|---------------|--------------------|
| $uri | URI of the request |
If none of the expressions matches a real file, a 404 is returned. If one of the expressions ends with `/index.html`,
that suffix is truncated—replaced by the final `/`—to prevent redirection loops caused by Go's handling of
`/index.html`. (Go’s FileHandler redirects to `/` when it encounters `/index.html`; therefore, attempting to load
`/index.html` would trigger a redirect and repeatedly try to load `/index.html` instead of `/`, resulting in a loop.)
An invocation of *SonicWeb* could then be as follows:
```sh
./sonicweb-linux-amd64 -root testroot/ -tryfile \$uri -tryfile /
```
Web Application Firewall
------------------------
*SonicWeb* integrates the [Coraza](https://github.com/corazawaf/coraza) Web Application Firewall middleware. It uses
rules to determine actions on the incoming (and outgoing) HTTP traffic. This project does not include the rulesets.
The rules can be activated using the `-wafcfg` parameter. It expects, for each invocation, a file containing a Coraza
configuration file. A good base ruleset can be obtained from [coreruleset.org](https://coreruleset.org).
There is also extensive documentation on how to write new rules.
*SonicWeb* can be started as follows:
```sh
./sonicweb-linux-amd64 -root testroot/ \
-wafcfg /etc/crs4/crs-setup.conf \
-wafcfg /etc/crs4/plugins/\*-config.conf \
-wafcfg /etc/crs4/plugins/\*-before.conf \
-wafcfg /etc/crs4/rules/\*.conf \
-wafcfg /etc/crs4/plugins/\*-after.conf
```
Docker Usage
------------
*SonicWeb* is also distributed as a Docker image. To start it, one can simply write:
```sh
docker run -p 8080:8080 ghcr.io/alphaone1/sonicweb:v1.9.0
```
and it will show this documentation. The entrypoint of the Dockerfile just starts *SonicWeb* without any parameters.
Therefore, `/www` is the default web root directory. Every parameter passed after the image name is appended as a
parameter to *SonicWeb*. For example, running
```sh
docker run -p 8080:8080 ghcr.io/alphaone1/sonicweb:v1.9.0 --log=debug
```
is equivalent to running:
```sh
./sonicweb-linux-amd64 --log=debug
```
The Docker image allows new web content to be mounted on `/www`, replacing the default content entirely. A new
web root directory, e.g., `myapp/`, can be mounted like this:
```sh
docker run -p 8080:8080 -v ./myapp:/www:ro ghcr.io/alphaone1/sonicweb:v1.9.0
```
Note that without specifying the `:ro` flag, the content will be mounted as read-write. *SonicWeb* does not write into
the mounted directory. Nevertheless, it poses a potential risk. Ensure that the mounted content is readable by the
non-root user that *SonicWeb* uses (UID 65532).
If telemetry is needed, port 8081 needs to be exposed additionally:
```sh
docker run -p 8080:8080 -p 8081:8081 ghcr.io/alphaone1/sonicweb:v1.9.0
```