diff options
author | netblue30 <netblue30@yahoo.com> | 2018-07-06 09:34:52 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2018-07-06 09:34:52 -0400 |
commit | a8abd88081fabbc9590dd33d413cd0a0641ef642 (patch) | |
tree | 379295500c4b0d36e99a76e03c8ab9d73c0b6b68 /src | |
parent | Merge pull request #2033 from smitsohu/whitelist (diff) | |
download | firejail-a8abd88081fabbc9590dd33d413cd0a0641ef642.tar.gz firejail-a8abd88081fabbc9590dd33d413cd0a0641ef642.tar.zst firejail-a8abd88081fabbc9590dd33d413cd0a0641ef642.zip |
--netmask option
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 1 | ||||
-rw-r--r-- | src/firejail/main.c | 32 | ||||
-rw-r--r-- | src/firejail/network_main.c | 57 | ||||
-rw-r--r-- | src/firejail/profile.c | 34 | ||||
-rw-r--r-- | src/firejail/usage.c | 2 | ||||
-rw-r--r-- | src/man/firejail-profile.txt | 6 | ||||
-rw-r--r-- | src/man/firejail.txt | 25 |
7 files changed, 134 insertions, 23 deletions
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 { | |||
166 | // inside the sandbox | 166 | // inside the sandbox |
167 | char *devsandbox; // name of the device inside the sandbox | 167 | char *devsandbox; // name of the device inside the sandbox |
168 | uint32_t ipsandbox; // ip address inside the sandbox | 168 | uint32_t ipsandbox; // ip address inside the sandbox |
169 | uint32_t masksandbox; // network mask inside the sandbox | ||
169 | char *ip6sandbox; // ipv6 address inside the sandbox | 170 | char *ip6sandbox; // ipv6 address inside the sandbox |
170 | uint8_t macsandbox[6]; // mac address inside the sandbox | 171 | uint8_t macsandbox[6]; // mac address inside the sandbox |
171 | uint32_t iprange_start;// iprange arp scan start range | 172 | 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) { | |||
1980 | exit_err_feature("networking"); | 1980 | exit_err_feature("networking"); |
1981 | } | 1981 | } |
1982 | 1982 | ||
1983 | else if (strncmp(argv[i], "--netmask=", 10) == 0) { | ||
1984 | if (checkcfg(CFG_NETWORK)) { | ||
1985 | Bridge *br = last_bridge_configured(); | ||
1986 | if (br == NULL) { | ||
1987 | fprintf(stderr, "Error: no network device configured\n"); | ||
1988 | exit(1); | ||
1989 | } | ||
1990 | if (br->arg_ip_none || br->masksandbox) { | ||
1991 | fprintf(stderr, "Error: cannot configure the network mask twice for the same interface\n"); | ||
1992 | exit(1); | ||
1993 | } | ||
1994 | |||
1995 | // configure this network mask for the last bridge defined | ||
1996 | if (atoip(argv[i] + 10, &br->masksandbox)) { | ||
1997 | fprintf(stderr, "Error: invalid network mask\n"); | ||
1998 | exit(1); | ||
1999 | } | ||
2000 | |||
2001 | // if the bridge is not configured, use this mask as the bridge mask | ||
2002 | if (br->mask == 0) | ||
2003 | br->mask = br->masksandbox; | ||
2004 | else { | ||
2005 | fprintf(stderr, "Error: interface %s already has a network mask defined; " | ||
2006 | "please remove --netmask\n", | ||
2007 | br->dev); | ||
2008 | exit(1); | ||
2009 | } | ||
2010 | } | ||
2011 | else | ||
2012 | exit_err_feature("networking"); | ||
2013 | } | ||
2014 | |||
1983 | else if (strncmp(argv[i], "--ip6=", 6) == 0) { | 2015 | else if (strncmp(argv[i], "--ip6=", 6) == 0) { |
1984 | if (checkcfg(CFG_NETWORK)) { | 2016 | if (checkcfg(CFG_NETWORK)) { |
1985 | Bridge *br = last_bridge_configured(); | 2017 | 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) { | |||
61 | // allow unconfigured interfaces | 61 | // allow unconfigured interfaces |
62 | if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) { | 62 | if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) { |
63 | fwarning("the network interface %s is not configured\n", br->dev); | 63 | fwarning("the network interface %s is not configured\n", br->dev); |
64 | br->configured = 1; | 64 | // don't configure an ip address on unconfigured interfaces |
65 | br->arg_ip_none = 1; | 65 | // br->arg_ip_none = 1; |
66 | return; | ||
67 | } | ||
68 | if (arg_debug) { | ||
69 | if (br->macvlan == 0) | ||
70 | printf("Bridge device %s at %d.%d.%d.%d/%d\n", | ||
71 | br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); | ||
72 | else | ||
73 | printf("macvlan parent device %s at %d.%d.%d.%d/%d\n", | ||
74 | br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); | ||
75 | } | 66 | } |
67 | else { | ||
68 | if (arg_debug) { | ||
69 | if (br->macvlan == 0) | ||
70 | printf("Bridge device %s at %d.%d.%d.%d/%d\n", | ||
71 | br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); | ||
72 | else | ||
73 | printf("macvlan parent device %s at %d.%d.%d.%d/%d\n", | ||
74 | br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); | ||
75 | } | ||
76 | 76 | ||
77 | uint32_t range = ~br->mask + 1; // the number of potential addresses | 77 | uint32_t range = ~br->mask + 1; // the number of potential addresses |
78 | // this software is not supported for /31 networks | 78 | // this software is not supported for /31 networks |
79 | if (range < 4) { | 79 | if (range < 4) { |
80 | fprintf(stderr, "Error: the software is not supported for /31 networks\n"); | 80 | fprintf(stderr, "Error: the software is not supported for /31 networks\n"); |
81 | exit(1); | 81 | exit(1); |
82 | } | ||
82 | } | 83 | } |
84 | |||
83 | br->configured = 1; | 85 | br->configured = 1; |
84 | } | 86 | } |
85 | 87 | ||
@@ -91,7 +93,7 @@ void net_configure_sandbox_ip(Bridge *br) { | |||
91 | 93 | ||
92 | if (br->arg_ip_none) | 94 | if (br->arg_ip_none) |
93 | br->ipsandbox = 0; | 95 | br->ipsandbox = 0; |
94 | else if (br->ipsandbox) { | 96 | else if (br->ipsandbox && br->ip && br->mask) { |
95 | // check network range | 97 | // check network range |
96 | char *rv = in_netrange(br->ipsandbox, br->ip, br->mask); | 98 | char *rv = in_netrange(br->ipsandbox, br->ip, br->mask); |
97 | if (rv) { | 99 | if (rv) { |
@@ -104,9 +106,20 @@ void net_configure_sandbox_ip(Bridge *br) { | |||
104 | exit(1); | 106 | exit(1); |
105 | } | 107 | } |
106 | } | 108 | } |
107 | else | 109 | else if (br->ipsandbox && br->masksandbox) { |
110 | // send an ARP request and check if there is anybody on this IP address | ||
111 | if (arp_check(br->dev, br->ipsandbox)) { | ||
112 | fprintf(stderr, "Error: IP address %d.%d.%d.%d is already in use\n", PRINT_IP(br->ipsandbox)); | ||
113 | exit(1); | ||
114 | } | ||
115 | } | ||
116 | else if (br->ip && br->mask) | ||
108 | // ip address assigned by arp-scan for a bridge device | 117 | // ip address assigned by arp-scan for a bridge device |
109 | br->ipsandbox = arp_assign(br->dev, br); //br->ip, br->mask); | 118 | br->ipsandbox = arp_assign(br->dev, br); //br->ip, br->mask); |
119 | else { | ||
120 | br->ipsandbox = 0; | ||
121 | br->arg_ip_none = 1; | ||
122 | } | ||
110 | } | 123 | } |
111 | 124 | ||
112 | 125 | ||
@@ -148,21 +161,29 @@ void check_default_gw(uint32_t defaultgw) { | |||
148 | assert(defaultgw); | 161 | assert(defaultgw); |
149 | 162 | ||
150 | if (cfg.bridge0.configured) { | 163 | if (cfg.bridge0.configured) { |
164 | if (cfg.bridge0.ip == 0 && cfg.bridge0.ipsandbox) | ||
165 | return; | ||
151 | char *rv = in_netrange(defaultgw, cfg.bridge0.ip, cfg.bridge0.mask); | 166 | char *rv = in_netrange(defaultgw, cfg.bridge0.ip, cfg.bridge0.mask); |
152 | if (rv == 0) | 167 | if (rv == 0) |
153 | return; | 168 | return; |
154 | } | 169 | } |
155 | if (cfg.bridge1.configured) { | 170 | if (cfg.bridge1.configured) { |
171 | if (cfg.bridge1.ip == 0 && cfg.bridge1.ipsandbox) | ||
172 | return; | ||
156 | char *rv = in_netrange(defaultgw, cfg.bridge1.ip, cfg.bridge1.mask); | 173 | char *rv = in_netrange(defaultgw, cfg.bridge1.ip, cfg.bridge1.mask); |
157 | if (rv == 0) | 174 | if (rv == 0) |
158 | return; | 175 | return; |
159 | } | 176 | } |
160 | if (cfg.bridge2.configured) { | 177 | if (cfg.bridge2.configured) { |
178 | if (cfg.bridge2.ip == 0 && cfg.bridge2.ipsandbox) | ||
179 | return; | ||
161 | char *rv = in_netrange(defaultgw, cfg.bridge2.ip, cfg.bridge2.mask); | 180 | char *rv = in_netrange(defaultgw, cfg.bridge2.ip, cfg.bridge2.mask); |
162 | if (rv == 0) | 181 | if (rv == 0) |
163 | return; | 182 | return; |
164 | } | 183 | } |
165 | if (cfg.bridge3.configured) { | 184 | if (cfg.bridge3.configured) { |
185 | if (cfg.bridge3.ip == 0 && cfg.bridge3.ipsandbox) | ||
186 | return; | ||
166 | char *rv = in_netrange(defaultgw, cfg.bridge3.ip, cfg.bridge3.mask); | 187 | char *rv = in_netrange(defaultgw, cfg.bridge3.ip, cfg.bridge3.mask); |
167 | if (rv == 0) | 188 | if (rv == 0) |
168 | return; | 189 | 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) { | |||
481 | return 0; | 481 | return 0; |
482 | } | 482 | } |
483 | 483 | ||
484 | else if (strncmp(ptr, "netmask ", 8) == 0) { | ||
485 | #ifdef HAVE_NETWORK | ||
486 | if (checkcfg(CFG_NETWORK)) { | ||
487 | Bridge *br = last_bridge_configured(); | ||
488 | if (br == NULL) { | ||
489 | fprintf(stderr, "Error: no network device configured\n"); | ||
490 | exit(1); | ||
491 | } | ||
492 | if (br->arg_ip_none || br->masksandbox) { | ||
493 | fprintf(stderr, "Error: cannot configure the network mask twice for the same interface\n"); | ||
494 | exit(1); | ||
495 | } | ||
496 | |||
497 | // configure this network mask for the last bridge defined | ||
498 | if (atoip(ptr + 8, &br->masksandbox)) { | ||
499 | fprintf(stderr, "Error: invalid network mask\n"); | ||
500 | exit(1); | ||
501 | } | ||
502 | |||
503 | // if the bridge is not configured, use this mask as the bridge mask | ||
504 | if (br->mask == 0) | ||
505 | br->mask = br->masksandbox; | ||
506 | else { | ||
507 | fprintf(stderr, "Error: interface %s already has a network mask defined; " | ||
508 | "please remove --netmask\n", | ||
509 | br->dev); | ||
510 | exit(1); | ||
511 | } | ||
512 | } | ||
513 | else | ||
514 | warning_feature_disabled("networking"); | ||
515 | #endif | ||
516 | return 0; | ||
517 | } | ||
484 | else if (strncmp(ptr, "ip ", 3) == 0) { | 518 | else if (strncmp(ptr, "ip ", 3) == 0) { |
485 | #ifdef HAVE_NETWORK | 519 | #ifdef HAVE_NETWORK |
486 | if (checkcfg(CFG_NETWORK)) { | 520 | 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 = | |||
120 | " --netfilter.print=name|pid - print the firewall.\n" | 120 | " --netfilter.print=name|pid - print the firewall.\n" |
121 | " --netfilter6=filename - enable IPv6 firewall.\n" | 121 | " --netfilter6=filename - enable IPv6 firewall.\n" |
122 | " --netfilter6.print=name|pid - print the IPv6 firewall.\n" | 122 | " --netfilter6.print=name|pid - print the IPv6 firewall.\n" |
123 | " --netmask=address - define a network mask when dealing with unconfigured" | ||
124 | "\tparrent interfaces.\n" | ||
123 | " --netns=name - Run the program in a named, persistent network namespace.\n" | 125 | " --netns=name - Run the program in a named, persistent network namespace.\n" |
124 | " --netstats - monitor network statistics.\n" | 126 | " --netstats - monitor network statistics.\n" |
125 | #endif | 127 | #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 | |||
@@ -605,6 +605,12 @@ Use this option to deny network access to programs that don't | |||
605 | really need network access. | 605 | really need network access. |
606 | 606 | ||
607 | .TP | 607 | .TP |
608 | \fBnetmask address | ||
609 | Use this option when you want to assign an IP address in a new namespace and | ||
610 | the parent interface specified by --net is not configured. An IP address and | ||
611 | a default gateway address also have to be added. | ||
612 | |||
613 | .TP | ||
608 | \fBveth-name name | 614 | \fBveth-name name |
609 | Use this name for the interface connected to the bridge for --net=bridge_interface commands, | 615 | Use this name for the interface connected to the bridge for --net=bridge_interface commands, |
610 | instead of the default one. | 616 | instead of the default one. |
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 | |||
@@ -824,11 +824,6 @@ Note: \-\-net=none can crash the application on some platforms. | |||
824 | In these cases, it can be replaced with \-\-protocol=unix. | 824 | In these cases, it can be replaced with \-\-protocol=unix. |
825 | 825 | ||
826 | .TP | 826 | .TP |
827 | \fB\-\-netns=name | ||
828 | Run the program in a named, persistent network namespace. These can | ||
829 | be created and configured using "ip netns". | ||
830 | |||
831 | .TP | ||
832 | \fB\-\-netfilter | 827 | \fB\-\-netfilter |
833 | Enable a default firewall if a new network namespace is created inside the sandbox. | 828 | Enable a default firewall if a new network namespace is created inside the sandbox. |
834 | This option has no effect for sandboxes using the system network namespace. | 829 | This option has no effect for sandboxes using the system network namespace. |
@@ -955,6 +950,26 @@ $ firejail --name=browser --net=eth0 --netfilter firefox & | |||
955 | $ firejail --netfilter6.print=browser | 950 | $ firejail --netfilter6.print=browser |
956 | 951 | ||
957 | .TP | 952 | .TP |
953 | \fB\-\-netmask=address | ||
954 | Use this option when you want to assign an IP address in a new namespace and | ||
955 | the parent interface specified by --net is not configured. An IP address and | ||
956 | a default gateway address also have to be added. By default the new namespace | ||
957 | interface comes without IP address and default gateway configured. Example: | ||
958 | .br | ||
959 | |||
960 | .br | ||
961 | $ sudo /sbin/brctl addbr br0 | ||
962 | .br | ||
963 | $ sudo /sbin/ifconfig br0 up | ||
964 | .br | ||
965 | $ firejail --ip=10.10.20.67 --netmask=255.255.255.0 --defaultgw=10.10.20.1 | ||
966 | |||
967 | .TP | ||
968 | \fB\-\-netns=name | ||
969 | Run the program in a named, persistent network namespace. These can | ||
970 | be created and configured using "ip netns". | ||
971 | |||
972 | .TP | ||
958 | \fB\-\-netstats | 973 | \fB\-\-netstats |
959 | Monitor network namespace statistics, see \fBMONITORING\fR section for more details. | 974 | Monitor network namespace statistics, see \fBMONITORING\fR section for more details. |
960 | .br | 975 | .br |