# Webship Web Server: Secure Settings by Default
A secure web server should not depend on an operator remembering one more setting at 2 a.m. It should begin from a protective baseline, reject unsafe configuration, and require deliberate choices before it exposes sensitive capabilities.
That is the model behind Webship. Its default configuration turns on the main request and response defenses, limits the resources an attacker can consume, and leaves optional control surfaces disabled. You can tune those defaults for a real application, but you do not have to discover every protection before the first request arrives.
Secure by default does not mean secure without context. Certificates, application authorization, network policy, secrets, and incident response still belong to the operator. Webship’s job is to make the safe starting point obvious—and make accidental weakening harder.
The protections that start enabled
Webship enables six layers in its base configuration:
| Layer | Default behavior | What it reduces | | --- | --- | --- | | Dot-file protection | Denies dot-prefixed static path segments | Accidental exposure of environment files, repository metadata, and local configuration | | Web application firewall | Blocks known attack patterns | SQL injection, cross-site scripting, traversal, sensitive-path probes, command injection, header smuggling, and unsupported request encodings | | DDoS controls | Runs in normal mode with bounded client state | Request floods, unbounded tracking, and avoidable resource exhaustion | | Bot challenge | Uses a signed challenge cookie | Low-cost automated abuse and repeat scanning | | Response security headers | Adds a restrictive browser policy | MIME confusion, framing, referrer leakage, dangerous browser capabilities, and broad content loading | | API Shield | Uses block mode and rejects unknown routes once an API contract is defined | Shadow endpoints, unintended methods, unexpected content types, and missing authorization requirements |
The default WAF also places hard bounds around what it inspects: 32 KiB of request headers, a 2,048-byte path, and a 1 MiB request body. These are security limits, not arbitrary performance switches. If an application legitimately needs larger requests, raise the relevant limit for that application and test the result instead of disabling inspection globally.
DDoS protection starts in normal mode at 600 requests per minute with a burst allowance of 100 per client key. Its client-state table is bounded at 65,536 entries. These values are a baseline, not a universal traffic model: a public API, a download service, and an internal admin panel should not share the same application-specific limits.
Browser protections are part of the baseline
Webship’s response-header policy is enabled even when an application forgets to add its own. The default includes:
- X-Content-Type-Options: nosniff;
- a frame-deny policy;
- Referrer-Policy: no-referrer;
- Strict-Transport-Security for one year, including subdomains;
- Content-Security-Policy limited to same-origin content, with framing and base-URI restrictions;
- Permissions-Policy disabling geolocation, microphone, and camera access.
These defaults are intentionally restrictive. Review HSTS before applying it to a domain with subdomains that are not fully HTTPS-ready. Review Content-Security-Policy before an application loads scripts, styles, fonts, images, or connections from other origins. A secure default should fail visibly during deployment, not be silently weakened in production.
Optional surfaces stay closed
Webship does not expose every feature just because the binary contains it. Reverse proxying, WebTransport, observability endpoints, automatic TLS, response provenance, and the MCP control endpoint are disabled by default.
The MCP endpoint is loopback-scoped when enabled and requires an explicit security configuration. Metrics and statistics require instrumentation to be deliberately enabled. Automatic certificate management requires the operator to choose an ACME directory, contacts, storage, and terms-of-service acceptance. This keeps operational features from becoming surprise network surfaces.
The base listener also binds to 127.0.0.1. An operator must explicitly select a public address. That single choice creates a useful review point for firewall rules, service permissions, TLS identity, and deployment topology.
Reverse proxying preserves the trust boundary
When reverse proxying is enabled, TLS pass-through remains the default. Webship forwards encrypted traffic without taking possession of application plaintext or active session keys. The origin remains responsible for TLS and the negotiated protocol.
Enable TLS termination only when Webship must inspect HTTP requests, route by path, apply WAF and API policy, rewrite headers, or cache responses. Termination is not inherently less secure; it moves the trust boundary. The important decision is which machine is allowed to see plaintext and why.
Pass-through also has functional limits. TCP routing is based on ClientHello SNI because the HTTP request is encrypted. HTTP/3 pass-through requires routes to share one UDP origin. If you need content-aware security at the edge, terminate TLS there and protect the edge-to-origin hop separately.
A production baseline you can review
The following excerpt makes the important defaults explicit instead of relying on omission:
listen = "0.0.0.0:443"
deny_dotfiles = true
[tls]
unknown_sni = "reject"
[ddos]
enabled = true
mode = "normal"
requests_per_minute = 600
burst = 100
block_seconds = 60
max_tracked_clients = 65536
[security]
enabled = true
rate_limit_max_entries = 65536
[security.waf]
enabled = true
mode = "block"
sqli = true
xss = true
traversal = true
sensitive_paths = true
header_abuse = true
max_header_bytes = 32768
max_path_bytes = 2048
max_body_bytes = 1048576
[security.response_headers]
enabled = true
nosniff = true
frame_deny = true
referrer_no_referrer = true
hsts = "max-age=31536000; includeSubDomains"
content_security_policy = "default-src 'self'; frame-ancestors 'none'; base-uri 'self'"
permissions_policy = "geolocation=(), microphone=(), camera=()"On a multi-domain listener, unknown_sni = "reject" prevents an unrecognized hostname from receiving the listener’s default certificate. Webship’s automatic-TLS listeners already reject unknown names until a certificate exists.
Validation is a security control
Webship validates configuration before it binds listeners. Unknown fields, invalid limits, incomplete identities, conflicting listeners, and unsupported protocol combinations fail startup with a specific error. The same validation runs before a live configuration is installed. A failed reload leaves the current configuration active.
The authenticated MCP configuration path adds another guard: it refuses live changes that would disable an active WAF, DDoS layer, API Shield, bot challenge, edge-auth policy, or response-header layer. Version checks prevent one administrator from overwriting a newer configuration snapshot. Process-bound settings still require a restart instead of pretending that a partial live change succeeded.
This is a useful distinction. Secure defaults protect a new deployment. Transactional validation and guarded updates protect a running one.
What operators still need to decide
Before exposing Webship to the internet:
- Configure a trusted TLS identity and protect the private key.
- Set unknown SNI handling for the listener topology.
- Confirm that HSTS and Content-Security-Policy match every application and subdomain.
- Define API Shield endpoints, accepted methods, content types, and authorization requirements.
- Add route-specific rate limits instead of relying only on the global baseline.
- Enable edge authentication for protected hosts or paths and use short-lived tokens.
- Keep MCP and observability listeners private, authenticated, and separate from public traffic.
- Run Webship with a dedicated unprivileged account, a read-only application root where possible, and only the operating-system capabilities it needs.
- Validate configuration before rollout, then test blocked and allowed traffic in a canary environment.
- Monitor security audit events and rehearse the switch from normal mode to under_attack or lockdown.
A safer default is a beginning, not a claim
No web server can decide which users should see your invoices, which origins may call your API, or how quickly your business endpoint should accept requests. Those controls require application knowledge.
Webship supplies the lower layer: bounded parsers, strict configuration, defensive response headers, request inspection, abuse controls, and closed optional surfaces. The result is not “security solved.” It is a smaller gap between installing a server and operating it responsibly.
Review the complete Webship documentation before production deployment. The configuration schema and the running binary remain the authoritative sources for the exact version you operate.