mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 14:16:14 -06:00
netfilter template support
This commit is contained in:
parent
eb4b505ac2
commit
ead4ec3089
20 changed files with 633 additions and 33 deletions
|
|
@ -276,10 +276,13 @@ test-fs:
|
|||
test-fcopy:
|
||||
cd test/fcopy; ./fcopy.sh | grep TESTING
|
||||
|
||||
test: test-profiles test-private-lib test-fcopy test-fs test-utils test-sysutils test-environment test-apps test-apps-x11 test-apps-x11-xorg test-filters test-arguments
|
||||
test-fnetfilter:
|
||||
cd test/fnetfilter; ./fnetfilter.sh | grep TESTING
|
||||
|
||||
test: test-profiles test-private-lib test-fcopy test-fnetfilter test-fs test-utils test-sysutils test-environment test-apps test-apps-x11 test-apps-x11-xorg test-filters test-arguments
|
||||
echo "TEST COMPLETE"
|
||||
|
||||
test-travis: test-profiles test-fcopy test-fs test-utils test-sysutils test-environment test-filters test-arguments
|
||||
test-travis: test-profiles test-fcopy test-fnetfilter test-fs test-utils test-sysutils test-environment test-filters test-arguments
|
||||
echo "TEST COMPLETE"
|
||||
|
||||
##########################################
|
||||
|
|
|
|||
13
README.md
13
README.md
|
|
@ -210,18 +210,27 @@ $
|
|||
--debug-private-lib
|
||||
Debug messages for --private-lib option.
|
||||
|
||||
--netfilter=filename,arg1,arg2,arg3 ...
|
||||
This is the template version of the previous command. $ARG1,
|
||||
$ARG2, $ARG3 ... in the firewall script are replaced with arg1,
|
||||
arg2, arg3 ... passed on the command line. Up to 16 arguments
|
||||
are supported. Example:
|
||||
|
||||
$ firejail --net=eth0 --ip=192.168.1.105 \
|
||||
--netfilter=/etc/firejail/tcpserver.net,5001 server-program
|
||||
|
||||
--netfilter.print=name|pid
|
||||
Print the firewall installed in the sandbox specified by name
|
||||
or PID. Example:
|
||||
|
||||
$ firejail --net=browser --net=eth0 --netfilter firefox &
|
||||
$ firejail --name=browser --net=eth0 --netfilter firefox &
|
||||
$ firejail --netfilter.print=browser
|
||||
|
||||
--netfilter6.print=name|pid
|
||||
Print the IPv6 firewall installed in the sandbox specified by
|
||||
name or PID. Example:
|
||||
|
||||
$ firejail --net=browser --net=eth0 --netfilter firefox &
|
||||
$ firejail --name=browser --net=eth0 --netfilter firefox &
|
||||
$ firejail --netfilter6.print=browser
|
||||
|
||||
`````
|
||||
|
|
|
|||
1
RELNOTES
1
RELNOTES
|
|
@ -27,6 +27,7 @@ firejail (0.9.51) baseline; urgency=low
|
|||
* feature: profile build tool (--build)
|
||||
* feature: --netfilter.print
|
||||
* feature: --netfilter6.print
|
||||
* feature: netfilter template support
|
||||
* new profiles: upstreamed many profiles from the following sources:
|
||||
https://github.com/chiraag-nataraj/firejail-profiles,
|
||||
https://github.com/nyancat18/fe,
|
||||
|
|
|
|||
27
etc/tcpserver.net
Normal file
27
etc/tcpserver.net
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
*filter
|
||||
:INPUT DROP [0:0]
|
||||
:FORWARD DROP [0:0]
|
||||
:OUTPUT DROP [0:0]
|
||||
|
||||
###################################################################
|
||||
# Simple tcp filter template. $ARG1 is the port number.
|
||||
#
|
||||
# Usage: $ARG1 in this template is replaced by 5001 from command line below
|
||||
#
|
||||
# firejail --net=eth0 --ip=192.168.1.105 --netfilter=/etc/firejail/tcpserver.net,5001 server-program
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# allow server traffic
|
||||
-A INPUT -p tcp --dport $ARG1 -m state --state NEW,ESTABLISHED -j ACCEPT
|
||||
-A OUTPUT -p tcp --sport $ARG1 -m state --state ESTABLISHED -j ACCEPT
|
||||
|
||||
# allow incoming ping
|
||||
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
|
||||
-A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
|
||||
|
||||
# allow outgoing DNS
|
||||
-A OUTPUT -p udp --dport 53 -j ACCEPT
|
||||
-A INPUT -p udp --sport 53 -j ACCEPT
|
||||
|
||||
COMMIT
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
void check_netfilter_file(const char *fname) {
|
||||
EUID_ASSERT();
|
||||
|
||||
|
|
@ -44,7 +43,6 @@ void check_netfilter_file(const char *fname) {
|
|||
free(tmp);
|
||||
}
|
||||
|
||||
|
||||
void netfilter(const char *fname) {
|
||||
// find iptables command
|
||||
struct stat s;
|
||||
|
|
@ -150,6 +148,16 @@ void netfilter_print(pid_t pid, int ipv6) {
|
|||
}
|
||||
free(comm);
|
||||
|
||||
// check privileges for non-root users
|
||||
uid_t uid = getuid();
|
||||
if (uid != 0) {
|
||||
uid_t sandbox_uid = pid_get_uid(pid);
|
||||
if (uid != sandbox_uid) {
|
||||
fprintf(stderr, "Error: permission is denied to join a sandbox created by a different user.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// check network namespace
|
||||
char *name;
|
||||
if (asprintf(&name, "/run/firejail/network/%d-netmap", pid) == -1)
|
||||
|
|
@ -196,4 +204,3 @@ void netfilter_print(pid_t pid, int ipv6) {
|
|||
|
||||
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, iptables, "-vL");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ void usage(void) {
|
|||
printf(" --net=ethernet_interface - enable network namespaces and connect to this\n");
|
||||
printf("\tEthernet interface.\n");
|
||||
printf(" --net=none - enable a new, unconnected network namespace.\n");
|
||||
printf(" --netfilter[=filename] - enable firewall.\n");
|
||||
printf(" --netfilter[=filename,arg1,arg2,arg3 ...] - enable firewall.\n");
|
||||
printf(" --netfilter.print=name|pid - print the firewall.\n");
|
||||
printf(" --netfilter6=filename - enable IPv6 firewall.\n");
|
||||
printf(" --netfilter6.print=name|pid - print the IPv6 firewall.\n");
|
||||
|
|
|
|||
|
|
@ -20,8 +20,12 @@
|
|||
#include "../include/common.h"
|
||||
|
||||
#define MAXBUF 4098
|
||||
#define MAXARGS 16
|
||||
static char *args[MAXARGS] = {0};
|
||||
static int argcnt = 0;
|
||||
int arg_quiet = 0;
|
||||
|
||||
|
||||
static char *default_filter =
|
||||
"*filter\n"
|
||||
":INPUT DROP [0:0]\n"
|
||||
|
|
@ -29,7 +33,7 @@ static char *default_filter =
|
|||
":OUTPUT ACCEPT [0:0]\n"
|
||||
"-A INPUT -i lo -j ACCEPT\n"
|
||||
"-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n"
|
||||
"# echo replay is handled by -m state RELATED/ESTABLISHED below\n"
|
||||
"# echo replay is handled by -m state RELATED/ESTABLISHED above\n"
|
||||
"#-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT\n"
|
||||
"-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT\n"
|
||||
"-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT\n"
|
||||
|
|
@ -46,6 +50,111 @@ static void usage(void) {
|
|||
printf("\tfnetfilter netfilter-command destination-file\n");
|
||||
}
|
||||
|
||||
|
||||
static void copy(const char *src, const char *dest) {
|
||||
FILE *fp1 = fopen(src, "r");
|
||||
if (!fp1) {
|
||||
fprintf(stderr, "Error fnetfilter: cannot open %s\n", src);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
FILE *fp2 = fopen(dest, "w");
|
||||
if (!fp2) {
|
||||
fprintf(stderr, "Error fnetfilter: cannot open %s\n", dest);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char buf[MAXBUF];
|
||||
while (fgets(buf, MAXBUF, fp1))
|
||||
fprintf(fp2, "%s", buf);
|
||||
|
||||
fclose(fp1);
|
||||
fclose(fp2);
|
||||
}
|
||||
|
||||
static void process_template(char *src, const char *dest) {
|
||||
char *arg_start = strchr(src, ',');
|
||||
assert(arg_start);
|
||||
*arg_start = '\0';
|
||||
arg_start++;
|
||||
if (*arg_start == '\0') {
|
||||
fprintf(stderr, "Error fnetfilter: you need to provide at least on argument\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// extract the arguments from command line
|
||||
char *token = strtok(arg_start, ",");
|
||||
while (token) {
|
||||
// look for abnormal things
|
||||
int len = strlen(token);
|
||||
if (strcspn(token, "\\&!?\"'<>%^(){};,*[]") != (size_t)len) {
|
||||
fprintf(stderr, "Error fnetfilter: invalid argument in netfilter command\n");
|
||||
exit(1);
|
||||
}
|
||||
args[argcnt] = token;
|
||||
argcnt++;
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
printf("argcnt %d\n", argcnt);
|
||||
int i;
|
||||
for (i = 0; i < argcnt; i++)
|
||||
printf("%s\n", args[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// open the files
|
||||
FILE *fp1 = fopen(src, "r");
|
||||
if (!fp1) {
|
||||
fprintf(stderr, "Error fnetfilter: cannot open %s\n", src);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
FILE *fp2 = fopen(dest, "w");
|
||||
if (!fp2) {
|
||||
fprintf(stderr, "Error fnetfilter: cannot open %s\n", dest);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int line = 0;
|
||||
char buf[MAXBUF];
|
||||
while (fgets(buf, MAXBUF, fp1)) {
|
||||
line++;
|
||||
char *ptr = buf;
|
||||
while (*ptr != '\0') {
|
||||
if (*ptr != '$')
|
||||
fputc(*ptr, fp2);
|
||||
else {
|
||||
// parsing
|
||||
int index = 0;
|
||||
int rv = sscanf(ptr, "$ARG%u", &index) ;
|
||||
if (rv != 1) {
|
||||
fprintf(stderr, "Error fnetfilter: invalid template argument on line %d\n", line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// print argument
|
||||
if (index < 1 || index > argcnt) {
|
||||
fprintf(stderr, "Error fnetfilter: $ARG%d on line %d was not defined\n", index, line);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(fp2, "%s", args[index - 1]);
|
||||
|
||||
// march to the end of argument
|
||||
ptr += 4;
|
||||
while (isdigit(*ptr))
|
||||
ptr++;
|
||||
ptr--;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp1);
|
||||
fclose(fp2);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
#if 0
|
||||
{
|
||||
|
|
@ -61,7 +170,7 @@ printf("\n");
|
|||
if (quiet && strcmp(quiet, "yes") == 0)
|
||||
arg_quiet = 1;
|
||||
|
||||
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
|
||||
if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0)) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -75,6 +184,12 @@ printf("\n");
|
|||
char *command = (argc == 3)? argv[1]: NULL;
|
||||
//printf("command %s\n", command);
|
||||
//printf("destfile %s\n", destfile);
|
||||
// destfile is a real filename
|
||||
int len = strlen(destfile);
|
||||
if (strcspn(destfile, "\\&!?\"'<>%^(){};,*[]") != (size_t)len) {
|
||||
fprintf(stderr, "Error fnetfilter: invalid destination file in netfilter command\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// handle default config (command = NULL, destfile)
|
||||
if (command == NULL) {
|
||||
|
|
@ -88,28 +203,11 @@ printf("\n");
|
|||
fclose(fp);
|
||||
}
|
||||
else {
|
||||
// copy the file
|
||||
FILE *fp1 = fopen(command, "r");
|
||||
if (!fp1) {
|
||||
fprintf(stderr, "Error fnetfilter: cannot open %s\n", command);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
FILE *fp2 = fopen(destfile, "w");
|
||||
if (!fp2) {
|
||||
fprintf(stderr, "Error fnetfilter: cannot open %s\n", destfile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char buf[MAXBUF];
|
||||
while (fgets(buf, MAXBUF, fp1))
|
||||
fprintf(fp2, "%s", buf);
|
||||
|
||||
fclose(fp1);
|
||||
fclose(fp2);
|
||||
if (strrchr(command, ','))
|
||||
process_template(command, destfile);
|
||||
else
|
||||
copy(command, destfile);
|
||||
}
|
||||
|
||||
|
||||
printf("fnetfilter running\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -937,13 +937,32 @@ is a desktop client firewall that disable access to local network. Example:
|
|||
$ firejail --netfilter=/etc/firejail/nolocal.net \\
|
||||
.br
|
||||
--net=eth0 firefox
|
||||
|
||||
|
||||
|
||||
|
||||
.TP
|
||||
\fB\-\-netfilter=filename,arg1,arg2,arg3 ...
|
||||
This is the template version of the previous command. $ARG1, $ARG2, $ARG3 ... in the firewall script
|
||||
are replaced with arg1, arg2, arg3 ... passed on the command line. Up to 16 arguments are supported.
|
||||
Example:
|
||||
.br
|
||||
|
||||
.br
|
||||
$ firejail --net=eth0 --ip=192.168.1.105 \\
|
||||
.br
|
||||
--netfilter=/etc/firejail/tcpserver.net,5001 server-program
|
||||
.br
|
||||
|
||||
|
||||
|
||||
.TP
|
||||
\fB\-\-netfilter.print=name|pid
|
||||
Print the firewall installed in the sandbox specified by name or PID. Example:
|
||||
.br
|
||||
|
||||
.br
|
||||
$ firejail --net=browser --net=eth0 --netfilter firefox &
|
||||
$ firejail --name=browser --net=eth0 --netfilter firefox &
|
||||
.br
|
||||
$ firejail --netfilter.print=browser
|
||||
|
||||
|
|
@ -959,7 +978,7 @@ Print the IPv6 firewall installed in the sandbox specified by name or PID. Examp
|
|||
.br
|
||||
|
||||
.br
|
||||
$ firejail --net=browser --net=eth0 --netfilter firefox &
|
||||
$ firejail --name=browser --net=eth0 --netfilter firefox &
|
||||
.br
|
||||
$ firejail --netfilter6.print=browser
|
||||
|
||||
|
|
|
|||
37
test/fnetfilter/cmdline.exp
Executable file
37
test/fnetfilter/cmdline.exp
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/expect -f
|
||||
# This file is part of Firejail project
|
||||
# Copyright (C) 2014-2017 Firejail Authors
|
||||
# License GPL v2
|
||||
|
||||
set timeout 10
|
||||
spawn $env(SHELL)
|
||||
match_max 100000
|
||||
|
||||
send -- "fnetfilter\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 1\n";exit}
|
||||
"Usage:"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter -h\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 2\n";exit}
|
||||
"Usage:"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter -h a b c d\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 2\n";exit}
|
||||
"Usage:"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter a b c d\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 2\n";exit}
|
||||
"Usage:"
|
||||
}
|
||||
after 100
|
||||
puts "\nall done\n"
|
||||
52
test/fnetfilter/copy.exp
Executable file
52
test/fnetfilter/copy.exp
Executable file
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/expect -f
|
||||
# This file is part of Firejail project
|
||||
# Copyright (C) 2014-2017 Firejail Authors
|
||||
# License GPL v2
|
||||
|
||||
set timeout 10
|
||||
spawn $env(SHELL)
|
||||
match_max 100000
|
||||
|
||||
send -- "rm outfile\r"
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter test1.net outfile\r"
|
||||
after 100
|
||||
|
||||
send -- "cat outfile\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 1\n";exit}
|
||||
"test1"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 2\n";exit}
|
||||
"*filter"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 3\n";exit}
|
||||
"INPUT -m state --state RELATED,ESTABLISHED"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 4\n";exit}
|
||||
"disable STUN"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter foo outfile\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 5\n";exit}
|
||||
"cannot open foo"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter test1.net outlocked\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 6\n";exit}
|
||||
"cannot open outlocked"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "rm outfile\r"
|
||||
after 100
|
||||
|
||||
puts "\nall done\n"
|
||||
40
test/fnetfilter/default.exp
Executable file
40
test/fnetfilter/default.exp
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/expect -f
|
||||
# This file is part of Firejail project
|
||||
# Copyright (C) 2014-2017 Firejail Authors
|
||||
# License GPL v2
|
||||
|
||||
set timeout 10
|
||||
spawn $env(SHELL)
|
||||
match_max 100000
|
||||
|
||||
send -- "rm outfile\r"
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter outfile\r"
|
||||
after 100
|
||||
|
||||
send -- "cat outfile\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 1\n";exit}
|
||||
"*filter"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 2\n";exit}
|
||||
"INPUT -m state --state RELATED,ESTABLISHED"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 3\n";exit}
|
||||
"disable STUN"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter test1.net,33\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 4\n";exit}
|
||||
"invalid destination file in netfilter command"
|
||||
}
|
||||
after 100
|
||||
send -- "rm outfile\r"
|
||||
after 100
|
||||
|
||||
puts "\nall done\n"
|
||||
28
test/fnetfilter/fnetfilter.sh
Executable file
28
test/fnetfilter/fnetfilter.sh
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
# This file is part of Firejail project
|
||||
# Copyright (C) 2014-2017 Firejail Authors
|
||||
# License GPL v2
|
||||
|
||||
export MALLOC_CHECK_=3
|
||||
export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
|
||||
|
||||
if [ -f /etc/debian_version ]; then
|
||||
libdir=$(dirname "$(dpkg -L firejail | grep fcopy)")
|
||||
export PATH="$PATH:$libdir"
|
||||
fi
|
||||
|
||||
export PATH="$PATH:/usr/lib/firejail"
|
||||
|
||||
echo "TESTING: fnetfilter cmdline (test/fnetfilter/cmdline.exp)"
|
||||
./cmdline.exp
|
||||
|
||||
echo "TESTING: fnetfilter default (test/fnetfilter/default.exp)"
|
||||
./default.exp
|
||||
|
||||
echo "TESTING: fnetfilter copy (test/fnetfilter/copy.exp)"
|
||||
./copy.exp
|
||||
|
||||
echo "TESTING: fnetfilter template (test/fnetfilter/template.exp)"
|
||||
./template.exp
|
||||
|
||||
rm -f outfile
|
||||
0
test/fnetfilter/outlocked
Normal file
0
test/fnetfilter/outlocked
Normal file
82
test/fnetfilter/template.exp
Executable file
82
test/fnetfilter/template.exp
Executable file
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/expect -f
|
||||
# This file is part of Firejail project
|
||||
# Copyright (C) 2014-2017 Firejail Authors
|
||||
# License GPL v2
|
||||
|
||||
set timeout 10
|
||||
spawn $env(SHELL)
|
||||
match_max 100000
|
||||
|
||||
send -- "rm outfile\r"
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter test2.net,icmp-type,destination-unreachable,time-exceeded,echo-request,3478,3479 outfile\r"
|
||||
after 100
|
||||
|
||||
send -- "cat outfile\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 1\n";exit}
|
||||
"*filter"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 2\n";exit}
|
||||
"INPUT -m state --state RELATED,ESTABLISHED"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 3\n";exit}
|
||||
"icmp-type echo-reply"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 4\n";exit}
|
||||
"icmp-type destination-unreachable"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 5\n";exit}
|
||||
"icmp-type time-exceeded"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 6\n";exit}
|
||||
"icmp-type echo-request"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 7\n";exit}
|
||||
"dport 3478"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 8\n";exit}
|
||||
"dport 3479"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 8\n";exit}
|
||||
"dport 3478"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 10\n";exit}
|
||||
"dport 3479"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter test2.net,icmp-type,destination-unreachable,time-exceeded,echo-request outfile\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 11\n";exit}
|
||||
"ARG5 on line 14 was not defined"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter test2.net,icmp-type,destination-unreachable,time-exceeded,echo-request\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 12\n";exit}
|
||||
"invalid destination file in netfilter command"
|
||||
}
|
||||
after 100
|
||||
|
||||
send -- "fnetfilter test3.net,44 outfile\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 13\n";exit}
|
||||
"invalid template argument on line 1"
|
||||
}
|
||||
after 100
|
||||
send -- "rm outfile\r"
|
||||
after 100
|
||||
|
||||
puts "\nall done\n"
|
||||
19
test/fnetfilter/test1.net
Normal file
19
test/fnetfilter/test1.net
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
*filter
|
||||
# test2
|
||||
:INPUT DROP [0:0]
|
||||
:FORWARD DROP [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
-A INPUT -i lo -j ACCEPT
|
||||
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
# echo replay is handled by -m state RELATED/ESTABLISHED above
|
||||
#-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
|
||||
-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
|
||||
-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
|
||||
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
|
||||
# disable STUN
|
||||
-A OUTPUT -p udp --dport 3478 -j DROP
|
||||
-A OUTPUT -p udp --dport 3479 -j DROP
|
||||
-A OUTPUT -p tcp --dport 3478 -j DROP
|
||||
-A OUTPUT -p tcp --dport 3479 -j DROP
|
||||
COMMIT
|
||||
|
||||
19
test/fnetfilter/test2.net
Normal file
19
test/fnetfilter/test2.net
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
*filter
|
||||
# test2
|
||||
:INPUT DROP [0:0]
|
||||
:FORWARD DROP [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
-A INPUT -i lo -j ACCEPT
|
||||
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
# echo replay is handled by -m state RELATED/ESTABLISHED above
|
||||
#-A INPUT -p icmp --$ARG1 echo-reply -j ACCEPT
|
||||
-A INPUT -p icmp --$ARG1 $ARG2 -j ACCEPT
|
||||
-A INPUT -p icmp --$ARG1 $ARG3 -j ACCEPT
|
||||
-A INPUT -p icmp --$ARG1 $ARG4 -j ACCEPT
|
||||
# disable STUN
|
||||
-A OUTPUT -p udp --dport $ARG5 -j DROP
|
||||
-A OUTPUT -p udp --dport $ARG6 -j DROP
|
||||
-A OUTPUT -p tcp --dport $ARG5 -j DROP
|
||||
-A OUTPUT -p tcp --dport $ARG6 -j DROP
|
||||
COMMIT
|
||||
|
||||
1
test/fnetfilter/test3.net
Normal file
1
test/fnetfilter/test3.net
Normal file
|
|
@ -0,0 +1 @@
|
|||
asdfasdf $ARG asdfasdfdasf
|
||||
44
test/network/netfilter-template.exp
Executable file
44
test/network/netfilter-template.exp
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/expect -f
|
||||
# This file is part of Firejail project
|
||||
# Copyright (C) 2014-2017 Firejail Authors
|
||||
# License GPL v2
|
||||
|
||||
set timeout 10
|
||||
spawn $env(SHELL)
|
||||
match_max 100000
|
||||
|
||||
send -- "firejail --net=br1 --ip=10.10.30.10 --name=test1 --netfilter=/etc/firejail/tcpserver.net,5555 ./tcpserver 5555\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 1\n";exit}
|
||||
"Child process initialized"
|
||||
}
|
||||
sleep 1
|
||||
|
||||
spawn $env(SHELL)
|
||||
send -- "telnet 10.10.30.10 5555\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 2\n";exit}
|
||||
"Connected to 10.10.30.10"
|
||||
}
|
||||
sleep 1
|
||||
|
||||
send "sdfklsjadfl;ksadjfl;sdkfj\r"
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 3\n";exit}
|
||||
"response"
|
||||
}
|
||||
expect {
|
||||
timeout {puts "TESTING ERROR 4\n";exit}
|
||||
"Connection closed"
|
||||
}
|
||||
sleep 1
|
||||
|
||||
send -- "telnet 10.10.30.10 5556\r"
|
||||
expect {
|
||||
timeout {puts "OK\n"}
|
||||
"Connected to 10.10.30.10" {puts "TESTING ERROR 6\n";exit}
|
||||
"dikasdfjasdjf"
|
||||
}
|
||||
|
||||
after 100
|
||||
puts "all done\n"
|
||||
|
|
@ -8,6 +8,12 @@ export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
|
|||
|
||||
sudo ./configure
|
||||
|
||||
echo "TESTING: netfilter template (netfilter-template.exp)"
|
||||
rm -f ./tcpserver
|
||||
gcc -o tcpserver tcpserver.c
|
||||
./netfilter-template.exp
|
||||
rm ./tcpserver
|
||||
|
||||
echo "TESTING: firemon interface (firemon-interfaces.exp)"
|
||||
sudo ./firemon-interfaces.exp
|
||||
|
||||
|
|
|
|||
108
test/network/tcpserver.c
Normal file
108
test/network/tcpserver.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2017 Firejail Authors
|
||||
*
|
||||
* This file is part of firejail project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int fd, newfd, client_len;
|
||||
struct sockaddr_in serv_addr, client_addr;
|
||||
int n, pid;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: ./server port-number\n");
|
||||
return 1;
|
||||
}
|
||||
int portno = atoi(argv[1]);
|
||||
|
||||
// init socket
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
perror("ERROR opening socket");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Initialize socket structure
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
serv_addr.sin_port = htons(portno);
|
||||
|
||||
// bind
|
||||
if (bind(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
perror("bind");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// listen - 5 pending conncections
|
||||
if (listen(fd, 5) < 0) {
|
||||
perror("listen");
|
||||
return 1;
|
||||
}
|
||||
client_len = sizeof(client_addr);
|
||||
|
||||
while (1) {
|
||||
newfd = accept(fd, (struct sockaddr *) &client_addr, &client_len);
|
||||
|
||||
if (newfd < 0) {
|
||||
perror("accept");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create child process */
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0) {
|
||||
perror("fork");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
// child
|
||||
close(fd);
|
||||
#define MAXBUF 4096
|
||||
char buf[MAXBUF];
|
||||
memset(buf, 0, MAXBUF);
|
||||
|
||||
int rcv = read(newfd, buf, MAXBUF - 1);
|
||||
if (rcv < 0) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int sent = write(newfd, "response\n", 9);
|
||||
if (sent < 9) {
|
||||
perror("write");
|
||||
return 1;
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
close(newfd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue