Skip to main content

A Flexible Network Data Analysis Framework

Project description

NFStream Logo


NFStream is a Python package providing fast, flexible, and expressive data structures designed to make working with online or offline network data both easy and intuitive. It aims to be the fundamental high-level building block for doing practical, real world network data analysis in Python. Additionally, it has the broader goal of becoming a common network data processing framework for researchers providing data reproducibility across experiments.

Live Notebook live notebook
Project Website website
Discussion Channel Gitter
Latest Release latest release
Supported Versions python3
Project License License
Build Status Github WorkFlows Travis CI
Code Quality Quality
Code Coverage Coverage

Main Features

  • Performance: NFStream is designed to be fast (with native PyPy support) with a small CPU and memory footprint.
  • Layer-7 visibility: NFStream deep packet inspection engine is based on nDPI. It allows NFStream to perform reliable encrypted applications identification and metadata extraction (e.g. TLS, QUIC, TOR, HTTP, SSH, DNS, etc.).
  • Flexibility: add a flow feature in 2 lines as an NFPlugin.
  • Machine Learning oriented: add your trained model as an NFPlugin.

How to use it?

  • Dealing with a big pcap file and just want to aggregate it as network flows? NFStream make this path easier in few lines:
from nfstream import NFStreamer
my_awesome_streamer = NFStreamer(source="facebook.pcap", # or network interface
                                 snaplen=65535,
                                 idle_timeout=30,
                                 active_timeout=300,
                                 plugins=(),
                                 dissect=True,
                                 max_tcp_dissections=80,
                                 max_udp_dissections=16,
                                 statistics=False,
                                 enable_guess=True,
                                 decode_tunnels=True,
                                 bpf_filter=None,
                                 promisc=True
)

for flow in my_awesome_streamer:
    print(flow)  # print it.
    print(flow.to_namedtuple()) # convert it to a namedtuple.
    print(flow.to_json()) # convert it to json.
    print(flow.keys()) # get flow keys.
    print(flow.values()) # get flow values.
NFEntry(id=0,
        bidirectional_first_seen_ms=1472393122365,
        bidirectional_last_seen_ms=1472393123665,
        src2dst_first_seen_ms=1472393122365,
        src2dst_last_seen_ms=1472393123408,
        dst2src_first_seen_ms=1472393122668,
        dst2src_last_seen_ms=1472393123665,
        src_ip='192.168.43.18',
        src_ip_type=1,
        dst_ip='66.220.156.68',
        dst_ip_type=0,
        version=4,
        src_port=52066,
        dst_port=443,
        protocol=6,
        vlan_id=4,
        bidirectional_packets=19,
        bidirectional_raw_bytes=5745,
        bidirectional_ip_bytes=5479,
        bidirectional_duration_ms=1300,
        src2dst_packets=9,
        src2dst_raw_bytes=1345,
        src2dst_ip_bytes=1219,
        src2dst_duration_ms=1300,
        dst2src_packets=10,
        dst2src_raw_bytes=4400,
        dst2src_ip_bytes=4260,
        dst2src_duration_ms=997,
        expiration_id=0,
        master_protocol=91,
        app_protocol=119,
        application_name='TLS.Facebook',
        category_name='SocialNetwork',
        client_info='facebook.com',
        server_info='*.facebook.com,*.facebook.net,*.fb.com,\
                     *.fbcdn.net,*.fbsbx.com,*.m.facebook.com,\
                     *.messenger.com,*.xx.fbcdn.net,*.xy.fbcdn.net,\
                     *.xz.fbcdn.net,facebook.com,fb.com,messenger.com',
        j3a_client='bfcc1a3891601edb4f137ab7ab25b840',
        j3a_server='2d1eb5817ece335c24904f516ad5da12')
from nfstream import NFStreamer
my_awesome_streamer = NFStreamer(source="facebook.pcap", statistics=True)
for flow in my_awesome_streamer:
    print(flow)
NFEntry(id=0,      
        bidirectional_first_seen_ms=1472393122365,
        bidirectional_last_seen_ms=1472393123665,
        src2dst_first_seen_ms=1472393122365,
        src2dst_last_seen_ms=1472393123408,
        dst2src_first_seen_ms=1472393122668,
        dst2src_last_seen_ms=1472393123665,
        src_ip='192.168.43.18',
        src_ip_type=1,
        dst_ip='66.220.156.68',
        dst_ip_type=0,
        version=4,
        src_port=52066,
        dst_port=443,
        protocol=6,
        vlan_id=4,
        bidirectional_packets=19,
        bidirectional_raw_bytes=5745,
        bidirectional_ip_bytes=5479,
        bidirectional_duration_ms=1300,
        src2dst_packets=9,
        src2dst_raw_bytes=1345,
        src2dst_ip_bytes=1219,
        src2dst_duration_ms=1300,
        dst2src_packets=10,
        dst2src_raw_bytes=4400,
        dst2src_ip_bytes=4260,
        dst2src_duration_ms=997,
        expiration_id=0,
        bidirectional_min_raw_ps=66,
        bidirectional_mean_raw_ps=302.36842105263156,
        bidirectional_stdev_raw_ps=425.53315715259754,
        bidirectional_max_raw_ps=1454,
        src2dst_min_raw_ps=66,
        src2dst_mean_raw_ps=149.44444444444446,
        src2dst_stdev_raw_ps=132.20354676701294,
        src2dst_max_raw_ps=449,
        dst2src_min_raw_ps=66,
        dst2src_mean_raw_ps=440.0,
        dst2src_stdev_raw_ps=549.7164925870628,
        dst2src_max_raw_ps=1454,
        bidirectional_min_ip_ps=52,
        bidirectional_mean_ip_ps=288.36842105263156,
        bidirectional_stdev_ip_ps=425.53315715259754,
        bidirectional_max_ip_ps=1440,
        src2dst_min_ip_ps=52,
        src2dst_mean_ip_ps=135.44444444444446,
        src2dst_stdev_ip_ps=132.20354676701294,
        src2dst_max_ip_ps=435,
        dst2src_min_ip_ps=52,
        dst2src_mean_ip_ps=426.0,
        dst2src_stdev_ip_ps=549.7164925870628,
        dst2src_max_ip_ps=1440,
        bidirectional_min_piat_ms=0,
        bidirectional_mean_piat_ms=72.22222222222223,
        bidirectional_stdev_piat_ms=137.34994188549086,
        bidirectional_max_piat_ms=398,
        src2dst_min_piat_ms=0,
        src2dst_mean_piat_ms=130.375,
        src2dst_stdev_piat_ms=179.72036811192467,
        src2dst_max_piat_ms=415,
        dst2src_min_piat_ms=0,
        dst2src_mean_piat_ms=110.77777777777777,
        dst2src_stdev_piat_ms=169.51458475436397,
        dst2src_max_piat_ms=1,
        bidirectional_syn_packets=2,
        bidirectional_cwr_packets=0,
        bidirectional_ece_packets=0,
        bidirectional_urg_packets=0,
        bidirectional_ack_packets=18,
        bidirectional_psh_packets=9,
        bidirectional_rst_packets=0,
        bidirectional_fin_packets=0,
        src2dst_syn_packets=1,
        src2dst_cwr_packets=0,
        src2dst_ece_packets=0,
        src2dst_urg_packets=0,
        src2dst_ack_packets=8,
        src2dst_psh_packets=4,
        src2dst_rst_packets=0,
        src2dst_fin_packets=0,
        dst2src_syn_packets=1,
        dst2src_cwr_packets=0,
        dst2src_ece_packets=0,
        dst2src_urg_packets=0,
        dst2src_ack_packets=10,
        dst2src_psh_packets=5,
        dst2src_rst_packets=0,
        dst2src_fin_packets=0,
        master_protocol=91,
        app_protocol=119,
        application_name='TLS.Facebook',
        category_name='SocialNetwork',
        client_info='facebook.com',
        server_info='*.facebook.com,*.facebook.net,*.fb.com,\
                     *.fbcdn.net,*.fbsbx.com,*.m.facebook.com,\
                     *.messenger.com,*.xx.fbcdn.net,*.xy.fbcdn.net,\
                     *.xz.fbcdn.net,facebook.com,fb.com,messenger.com',
        j3a_client='bfcc1a3891601edb4f137ab7ab25b840',
        j3a_server='2d1eb5817ece335c24904f516ad5da12')
  • From pcap to Pandas DataFrame?
my_dataframe = NFStreamer(source='devil.pcap').to_pandas(ip_anonymization=False)
my_dataframe.head(5)
  • From pcap to csv file?
flows_rows_count = NFStreamer(source='devil.pcap').to_csv(path="devil.pcap.csv",
                                                          sep="|",
                                                          ip_anonymization=False)
  • Didn't find a specific flow feature? add a plugin to NFStream in few lines:
from nfstream import NFPlugin

class packet_with_666_size(NFPlugin):
    def on_init(self, pkt): # flow creation with the first packet
        if pkt.raw_size == 666:
            return 1
        else:
            return 0

    def on_update(self, pkt, flow): # flow update with each packet belonging to the flow
        if pkt.raw_size == 666:
            flow.packet_with_666_size += 1

streamer_awesome = NFStreamer(source='devil.pcap', plugins=[packet_with_666_size()])
for flow in streamer_awesome:
    print(flow.packet_with_666_size) # see your dynamically created metric in generated flows

Run your Machine Learning models

In the following, we want to run an early classification of flows based on a trained machine learning model than takes as features the 3 first packets size of a flow.

Computing required features

from nfstream import NFPlugin

class feat_1(NFPlugin):
    def on_init(self, obs):
        return obs.raw_size

class feat_2(NFPlugin):
    def on_update(self, obs, entry):
        if entry.bidirectional_packets == 2:
            entry.feat_2 = obs.raw_size

class feat_3(NFPlugin):
    def on_update(self, obs, entry):
        if entry.bidirectional_packets == 3:
            entry.feat_3 = obs.raw_size

Trained model prediction

class model_prediction(NFPlugin):
    def on_update(self, obs, entry):
        if entry.bidirectional_packets == 3:
            entry.model_prediction = self.user_data.predict_proba([entry.feat_1,
                                                                   entry.feat_2,
                                                                   entry.feat_3])
            # optionally we can trigger NFStreamer to immediately expires the flow
            # entry.expiration_id = -1

Start your ML powered streamer

my_model = function_to_load_your_model() # or whatever
ml_streamer = NFStreamer(source='devil.pcap',
                         plugins=[feat_1(volatile=True),
                                  feat_2(volatile=True),
                                  feat_3(volatile=True),
                                  model_prediction(user_data=my_model)
                                  ])
for flow in ml_streamer:
     print(flow.model_prediction) # now you will see your trained model prediction.

Installation

Using pip

Binary installers for the latest released version are available:

python3 -m pip install nfstream

Build from sources

If you want to build NFStream from sources on your local machine:

linux Linux

sudo apt-get update
sudo apt-get install autoconf automake libtool pkg-config libpcap-dev flex bison
sudo apt-get install libusb-1.0-0-dev libdbus-glib-1-dev libbluetooth-dev libnl-genl-3-dev
git clone https://github.com/aouinizied/nfstream.git
cd nfstream
python3 -m pip install -r requirements.txt
python3 setup.py bdist_wheel

osx MacOS

brew install autoconf automake libtool pkg-config
git clone https://github.com/aouinizied/nfstream.git
cd nfstream
python3 -m pip install -r requirements.txt
python3 setup.py bdist_wheel

Contributing

Please read Contributing for details on our code of conduct, and the process for submitting pull requests to us.

Ethics

NFStream is intended for network data research and forensics. Researchers and network data scientists can use these framework to build reliable datasets, train and evaluate network applied machine learning models. As with any packet monitoring tool, NFStream could potentially be misused. Do not run it on any network of which you are not the owner or the administrator.

License

This project is licensed under the LGPLv3 License - see the License file 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 Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

nfstream-5.2.0-pp36-pypy36_pp73-macosx_10_15_x86_64.whl (433.7 kB view details)

Uploaded PyPy macOS 10.15+ x86-64

nfstream-5.2.0-cp38-cp38-manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.8

nfstream-5.2.0-cp38-cp38-manylinux1_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.8

nfstream-5.2.0-cp38-cp38-macosx_10_15_x86_64.whl (433.7 kB view details)

Uploaded CPython 3.8 macOS 10.15+ x86-64

nfstream-5.2.0-cp37-cp37m-manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.7m

nfstream-5.2.0-cp37-cp37m-manylinux1_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.7m

nfstream-5.2.0-cp37-cp37m-macosx_10_15_x86_64.whl (433.7 kB view details)

Uploaded CPython 3.7m macOS 10.15+ x86-64

nfstream-5.2.0-cp36-cp36m-manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.6m

nfstream-5.2.0-cp36-cp36m-manylinux1_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.6m

nfstream-5.2.0-cp36-cp36m-macosx_10_15_x86_64.whl (433.7 kB view details)

Uploaded CPython 3.6m macOS 10.15+ x86-64

File details

Details for the file nfstream-5.2.0-pp36-pypy36_pp73-manylinux1_x86_64.whl.

File metadata

  • Download URL: nfstream-5.2.0-pp36-pypy36_pp73-manylinux1_x86_64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: PyPy
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 PyPy/7.3.1

File hashes

Hashes for nfstream-5.2.0-pp36-pypy36_pp73-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 d1e7a7b90f9f610079e8eeb6d661517cb131133d226506aaf426abfc867d652f
MD5 679e4669dd29077dd1e22ad1d674fc1c
BLAKE2b-256 65c1637c556f013c6f323e109cf7510f0b56427f4ed83a422f0850869ad98e1b

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-pp36-pypy36_pp73-macosx_10_15_x86_64.whl.

File metadata

  • Download URL: nfstream-5.2.0-pp36-pypy36_pp73-macosx_10_15_x86_64.whl
  • Upload date:
  • Size: 433.7 kB
  • Tags: PyPy, macOS 10.15+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 PyPy/7.3.1

File hashes

Hashes for nfstream-5.2.0-pp36-pypy36_pp73-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 5cea6ef3916447b349eb24e9d71e5f1f4f4c884934cb1661d3f8360d9d819dbf
MD5 f462f2ef7a80950ee0a892f4e53730a5
BLAKE2b-256 dce102b2b6440f38f05db620efac5178d243d713337ee32eb310f49d26469358

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-cp38-cp38-manylinux2014_aarch64.whl.

File metadata

  • Download URL: nfstream-5.2.0-cp38-cp38-manylinux2014_aarch64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.0

File hashes

Hashes for nfstream-5.2.0-cp38-cp38-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1ea91186be035d22a1cbc38f9b2cd27306062fe24f0268db204c417e976a7d51
MD5 ea7b168e44f5f3d0e9d548b7b70d1eba
BLAKE2b-256 741d78c2d10cf55d94dfcb92f0d04c9649b24b65eca84c961a31f3c7ac922ca4

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-cp38-cp38-manylinux1_x86_64.whl.

File metadata

  • Download URL: nfstream-5.2.0-cp38-cp38-manylinux1_x86_64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.3

File hashes

Hashes for nfstream-5.2.0-cp38-cp38-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 ee73b7090757e5c0a954484e7e28dbd0878c3ab95a906d816a9aa89443bec4be
MD5 14f9886ed21db182c7b2f2edaaa8e5ec
BLAKE2b-256 0d5528128af3a1486376b37bc525d0aa27fe6741e3b20ecfb096474fbcfdce93

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-cp38-cp38-macosx_10_15_x86_64.whl.

File metadata

  • Download URL: nfstream-5.2.0-cp38-cp38-macosx_10_15_x86_64.whl
  • Upload date:
  • Size: 433.7 kB
  • Tags: CPython 3.8, macOS 10.15+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.3

File hashes

Hashes for nfstream-5.2.0-cp38-cp38-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 2418578a3e14dc04605a75b412b7ca7017261ae8dcd18b0428806dbabf4b4595
MD5 72ed51ff5f3d4e4e90d8a3515dc40e30
BLAKE2b-256 05f1db56aea65d366d9e78131c5019a26171c2fd46fe9b12825902082562a0b7

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-cp37-cp37m-manylinux2014_aarch64.whl.

File metadata

  • Download URL: nfstream-5.2.0-cp37-cp37m-manylinux2014_aarch64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.7m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.7.5

File hashes

Hashes for nfstream-5.2.0-cp37-cp37m-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a94fa2ff0234837d8e51799875cef53e20c0a85726c203bab4f7d6d50abecc2a
MD5 a4844860bb3645f4b8649b157c4f39cd
BLAKE2b-256 467fe3dab2ec7f4a7240f65617812f85ceff1614fee577fb3d74bf3e5315903c

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-cp37-cp37m-manylinux1_x86_64.whl.

File metadata

  • Download URL: nfstream-5.2.0-cp37-cp37m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.7m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.7.8

File hashes

Hashes for nfstream-5.2.0-cp37-cp37m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 b556a38416802847a4e6ef182695fceaf7b45f7136fdafbe284297fb740bb268
MD5 53f3c27cf8665ef3cfbdc1697859febb
BLAKE2b-256 cbdbb04284c50def949eb96cf458ea65f96bee82c18e26608accf47cd1c2a6f2

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-cp37-cp37m-macosx_10_15_x86_64.whl.

File metadata

  • Download URL: nfstream-5.2.0-cp37-cp37m-macosx_10_15_x86_64.whl
  • Upload date:
  • Size: 433.7 kB
  • Tags: CPython 3.7m, macOS 10.15+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.7.8

File hashes

Hashes for nfstream-5.2.0-cp37-cp37m-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 198a6102e7172dbd7b98bb6b62ff84e32cc899cbb44addfc3ecd6bcf966c04b3
MD5 2d1e8d3f298d68e7d5a753f3e866b7d4
BLAKE2b-256 21ea5c60c1e66d389d33d56a198ef0ffbddce97abee7b2d5a71e78921c9d2d45

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-cp36-cp36m-manylinux2014_aarch64.whl.

File metadata

  • Download URL: nfstream-5.2.0-cp36-cp36m-manylinux2014_aarch64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.6m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.6.9

File hashes

Hashes for nfstream-5.2.0-cp36-cp36m-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e587ff45fac38131ed85c5e0f78ed55ad12e5783cb73f17853aecfe90bcf615f
MD5 48922a94e95c548bc79919f32c9d4081
BLAKE2b-256 47954e11cb4b0c478518d9748174d810bbaf368d165723f2c69b5819016573b9

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-cp36-cp36m-manylinux1_x86_64.whl.

File metadata

  • Download URL: nfstream-5.2.0-cp36-cp36m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.6m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.6.11

File hashes

Hashes for nfstream-5.2.0-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 1efc6993a9cddc34c1d1518be00398f98a930ee25537dfe5d48b993fd80fbcc1
MD5 d9b49832da96c7eac1405de0f70c6d69
BLAKE2b-256 d01d2ed1835d6a02f0aff953e0ab6e21df3bbccf23c9456350c83350f23c8ee1

See more details on using hashes here.

File details

Details for the file nfstream-5.2.0-cp36-cp36m-macosx_10_15_x86_64.whl.

File metadata

  • Download URL: nfstream-5.2.0-cp36-cp36m-macosx_10_15_x86_64.whl
  • Upload date:
  • Size: 433.7 kB
  • Tags: CPython 3.6m, macOS 10.15+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.6.11

File hashes

Hashes for nfstream-5.2.0-cp36-cp36m-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 30c5ce40d8acd5914ec95911911af58f8b036a6008a9cbab6c996636d7fe2f0c
MD5 7172b1b9723761640c16856b43ccd7a4
BLAKE2b-256 a5ed33aef0dc93870d70adbe306ee6448bc7a2c6f94149d43b37c863040bff48

See more details on using hashes here.

Supported by

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