Ron is a lightweight monitoring endpoint for Winter CMS. It exposes a single, IP-restricted HTTP endpoint that a central watchdog service can poll to learn the state of an installation:
- the CMS build number and whether core files have been modified,
- integrity hashes of critical entry files (
index.php,.htaccess), - the full plugin inventory (versions, enabled/frozen state, and whether each plugin was installed via Composer or dropped in manually),
- the project's Composer requirements, and
- on demand, the complete
composer.lockfor dependency auditing.
This plugin is still work in progress. Please use with care.
- Winter CMS (Winter Storm
^1.2) - PHP
>= 8.0.2
Install via Composer from the Baoweb private (Satis) repository:
composer require baoweb/wn-ronthewatchdog-pluginThis installs the plugin into plugins/baoweb/ronwatchdog. (Make sure the Baoweb Satis
repository is registered under repositories in your project's composer.json first.)
All settings have sensible, secure-by-default values. You can override them with environment
variables, or by creating a config file at config/baoweb/ronwatchdog/config.php.
| Variable | Default | Description |
|---|---|---|
RONTHEWATCHDOG_WHITELISTED_IP |
false |
The single IP address allowed to call the endpoint. Until set, every request is rejected with a 404. |
RONTHEWATCHDOG_CUSTOM_URL |
ron-the-watchdog |
The obscured URL segment the endpoint is mounted under (see Endpoints). |
RONTHEWATCHDOG_WHITELISTED_IP=127.0.0.1
RONTHEWATCHDOG_CUSTOM_URL=some-hard-to-guess-stringCreate config/baoweb/ronwatchdog/config.php to override any of the defaults:
return [
/**
* The single IP address allowed to make requests to the endpoint.
* Any request from a different IP receives a 404 response.
* Defaults to env('RONTHEWATCHDOG_WHITELISTED_IP', false) — i.e. locked down
* until you configure it.
*/
'whitelisted_ip' => env('RONTHEWATCHDOG_WHITELISTED_IP', false),
/**
* The obscured URL segment the endpoint is mounted under, e.g.
* /ron/<custom_url>. Use `php artisan ron:generate` to produce a random one.
*/
'custom_url' => env('RONTHEWATCHDOG_CUSTOM_URL', 'ron-the-watchdog'),
/**
* The hashing algorithm used for the file integrity hashes.
* Currently only 'md5' is implemented; any other value yields 'false'.
*/
'hash_algorithm' => 'md5',
/**
* Include the index.php / .htaccess integrity hashes in the output.
*/
'send_file_hashes' => true,
/**
* Include the plugin inventory in the output.
*/
'send_plugin_info' => true,
/**
* Include the Composer requirements in the output.
*/
'send_package_info' => true,
];| Option | Default | Description |
|---|---|---|
whitelisted_ip |
false |
Only this IP may call the endpoint; all others get a 404. |
custom_url |
ron-the-watchdog |
URL segment the endpoint is served under. |
hash_algorithm |
md5 |
Algorithm for file hashes. Only md5 is implemented; other values → false. |
send_file_hashes |
true |
Toggle the hashes / algorithm block in the main response. |
send_plugin_info |
true |
Toggle the plugins block in the main response. |
send_package_info |
true |
Toggle the packages block in the main response. |
Access is gated by two independent mechanisms:
- IP whitelist — only requests from
whitelisted_ipare served; everyone else receives a standardcms::404response, so the endpoint is indistinguishable from a missing page. - Obscured URL — the endpoint lives under a configurable, hard-to-guess segment
(
custom_url).
Generate a strong random URL segment with the bundled console command and put the result in
RONTHEWATCHDOG_CUSTOM_URL:
php artisan ron:generateWith the defaults, the endpoint is mounted at /ron/ron-the-watchdog. Replacing
ron-the-watchdog with your configured custom_url:
Returns a JSON snapshot of the installation. The optional blocks are included only when their
corresponding send_* option is enabled.
Returns the raw contents of the project's composer.lock as JSON, for exact dependency-version
auditing. If no composer.lock is present, responds with 404 and
{ "error": "composer.lock not found" }.
| Command | Description |
|---|---|
php artisan ron:generate |
Print a random 20–30 character string suitable for RONTHEWATCHDOG_CUSTOM_URL. |
- Version / modified flag come from Winter's
UpdateManagerbuild-number detection. - File hashes are computed over
index.phpand.htaccessin the project root. - Plugin inventory is read from Winter's
PluginManagerand thePluginVersionrecords. A plugin is reported asis_customwhen its vendor/name is not found among the project's Composerrequireentries. - Packages are read from the project's root
composer.json(requireandrequire-dev).
MIT © Baoweb. See LICENCE.
{ "cms": "winter-cms", "version": 475, // CMS build number "modified": false, // true if core files differ from the reference build // present when send_file_hashes = true "hashes": { "index": "d41d8cd98f00b204e9800998ecf8427e", "htaccess": "098f6bcd4621d373cade4e832627b4f6" }, "algorithm": "md5", // present when send_plugin_info = true "plugins": [ { "fullName": "Baoweb.RonWatchdog", "name": "RonWatchdog", "namespace": "Baoweb", "version": "2.0.0", "is_disabled": false, "is_frozen": false, "is_custom": false // true = not found among Composer requirements (manually installed) } ], // present when send_package_info = true "packages": [ { "name": "winter/storm", "version": "^1.2", "is_dev": false } ], "meta": { "generated_by": { "plugin": "ron-the-watchdog", "version": "2.0.0" // taken from this plugin's version.yaml } } }