From 477143d7e8203881efdc4ff153aa2e4d3098feab Mon Sep 17 00:00:00 2001 From: Zied Aouini Date: Sun, 29 Mar 2020 21:44:32 +0200 Subject: [PATCH] Move docs to nfstream website. --- README.md | 18 +- docs/Makefile | 20 -- docs/make.bat | 35 --- docs/source/architecture.rst | 94 -------- docs/source/asset/arch.png | Bin 34829 -> 0 bytes docs/source/changelog.rst | 166 ------------- docs/source/conf.py | 53 ---- docs/source/contributing.rst | 113 --------- docs/source/get_started.rst | 227 ------------------ docs/source/index.rst | 42 ---- docs/source/installation.rst | 36 --- docs/source/plugins.rst | 109 --------- .../asset/logo_main.png => logo_main.png | Bin setup.py | 6 +- 14 files changed, 6 insertions(+), 913 deletions(-) delete mode 100644 docs/Makefile delete mode 100644 docs/make.bat delete mode 100644 docs/source/architecture.rst delete mode 100644 docs/source/asset/arch.png delete mode 100644 docs/source/changelog.rst delete mode 100644 docs/source/conf.py delete mode 100644 docs/source/contributing.rst delete mode 100644 docs/source/get_started.rst delete mode 100644 docs/source/index.rst delete mode 100644 docs/source/installation.rst delete mode 100644 docs/source/plugins.rst rename docs/source/asset/logo_main.png => logo_main.png (100%) diff --git a/README.md b/README.md index c74e084..f38c87c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

+

nfstream: a flexible network data analysis framework

[**nfstream**][repo] 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 @@ -67,14 +67,6 @@ the broader goal of becoming **a common network data processing framework for re - - Documentation Status - - - ReadTheDocs - - - Code Quality @@ -235,13 +227,13 @@ As with any packet monitoring tool, **nfstream** could potentially be misused. This project is licensed under the GPLv3 License - see the [**License**][license] file for details [license]: https://github.com/aouinizied/nfstream/blob/master/LICENSE -[contribute]: https://nfstream.readthedocs.io/en/latest/contributing.html +[contribute]: https://nfstream.github.io/docs/community [contributors]: https://github.com/aouinizied/nfstream/graphs/contributors [linkedin]: https://www.linkedin.com/in/dr-zied-aouini [github]: https://github.com/aouinizied -[documentation]: https://nfstream.readthedocs.io/en/latest/index.html -[ndpi]: https://github.com/ntop/nDPI -[nfplugin]: https://nfstream.readthedocs.io/en/latest/plugins.html +[documentation]: https://nfstream.github.io/ +[ndpi]: https://nfstream.github.io/docs/visibility +[nfplugin]: https://nfstream.github.io/docs/api#nfplugin [reliable]: http://people.ac.upc.edu/pbarlet/papers/ground-truth.pam2014.pdf [repo]: https://github.com/aouinizied/nfstream [demo]: https://mybinder.org/v2/gh/aouinizied/nfstream-tutorials/master?filepath=demo_notebook.ipynb diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d0c3cbf..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 9534b01..0000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/source/architecture.rst b/docs/source/architecture.rst deleted file mode 100644 index 6bed527..0000000 --- a/docs/source/architecture.rst +++ /dev/null @@ -1,94 +0,0 @@ -############ -Architecture -############ - -.. image:: asset/arch.png - :scale: 100% - :align: center - - -A step by step walk through each process involved when performing flow monitoring is -developed in this section. Our aim is to provide you with a reminder about how -things works in theory. Consequently, an easier understanding of nfstream features -and implementation is possible. - -****************** -Packet observation -****************** - -Packet observation is a key stage in a flow monitoring architecture as it is the -starting point. Consequently, we detail in the following each step involved at this -phase: - -**Packet capture:** This step is performed on the Network Interface Card (NIC) level. -After passing various checks such as checksum error, packets stored in on-card -reception buffers are moved to the hosting device memory. Several libraries are -available to capture network traffic such as libpcap for UNIX based operating systems -Winpcap for Windows. These libraries are running on the top of the operating system -stack which may reduce performances passing through several layers. -To overcome such limitation in a high speed network context, software optimization -technique are proposed and could be considered (e.g. Intel DPDK, PF-RING, netmap). - -**Timestamping:** As packets may come from several observation points, reordering -process is based on packet’s timestamp. While hardware timestamping provides a high -accuracy up to 100 nanoseconds in case of the IEEE 1588 protocol, it’s not supported -by most of commodity NIC. Software timestamping is widely used to outcome this lack -providing an accuracy up to 100 microseconds. - -**Truncation (optional):** Defining a snapshot length, the process selects precise -bytes from the packet. It is performed in some cases to reduce the amount of data -captured by the probe and therefore CPU and bus bandwidth load. - -**Packet sampling (optional):** is generally performed to reduce load on subsequent -stages. It can be systematic (periodic sampling scheme) or random. The latter is -recommended as periodic scheme may introduce unwanted correlation in the observed -network data. - -**Packet filtering (optional):** performs filtering of packets to separate packets -having specific properties from those not having them. A packet is selected if -some specific fields are equal or in the range of given values. Another technique is -a hash based filtering, applying a hash function on a portion of the packet, -the result is compared to a value or a range of values. - -************* -Flow metering -************* -It includes packets aggregation into flows and flow entry expiration management. -Second, the metering process associates a packet to a flow entry using a defined key. -Third, it performs the aggregation of packets into flow entry based on a set of metrics. -Then, a flow entry is cached until it is considered as terminated (entry expiration). -Finally, optional steps such as flow sampling and filtering may be performed. - -**Flow Cache:** Flow cache consist of table in which the metering process stores -information regarding active flows in the network. A flow key (typically IP source -and destination addresses, source and destination ports, protocol and the VLAN -identifier) determines whether a packet is matching an existing flow entry in the cache -or not. In the first case, flow’s counters are updated. In the latter one, a new entry -is created. Non-key fields are utilized to collect flow metrics (e.g. packets/bytes -count, etc.). If IP addresses are part of flows key, and that traffic between two -pairs generates flows on both directions. We define a flow as bidirectional when we consider that pair and it reverse -belongs to same entry.The cache’s size depends on exporter device memory capacity -and should be configured based on criteria such as key/non-key fields, maximum number -of flows expected and expiration policy. - -**Entry expiration:** Cache entries are maintained in the cache table until they are -considered as terminated. Termination of a flow is triggered by an expiration event. -The metering process should consider an entry as expired based on: - -* Natural expiration: observed TCP packet belonging to a flow with FIN/RST flag. -* Active timeout: a flow entry expires after being considered active during a certain period. -* Idle timeout: a flow entry expires if no packets belonging to it are observed during a specific period.. - -It is possible to configure our metering process based on expiration policy to -reduce the amount of records exported. - -**Flow Sampling and Filtering:** Flow sampling and filtering processes are quite like packet sampling and filtering -process explained above. The major differences are the processed unit; while packet sampling and filtering process -packets, flow sampling and filtering process flow records coming from the metering process. - -****** -Export -****** -Export involves two steps which are mainly **formatting** and **export protocol**. While the first decide how an export is -formatted (number of flow per export, json or other, etc.), the latter determine the used -export protocol (file, mqtt, zmq, etc.). \ No newline at end of file diff --git a/docs/source/asset/arch.png b/docs/source/asset/arch.png deleted file mode 100644 index 95a28397d8a5904a5ca641ab0666e0085ed8605b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34829 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. - * - src2dst_bytes - - int - - Flow bytes (full packet lentgh) accumulator (source->destination). - * - dst2src_packets - - int - - Flow packets accumulator (destination->source). - * - dst2src_bytes - - int - - Flow bytes (full packet lentgh) accumulator (destination->source). - * - expiration_id - - int - - Identifier of flow expiration trigger. Can be ``0`` for idle_timeout, ``1`` for active_timeout or 'negative' for custom expiration. - * - master_protocol - - int - - nDPI master protocol identifier. - * - app_protocol - - int - - nDPI app protocol identifier. - * - application_name - - str - - nDPI application name. - * - category_name - - str - - nDPI application category name. - * - client_info - - str - - Dissected client informations. Can be ``http_detected_os`` for HTTP, ``client_signature`` for SSH or ``client_requested_server_name`` for SSL. - * - server_info - - str - - Dissected server informations. Can be ``host_server_name`` for HTTP or DNS, ``server_signature`` for SSH or ``server_names`` for SSL. - * - j3a_client - - str - - J3A_ client fingerprint. - * - j3a_server - - str - - J3A_ server fingerprint. - -**NFEntry** is an aggregation of **NFPacket** objects. - -*************** -NFPacket object -*************** - -.. list-table:: NFPacket object - :widths: 25 25 50 - :header-rows: 1 - - * - attribute name - - attribute type - - attribute description - * - time - - int - - Packet timestamp in milliseconds. - * - raw_size - - int - - Packet raw size. - * - ip_size - - int - - IP packet size. - * - transport_size - - int - - Transport packet size. - * - payload_size - - int - - Packet payload size. - * - ip_src - - int - - Source IP address int value. - * - ip_dst - - int - - Destination IP address int value. - * - src_port - - int - - Transport layer source port. - * - dst_port - - int - - Transport layer destination port. - * - protocol - - int - - Transport layer protocol. - * - vlan_id - - int - - Virtual LAN identifier. - * - version - - int - - IP version. - * - tcp_flags - - int - - Packet observed TCP flags. - * - ip_packet - - bytes - - Raw content starting from IP Header. - * - direction - - int - - Packet direction: ``0`` for src_to_dst and ``1`` for dst_to_src. - - -.. _J3A: https://github.com/salesforce/ja3 diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index f850e56..0000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,42 +0,0 @@ -.. nfstream documentation master file, created by - sphinx-quickstart on Sat Oct 19 16:26:59 2019. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -#################################################### -nfstream: a flexible network data analysis framework -#################################################### - -.. image:: asset/logo_main.png - :width: 140 - :height: 140 - :align: right - -**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. - -**Main Features** - -* **Performance:** **nfstream** is designed to be fast (x10 faster with pypy3 support) with a small CPU and memory footprint. -* **Layer-7 visibility:** **nfstream** deep packet inspection engine is based on nDPI_ library. It allows nfstream to perform reliable_ encrypted applications identification and metadata extraction (e.g. TLS, SSH, DNS, HTTP). -* **Flexibility:** add a flow feature in 2 lines as an NFPlugin_. -* **Machine Learning oriented:** add your trained model as an NFPlugin_. - - - -.. toctree:: - :maxdepth: 2 - :caption: Table of Contents: - - installation - architecture - get_started - plugins - contributing - changelog - - -.. _nDPI: https://www.ntop.org/products/deep-packet-inspection/ndpi/ -.. _NFPlugin: https://nfstream.readthedocs.io/en/latest/plugins.html -.. _reliable: http://people.ac.upc.edu/pbarlet/papers/ground-truth.pam2014.pdf diff --git a/docs/source/installation.rst b/docs/source/installation.rst deleted file mode 100644 index eb51c1d..0000000 --- a/docs/source/installation.rst +++ /dev/null @@ -1,36 +0,0 @@ -################### -Installing nfstream -################### - -************ -Installation -************ - -**using pip** - -Binary installers for the latest released version are available: - -.. code-block:: bash - - python3 -m pip install nfstream - - -**from source: linux** - -.. code-block:: bash - - sudo apt-get install autoconf automake libtool pkg-config libpcap-dev - git clone https://github.com/aouinizied/nfstream.git - cd nfstream - python3 -m pip install -r requirements.txt - python3 setup.py bdist_wheel - -**from source: macos** - -.. code-block:: bash - - 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 diff --git a/docs/source/plugins.rst b/docs/source/plugins.rst deleted file mode 100644 index 5461683..0000000 --- a/docs/source/plugins.rst +++ /dev/null @@ -1,109 +0,0 @@ -################## -Extending nfstream -################## - -nfstream is designed to be flexible and machine learning oriented. In the following section, we depict the use of NFPlugin -in both cases. - -.. code-block:: python - - from nfstream import NFPlugin - - class my_awesome_plugin(NFPlugin): - def on_update(self, obs, entry): - if obs.raw_size >= 666: - entry.my_awesome_plugin += 1 - - - streamer_awesome = NFStreamer(source='devil.pcap', plugins=[my_awesome_plugin()]) - for flow in streamer_awesome: - print(flow.my_awesome_plugin) # now you will see your dynamically created metric in generated flows - -******************* -NFPlugin parameters -******************* -* ``name`` [default= ``class name`` ] - - - Plugin name. Must be unique as it's dynamically created as a flow attribute. - -* ``volatile`` [default= ``False`` ] - - - Volatile plugin is available only when flow is processed. At flow expiration level, plugin is automatically removed (will not appear as flow attribute). - -* ``user_data`` [default= ``None`` ] - - - user_data passed to the plugin. Example: external module, pickled sklearn model, etc. - -**************** -NFPlugin methods -**************** -* ``on_init(self, obs)`` [default= ``return 0`` ] - - - Method called at entry creation). When aggregating packets into flows, this method is called on ``NFEntry`` object creation based on first ``NFPacket`` object belonging to it. - -* ``on_update(self, obs, entry)`` [default= ``pass`` ] - - - Method called to update each entry with its belonging obs. When aggregating packets into flows, the entry is an ``NFEntry`` object and the obs is an ``NFPacket`` object. - -* ``on_expire(self, entry)`` [default= ``pass`` ] - - - Method called at entry expiration. When aggregating packets into flows, the entry is an ``NFEntry`` - -* ``cleanup(self)`` [default= ``pass`` ] - - - Method called for plugin cleanup. - -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 -*************************** - -.. code-block:: python - - from nfstream import NFPlugin - - class feat_1(NFPlugin): - def on_init(self, obs): - entry.feat_1 == obs.raw_size - - class feat_2(NFPlugin): - def on_update(self, obs, entry): - if entry.total_packets == 2: - entry.feat_2 == obs.raw_size - - class feat_3(NFPlugin): - def on_update(self, obs, entry): - if entry.total_packets == 3: - entry.feat_3 == obs.raw_size - -************************ -Trained model prediction -************************ - -.. code-block:: python - - class model_prediction(NFPlugin): - def on_update(self, obs, entry): - if entry.total_packets == 3: - entry.model_prediction = self.user_data.predict_proba([entry.feat_1 , entry.feat_2 , entry.feat_3]) - # optionally we can force NFStreamer to immediately expires the flow - # entry.expiration_id = -1 - - -*********************** -Start your new streamer -*********************** - -.. code-block:: python - - 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 as part of the flow :) \ No newline at end of file diff --git a/docs/source/asset/logo_main.png b/logo_main.png similarity index 100% rename from docs/source/asset/logo_main.png rename to logo_main.png diff --git a/setup.py b/setup.py index 2e0079c..1f0f126 100644 --- a/setup.py +++ b/setup.py @@ -94,10 +94,6 @@ install_requires = ['cffi>=1.14.0', 'pyzmq>=19.0.0', 'pandas>=1.0.1'] -if os.getenv('READTHEDOCS'): - install_requires.append('numpydoc>=0.8') - install_requires.append('sphinx_rtd_theme>=0.4.3') - try: from wheel.bdist_wheel import bdist_wheel as _bdist_wheel @@ -152,6 +148,6 @@ setup( 'Topic :: Scientific/Engineering :: Artificial Intelligence' ], project_urls={ - 'Documentation': 'https://nfstream.readthedocs.io', + 'GitHub': 'https://nfstream.github.io', } )