mfhepp / py4docker

Template for running Python 3.x shell scripts and notebooks in a Docker container for isolation, security, and portability
MIT License
2 stars 0 forks source link

Add mechanism for limiting and logging outbound network traffic #1

Open mfhepp opened 1 year ago

mfhepp commented 1 year ago

There should be a feature or recipe so that outbound network traffic would be logged or displayed, so that one can see and/or control the network traffic from the script, e.g. for spotting information exfiltration.

Most likely, this can be done by adding a proxy and a firewall component, e.g. iptables and either squid or mitmproxy

mfhepp commented 1 year ago

Also useful:

Option 1: Add a separate squid proxy in separate container (similar to https://github.com/sameersbn/docker-squid) and then force the docker run ... command to use that proxy. Option 2: Add and start a squid proxy (with https / ssl_bump) to the script container and redirect all traffic from the container via that proxy. Not sure this is bullet-proof.

Note to self: Exfiltration may use direct TLS connections or DNS or other protocols, so those need to be blocked.

mfhepp commented 1 year ago

Next iteration: squid will not be sufficient, as information exfiltration could take place via DNS lookups, which would not be recognized by the proxy.

Hence, I think setting up iptables is a better way of limiting access; a useful resource regarding rules for DNS and HTTP/HTTPS is here.

TBD are the implications of root user privileges inside the container (but likely none).

mfhepp commented 1 year ago

The actual interplay between the container and the host regarding iptables etc. is unfortunately pretty complicated, and some people raised concerns that it is not without flaws.

If we manage this on the host side of things, it will not be very portable. If we manage it inside the container, it may interfere with aspects of the networking on the host.

Here is a report on how iptables can be set up inside a Docker container, so this might work. But it is uncertain if such a deep hack will be very long-lasting with future versions of Docker.

Another route may be to add a logging and filtering component to the Python runtime, e.g. via PEP-0578: Python Runtime Audit Hooks. This will likely not be as secure as a component outside the container or at the OS level of the container (because a malicious library may have installed malware in the container's OS components, e.g. via shell commands), but it may be effective against script-kiddy-level exfiltration.

mfhepp commented 1 year ago

Regarding Python Runtime Audit Hooks, the examples from https://blog.jerrycodes.com/sneak-peek-python-3-8/ would already get us pretty far (slightly modified):

import sys

import requests

def audit(event, args):
    if 'socket' in event:
        print(f'WARNING: Outbound network operation: event={event}, args={args}')

def get_some_URL():
    return requests.get('https://en.wikipedia.org/wiki/Python_(programming_language)')

sys.addaudithook(audit)
get_some_URL()

The question is if this can me made so that it will also catch network events started by shell commands from Python, like

import os

os.system('curl -I https://www.nytimes.com')

and such that use shell commands to add malicious activities to other component, or during the installation of libraries (though this would mostly take place only during the build of the image, where no access to the local file system will be granted).

TBC

mfhepp commented 1 year ago

Proposal:

  1. Define a list of events that should be reported (the full list of Python audit events is here.
  2. Register audit hook for those.
  3. Inside the hook, either send a message to the logger or optionally block actions (e.g. any non-whitelisted IP).
mfhepp commented 1 year ago

A few more thoughts: