Ctrl K
ComunidadGuías…

CONTRIBUTING.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Contributing

Thanks for your interest in unmask. Bug reports, documentation fixes, and
small focused PRs are all welcome.

## Reporting bugs

Open an issue with:

- distro / version (`cat /etc/os-release`)
- nginx version (`nginx -v`) or web server you use
- relevant log lines (`journalctl -u unmask` — `/var/log/unmask.log` on SysVinit, `docker logs unmask` for the container — and your web server's error log)
- reproduction steps

For suspected security issues, **please do not open a public issue** —
follow [SECURITY.md](SECURITY.md) (report privately through GitHub's
vulnerability report form).

## Development setup

unmask is three components in one repo:

- `admin/` — Go static binary (`unmask`). Requires the Go version in `admin/go.mod` (1.27+).
- `nginx-module/` — C plugin (`ngx_http_unmask_module`). Built against
  matching nginx source.
- `admin/assets/static/challenge.{html,js}` — plain JavaScript challenge
  page. No build step.

```sh
# admin binary
cd admin && go build -o unmask ./cmd/unmask

# rpm/deb/apk packages (= nfpm)
make package
```

End-to-end tests live in `e2e/` and run against the dockerized stack.

## Running the tests

What CI runs, and how to run each part here before a push:

```sh
# Go: unit tests (the handlers package takes a few minutes), vet, gofmt.
cd admin && go test ./... && go vet ./... && gofmt -l .
# The i18n catalogs: parity of ja / en, no mixed-up locale, every key a
# template uses.  Run whenever i18n.go or a template changes.
cd admin && go test ./internal/i18n/
# The same tests against MariaDB (they skip without a server): starts a
# throwaway mariadb container, so it needs docker.
make test-mariadb
# golangci-lint, exactly as CI runs it (pins the Go version from go.mod).
make lint
# The C parsers: unit tests, the same under ASan/UBSan, and the fuzzers.
make test-plugin-parser test-plugin-parser-san fuzz-plugin
# The package scripts (install, upgrade, removal, against a throwaway root).
for t in rpm/scripts/*_test.sh; do bash "$t"; done
# Production figures and node names must not reach public text.
./tools/check-public-text.sh
# The docker e2e stack: nginx + the module + the daemon, 70-odd scenarios.
make e2e-docker
# The packages, through install, upgrade and removal on Ubuntu, AlmaLinux and
# Alpine containers, each with its package manager and nginx (docker, nfpm).
make e2e-lifecycle-modern
# The admin UI in a browser (node + a Chromium; `npm ci` in e2e/ui first).
# UI_E2E_ONLY=<substring> runs the matching test files alone.
make e2e-ui
cd e2e/ui && UI_E2E_ONLY=crawler-modes ./run.sh
```

A change to a template is covered by the handlers tests and the UI
tests; a change to the module or its build also runs the module-matrix
workflow in CI (every nginx version the plugin ships).

## Pull request guidelines

- One logical change per PR. Split unrelated changes.
- Match the existing code style — Go uses `gofmt`; C follows the nginx
  source style.
- Update `CHANGELOG.md` under `[Unreleased]` with a brief entry.
- Run `go test -timeout 20m ./...` from `admin/` before submitting (the
  handlers package can take longer than go test's default ten minutes on a
  slow machine).
- forward-auth mode is frozen: its decision path
  (`admin/internal/handlers/auth_check.go`, reached through `auth_request` or
  Apache `mod_lua`) takes bug and security fixes only.  Wire a new feature into
  the nginx module path (the `nginxconf` templates and the module); it needs no
  forward-auth counterpart.

## Release gate

CI runs on every push: Go lint, vet and tests (the MariaDB ones against a
server of their own), the C parsers' unit tests and a sanitizer fuzz, the module built against a few recent nginx versions,
the container images, the docker e2e stack (`make e2e-docker`, which
anyone can run), and the packages through install, upgrade and removal on
three distributions (`make e2e-lifecycle-modern`).  When the module or its build changes, a second workflow
(`module-matrix`) builds the .so against every nginx version the plugin
package ships -- fifteen, from 1.10.3 to the current stable -- against
OpenSSL 3 and, in containers whose recipes are under `build-docker/`,
OpenSSL 1.1, OpenSSL 1.0 and glibc 2.12; every .so in the plugin package
can be rebuilt from this tree.  Every build reads its hardening back out of
the .so, and one .so of each container-built set is loaded into an nginx of
that ABI (`make module-load-test`).  Before a release the
maintainer also installs the packages on a lab of real distributions
(`make distro-check`: the official install path on ten distributions,
CentOS 6 among them, through to `nginx -t`, the module loading and a
challenged request), which needs the lab and is not part of CI.

## Clean-room reimplementation

The JA4 parser in `nginx-module/` is implemented from the public JA4
specification (https://github.com/FoxIO-LLC/ja4/blob/main/technical_details/JA4.md)
alone.  FoxIO's reference nginx module is published under the Business
Source License: do not consult its source while working on the parser, and
do not copy from it.  A PR that lifts code from it is not merged.
`THIRD-PARTY-NOTICES.md` records what the tree does bundle and the license
of each piece; keep it, and `NOTICE`, in step with `admin/go.mod` when a
dependency changes.

## Commit messages

- Subject line: imperative, under ~70 chars, prefixed by area
  (`admin:`, `nginx:`, `challenge:`, `docs:`, `rpm:`, etc.).
- Body: explain the *why*, not the *what*.
- English only for new commits (the historical log contains Japanese for
  pre-OSS history).

## Code language policy

All files in the repository must be written in English — including comments,
log messages, and identifiers.

Exceptions (preserved as Japanese):

- `admin/internal/i18n/i18n.go` Japanese locale values
- `admin/assets/static/challenge.js` Japanese i18n maps
- The `<option value="ja">日本語</option>` picker native name

## Developer Certificate of Origin (DCO)

Every commit must carry a `Signed-off-by:` trailer that asserts you have
the right to submit the change under the project's license.  We follow
the [Developer Certificate of Origin 1.1](https://developercertificate.org/).

The trailer is one line at the bottom of the commit message:

```
Signed-off-by: Your Name <you@example.com>
```

`git commit -s` adds it automatically.  By including it you are stating
the four conditions in the DCO 1.1 text (= roughly: you wrote it, or you
have permission from whoever did, and you are OK with it being open-source
under the project's license).

A simple lightweight alternative to a CLA — no separate document to sign,
the assertion is in the commit history itself.

## License

By contributing, you agree that your contributions will be licensed under
the Apache License 2.0 (see `LICENSE`).