Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added vrrp passthrough support #11

Merged
merged 1 commit into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

---
# [0.4.1] - 2023-06-30

###

- Added support for inbound vrrp on a per port basis.

# [0.4.0] - 2023-06-29

###
Expand Down
49 changes: 35 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ expected output:
The firewall can support subtending devices for two interface scenarios i.e.
external and trusted.

external inet <----> (ens33)[ebpf-router](ens37) <----> trusted clients
external inet <----> (ens33)[ebpf-router](ens37) <----> trusted client(s)

with zfw_tc_ingress.o applied ingress on ens33 and zfw_tc_oubound_track.o applied egress on ens33 the router will
statefully track outbound udp and tcp connections on ens33 and allow the associated inbound traffic. While
Expand Down Expand Up @@ -286,10 +286,28 @@ fall through to rule check instead where a more specific rule could be applied.
interface setting and can be set for all interfaces except loopback. This would need to be put in
/opt/openziti/bin/user/user_rules.sh to survive reboot.

- Disable
```
sudo zfw -x ens33
sudo zfw -x <ens33 | all>
```

- Enable
```
sudo zfw -x <ens33 | all> -d
```

### vrrp passthrough
- Enable
```
sudo zfw --vrrp-enable <ens33 | all>
```

- Disable
```
sudo zfw --vrrp-enable <ens33 | all> -d
```


### Inserting / Deleting rules

The -t, --tproxy-port is has a dual purpose one it to signify the tproxy port used by openziti routers in tproxy mode and the other is to identify either local passthrough with value of 0 and the other is tunnel redirect mode with value of 65535.
Expand Down Expand Up @@ -371,7 +389,7 @@ target proto origin destination mapping:
PASSTHRU udp 0.0.0.0/0 192.168.100.100/32 dpts=50000:60000 PASSTHRU to 192.168.100.100/32 []
```

Example: List rules in firewall for a given prefix
- Example: List rules in firewall for a given prefix
Usage: zfw -L -c <ip dest address or prefix> -m <prefix len> -p <protocol>
```
sudo zfw -L -c 192.168.100.100 -m 32
Expand All @@ -382,7 +400,7 @@ target proto origin destination mapping:
PASSTHRU udp 0.0.0.0/0 192.168.100.100/32 dpts=50000:60000 PASSTHRU to 192.168.100.100/32 []
PASSTHRU tcp 0.0.0.0/0 192.168.100.100/32 dpts=60000:65535 PASSTHRU to 192.168.100.100/32 []
```
Example: List all interface settings
- Example: List all interface settings

```
sudo zfw -L -E
Expand All @@ -394,42 +412,45 @@ icmp echo :1
verbose :0
ssh disable :0
per interface :0
tc ingress filter :1
tc ingress filter :0
tc egress filter :0
tun mode intercept :0
vrrp enable :0
--------------------------

ens33: 3
ens33: 2
--------------------------
icmp echo :0
verbose :1
ssh disable :1
per interface :1
verbose :0
ssh disable :0
per interface :0
tc ingress filter :1
tc egress filter :1
tun mode intercept :0
tun mode intercept :1
vrrp enable :1
--------------------------

ens37: 4
ens37: 3
--------------------------
icmp echo :0
verbose :0
ssh disable :0
per interface :0
tc ingress filter :1
tc ingress filter :0
tc egress filter :0
tun mode intercept :0
vrrp enable :0
--------------------------

tun0: 9
tun0: 18
--------------------------
verbose :0
cidr :100.64.0.0
mask :10
--------------------------
```

Example Detaching bpf from interface:
- Example Detaching bpf from interface:

```
sudo zfw --set-tc-filter <interface name> --direction <ingress | egress> --disable
Expand Down
98 changes: 79 additions & 19 deletions src/zfw.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ static bool passthru = false;
static bool intercept = false;
static bool echo = false;
static bool verbose = false;
static bool vrrp = false;
static bool per_interface = false;
static bool interface = false;
static bool disable = false;
Expand Down Expand Up @@ -108,10 +109,11 @@ static char *verbose_interface;
static char *ssh_interface;
static char *prefix_interface;
static char *tun_interface;
static char *vrrp_interface;
static char *tc_interface;
static char *object_file;
static char *direction_string;
const char *argp_program_version = "0.4.0";
const char *argp_program_version = "0.4.1";

static __u8 if_list[MAX_IF_LIST_ENTRIES];
int ifcount = 0;
Expand Down Expand Up @@ -149,6 +151,7 @@ struct diag_ip4
bool tc_ingress;
bool tc_egress;
bool tun_mode;
bool vrrp;
};

struct tproxy_port_mapping
Expand Down Expand Up @@ -726,6 +729,7 @@ void usage(char *message)
fprintf(stderr, " zfw -X <ifname> -O <object file name> -z direction\n");
fprintf(stderr, " zfw -X <ifname> -O <object file name> -z direction -d\n");
fprintf(stderr, " zfw -Q\n");
fprintf(stderr, " zfw --vrrp-enable <ifname>\n");
fprintf(stderr, " zfw -V\n");
fprintf(stderr, " zfw --help\n");
exit(1);
Expand Down Expand Up @@ -916,6 +920,18 @@ bool set_diag(uint32_t *idx)
}
printf("Set tun mode to %d for %s\n", !disable, tun_interface);
}
if (vrrp)
{
if (!disable)
{
o_diag.vrrp = true;
}
else
{
o_diag.vrrp = false;
}
printf("Set vrrp mode to %d for %s\n", !disable, vrrp_interface);
}
int ret = syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &diag_map, sizeof(diag_map));
if (ret)
{
Expand All @@ -942,6 +958,7 @@ bool set_diag(uint32_t *idx)
printf("%-24s:%d\n", "tc ingress filter", o_diag.tc_ingress);
printf("%-24s:%d\n", "tc egress filter", o_diag.tc_egress);
printf("%-24s:%d\n", "tun mode intercept", o_diag.tun_mode);
printf("%-24s:%d\n", "vrrp enable", o_diag.vrrp);
printf("--------------------------\n\n");
}
}
Expand Down Expand Up @@ -1097,8 +1114,9 @@ void interface_diag()
ssh_interface = address->ifa_name;
diag_interface = address->ifa_name;
tun_interface = address->ifa_name;
vrrp_interface = address->ifa_name;
}
if(!strncmp(address->ifa_name, "tun", 3) && (tun || per_interface || ssh_disable || echo)){
if(!strncmp(address->ifa_name, "tun", 3) && (tun || per_interface || ssh_disable || echo || vrrp)){
if(per_interface && !strncmp(prefix_interface, "tun", 3)){
printf("%s:zfw does not allow setting on tun interfaces!\n", address->ifa_name);
}
Expand All @@ -1111,10 +1129,13 @@ void interface_diag()
if(echo && !strncmp(echo_interface, "tun", 3)){
printf("%s:zfw does not allow setting on tun interfaces!\n", address->ifa_name);
}
if(vrrp && !strncmp(vrrp_interface, "tun", 3)){
printf("%s:zfw does not allow setting on tun interfaces!\n", address->ifa_name);
}
address = address->ifa_next;
continue;
}
if(!strncmp(address->ifa_name, "ziti", 4) && (tun || per_interface || ssh_disable || echo)){
if(!strncmp(address->ifa_name, "ziti", 4) && (tun || per_interface || ssh_disable || echo || vrrp)){
if(per_interface && !strncmp(prefix_interface, "ziti", 4)){
printf("%s:zfw does not allow setting on tun interfaces!\n", address->ifa_name);
}
Expand All @@ -1127,17 +1148,28 @@ void interface_diag()
if(echo && !strncmp(echo_interface, "ziti", 4)){
printf("%s:zfw does not allow setting on tun interfaces!\n", address->ifa_name);
}
if(vrrp && !strncmp(vrrp_interface, "ziti", 4)){
printf("%s:zfw does not allow setting on tun interfaces!\n", address->ifa_name);
}
address = address->ifa_next;
continue;
}
if (echo && strncmp(address->ifa_name,"tun", 3) && strncmp(address->ifa_name,"ziti", 4))
if (echo) //&& strncmp(address->ifa_name,"tun", 3) && strncmp(address->ifa_name,"ziti", 4))
{
if (!strcmp(echo_interface, address->ifa_name))
{
set_diag(&idx);
}
}

if (vrrp)
{
if (!strcmp(vrrp_interface, address->ifa_name))
{
set_diag(&idx);
}
}

if (verbose)
{
if(!strncmp(address->ifa_name, "tun", 3) && !strncmp(verbose_interface,"tun", 3)){
Expand Down Expand Up @@ -1911,14 +1943,15 @@ static struct argp_option options[] = {
{"delete", 'D', NULL, 0, "Delete map rule", 0},
{"list", 'L', NULL, 0, "List map rules", 0},
{"flush", 'F', NULL, 0, "Flush all map rules", 0},
{"set-tun-mode", 'T', "", 0, "set tun mode on interface", 0},
{"disable-ebpf", 'Q', NULL, 0, "delete tc from all interface and remove all maps", 0},
{"per-interface-rules", 'P', "", 0, "set interface to per interface rule aware", 0},
{"disable-ssh", 'x', "", 0, "disable inbound ssh to interface (default enabled)", 0},
{"set-tun-mode", 'T', "", 0, "Set tun mode on interface", 0},
{"disable-ebpf", 'Q', NULL, 0, "Delete tc from all interface and remove all maps", 0},
{"per-interface-rules", 'P', "", 0, "Set interface to per interface rule aware", 0},
{"disable-ssh", 'x', "", 0, "Disable inbound ssh to interface (default enabled)", 0},
{"dcidr-block", 'c', "", 0, "Set dest ip prefix i.e. 192.168.1.0 <mandatory for insert/delete/list>", 0},
{"icmp-echo", 'e', "", 0, "enable inbound icmp echo to interface", 0},
{"verbose", 'v', "", 0, "enable verbose tracing on interface", 0},
{"disable", 'd', NULL, 0, "disable associated diag operation i.e. -e eth0 -d to disable inbound echo on eth0", 0},
{"icmp-echo", 'e', "", 0, "Enable inbound icmp echo to interface", 0},
{"verbose", 'v', "", 0, "Enable verbose tracing on interface", 0},
{"vrrp-enable", 'R', "", 0, "Enable vrrp passthrough on interface", 0},
{"disable", 'd', NULL, 0, "Disable associated diag operation i.e. -e eth0 -d to disable inbound echo on eth0", 0},
{"ocidr-block", 'o', "", 0, "Set origin ip prefix i.e. 192.168.1.0 <mandatory for insert/delete/list>", 0},
{"dprefix-len", 'm', "", 0, "Set dest prefix length (1-32) <mandatory for insert/delete/list >", 0},
{"oprefix-len", 'n', "", 0, "Set origin prefix length (1-32) <mandatory for insert/delete/list >", 0},
Expand All @@ -1927,13 +1960,13 @@ static struct argp_option options[] = {
{"tproxy-port", 't', "", 0, "Set high-port value (0-65535)> <mandatory for insert>", 0},
{"protocol", 'p', "", 0, "Set protocol (tcp or udp) <mandatory insert/delete>", 0},
{"route", 'r', NULL, 0, "Add or Delete static ip/prefix for intercept dest to lo interface <optional insert/delete>", 0},
{"intercepts", 'i', NULL, 0, "list intercept rules <optional for list>", 0},
{"passthrough", 'f', NULL, 0, "list passthrough rules <optional list>", 0},
{"intercepts", 'i', NULL, 0, "List intercept rules <optional for list>", 0},
{"passthrough", 'f', NULL, 0, "List passthrough rules <optional list>", 0},
{"interface", 'N', "", 0, "Interface <optional insert>", 0},
{"list-diag", 'E', NULL, 0, "", 0},
{"set-tc-filter", 'X', "", 0, "add/remove TC filter to/from interface", 0},
{"object-file", 'O', "", 0, "set object file", 0},
{"direction", 'z', "", 0, "set direction", 0},
{"set-tc-filter", 'X', "", 0, "Add/remove TC filter to/from interface", 0},
{"object-file", 'O', "", 0, "Set object file", 0},
{"direction", 'z', "", 0, "Set direction", 0},
{0}};

static error_t parse_opt(int key, char *arg, struct argp_state *state)
Expand Down Expand Up @@ -2020,6 +2053,28 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
case 'Q':
ebpf_disable = true;
break;
case 'R':
if (!strlen(arg) || (strchr(arg, '-') != NULL))
{
fprintf(stderr, "Interface name or all required as arg to -R, --vrrp-enable: %s\n", arg);
fprintf(stderr, "%s --help for more info\n", program_name);
exit(1);
}
get_index(arg, &idx);
if(strcmp("all", arg) && idx == 0){
printf("Interface not found: %s\n", arg);
exit(1);
}
vrrp = true;
if (!strcmp("all", arg))
{
all_interface = true;
}
else
{
vrrp_interface = arg;
}
break;
case 'T':
if (!strlen(arg) || (strchr(arg, '-') != NULL))
{
Expand Down Expand Up @@ -2316,6 +2371,11 @@ int main(int argc, char **argv)
usage("-T, --set-tun-mode cannot be set as a part of combination call to zfw");
}

if (( vrrp && (tun || echo || ssh_disable || verbose || per_interface || add || delete || list || flush || tcfilter)))
{
usage("-R, --vrrp-enable cannot be set as a part of combination call to zfw");
}

if ((tcfilter && (echo || ssh_disable || verbose || per_interface || add || delete || list || flush)))
{
usage("-X, --set-tc-filter cannot be set as a part of combination call to zfw");
Expand Down Expand Up @@ -2351,9 +2411,9 @@ int main(int argc, char **argv)
usage("Missing argument -r, --route requires -I --insert, -D --delete or -F --flush");
}

if (disable && (!ssh_disable && !echo && !verbose && !per_interface && !tcfilter && !tun))
if (disable && (!ssh_disable && !echo && !verbose && !per_interface && !tcfilter && !tun && !vrrp))
{
usage("Missing argument at least one of -e, -v, -x, or -E, -P, -T, -X");
usage("Missing argument at least one of -e, -v, -x, or -E, -P, -R, -T, -X");
}

if (direction && !tcfilter)
Expand Down Expand Up @@ -2504,7 +2564,7 @@ int main(int argc, char **argv)
map_list();
}
}
else if (verbose || ssh_disable || echo || per_interface || tun)
else if (vrrp || verbose || ssh_disable || echo || per_interface || tun)
{
interface_diag();
exit(0);
Expand Down
Loading