Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add local mount ns support to nsutil #499

Merged
merged 1 commit into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ name: release

on:
workflow_dispatch:
inputs:
inputs:
release_tag:
description: 'release tag'
required: true
release_title:
description: 'release title'
required: false
release_notes:
description: 'release notes'
description: 'release notes'
required: false
default: ''

Expand All @@ -22,6 +22,11 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
qemu-version: '6.0.0'

- name: Build go binary for pause
run : ./../../build/go-multiarch-build.sh "go build -o ./../../build/_output/pause-linux"
working-directory: custom/pause
Expand All @@ -30,15 +35,30 @@ jobs:
run : ./../../build/go-multiarch-build.sh "go build -o ./../../build/_output/nsutil-linux"
working-directory: custom/nsutil

- name: Build shared libraries for nsutil amd64
run: gcc -shared -fPIC nsutil.c -o ./../../build/_output/nsutil_amd64.so
working-directory: custom/nsutil

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Build arm64 Docker image
run: docker buildx build --platform linux/arm64 -t myapp-arm64 --load .
working-directory: custom/nsutil

- name: Extract compiled binary
run: docker create --name myapp-arm64-container myapp-arm64 && docker cp myapp-arm64-container:/app/nsutil.so ./../../build/_output/nsutil_arm64.so
working-directory: custom/nsutil

- name: Build go binary for promql-cli
run : |
cp custom/promql-cli/promql-linux-amd64 build/_output/
cp custom/promql-cli/promql-linux-arm64 build/_output/

- name: Build go binary for dns_interceptor
run : go build -o ./../../build/_output/dns_interceptor
working-directory: custom/dns_interceptor

- name: create release along with artifact
uses: ncipollo/release-action@v1
with:
Expand Down
3 changes: 3 additions & 0 deletions custom/hardened-alpine/experiment/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ RUN curl -L https://github.com/chaosnative/promql-cli/releases/download/3.0.0/pr
#Installing nsutil cli binaries
RUN curl -L https://github.com/litmuschaos/test-tools/releases/download/${LITMUS_VERSION}/nsutil-linux-${TARGETARCH} --output /usr/local/bin/nsutil && chmod +x /usr/local/bin/nsutil

#Installing nsutil shared lib
RUN curl -L https://github.com/litmuschaos/test-tools/releases/download/${LITMUS_VERSION}/nsutil-${TARGETARCH}.so --output /usr/local/lib/nsutil.so && chmod +x /usr/local/lib/nsutil.so

#Installing pause cli binaries
RUN curl -L https://github.com/litmuschaos/test-tools/releases/download/${LITMUS_VERSION}/pause-linux-${TARGETARCH} --output /usr/local/bin/pause && chmod +x /usr/local/bin/pause

Expand Down
13 changes: 13 additions & 0 deletions custom/nsutil/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM arm64v8/ubuntu:latest

# Install gcc for compiling C code
RUN apt-get update && apt-get install -y gcc

# Set the working directory
WORKDIR /app

# Copy your C code into the container
COPY nsutil.c /app

# Compile the C code
RUN gcc -shared -fPIC nsutil.c -o nsutil.so
17 changes: 12 additions & 5 deletions custom/nsutil/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import (
)

// user and mnt ns not supported
var ns = []string{"net", "pid", "cgroup", "uts", "ipc"}
var nsSelected = make([]bool, 6)

var t int // target pid
var (
ns = []string{"net", "pid", "cgroup", "uts", "ipc", "mnt"}
nsSelected = make([]bool, 7)
t int // target pid
libPath string
)

// rootCmd represents the base command
var rootCmd = &cobra.Command{
Expand All @@ -41,7 +43,9 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&nsSelected[2], "cgroup", "c", false, "cgroup namespace to enter")
rootCmd.PersistentFlags().BoolVarP(&nsSelected[3], "uts", "u", false, "uts namespace to enter")
rootCmd.PersistentFlags().BoolVarP(&nsSelected[4], "ipc", "i", false, "ipc namespace to enter")
rootCmd.PersistentFlags().BoolVarP(&nsSelected[5], "mnt", "m", false, "mnt namespace to enter")
rootCmd.PersistentFlags().IntVarP(&t, "target", "t", 0, "target process id (required)")
rootCmd.PersistentFlags().StringVar(&libPath, "lib-path", "/usr/local/lib/nsutil.so", "shared library path to be preloaded")
err := rootCmd.MarkPersistentFlagRequired("target")
if err != nil {
log.WithError(err).Fatal("Failed to mark required flag")
Expand All @@ -55,6 +59,9 @@ func nsutil(cmd *cobra.Command, args []string) {
// target command
nCmd := exec.Command(args[0], args[1:]...)
nCmd.Env = os.Environ()
if nsSelected[5] {
nCmd.Env = append(nCmd.Env, fmt.Sprintf("LD_PRELOAD=%s", libPath), fmt.Sprintf("MNT_PATH=%s", fmt.Sprintf("/proc/"+strconv.Itoa(t)+"/ns/mnt")))
}
nCmd.Stdin = os.Stdin
nCmd.Stdout = os.Stdout
nCmd.Stderr = os.Stderr
Expand Down Expand Up @@ -97,7 +104,7 @@ func nsutil(cmd *cobra.Command, args []string) {
func getNSFiles() map[string]*os.File {
nsMap := map[string]*os.File{}
for i, n := range ns {
if !nsSelected[i] {
if !nsSelected[i] || n == "mnt" {
continue
}
file, err := getFileFromNS("/proc/" + strconv.Itoa(t) + "/ns/" + n)
Expand Down
31 changes: 31 additions & 0 deletions custom/nsutil/nsutil.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
#include <sys/stat.h>

void nsenter() {
char *mnt_path = getenv("MNT_PATH");
if (mnt_path != NULL) {
int fd = open(mnt_path, O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}

int ns = setns(fd, 0);
if (ns == -1) {
perror("setns");
exit(EXIT_FAILURE);
}
}

unsetenv("LD_PRELOAD");
}

__attribute__((constructor)) void ctor() {
nsenter();
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ require (
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading