https://github.com/alphaone1/sonicweb
Lightweight static file webserver
https://github.com/alphaone1/sonicweb
lightweight static-site webapplicationfirewall webserver
Last synced: 8 months 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 (almost 2 years ago)
- Default Branch: master
- Last Pushed: 2025-08-18T16:10:02.000Z (8 months ago)
- Last Synced: 2025-08-18T17:42:05.371Z (8 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
* usage of OWASP [Coraza](https://github.com/corazawaf/coraza) middleware
to follow best security practices
* HTTPS using [Let's Encrypt](https://letsencrypt.org) certificates
* easy integration in monitoring using [Prometheus](https://prometheus.io) and/or
[Jaeger Tracing](https://jaegertracing.io)
* no complications with configuration files
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 | |
| -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} | endpoint to send trace data to | `""` | |
| -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
$ ./sonic-linux-amd64 -root testroot/
|\
||\
_________||\\
\ \ /|
\ ___ \ / |
/ /.-.\ _V__| _ _ __ __
/ // \ / ___/____ ____ (_)___| | / /__ / /_
/___ // _ | \__ \/ __ \/ __ \/ / ___/ | /| / / _ \/ __ \
| \(_)/ ___/ / /_/ / / / / / /__ | |/ |/ / __/ /_/ /
| , \_/ /____/\____/_/ /_/_/\___/ |__/|__/\___/_.___/
| / \ \
|/ \ _______\ Version: v1.5.1
\ | of: 2025-08-18T15:43:26Z
\ | using: go1.25.0
\|
time=2025-08-18T17:55:41.408257+02:00 level=INFO msg=logging level=info
time=2025-08-18T17:55:41.408493+02:00 level=INFO msg="using root directory" root=testroot/
time=2025-08-18T17:55:41.408519+02:00 level=INFO msg="using base path" path=/
time=2025-08-18T17:55:41.408530+02:00 level=INFO msg="tracing disabled"
time=2025-08-18T17:55:41.408538+02:00 level=INFO msg="registering handler for FileServer"
time=2025-08-18T17:55:41.412176+02:00 level=INFO msg="starting server" address=:8080 t_init=4.125504ms
time=2025-08-18T17:55:41.412315+02:00 level=INFO msg="serving pprof disabled"
time=2025-08-18T17:55:41.412422+02:00 level=INFO msg="serving telemetry" address=:8081/metrics
```
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:
```shell
$ ./sonic-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:
```shell
$ ./sonic-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:
```shell
$ ./sonic-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:
```shell
$ ./sonic-linux-amd64 -root testroot/ \
-acmedomain example.com \
-acmedomain www.example.com \
-acmeendpoint "https://acme-staging-v02.api.letsencrypt.org/directory"
```
Additional Headers
------------------
In some situations, it is necessary to add HTTP headers to the response.
*SonicWeb* provides the `-header` parameter to facilitate this.
```shell
$ ./sonic-linux-amd64 -root testroot/ -header "Environment: production"
```
To add a huge number of headers the `-headerfile` parameter can be used:
```shell
$ ./sonic-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 an own version of the `Server` header,
it can be replaced, e.g., to misguide 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:
```shell
$ ./sonic-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:
```shell
$ ./sonic-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
```
Building
--------
For easier management, a `Makefile` is included, using it, the build is as easy as:
```sh
make
```
If your operating system does not provide a usable form of `make`, you can also do:
```sh
CGO_ENABLED=0 go build -trimpath -ldflags "-s -w"
```