From a8abd88081fabbc9590dd33d413cd0a0641ef642 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Fri, 6 Jul 2018 09:34:52 -0400 Subject: --netmask option --- README.md | 13 ++++++++++ RELNOTES | 4 ++++ src/firejail/firejail.h | 1 + src/firejail/main.c | 32 +++++++++++++++++++++++++ src/firejail/network_main.c | 57 ++++++++++++++++++++++++++++++-------------- src/firejail/profile.c | 34 ++++++++++++++++++++++++++ src/firejail/usage.c | 2 ++ src/man/firejail-profile.txt | 6 +++++ src/man/firejail.txt | 25 +++++++++++++++---- 9 files changed, 151 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 15234f80f..616930e8a 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,19 @@ We also keep a list of profile fixes for previous released versions in [etc-fixe $ firejail --net=eth0 --ip=192.168.1.80 --dns=8.8.8.8 firefox $ firejail --net=wlan0 firefox + --netmask=address + Use this option when you want to assign an IP address in a new + namespace and the parent interface specified by --net is not + configured. An IP address and a default gateway address + also have to be added. By default the new namespace interface + comes without IP address and default gateway configured. Exam‐ + ple: + + $ sudo /sbin/brctl addbr br0 + $ sudo /sbin/ifconfig br0 up + $ firejail --ip=10.10.20.67 --netmask=255.255.255.0 + --defaultgw=10.10.20.1 + --nou2f Disable U2F devices. diff --git a/RELNOTES b/RELNOTES index 979633aef..e5c9b0fc1 100644 --- a/RELNOTES +++ b/RELNOTES @@ -1,6 +1,10 @@ firejail (0.9.55) baseline; urgency=low * work in progress * modif: removed CFG_CHROOT_DESKTOP configuration option + * support wireless devices in --net option + * allow IP address configuration if the parent interface specified + by --net is not configured (--netmask) + * disable U2F devices (--nou2f) * add --private-cache to support private ~/.cache * support full paths in private-lib * globbing support in private-lib diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index f554c8ddf..7a711cef3 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -166,6 +166,7 @@ typedef struct bridge_t { // inside the sandbox char *devsandbox; // name of the device inside the sandbox uint32_t ipsandbox; // ip address inside the sandbox + uint32_t masksandbox; // network mask inside the sandbox char *ip6sandbox; // ipv6 address inside the sandbox uint8_t macsandbox[6]; // mac address inside the sandbox uint32_t iprange_start;// iprange arp scan start range diff --git a/src/firejail/main.c b/src/firejail/main.c index 50b2da7b9..c57e5910a 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -1980,6 +1980,38 @@ int main(int argc, char **argv) { exit_err_feature("networking"); } + else if (strncmp(argv[i], "--netmask=", 10) == 0) { + if (checkcfg(CFG_NETWORK)) { + Bridge *br = last_bridge_configured(); + if (br == NULL) { + fprintf(stderr, "Error: no network device configured\n"); + exit(1); + } + if (br->arg_ip_none || br->masksandbox) { + fprintf(stderr, "Error: cannot configure the network mask twice for the same interface\n"); + exit(1); + } + + // configure this network mask for the last bridge defined + if (atoip(argv[i] + 10, &br->masksandbox)) { + fprintf(stderr, "Error: invalid network mask\n"); + exit(1); + } + + // if the bridge is not configured, use this mask as the bridge mask + if (br->mask == 0) + br->mask = br->masksandbox; + else { + fprintf(stderr, "Error: interface %s already has a network mask defined; " + "please remove --netmask\n", + br->dev); + exit(1); + } + } + else + exit_err_feature("networking"); + } + else if (strncmp(argv[i], "--ip6=", 6) == 0) { if (checkcfg(CFG_NETWORK)) { Bridge *br = last_bridge_configured(); diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c index 1516b94d2..488615bda 100644 --- a/src/firejail/network_main.c +++ b/src/firejail/network_main.c @@ -61,25 +61,27 @@ void net_configure_bridge(Bridge *br, char *dev_name) { // allow unconfigured interfaces if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) { fwarning("the network interface %s is not configured\n", br->dev); - br->configured = 1; - br->arg_ip_none = 1; - return; - } - if (arg_debug) { - if (br->macvlan == 0) - printf("Bridge device %s at %d.%d.%d.%d/%d\n", - br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); - else - printf("macvlan parent device %s at %d.%d.%d.%d/%d\n", - br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); +// don't configure an ip address on unconfigured interfaces +// br->arg_ip_none = 1; } + else { + if (arg_debug) { + if (br->macvlan == 0) + printf("Bridge device %s at %d.%d.%d.%d/%d\n", + br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); + else + printf("macvlan parent device %s at %d.%d.%d.%d/%d\n", + br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); + } - uint32_t range = ~br->mask + 1; // the number of potential addresses - // this software is not supported for /31 networks - if (range < 4) { - fprintf(stderr, "Error: the software is not supported for /31 networks\n"); - exit(1); + uint32_t range = ~br->mask + 1; // the number of potential addresses + // this software is not supported for /31 networks + if (range < 4) { + fprintf(stderr, "Error: the software is not supported for /31 networks\n"); + exit(1); + } } + br->configured = 1; } @@ -91,7 +93,7 @@ void net_configure_sandbox_ip(Bridge *br) { if (br->arg_ip_none) br->ipsandbox = 0; - else if (br->ipsandbox) { + else if (br->ipsandbox && br->ip && br->mask) { // check network range char *rv = in_netrange(br->ipsandbox, br->ip, br->mask); if (rv) { @@ -104,9 +106,20 @@ void net_configure_sandbox_ip(Bridge *br) { exit(1); } } - else + else if (br->ipsandbox && br->masksandbox) { + // send an ARP request and check if there is anybody on this IP address + if (arp_check(br->dev, br->ipsandbox)) { + fprintf(stderr, "Error: IP address %d.%d.%d.%d is already in use\n", PRINT_IP(br->ipsandbox)); + exit(1); + } + } + else if (br->ip && br->mask) // ip address assigned by arp-scan for a bridge device br->ipsandbox = arp_assign(br->dev, br); //br->ip, br->mask); + else { + br->ipsandbox = 0; + br->arg_ip_none = 1; + } } @@ -148,21 +161,29 @@ void check_default_gw(uint32_t defaultgw) { assert(defaultgw); if (cfg.bridge0.configured) { + if (cfg.bridge0.ip == 0 && cfg.bridge0.ipsandbox) + return; char *rv = in_netrange(defaultgw, cfg.bridge0.ip, cfg.bridge0.mask); if (rv == 0) return; } if (cfg.bridge1.configured) { + if (cfg.bridge1.ip == 0 && cfg.bridge1.ipsandbox) + return; char *rv = in_netrange(defaultgw, cfg.bridge1.ip, cfg.bridge1.mask); if (rv == 0) return; } if (cfg.bridge2.configured) { + if (cfg.bridge2.ip == 0 && cfg.bridge2.ipsandbox) + return; char *rv = in_netrange(defaultgw, cfg.bridge2.ip, cfg.bridge2.mask); if (rv == 0) return; } if (cfg.bridge3.configured) { + if (cfg.bridge3.ip == 0 && cfg.bridge3.ipsandbox) + return; char *rv = in_netrange(defaultgw, cfg.bridge3.ip, cfg.bridge3.mask); if (rv == 0) return; diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 22db6f5fb..fc575d4b5 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -481,6 +481,40 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { return 0; } + else if (strncmp(ptr, "netmask ", 8) == 0) { +#ifdef HAVE_NETWORK + if (checkcfg(CFG_NETWORK)) { + Bridge *br = last_bridge_configured(); + if (br == NULL) { + fprintf(stderr, "Error: no network device configured\n"); + exit(1); + } + if (br->arg_ip_none || br->masksandbox) { + fprintf(stderr, "Error: cannot configure the network mask twice for the same interface\n"); + exit(1); + } + + // configure this network mask for the last bridge defined + if (atoip(ptr + 8, &br->masksandbox)) { + fprintf(stderr, "Error: invalid network mask\n"); + exit(1); + } + + // if the bridge is not configured, use this mask as the bridge mask + if (br->mask == 0) + br->mask = br->masksandbox; + else { + fprintf(stderr, "Error: interface %s already has a network mask defined; " + "please remove --netmask\n", + br->dev); + exit(1); + } + } + else + warning_feature_disabled("networking"); +#endif + return 0; + } else if (strncmp(ptr, "ip ", 3) == 0) { #ifdef HAVE_NETWORK if (checkcfg(CFG_NETWORK)) { diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 0289278d2..d9ce96f10 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c @@ -120,6 +120,8 @@ static char *usage_str = " --netfilter.print=name|pid - print the firewall.\n" " --netfilter6=filename - enable IPv6 firewall.\n" " --netfilter6.print=name|pid - print the IPv6 firewall.\n" + " --netmask=address - define a network mask when dealing with unconfigured" + "\tparrent interfaces.\n" " --netns=name - Run the program in a named, persistent network namespace.\n" " --netstats - monitor network statistics.\n" #endif diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 59f15f75c..50455b038 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt @@ -604,6 +604,12 @@ available in the new namespace is a new loopback interface (lo). Use this option to deny network access to programs that don't really need network access. +.TP +\fBnetmask address +Use this option when you want to assign an IP address in a new namespace and +the parent interface specified by --net is not configured. An IP address and +a default gateway address also have to be added. + .TP \fBveth-name name Use this name for the interface connected to the bridge for --net=bridge_interface commands, diff --git a/src/man/firejail.txt b/src/man/firejail.txt index d527c05d8..24d4bbd8c 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -823,11 +823,6 @@ $ firejail \-\-net=none vlc Note: \-\-net=none can crash the application on some platforms. In these cases, it can be replaced with \-\-protocol=unix. -.TP -\fB\-\-netns=name -Run the program in a named, persistent network namespace. These can -be created and configured using "ip netns". - .TP \fB\-\-netfilter Enable a default firewall if a new network namespace is created inside the sandbox. @@ -954,6 +949,26 @@ $ firejail --name=browser --net=eth0 --netfilter firefox & .br $ firejail --netfilter6.print=browser +.TP +\fB\-\-netmask=address +Use this option when you want to assign an IP address in a new namespace and +the parent interface specified by --net is not configured. An IP address and +a default gateway address also have to be added. By default the new namespace +interface comes without IP address and default gateway configured. Example: +.br + +.br +$ sudo /sbin/brctl addbr br0 +.br +$ sudo /sbin/ifconfig br0 up +.br +$ firejail --ip=10.10.20.67 --netmask=255.255.255.0 --defaultgw=10.10.20.1 + +.TP +\fB\-\-netns=name +Run the program in a named, persistent network namespace. These can +be created and configured using "ip netns". + .TP \fB\-\-netstats Monitor network namespace statistics, see \fBMONITORING\fR section for more details. -- cgit v1.2.3-54-g00ecf