Skip to main content

Netchecks is a cloud native tool for specifying and regularly checking assertions about network conditions. Use netchecks to proactively verify whether security controls are working as intended, alerting on misconfiguration.

Project description

Netchecks

Netchecks Logo

Kubernetes HELM ArtifactHub - Netchecks GitHub release (with filter) PyPI PyPI - Python Version Coverage Status CI status Website Linting: ruff PyPI Downloads License

Netchecks is a set of tools for testing network conditions and asserting that they are as expected.

There are two main components:

  • Netchecks Operator - Kubernetes Operator (Rust/kube-rs) that runs network checks and reports results as PolicyReport resources. See the operator README for more details and the full documentation can be found at https://netchecks.io
  • Netcheck CLI and Python Library - Command line tool for running network checks and asserting that they are as expected. Keep reading for the quickstart guide.

Netcheck Command Line Tool

netcheck is a configurable command line application for testing network conditions are as expected. It can be used to validate DNS, HTTP, and TCP connectivity and can be configured to assert that the results are as expected, for example:

netcheck http --url=https://github.com/status --validation-rule "data.body.contains('GitHub lives!') && data['status-code'] in [200, 201]"

Installation

Install the Python package from PyPi:

pip install netcheck

The cli can also be run via Docker:

docker run -it ghcr.io/hardbyte/netchecks:main

Individual Assertions

By default netcheck outputs a JSON result to stdout including response details:

$ netcheck dns
{
  "spec": {
    "type": "dns",
    "nameserver": null,
    "host": "github.com",
    "timeout": 30.0
  },
  "data": {
    "canonical_name": "github.com.",
    "expiration": 1675825244.2986872,
    "response": "id 6176\nopcode QUERY\nrcode NOERROR\nflags QR RD RA\nedns 0\npayload 65494\n;QUESTION\ngithub.com. IN A\n;ANSWER\ngithub.com. 60 IN A 20.248.137.48\n;AUTHORITY\n;ADDITIONAL",
    "A": [
      "20.248.137.48"
    ],
    "startTimestamp": "2023-02-08T02:59:44.248174",
    "endTimestamp": "2023-02-08T02:59:44.298773"
  },
  "status": "pass"
}

Pass the -v flag to see log messages.

Each check can be configured, e.g. you can specify the server and host for a dns check, and tell netcheck whether a particular configuration is expected to pass or fail:

netcheck dns --server 1.1.1.1 --host hardbyte.nz --should-pass
{
  "spec": {
    "type": "dns",
    "nameserver": "1.1.1.1",
    "host": "hardbyte.nz",
    "timeout": 30.0,
    "pattern": "\ndata['response-code'] == 'NOERROR' &&\nsize(data['A']) >= 1 && \n(timestamp(data['endTimestamp']) - timestamp(data['startTimestamp']) < duration('10s'))\n"
  },
  "data": {
    "canonical_name": "hardbyte.nz.",
    "expiration": 1683241225.5542665,
    "response": "id 53196\nopcode QUERY\nrcode NOERROR\nflags QR RD RA\n;QUESTION\nhardbyte.nz. IN A\n;ANSWER\nhardbyte.nz. 3600 IN A 209.58.165.79\n;AUTHORITY\n;ADDITIONAL",
    "A": [
      "209.58.165.79"
    ],
    "response-code": "NOERROR",
    "startTimestamp": "2023-05-04T22:00:24.491750",
    "endTimestamp": "2023-05-04T22:00:25.554344"
  },
  "status": "pass"
}

Netcheck can handle checks that are expected to fail:

$ netcheck dns --server=1.1.1.1 --host=made.updomain --should-fail

Note the resulting status will show pass if the check fails as expected, and fail if the check passes unexpectedly!

netcheck has built in default validation for each check type. For example, the dns check will pass if the DNS response code is NOERROR, there is at least one A record, and resolver responds in under 10 seconds. Custom validation is also possible, see the Custom Validation section below.

Custom Validation

Custom validation can be added to checks by providing a validation-rule option on the command line, or a validation key in the rules of a test spec when configuring via json.

For example to override the default validation for the dns check to check that the A record resolves to a particular IP:

netcheck dns --host github.com --validation-rule "data['A'].contains('20.248.137.48')"

The validation rule is a CEL expression that is evaluated with the data returned by the check and spec objects in scope. For an introduction to CEL see https://github.com/google/cel-spec/blob/master/doc/intro.md

http checks

http checks are also available:

Assert that GitHub's status page includes the text "GitHub lives!" and that the response code is 200:

netcheck http --url=https://github.com/status --validation-rule "data.body.contains('GitHub lives!') && data['status-code'] in [200, 201]"

Provide a header with a request:

netcheck http --url https://pie.dev/headers --header "X-Header:special"

Validate that the response body is valid JSON and includes a headers object containing the X-Header key with the value special:

netcheck http --url https://pie.dev/headers \
  --header "X-Header:special" \
  --validation-rule "parse_json(data.body).headers['X-Header'] == 'special'"

Ensure that a POST request fails:

$ netcheck http --method=post --url=https://s3.ap-southeast-2.amazonaws.com --should-fail

Configuration via file

The main way to run netcheck is passing in a list of assertions. A json file can be provided with a list of assertions to be checked:

{
  "assertions": [
    {
      "name":  "deny-cloudflare-dns", 
      "rules": [
        {"type": "dns", "server":  "1.1.1.1", "host": "github.com"}
      ]
    }
  ]
}

And the run command can be called:

$ netcheck run --config tests/testdata/dns-config.json

The output should be valid JSON containing results for each assertion.

Multiple assertions with multiple rules can be specified in the config file, configuration can be provided to each rule such as headers and custom validation:

{
  "assertions": [
    {"name":  "get-with-header", "rules": [
      {"type": "http", "url": "https://pie.dev/headers", "headers": {"X-Test-Header":  "value"}},
      {"type": "http", "url": "https://pie.dev/headers", "headers": {"X-Header": "secret"}, "validation": "parse_json(data.body).headers['X-Header'] == 'secret'" }
    ]}
  ]
}

External Data

Finally, external context can be referenced to inject data. The following example is a valid config file, if a bit contrived:

{
  "assertions": [
    {
      "name": "example-assertion",
      "rules": [
        {
          "type": "http",
          "url": "{{customdata.url}}",
          "headers": {"{{customdata.header}}": "{{ b64decode(token) }}"},
          "validation": "parse_json(data.body).headers['X-Header'] == 'secret'"
        }
      ]
    }
  ],
  "contexts": [
    {"name": "customdata", "type": "inline", "data": {"url": "https://pie.dev/headers", "header": "X-Header"}},
    {"name": "token", "type": "inline", "data": "c2VjcmV0=="},
    {"name": "selfref", "type": "file", "path": "example-config.json"}
  ]
}

In the above example the customdata and token contexts are injected into the rule. The customdata.url is used as the URL for the request, customdata.header is used as the name of the header. The token is base64 decoded and used as the value of the header. The selfref context is unused but shows how to load data an external JSON file which is used extensively by the Kubernetes operator to inject data.

Development

Install dev dependencies with uv:

uv sync

Testing

Pytest is used for testing:

uv run pytest tests

Releasing

Update version in pyproject.toml, operator/Cargo.toml, and operator/charts/netchecks/Chart.yaml (appVersion). Push to main and create a GitHub release with a v* tag. CI automatically publishes to PyPI, builds Docker images, and releases the Helm chart. See releasing docs for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

netcheck-0.9.0.tar.gz (25.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

netcheck-0.9.0-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file netcheck-0.9.0.tar.gz.

File metadata

  • Download URL: netcheck-0.9.0.tar.gz
  • Upload date:
  • Size: 25.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for netcheck-0.9.0.tar.gz
Algorithm Hash digest
SHA256 0d88f7de4103f7ad4f3283b815c0bd2c897ed309cb3ceb0ca16b02bd11b73bde
MD5 6506d3c3387b5401cebe8d9afd5234ca
BLAKE2b-256 9be14edce3d49555aa97c4c8818a3d461c98031f012141d652975528c2cd3d05

See more details on using hashes here.

File details

Details for the file netcheck-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: netcheck-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for netcheck-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c859f3ab02084ba752600a89507f1ffcae81583b046266e7208f953960edf0be
MD5 36f3d1e3e6681331d6d7b0e009d954a1
BLAKE2b-256 1abf9634bf8be824cdd1ea4d3974bd09a0e6fb55a9c01ba05e921bed6a49b1e0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page