diff --git a/Makefile b/Makefile index 38fd7d4..c5ed40e 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,19 @@ CC := gcc ROOTFSIMAGE := alpine-minirootfs-3.15.0-x86_64.tar.gz ROOTFSIMAGEURL := https://dl-cdn.alpinelinux.org/alpine/v3.15/releases/x86_64/alpine-minirootfs-3.15.0-x86_64.tar.gz +# Colors +NONE := \033[00m +RED := \033[01;31m +GREEN := \033[01;32m +YELLOW := \033[01;33m +BLUE := \033[01;34m +PURPLE := \033[01;35m +CYAN := \033[01;36m +WHITE := \033[01;37m +BOLD := \033[1m +BLINK := \033[5m +UNDERLINE := \033[4m + # Target Binary TARGET := isolate USERNS := userns @@ -33,40 +46,40 @@ all: rootfs utils pidns mountns mountns userns networkns $(TARGET) rootfs: @$(RM) -rf $(ROOTFSIMAGE) $(ROOTFSDIR) @mkdir -p $(ROOTFSDIR) - @echo "[+] Fetching Alpine rootfs image" && wget -q --show-progress $(ROOTFSIMAGEURL) -O $(ROOTFSIMAGE) - @echo "[+] Extracting Rootfs" && tar -xzf $(ROOTFSIMAGE) -C $(ROOTFSDIR) && echo "Done!" + @echo -e "[+] Fetching $(GREEN)Rootfs$(NONE) tarball" && wget -q --no-check-certificate --show-progress $(ROOTFSIMAGEURL) -O $(ROOTFSIMAGE) + @echo "[+] Extracting $(CYAN)Rootfs$(NONE)" && tar -xzf $(ROOTFSIMAGE) -C $(ROOTFSDIR) && echo "Done!" @$(RM) -rf $(ROOTFSIMAGE) utils: $(SRCDIR)/$(UTILS).c - @echo "[+] Compiling Program Utils" + @echo -e "[+] Compiling $(YELLOW)Program Utils$(NONE)" @mkdir -p $(OBJDIR) $(CC) $(CFLAGS) -I ${INCDIR} -c -o $(OBJDIR)/$(UTILS).o $(SRCDIR)/$(UTILS).c pidns: $(SRCDIR)/$(PIDNS).c @mkdir -p $(OBJDIR) - @echo "[+] Compiling PID Namespace Program" + @echo -e "[+] Compiling $(RED)PID$(NONE) Namespace Program" $(CC) $(CFLAGS) -I ${INCDIR} -c -o $(OBJDIR)/$(PIDNS).o $(SRCDIR)/$(PIDNS).c mountns: $(SRCDIR)/$(MOUNTNS).c @mkdir -p $(OBJDIR) - @echo "[+] Compiling Mount Namespace Program" + @echo -e "[+] Compiling $(PURPLE)MOUNT$(NONE) Namespace Program" $(CC) $(CFLAGS) -I ${INCDIR} -c -o $(OBJDIR)/$(MOUNTNS).o $(SRCDIR)/$(MOUNTNS).c userns: $(SRCDIR)/$(USERNS).c @mkdir -p $(OBJDIR) - @echo "[+] Compiling User Namespace Program" + @echo -e "[+] Compiling $(BLUE)USER$(NONE) Namespace Program" $(CC) $(CFLAGS) -I ${INCDIR} -c -o $(OBJDIR)/$(USERNS).o $(SRCDIR)/$(USERNS).c networkns: $(SRCDIR)/$(NETNS).c @mkdir -p $(OBJDIR) - @echo "[+] Compiling Network Namespace Program" + @echo -e "[+] Compiling $(CYAN)NETWORK$(NONE) Namespace Program" $(CC) $(CFLAGS) -I ${INCDIR} -I ${LIBNL} -c -o $(OBJDIR)/$(NETNS).o $(SRCDIR)/$(NETNS).c $(LDFLAGS) $(TARGET): $(SRCDIR)/$(TARGET).c $(OBJDIR)/$(USERNS).o $(OBJDIR)/$(MOUNTNS).o $(OBJDIR)/$(UTILS).o - @echo "[+] Compiling" + @echo -e "[+] Compiling $(GREEN)$(UNDERLINE)$(TARGET)$(NONE) program" $(CC) $(CFLAGS) -I ${INCDIR} -c -o $(OBJDIR)/$(TARGET).o $(SRCDIR)/$(TARGET).c $(CC) $(CFLAGS) $(OBJDIR)/$(USERNS).o $(OBJDIR)/$(MOUNTNS).o $(OBJDIR)/$(TARGET).o $(OBJDIR)/$(UTILS).o $(OBJDIR)/$(PIDNS).o $(OBJDIR)/$(NETNS).o $(LDFLAGS) -o $(TARGET) @@ -76,3 +89,4 @@ $(TARGET): $(SRCDIR)/$(TARGET).c $(OBJDIR)/$(USERNS).o $(OBJDIR)/$(MOUNTNS).o $( #Clean only Objecst clean: @$(RM) -rf $(TARGET) $(ROOTFSDIR) $(OBJDIR) + @echo -e "[-] $(RED)$(BOLD)Cleanup Done$(NONE)!" diff --git a/README.md b/README.md index 53fc354..78a3408 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,11 @@

Why use Docker when you can just is0lat3?

Run a process in separate Namespaces to provide isolation for the processes. Namespaces isolation implemented so far: -- `uts`: Unix Timesharing (UTS) namespaces provide isolation for the hostname and domain name. +- `uts` +- `user` +- `network` +- `pid` +-`mount` ## How to compile? ```bash @@ -58,4 +62,4 @@ $ make clean # To-Do - Add routing inside Name-space -- COnfigure IP Tables to allow internet access \ No newline at end of file +- Configure IP Tables to allow internet access \ No newline at end of file diff --git a/include/networkns.h b/include/networkns.h index 37c4c52..b4eec38 100644 --- a/include/networkns.h +++ b/include/networkns.h @@ -10,9 +10,11 @@ #define IP0 "10.1.1.1" // IP address associated with VETH0 #define IP1 "10.1.1.2" // IP address associated with VETH1 #define NETMASK "255.255.255.0" // Netmask of our virtual network +#define METRICS 201 // Metrics for routing int prepare_networkns(int child_pid); int interface_up(char *ifname, char *ip, char *netmask, short if_flags); int ns_fd(int pid); +int add_route(); int create_veth(int child_pid); #endif \ No newline at end of file diff --git a/src/mountns.c b/src/mountns.c index 399af19..8f930dd 100644 --- a/src/mountns.c +++ b/src/mountns.c @@ -43,6 +43,7 @@ int prepare_mountns(void){ //prepare proc fs if (prepare_pidns() != 0){ + fprintf(stderr,"[" RED("!") "] Could not prepare "RED("PID")" namespace\n"); return -1; } fprintf(stdout,"[" GREEN("i") "] Successfully created " GREEN("PID") " namespace\n"); diff --git a/src/networkns.c b/src/networkns.c index 8f2955d..74c489c 100644 --- a/src/networkns.c +++ b/src/networkns.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "networkns.h" #include "utils.h" @@ -104,6 +106,40 @@ int interface_up(char *ifname, char *ip, char *netmask, short if_flags){ } +// Add routing table +int add_route(){ + //See: https://stackoverflow.com/questions/22733967/linux-how-to-set-default-route-from-c + int sockfd; + struct rtentry route; + struct sockaddr_in *addr; + int err = 0; + + // create the socket + if((sockfd = socket(AF_INET, SOCK_DGRAM, 0))<0){ + fprintf(stderr,"["RED("!")"] Could not create socket\n"); + return -1; + } + + memset(&route, 0, sizeof(route)); + addr = (struct sockaddr_in*) &route.rt_gateway; + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = inet_addr(IP0); + addr = (struct sockaddr_in*) &route.rt_dst; + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + addr = (struct sockaddr_in*) &route.rt_genmask; + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + route.rt_flags = RTF_UP | RTF_GATEWAY; + route.rt_metric = METRICS; + route.rt_dev = VETH1; + if ((err = ioctl(sockfd, SIOCADDRT, &route)) != 0) { + fprintf(stderr,"["RED("!")"] " RED("SIOCADDRT")" failed\n"); + return -1; + } + return 0; +} + // Get a file descriptor inside a namespace int ns_fd(int pid){ char *path; @@ -159,6 +195,10 @@ int prepare_networkns(int child_pid){ fprintf(stderr, "["RED("!")"] Could not setup %s interface\n", VETH1); return -1; } + if (add_route() != 0){ + fprintf(stderr, "["RED("!")"] Failed to add route\n"); + return -1; + } // See man setns(2) if (setns(host_fd, CLONE_NEWNET) < 0){