diff options
-rw-r--r-- | RELNOTES | 1 | ||||
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/main.c | 21 | ||||
-rw-r--r-- | src/firejail/network.c | 70 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 3 | ||||
-rw-r--r-- | src/firejail/usage.c | 1 | ||||
-rw-r--r-- | src/man/firejail.txt | 10 |
7 files changed, 107 insertions, 1 deletions
@@ -2,6 +2,7 @@ firejail (0.9.37) baseline; urgency=low | |||
2 | * development version | 2 | * development version |
3 | * security profiles fixes | 3 | * security profiles fixes |
4 | * dynamic allocation of noblacklist buffer | 4 | * dynamic allocation of noblacklist buffer |
5 | * --ip6 option - IPv6 support | ||
5 | -- netblue30 <netblue30@yahoo.com> | 6 | -- netblue30 <netblue30@yahoo.com> |
6 | 7 | ||
7 | firejail (0.9.36) baseline; urgency=low | 8 | firejail (0.9.36) baseline; urgency=low |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 3ffb2b527..15110607d 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -75,6 +75,7 @@ typedef struct bridge_t { | |||
75 | // inside the sandbox | 75 | // inside the sandbox |
76 | char *devsandbox; // name of the device inside the sandbox | 76 | char *devsandbox; // name of the device inside the sandbox |
77 | uint32_t ipsandbox; // ip address inside the sandbox | 77 | uint32_t ipsandbox; // ip address inside the sandbox |
78 | char *ip6sandbox; // ipv6 address inside the sandbox | ||
78 | uint8_t macsandbox[6]; // mac address inside the sandbox | 79 | uint8_t macsandbox[6]; // mac address inside the sandbox |
79 | uint32_t iprange_start;// iprange arp scan start range | 80 | uint32_t iprange_start;// iprange arp scan start range |
80 | uint32_t iprange_end; // iprange arp scan end range | 81 | uint32_t iprange_end; // iprange arp scan end range |
@@ -251,6 +252,7 @@ void net_dns_print(pid_t pid); | |||
251 | void net_if_up(const char *ifname); | 252 | void net_if_up(const char *ifname); |
252 | void net_if_down(const char *ifname); | 253 | void net_if_down(const char *ifname); |
253 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu); | 254 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu); |
255 | void net_if_ip6(const char *ifname, const char *addr6); | ||
254 | int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu); | 256 | int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu); |
255 | int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw); | 257 | int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw); |
256 | void net_ifprint(void); | 258 | void net_ifprint(void); |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 3f7a26b64..7b493a351 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -1095,6 +1095,27 @@ int main(int argc, char **argv) { | |||
1095 | } | 1095 | } |
1096 | } | 1096 | } |
1097 | } | 1097 | } |
1098 | else if (strncmp(argv[i], "--ip6=", 6) == 0) { | ||
1099 | Bridge *br = last_bridge_configured(); | ||
1100 | if (br == NULL) { | ||
1101 | fprintf(stderr, "Error: no network device configured\n"); | ||
1102 | return 1; | ||
1103 | } | ||
1104 | if (br->arg_ip_none || br->ip6sandbox) { | ||
1105 | fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n"); | ||
1106 | return 1; | ||
1107 | } | ||
1108 | |||
1109 | // configure this IP address for the last bridge defined | ||
1110 | // todo: verify ipv6 syntax | ||
1111 | br->ip6sandbox = argv[i] + 6; | ||
1112 | // if (atoip(argv[i] + 5, &br->ipsandbox)) { | ||
1113 | // fprintf(stderr, "Error: invalid IP address\n"); | ||
1114 | // return 1; | ||
1115 | // } | ||
1116 | } | ||
1117 | |||
1118 | |||
1098 | else if (strncmp(argv[i], "--defaultgw=", 12) == 0) { | 1119 | else if (strncmp(argv[i], "--defaultgw=", 12) == 0) { |
1099 | if (atoip(argv[i] + 12, &cfg.defaultgw)) { | 1120 | if (atoip(argv[i] + 12, &cfg.defaultgw)) { |
1100 | fprintf(stderr, "Error: invalid IP address\n"); | 1121 | fprintf(stderr, "Error: invalid IP address\n"); |
diff --git a/src/firejail/network.c b/src/firejail/network.c index ece406fc8..72bc5e7c6 100644 --- a/src/firejail/network.c +++ b/src/firejail/network.c | |||
@@ -274,7 +274,75 @@ void net_if_down(const char *ifname) { | |||
274 | close(sock); | 274 | close(sock); |
275 | } | 275 | } |
276 | 276 | ||
277 | // configure interface | 277 | struct ifreq6 { |
278 | struct in6_addr ifr6_addr; | ||
279 | uint32_t ifr6_prefixlen; | ||
280 | unsigned int ifr6_ifindex; | ||
281 | }; | ||
282 | // configure interface ipv6 address | ||
283 | // ex: firejail --net=eth0 --ip6=2001:0db8:0:f101::1/64 | ||
284 | void net_if_ip6(const char *ifname, const char *addr6) { | ||
285 | if (strchr(addr6, ':') == NULL) { | ||
286 | fprintf(stderr, "Error: invalid IPv6 address %s\n", addr6); | ||
287 | exit(1); | ||
288 | } | ||
289 | |||
290 | // extract prefix | ||
291 | unsigned long prefix; | ||
292 | char *ptr; | ||
293 | if ((ptr = strchr(addr6, '/'))) { | ||
294 | prefix = atol(ptr + 1); | ||
295 | if ((prefix < 0) || (prefix > 128)) { | ||
296 | fprintf(stderr, "Error: invalid prefix for IPv6 address %s\n", addr6); | ||
297 | exit(1); | ||
298 | } | ||
299 | *ptr = '\0'; // mark the end of the address | ||
300 | } | ||
301 | else | ||
302 | prefix = 128; | ||
303 | |||
304 | // extract address | ||
305 | struct sockaddr_in6 sin6; | ||
306 | memset(&sin6, 0, sizeof(sin6)); | ||
307 | sin6.sin6_family = AF_INET6; | ||
308 | int rv = inet_pton(AF_INET6, addr6, sin6.sin6_addr.s6_addr); | ||
309 | if (rv <= 0) { | ||
310 | fprintf(stderr, "Error: invalid IPv6 address %s\n", addr6); | ||
311 | exit(1); | ||
312 | } | ||
313 | |||
314 | // open socket | ||
315 | int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP); | ||
316 | if (sock < 0) { | ||
317 | fprintf(stderr, "Error: IPv6 is not supported on this system\n"); | ||
318 | exit(1); | ||
319 | } | ||
320 | |||
321 | // find interface index | ||
322 | struct ifreq ifr; | ||
323 | memset(&ifr, 0, sizeof(ifr)); | ||
324 | strncpy(ifr.ifr_name, ifname, IFNAMSIZ); | ||
325 | ifr.ifr_addr.sa_family = AF_INET; | ||
326 | if (ioctl(sock, SIOGIFINDEX, &ifr) < 0) { | ||
327 | perror("ioctl SIOGIFINDEX"); | ||
328 | exit(1); | ||
329 | } | ||
330 | |||
331 | // configure address | ||
332 | struct ifreq6 ifr6; | ||
333 | memset(&ifr6, 0, sizeof(ifr6)); | ||
334 | ifr6.ifr6_prefixlen = prefix; | ||
335 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; | ||
336 | memcpy((char *) &ifr6.ifr6_addr, (char *) &sin6.sin6_addr, sizeof(struct in6_addr)); | ||
337 | if (ioctl(sock, SIOCSIFADDR, &ifr6) < 0) { | ||
338 | perror("ioctl SIOCSIFADDR"); | ||
339 | exit(1); | ||
340 | } | ||
341 | |||
342 | close(sock); | ||
343 | } | ||
344 | |||
345 | // configure interface ipv4 address | ||
278 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) { | 346 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) { |
279 | if (strlen(ifname) > IFNAMSIZ) { | 347 | if (strlen(ifname) > IFNAMSIZ) { |
280 | fprintf(stderr, "Error: invalid network device name %s\n", ifname); | 348 | fprintf(stderr, "Error: invalid network device name %s\n", ifname); |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 25662d90e..ac0f62dab 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -107,6 +107,9 @@ static void sandbox_if_up(Bridge *br) { | |||
107 | net_if_ip(dev, br->ipsandbox, br->mask, br->mtu); | 107 | net_if_ip(dev, br->ipsandbox, br->mask, br->mtu); |
108 | net_if_up(dev); | 108 | net_if_up(dev); |
109 | } | 109 | } |
110 | |||
111 | if (br->ip6sandbox) | ||
112 | net_if_ip6(dev, br->ip6sandbox); | ||
110 | } | 113 | } |
111 | 114 | ||
112 | static void chk_chroot(void) { | 115 | static void chk_chroot(void) { |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index e4a5f1ff0..5eab05076 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -106,6 +106,7 @@ void usage(void) { | |||
106 | printf("\t--ip=none - no IP address and no default gateway address are configured\n"); | 106 | printf("\t--ip=none - no IP address and no default gateway address are configured\n"); |
107 | printf("\t\tin the new network namespace. Use this option in case you intend\n"); | 107 | printf("\t\tin the new network namespace. Use this option in case you intend\n"); |
108 | printf("\t\tto start an external DHCP client in the sandbox.\n\n"); | 108 | printf("\t\tto start an external DHCP client in the sandbox.\n\n"); |
109 | printf("\t--ip6=address - set interface IPv6 address.\n\n"); | ||
109 | printf("\t--iprange=address,address - configure an IP address in this range\n\n"); | 110 | printf("\t--iprange=address,address - configure an IP address in this range\n\n"); |
110 | printf("\t--ipc-namespace - enable a new IPC namespace if the sandbox was started\n"); | 111 | printf("\t--ipc-namespace - enable a new IPC namespace if the sandbox was started\n"); |
111 | printf("\t\tas a regular user. IPC namespace is enabled by default only if\n"); | 112 | printf("\t\tas a regular user. IPC namespace is enabled by default only if\n"); |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 9f834011e..c8dd7d786 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -462,6 +462,16 @@ Example: | |||
462 | $ firejail \-\-net=eth0 \-\-\ip=none | 462 | $ firejail \-\-net=eth0 \-\-\ip=none |
463 | 463 | ||
464 | .TP | 464 | .TP |
465 | \fB\-\-ip6=address | ||
466 | Assign IPv6 addresses to the last network interface defined by a \-\-net option. | ||
467 | .br | ||
468 | |||
469 | .br | ||
470 | Example: | ||
471 | .br | ||
472 | $ firejail \-\-net=eth0 \-\-ip6=2001:0db8:0:f101::1/64 firefox | ||
473 | |||
474 | .TP | ||
465 | \fB\-\-iprange=address,address | 475 | \fB\-\-iprange=address,address |
466 | Assign an IP address in the provided range to the last network interface defined by a \-\-net option. A | 476 | Assign an IP address in the provided range to the last network interface defined by a \-\-net option. A |
467 | default gateway is assigned by default. | 477 | default gateway is assigned by default. |