You see that the filter must be decorated with the <Code>pyfilter</Code> decorator and must return a statement about how to manage that packet.
<br/><Space h="sm" />
You can save every data about the current flow in the global variables, the code you write will be executed only once for flow. The globals variables are isolated between flows.
For each packet the filter functions will be called with the required paramethers and using the same globals as before.
<br/><Space h="sm" />
<strong>Saving data in globals of other modules is not recommended, because that memory is shared by the flows managed by the same thread and lead to unexpected behaviors.</strong>
<br/><Space h="sm" />
<strong>Global variables that starts with '__firegex' are reserved for internal use, don'tusethem.</strong>
Here there are all the statments you can return from a filter:
<List>
<List.Item><strong>ACCEPT: </strong> The packet will be accepted and forwarded to the destination. (default if None is returned)</List.Item>
<List.Item><strong>REJECT: </strong> The connection will be closed and all the packets will be dropped.</List.Item>
<List.Item><strong>DROP: </strong> This packet and all the following will be dropped. (This not simulate a connection closure)</List.Item>
<List.Item><strong>UNSTABLE_MANGLE: </strong> The packet will be modified and forwarded. You can edit the packet only with RawPacket data handler. (This is an unstable statement, use it carefully)</List.Item>
</List>
</Text>
<Title order={2} mt="lg" mb="sm">⚙️ Data Structures</Title>
<Text size="lg" my="xs">
Here there are all the data structure you can use for your filters:
<strong>l4_size: </strong> The size of l4 payload (read only)
</List.Item>
<List.Item>
<strong>raw_packet_header_len: </strong> The size of the raw packet header (read only)
</List.Item>
<List.Item>
<strong>raw_packet: </strong> The raw packet data with ip and TCP header. You can edit all the packet content and it will be modified if you send
the UNSTABLE_MANGLE statement. <strong>Be careful, beacause the associated layer 4 data can be different from 'data' filed that instead arrives from libtins.</strong>
When you edit this field, l4_size and l4_data will be updated automatically.
</List.Item>
<List.Item>
<strong>l4_data: </strong> The l4 payload data, directly taken by the raw packet. You can edit all the packet content and it will be modified if you send
the UNSTABLE_MANGLE statement. <strong>Be careful, beacause the associated layer 4 data can be different from 'data' filed that instead arrives from libtins.</strong> When you edit this field, l4_size and raw_packet will be updated automatically.
<Text size="lg">This data is the TCP input stream: this handler is called only on is_input=True packets. The filters that handles this data will be called only in this case.</Text>
<Space h="sm" />
<Text size="lg" ml="xs">
<List>
<List.Item>
<strong>data: </strong> The entire stream in input direction. (read only)
</List.Item>
<List.Item>
<strong>total_stream_size: </strong> The size of the entire stream in input direction. (read only)
<Text size="lg">This data is the TCP output stream: this handler is called only on is_input=False packets. The filters that handles this data will be called only in this case.</Text>
<Space h="sm" />
<Text size="lg" ml="xs">
<List>
<List.Item>
<strong>data: </strong> The entire stream in output direction. (read only)
</List.Item>
<List.Item>
<strong>total_stream_size: </strong> The size of the entire stream in output direction. (read only)
<Text size="lg">This data is the Http request processed by nfqueue. This handler can be called twice per request: once when the http headers are complete, and once when the body is complete.</Text>
<Text size="lg">If the http data arrives in 1 single TCP packet, this handler will be called once</Text>
<Space h="sm" />
<Text size="lg" ml="xs">
<List>
<List.Item>
<strong>url: </strong> The url of the request (read only)
</List.Item>
<List.Item>
<strong>headers: </strong> The headers of the request (read only). The keys and values are exactly the same as the original request (case sensitive).
</List.Item>
<List.Item>
<strong>get_header(key:str, default = None): </strong> A function that returns the value of a header: it matches the key without case sensitivity. If the header is not found, it returns the default value.
</List.Item>
<List.Item>
<strong>user_agent: </strong> The user agent of the request (read only)
</List.Item>
<List.Item>
<strong>content_encoding: </strong> The content encoding of the request (read only)
</List.Item>
<List.Item>
<strong>content_length: </strong> The content length of the request (read only)
</List.Item>
<List.Item>
<strong>body: </strong> The body of the request (read only). It'sNoneifthebodyhasnotarrivedyet.
<strong>stream:</strong>It's the buffer that contains the stream of the websocket traffic in output. This is used only if should_upgrade is True. (read only)
<Text size="lg">Same as HttpResponse, but this handler is called only when the headers are complete and body is not buffered. Body will always be None</Text>
<strong>FGEX_STREAM_MAX_SIZE: </strong> Sets the maximum size of the stream. If the stream exceeds this size, the FGEX_FULL_STREAM_ACTION will be performed. (this limit is applyed at the single stream related to the single data handler).
For example if TCPInputStream has reached the limit but HttpResponse has not, the action will be performed only on the TCPInputStream. The default is 1MB.
</List.Item>
<List.Item>
<strong>FGEX_FULL_STREAM_ACTION: </strong> Sets the action performed when the stream exceeds the FGEX_STREAM_MAX_SIZE. The default is FullStreamAction.FLUSH.
</List.Item>
</List>
Heres will be explained every type of action you can set:
<List>
<List.Item>
<strong>FLUSH: </strong> Flush the stream and continue to acquire new packets (default)
</List.Item>
<List.Item>
<strong>DROP: </strong> Drop the next stream packets - like a DROP action by filter
</List.Item>
<List.Item>
<strong>REJECT: </strong> Reject the stream and close the connection - like a REJECT action by filter
</List.Item>
<List.Item>
<strong>ACCEPT: </strong> Stops to call pyfilters and accept the traffic
</List.Item>
</List>
</Text>
<Title order={2} mt="lg" mb="sm">🚀 How It Works</Title>
<Text mb="sm" size="lg">
The proxy is built on a multi-threaded architecture and integrates Python for dynamic filtering:
You see that the filter must be decorated with the <Code>pyfilter</Code> decorator and must return a statement about how to manage that packet.
<br/><Space h="sm" />
You can save every data about the current flow in the global variables, the code you write will be executed only once for flow. The globals are isolated between flows.
For each packet the filter functions will be called with the required paramethers and the same globals as before.
<br/><Space h="sm" />
<strong>Saving data in globals of other modules is not recommended, because that memory is shared by the flows managed by the same thread and lead to unexpected behaviors.</strong>
<br/><Space h="sm" />
<strong>Global variables that starts with __firegex_ are reserved for internal use, don'tusethem.</strong>
changingpacketsit's possible but not sure to do with nfproxy, but the simulator can change the packets normally (on PacketRaw data is always == l4_data in the simulator, check the nfproxy docs for more info)
<br /><Space h="sm" />
You will need to install firegex library with <Code>pip install -U fgex</Code> and than use the simulator command
<Title order={2} mt="lg" mb="sm">🚀 How It Works</Title>
<Text mb="sm" size="lg">
This modules works in a simple way: this only thing done is to change the destination and source ip using <a href="https://netfilter.org/">nftables</a> rules so that the kernel will see that the request was done to the proxy port,
but externaly the packets exists as connections to the original service. This mangle is done only for external packet arriving from the external ip indicated, localhost traffic won'tbetouched.
</Text>
<Spaceh="xl"/>
</Container>
}
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.