~mser/pkg.mser.at

4d5a99c4899e000b973dd9fd7185a19e5639118b — cryzed 2 years ago d99c8fe
Try to use existing cgroup2 mount
2 files changed, 23 insertions(+), 8 deletions(-)

M packages/unshare-net/PKGBUILD
M packages/unshare-net/unshare-net
M packages/unshare-net/PKGBUILD => packages/unshare-net/PKGBUILD +2 -2
@@ 1,6 1,6 @@
# Maintainer: Michael Serajnik <m at mser dot at>
pkgname=unshare-net
pkgver=8
pkgver=9
pkgrel=1
pkgdesc="Selectively whitelist traffic to specified IPs and domains for target applications"
arch=("any")


@@ 8,7 8,7 @@ url="https://git.sr.ht/~mser/pkg.mser.at/tree/master/item/packages/unshare-net"
license=("AGPL3")
depends=("python")
source=("unshare-net")
sha512sums=('ec5ddabf897dee47304f2f418cefc095256cc89d5663773de4c0db91b02311b781bcd52c4d303d6e56c2b11b4ba751065b2340d1775398763deeff673aa67afc')
sha512sums=('9a8645754b8775ab1246d51a51c7609e302dcbfdf0df5bc65b70d3bf9502a4ddc8bd25bbb2429953565ad10665f1962ed2a49f4edbb50c7aecebf1a34dabc053')

package() {
  install -D --mode 755 "${srcdir}/unshare-net" --target-directory "${pkgdir}/usr/bin"

M packages/unshare-net/unshare-net => packages/unshare-net/unshare-net +21 -6
@@ 111,6 111,12 @@ def umount(path: pathlib.Path) -> subprocess.CompletedProcess:
    return run_command(("umount", str(path)), check=True)


def find_cgroup_mount_path() -> T.Optional[pathlib.Path]:
    process = run_command(("mount", "--types", "cgroup2"), capture_output=True, check=True, text=True)
    mounts = process.stdout.splitlines()
    return pathlib.Path(mounts[0].split(" on ", 1)[1].split(" type ", 1)[0]) if mount else None


def get_identifier() -> str:
    time_hash = hashlib.md5(str(time.time()).encode("ascii")).hexdigest()
    return f"unshare-net-{time_hash}"[:IPTABLES_MAX_CHAIN_NAME_LENGTH]


@@ 132,10 138,17 @@ def run(arguments: argparse.Namespace, command: list[str]) -> ExitCode:
        stderr("Not allowed to run target as root!")
        return ExitCode.FAILURE

    # Try to find an existing cgroup2 mount path
    cgroup_mount_path = find_cgroup_mount_path()
    cgroup_mount_created = False
    identifier = get_identifier()
    cgroup_mount_path = pathlib.Path(tempfile.mkdtemp(prefix="unshare-net-"))
    stderr(f"created {str(cgroup_mount_path)!r}")
    mount("--types", "cgroup2", "none", str(cgroup_mount_path))
    if not cgroup_mount_path:
        cgroup_mount_path = pathlib.Path(tempfile.mkdtemp(prefix="unshare-net-"))
        stderr(f"created {str(cgroup_mount_path)!r}")
        # These are the mount options by Arch Linux (systemd), so I assume they are fine
        mount("--types", "cgroup2", identifier, str(cgroup_mount_path), "--options", "defaults,nosuid,nodev,noexec")
        cgroup_mount_created = True

    cgroup_create(identifier, cgroup_mount_path)
    iptables_create_chain(identifier)
    iptables_create_chain(identifier, ipv6=True)


@@ 205,9 218,11 @@ def run(arguments: argparse.Namespace, command: list[str]) -> ExitCode:
    iptables_delete_chain(identifier)
    iptables_delete_chain(identifier, ipv6=True)
    cgroup_remove(identifier, cgroup_mount_path)
    umount(cgroup_mount_path)
    stderr(f"removing {str(cgroup_mount_path)!r}")
    cgroup_mount_path.rmdir()

    if cgroup_mount_created:
        stderr(f"removing {str(cgroup_mount_path)!r}")
        umount(cgroup_mount_path)
        cgroup_mount_path.rmdir()

    return ExitCode.SUCCESS