forked from mirrors/nixpkgs
895bcdd1cb
For example, the following sets up a container named ‘foo’. The container will have a single network interface eth0, with IP address 10.231.136.2. The host will have an interface c-foo with IP address 10.231.136.1. systemd.containers.foo = { privateNetwork = true; hostAddress = "10.231.136.1"; localAddress = "10.231.136.2"; config = { services.openssh.enable = true; }; }; With ‘privateNetwork = true’, the container has the CAP_NET_ADMIN capability, allowing it to do arbitrary network configuration, such as setting up firewall rules. This is secure because it cannot touch the interfaces of the host. The helper program ‘run-in-netns’ is needed at the moment because ‘ip netns exec’ doesn't quite do the right thing (it remounts /sys without bind-mounting the original /sys/fs/cgroups).
51 lines
1.2 KiB
C
51 lines
1.2 KiB
C
#define _GNU_SOURCE
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
#include <sched.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/mount.h>
|
|
#include <fcntl.h>
|
|
#include <linux/limits.h>
|
|
|
|
int main(int argc, char * * argv)
|
|
{
|
|
if (argc < 3) {
|
|
fprintf(stderr, "%s: missing arguments\n", argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
char nsPath[PATH_MAX];
|
|
|
|
sprintf(nsPath, "/run/netns/%s", argv[1]);
|
|
|
|
int fd = open(nsPath, O_RDONLY);
|
|
if (fd == -1) {
|
|
fprintf(stderr, "%s: opening network namespace: %s\n", argv[0], strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
if (setns(fd, CLONE_NEWNET) == -1) {
|
|
fprintf(stderr, "%s: setting network namespace: %s\n", argv[0], strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
umount2(nsPath, MNT_DETACH);
|
|
if (unlink(nsPath) == -1) {
|
|
fprintf(stderr, "%s: unlinking network namespace: %s\n", argv[0], strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
/* FIXME: Remount /sys so that /sys/class/net reflects the
|
|
interfaces visible in the network namespace. This requires
|
|
bind-mounting /sys/fs/cgroups etc. */
|
|
|
|
execv(argv[2], argv + 2);
|
|
fprintf(stderr, "%s: running command: %s\n", argv[0], strerror(errno));
|
|
return 1;
|
|
}
|