mirror of
https://github.com/google/nsjail.git
synced 2026-08-30 18:41:30 -07:00
net: support for network rules
This commit is contained in:
23
Makefile
23
Makefile
@@ -149,11 +149,27 @@ UID := $(shell id -u)
|
||||
|
||||
.PHONY: test
|
||||
test: $(BIN)
|
||||
# --- Basic sanity tests ---
|
||||
$(call run_test, ./nsjail -q -Mo --chroot / --user 99999 --group 99999 -- /bin/true, 0)
|
||||
$(call run_test, ./nsjail -q -Mo --chroot / --user 99999 --group 99999 -- /bin/false, 1)
|
||||
$(call run_test, ./nsjail --config tests/seccomp.cfg -q -t 2 -- /bin/bash -c 'strace -o /dev/null /bin/true || exit 77', 77)
|
||||
$(call run_test, ./nsjail --config tests/basic.cfg -q -t 2 -- /bin/bash -c 'strace -o /dev/null /bin/true && exit 77', 77)
|
||||
$(call run_test, ./nsjail --config tests/nat.cfg -q -t 3 -- /bin/bash -c 'sleep 0.2; ping -W 1 -c 1 8.8.8.8 && exit 77', 77)
|
||||
$(call run_test, ./nsjail --config tests/port-mappings.cfg -q -t 3 -- /bin/bash -c 'sleep 0.2; { netstat -tan | grep LISTEN; } && exit 77', 77)
|
||||
|
||||
# --- Traffic rules tests ---
|
||||
$(call run_test, ./nsjail --config tests/traffic-rules.cfg -q -t 2, 137)
|
||||
$(call run_test, ./nsjail --config tests/traffic-drop-tcp4.cfg -q -t 2, 137)
|
||||
$(call run_test, ./nsjail --config tests/traffic-drop-udp6.cfg -q -t 2, 137)
|
||||
$(call run_test, ./nsjail --config tests/traffic-mixed.cfg -q -t 2, 137)
|
||||
|
||||
# --- IPv4-only NAT tests ---
|
||||
$(call run_test, ./nsjail --config tests/nat-ip4-only.cfg -q -t 3 --cap CAP_NET_RAW -- /bin/bash -c 'sleep 0.2; ping -4 -W 1 -c 1 8.8.8.8 && exit 77', 77)
|
||||
|
||||
# --- IPv6-only NAT tests ---
|
||||
$(call run_test, ./nsjail --config tests/nat-ip6-only.cfg -q -t 3 -- /bin/true, 0)
|
||||
|
||||
# --- --experimental_mnt=old ---
|
||||
$(call run_test, ./nsjail $(OLD_EF) -q -Mo --rw --chroot / --user 99999 --group 99999 -- /bin/bash -c 'touch $(HOME)/nsjail_test && exit 77', 77)
|
||||
$(call run_test, ./nsjail $(OLD_EF) -q -Mo --chroot / --user 99999 --group 99999 -- /bin/bash -c 'touch $(HOME)/nsjail_test || exit 77', 77)
|
||||
$(call run_test, rm -f $(HOME)/nsjail_test, 0)
|
||||
@@ -174,6 +190,7 @@ test: $(BIN)
|
||||
$(call run_test, ./nsjail $(OLD_EF) --config configs/firefox-with-net-wayland.cfg -q -t 2, 137)
|
||||
$(call run_test, ./nsjail $(OLD_EF) --config configs/chromium-with-net-wayland.cfg -q -t 2, 137)
|
||||
|
||||
# --- --experimental_mnt=new ---
|
||||
$(call run_test, ./nsjail $(NEW_EF) -q -Mo --rw --chroot / --user 99999 --group 99999 -- /bin/bash -c 'touch $(HOME)/nsjail_test && exit 77', 77)
|
||||
$(call run_test, ./nsjail $(NEW_EF) -q -Mo --chroot / --user 99999 --group 99999 -- /bin/bash -c 'touch $(HOME)/nsjail_test || exit 77', 77)
|
||||
$(call run_test, rm -f $(HOME)/nsjail_test, 0)
|
||||
@@ -194,6 +211,12 @@ test: $(BIN)
|
||||
$(call run_test, ./nsjail $(NEW_EF) --config configs/firefox-with-net-wayland.cfg -q -t 2, 137)
|
||||
$(call run_test, ./nsjail $(NEW_EF) --config configs/chromium-with-net-wayland.cfg -q -t 2, 137)
|
||||
|
||||
@echo ""
|
||||
@echo "========================================"
|
||||
@echo " ✅ All tests passed!"
|
||||
@echo "========================================"
|
||||
@echo ""
|
||||
|
||||
# Dependencies (Generated by makedepend)
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
|
||||
@@ -388,6 +388,7 @@ static bool setupArgv(nsj_t* nsj, int argc, char** argv, int optind) {
|
||||
*/
|
||||
if (optind < argc) {
|
||||
nsj->argv.clear();
|
||||
nsj->njc.mutable_exec_bin()->set_path(argv[optind]);
|
||||
for (int i = optind; i < argc; i++) {
|
||||
nsj->argv.push_back(argv[i]);
|
||||
}
|
||||
|
||||
54
config.proto
54
config.proto
@@ -273,6 +273,60 @@ message NsJailConfig {
|
||||
optional string macvlan_vs_ma = 94 [default = ""];
|
||||
optional string macvlan_vs_mo = 95 [default = "private"];
|
||||
|
||||
message TrafficRule {
|
||||
enum TrafficAction {
|
||||
UNKNOWN_ACTION = 0;
|
||||
DROP = 1; /* Block the traffic silently */
|
||||
REJECT = 2; /* Block and send ICMP unreachable / TCP RST */
|
||||
ALLOW = 3; /* Explicitly allow */
|
||||
ENCAP = 4; /* Encapsulate and route (LWT) */
|
||||
}
|
||||
|
||||
enum EncapType {
|
||||
ENCAP_IP = 0;
|
||||
ENCAP_IP6 = 1;
|
||||
ENCAP_MPLS = 2;
|
||||
ENCAP_ILA = 3;
|
||||
}
|
||||
|
||||
enum IpFamily {
|
||||
IPV4 = 0;
|
||||
IPV6 = 1;
|
||||
}
|
||||
|
||||
enum Protocol {
|
||||
UNKNOWN_PROTO = 0; /* No protocol filter */
|
||||
TCP = 1;
|
||||
UDP = 2;
|
||||
ICMP = 3;
|
||||
ICMPV6 = 4;
|
||||
}
|
||||
|
||||
/* Match parameters (Selectors) */
|
||||
optional string src_ip = 1; /* Source IP or CIDR */
|
||||
optional string dst_ip = 2; /* Dest IP or CIDR */
|
||||
optional string iif = 3; /* Input interface */
|
||||
optional string oif = 4; /* Output interface */
|
||||
optional Protocol proto = 5 [default = UNKNOWN_PROTO];
|
||||
optional uint32 sport = 6; /* Source port */
|
||||
optional uint32 dport = 7; /* Dest port */
|
||||
optional uint32 sport_end = 8; /* For port ranges */
|
||||
optional uint32 dport_end = 9; /* For port ranges */
|
||||
|
||||
/* Action parameters */
|
||||
optional TrafficAction action = 10 [default = DROP];
|
||||
|
||||
/* Encap parameters */
|
||||
optional EncapType encap_type = 11 [default = ENCAP_IP];
|
||||
optional string encap_dst = 12; /* Destination IP (for IP/IP6) or MPLS label */
|
||||
optional uint32 encap_id = 13; /* Tunnel ID (VNI/Key) or MPLS TTL */
|
||||
optional uint64 encap_ila_locator = 14; /* ILA Locator */
|
||||
|
||||
/* Address family: IPV4 (default) or IPV6 */
|
||||
optional IpFamily ip_family = 15 [default = IPV4];
|
||||
}
|
||||
repeated TrafficRule traffic_rule = 100;
|
||||
|
||||
message UserNet {
|
||||
/* Enable User-Mode NAT (via pasta) */
|
||||
optional bool nat = 1 [default = false];
|
||||
|
||||
251
net.cc
251
net.cc
@@ -24,11 +24,15 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/fib_rules.h>
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netlink/route/nexthop.h>
|
||||
#include <netlink/route/route.h>
|
||||
#include <netlink/route/rule.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -45,7 +49,9 @@
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "logs.h"
|
||||
#include "macros.h"
|
||||
@@ -118,6 +124,8 @@ namespace net {
|
||||
|
||||
#define IFACE_NAME "vs"
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netlink/route/link.h>
|
||||
#include <netlink/route/link/macvlan.h>
|
||||
|
||||
@@ -417,36 +425,36 @@ bool initParent(nsj_t* nsj, int pid) {
|
||||
LOG_E("Could not allocate socket with nl_socket_alloc()");
|
||||
return false;
|
||||
}
|
||||
defer {
|
||||
nl_socket_free(sk);
|
||||
};
|
||||
|
||||
int err;
|
||||
if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) {
|
||||
LOG_E("Unable to connect socket: %s", nl_geterror(err));
|
||||
nl_socket_free(sk);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct nl_cache* link_cache;
|
||||
if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) {
|
||||
LOG_E("rtnl_link_alloc_cache(): %s", nl_geterror(err));
|
||||
nl_socket_free(sk);
|
||||
return false;
|
||||
}
|
||||
defer {
|
||||
nl_cache_free(link_cache);
|
||||
};
|
||||
|
||||
for (const auto& iface : nsj->njc.iface_own()) {
|
||||
if (!moveToNs(iface, sk, link_cache, pid)) {
|
||||
nl_cache_free(link_cache);
|
||||
nl_socket_free(sk);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!nsj->njc.macvlan_iface().empty() && !cloneIface(nsj, sk, link_cache, pid)) {
|
||||
nl_cache_free(link_cache);
|
||||
nl_socket_free(sk);
|
||||
return false;
|
||||
}
|
||||
|
||||
nl_cache_free(link_cache);
|
||||
nl_socket_free(sk);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -727,6 +735,213 @@ static bool ifaceConfig(const std::string& iface, const std::string& ip, const s
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parseIp(const std::string& ip_str, struct in_addr* addr, int* mask) {
|
||||
size_t slash = ip_str.find('/');
|
||||
std::string ip = ip_str;
|
||||
*mask = 32;
|
||||
if (slash != std::string::npos) {
|
||||
ip = ip_str.substr(0, slash);
|
||||
*mask = std::stoi(ip_str.substr(slash + 1));
|
||||
}
|
||||
return inet_pton(AF_INET, ip.c_str(), addr) == 1;
|
||||
}
|
||||
|
||||
static bool parseIp6(const std::string& ip_str, struct in6_addr* addr, int* mask) {
|
||||
size_t slash = ip_str.find('/');
|
||||
std::string ip = ip_str;
|
||||
*mask = 128;
|
||||
if (slash != std::string::npos) {
|
||||
ip = ip_str.substr(0, slash);
|
||||
*mask = std::stoi(ip_str.substr(slash + 1));
|
||||
}
|
||||
return inet_pton(AF_INET6, ip.c_str(), addr) == 1;
|
||||
}
|
||||
|
||||
static bool applyEncapRoute(struct nl_sock* sk, const nsjail::NsJailConfig_TrafficRule& rule,
|
||||
int family, uint32_t table_id) {
|
||||
struct rtnl_route* route = rtnl_route_alloc();
|
||||
if (!route) {
|
||||
LOG_E("rtnl_route_alloc() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
rtnl_route_set_table(route, table_id);
|
||||
rtnl_route_set_family(route, family);
|
||||
rtnl_route_set_scope(route, RT_SCOPE_UNIVERSE);
|
||||
rtnl_route_set_type(route, RTN_UNICAST);
|
||||
|
||||
struct nl_addr* dst = nl_addr_alloc(family == AF_INET ? 4 : 16);
|
||||
nl_addr_set_family(dst, family);
|
||||
nl_addr_set_prefixlen(dst, 0);
|
||||
rtnl_route_set_dst(route, dst);
|
||||
nl_addr_put(dst);
|
||||
|
||||
struct rtnl_nexthop* nh = rtnl_route_nh_alloc();
|
||||
if (!nh) {
|
||||
rtnl_route_put(route);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int ifindex =
|
||||
if_nametoindex(rule.has_oif() && !rule.oif().empty() ? rule.oif().c_str() : "lo");
|
||||
if (ifindex > 0) rtnl_route_nh_set_ifindex(nh, ifindex);
|
||||
|
||||
if (rule.has_encap_type()) {
|
||||
struct rtnl_nh_encap* encap = rtnl_nh_encap_alloc();
|
||||
if (!encap) {
|
||||
rtnl_route_nh_free(nh);
|
||||
rtnl_route_put(route);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rule.encap_type() == nsjail::NsJailConfig_TrafficRule::ENCAP_IP) {
|
||||
struct nl_addr* encap_dst;
|
||||
if (rule.has_encap_dst() &&
|
||||
nl_addr_parse(rule.encap_dst().c_str(), AF_INET, &encap_dst) == 0) {
|
||||
rtnl_nh_encap_ip(encap, encap_dst);
|
||||
if (rule.has_encap_id())
|
||||
rtnl_nh_set_encap_ip_id(encap, rule.encap_id());
|
||||
rtnl_route_nh_set_encap(nh, encap);
|
||||
nl_addr_put(encap_dst);
|
||||
}
|
||||
} else if (rule.encap_type() == nsjail::NsJailConfig_TrafficRule::ENCAP_IP6) {
|
||||
struct nl_addr* encap_dst;
|
||||
if (rule.has_encap_dst() &&
|
||||
nl_addr_parse(rule.encap_dst().c_str(), AF_INET6, &encap_dst) == 0) {
|
||||
rtnl_nh_encap_ip6(encap, encap_dst);
|
||||
if (rule.has_encap_id())
|
||||
rtnl_nh_set_encap_ip6_id(encap, rule.encap_id());
|
||||
rtnl_route_nh_set_encap(nh, encap);
|
||||
nl_addr_put(encap_dst);
|
||||
}
|
||||
} else if (rule.encap_type() == nsjail::NsJailConfig_TrafficRule::ENCAP_MPLS) {
|
||||
struct nl_addr* encap_dst;
|
||||
if (rule.has_encap_dst() &&
|
||||
nl_addr_parse(rule.encap_dst().c_str(), AF_MPLS, &encap_dst) == 0) {
|
||||
uint8_t ttl = rule.has_encap_id() ? rule.encap_id() : 255;
|
||||
rtnl_nh_encap_mpls(encap, encap_dst, ttl);
|
||||
rtnl_route_nh_set_encap(nh, encap);
|
||||
nl_addr_put(encap_dst);
|
||||
}
|
||||
} else if (rule.encap_type() == nsjail::NsJailConfig_TrafficRule::ENCAP_ILA) {
|
||||
if (rule.has_encap_ila_locator()) {
|
||||
rtnl_nh_encap_ila(encap, rule.encap_ila_locator());
|
||||
rtnl_route_nh_set_encap(nh, encap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rtnl_route_add_nexthop(route, nh);
|
||||
|
||||
int err = rtnl_route_add(sk, route, NLM_F_CREATE);
|
||||
if (err < 0) {
|
||||
LOG_E("rtnl_route_add() failed: %s", nl_geterror(err));
|
||||
rtnl_route_put(route);
|
||||
return false;
|
||||
}
|
||||
|
||||
rtnl_route_put(route);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool applyTrafficRule(
|
||||
struct nl_sock* sk, const nsjail::NsJailConfig_TrafficRule& rule, int family) {
|
||||
struct rtnl_rule* rtnl_rule = rtnl_rule_alloc();
|
||||
if (!rtnl_rule) {
|
||||
LOG_E("rtnl_rule_alloc() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
rtnl_rule_set_family(rtnl_rule, family);
|
||||
|
||||
if (rule.has_src_ip() && !rule.src_ip().empty()) {
|
||||
struct nl_addr* addr;
|
||||
if (nl_addr_parse(rule.src_ip().c_str(), family, &addr) < 0) {
|
||||
LOG_E("nl_addr_parse(src_ip, %s) failed", rule.src_ip().c_str());
|
||||
rtnl_rule_put(rtnl_rule);
|
||||
return false;
|
||||
}
|
||||
rtnl_rule_set_src(rtnl_rule, addr);
|
||||
nl_addr_put(addr);
|
||||
}
|
||||
if (rule.has_dst_ip() && !rule.dst_ip().empty()) {
|
||||
struct nl_addr* addr;
|
||||
if (nl_addr_parse(rule.dst_ip().c_str(), family, &addr) < 0) {
|
||||
LOG_E("nl_addr_parse(dst_ip, %s) failed", rule.dst_ip().c_str());
|
||||
rtnl_rule_put(rtnl_rule);
|
||||
return false;
|
||||
}
|
||||
rtnl_rule_set_dst(rtnl_rule, addr);
|
||||
nl_addr_put(addr);
|
||||
}
|
||||
if (rule.has_iif() && !rule.iif().empty()) rtnl_rule_set_iif(rtnl_rule, rule.iif().c_str());
|
||||
if (rule.has_oif() && !rule.oif().empty()) rtnl_rule_set_oif(rtnl_rule, rule.oif().c_str());
|
||||
if (rule.has_proto() && rule.proto() != nsjail::NsJailConfig_TrafficRule::UNKNOWN_PROTO) {
|
||||
switch (rule.proto()) {
|
||||
case nsjail::NsJailConfig_TrafficRule::TCP:
|
||||
rtnl_rule_set_ipproto(rtnl_rule, IPPROTO_TCP);
|
||||
break;
|
||||
case nsjail::NsJailConfig_TrafficRule::UDP:
|
||||
rtnl_rule_set_ipproto(rtnl_rule, IPPROTO_UDP);
|
||||
break;
|
||||
case nsjail::NsJailConfig_TrafficRule::ICMP:
|
||||
rtnl_rule_set_ipproto(rtnl_rule, IPPROTO_ICMP);
|
||||
break;
|
||||
case nsjail::NsJailConfig_TrafficRule::ICMPV6:
|
||||
rtnl_rule_set_ipproto(rtnl_rule, IPPROTO_ICMPV6);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rule.has_sport()) {
|
||||
if (rule.has_sport_end())
|
||||
rtnl_rule_set_sport_range(rtnl_rule, rule.sport(), rule.sport_end());
|
||||
else
|
||||
rtnl_rule_set_sport(rtnl_rule, rule.sport());
|
||||
}
|
||||
if (rule.has_dport()) {
|
||||
if (rule.has_dport_end())
|
||||
rtnl_rule_set_dport_range(rtnl_rule, rule.dport(), rule.dport_end());
|
||||
else
|
||||
rtnl_rule_set_dport(rtnl_rule, rule.dport());
|
||||
}
|
||||
|
||||
if (rule.has_action()) {
|
||||
if (rule.action() == nsjail::NsJailConfig_TrafficRule::DROP) {
|
||||
rtnl_rule_set_action(rtnl_rule, FR_ACT_BLACKHOLE);
|
||||
} else if (rule.action() == nsjail::NsJailConfig_TrafficRule::REJECT) {
|
||||
rtnl_rule_set_action(rtnl_rule, FR_ACT_UNREACHABLE);
|
||||
|
||||
} else if (rule.action() == nsjail::NsJailConfig_TrafficRule::ENCAP) {
|
||||
static uint32_t current_table = 1000;
|
||||
uint32_t table_id = current_table++;
|
||||
rtnl_rule_set_action(rtnl_rule, FR_ACT_TO_TBL);
|
||||
rtnl_rule_set_table(rtnl_rule, table_id);
|
||||
if (!applyEncapRoute(sk, rule, family, table_id)) {
|
||||
rtnl_rule_put(rtnl_rule);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (rule.action() == nsjail::NsJailConfig_TrafficRule::ALLOW) {
|
||||
rtnl_rule_set_action(rtnl_rule, FR_ACT_TO_TBL);
|
||||
rtnl_rule_set_table(rtnl_rule, RT_TABLE_MAIN); // Just pass to main routing
|
||||
}
|
||||
} else {
|
||||
rtnl_rule_set_action(rtnl_rule, FR_ACT_BLACKHOLE);
|
||||
}
|
||||
|
||||
int err = rtnl_rule_add(sk, rtnl_rule, NLM_F_CREATE);
|
||||
if (err < 0) {
|
||||
LOG_E("rtnl_rule_add() failed: %s", nl_geterror(err));
|
||||
rtnl_rule_put(rtnl_rule);
|
||||
return false;
|
||||
}
|
||||
|
||||
rtnl_rule_put(rtnl_rule);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initNsFromChild(nsj_t* nsj) {
|
||||
if (!nsj->njc.clone_newnet()) {
|
||||
return true;
|
||||
@@ -739,6 +954,30 @@ bool initNsFromChild(nsj_t* nsj) {
|
||||
nsj->njc.macvlan_vs_gw())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nsj->njc.traffic_rule_size() > 0) {
|
||||
struct nl_sock* sk = nl_socket_alloc();
|
||||
if (!sk) {
|
||||
LOG_E("nl_socket_alloc() failed");
|
||||
return false;
|
||||
}
|
||||
defer {
|
||||
nl_socket_free(sk);
|
||||
};
|
||||
if (nl_connect(sk, NETLINK_ROUTE) < 0) {
|
||||
LOG_E("nl_connect() failed");
|
||||
return false;
|
||||
}
|
||||
for (const auto& rule : nsj->njc.traffic_rule()) {
|
||||
int family = (rule.ip_family() == nsjail::NsJailConfig_TrafficRule::IPV6)
|
||||
? AF_INET6
|
||||
: AF_INET;
|
||||
if (!applyTrafficRule(sk, rule, family)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
32
tests/nat-ip4-only.cfg
Normal file
32
tests/nat-ip4-only.cfg
Normal file
@@ -0,0 +1,32 @@
|
||||
# Test config: NAT with IPv4 only (ip6_enabled=false)
|
||||
|
||||
name: "nat-ip4-only"
|
||||
|
||||
description: "Tests NAT mode with ip6_enabled set to false,"
|
||||
description: "verifying that IPv4-only operation works correctly."
|
||||
|
||||
mode: ONCE
|
||||
hostname: "NAT-IP4"
|
||||
cwd: "/tmp"
|
||||
|
||||
time_limit: 100
|
||||
|
||||
skip_setsid: true
|
||||
|
||||
user_net {
|
||||
nat: true
|
||||
ip6_enabled: false
|
||||
}
|
||||
|
||||
mount {
|
||||
src: "/"
|
||||
dst: "/"
|
||||
is_bind: true
|
||||
rw: false
|
||||
}
|
||||
|
||||
exec_bin {
|
||||
path: "/bin/bash"
|
||||
arg0: "sh"
|
||||
arg: "-i"
|
||||
}
|
||||
32
tests/nat-ip6-only.cfg
Normal file
32
tests/nat-ip6-only.cfg
Normal file
@@ -0,0 +1,32 @@
|
||||
# Test config: NAT with IPv6 only (ip4_enabled=false)
|
||||
|
||||
name: "nat-ip6-only"
|
||||
|
||||
description: "Tests NAT mode with ip4_enabled set to false,"
|
||||
description: "verifying that IPv6-only operation works correctly."
|
||||
|
||||
mode: ONCE
|
||||
hostname: "NAT-IP6"
|
||||
cwd: "/tmp"
|
||||
|
||||
time_limit: 100
|
||||
|
||||
skip_setsid: true
|
||||
|
||||
user_net {
|
||||
nat: true
|
||||
ip4_enabled: false
|
||||
}
|
||||
|
||||
mount {
|
||||
src: "/"
|
||||
dst: "/"
|
||||
is_bind: true
|
||||
rw: false
|
||||
}
|
||||
|
||||
exec_bin {
|
||||
path: "/bin/bash"
|
||||
arg0: "sh"
|
||||
arg: "-i"
|
||||
}
|
||||
32
tests/traffic-drop-tcp4.cfg
Normal file
32
tests/traffic-drop-tcp4.cfg
Normal file
@@ -0,0 +1,32 @@
|
||||
# Test: IPv4 traffic rule that drops all outgoing TCP traffic
|
||||
|
||||
name: "traffic-drop-tcp4"
|
||||
|
||||
description: "Tests that an IPv4 DROP rule on TCP port 80 blocks traffic."
|
||||
|
||||
mode: ONCE
|
||||
|
||||
skip_setsid: true
|
||||
mount_proc: true
|
||||
|
||||
mount {
|
||||
src: "/"
|
||||
dst: "/"
|
||||
is_bind: true
|
||||
}
|
||||
|
||||
user_net {
|
||||
nat: true
|
||||
}
|
||||
|
||||
traffic_rule {
|
||||
proto: TCP
|
||||
dport: 80
|
||||
action: DROP
|
||||
}
|
||||
|
||||
exec_bin {
|
||||
path: "/bin/bash"
|
||||
arg0: "sh"
|
||||
arg: "-i"
|
||||
}
|
||||
32
tests/traffic-drop-udp6.cfg
Normal file
32
tests/traffic-drop-udp6.cfg
Normal file
@@ -0,0 +1,32 @@
|
||||
# Test: IPv6 traffic rule that drops all outgoing UDP traffic on port 53
|
||||
|
||||
name: "traffic-drop-udp6"
|
||||
|
||||
description: "Tests that an IPv6 DROP rule on UDP port 53 is applied correctly."
|
||||
|
||||
mode: ONCE
|
||||
|
||||
skip_setsid: true
|
||||
mount_proc: true
|
||||
|
||||
mount {
|
||||
src: "/"
|
||||
dst: "/"
|
||||
is_bind: true
|
||||
}
|
||||
|
||||
user_net {
|
||||
nat: true
|
||||
}
|
||||
|
||||
traffic_rule {
|
||||
ip_family: IPV6
|
||||
proto: UDP
|
||||
action: DROP
|
||||
}
|
||||
|
||||
exec_bin {
|
||||
path: "/bin/bash"
|
||||
arg0: "sh"
|
||||
arg: "-i"
|
||||
}
|
||||
49
tests/traffic-mixed.cfg
Normal file
49
tests/traffic-mixed.cfg
Normal file
@@ -0,0 +1,49 @@
|
||||
# Test: Mixed IPv4 and IPv6 traffic rules using the unified traffic_rule field
|
||||
|
||||
name: "traffic-mixed"
|
||||
|
||||
description: "Tests a combination of IPv4 and IPv6 traffic rules in a single config,"
|
||||
description: "verifying the unified ip_family field works for both address families."
|
||||
|
||||
mode: ONCE
|
||||
|
||||
skip_setsid: true
|
||||
mount_proc: true
|
||||
|
||||
mount {
|
||||
src: "/"
|
||||
dst: "/"
|
||||
is_bind: true
|
||||
}
|
||||
|
||||
user_net {
|
||||
nat: true
|
||||
}
|
||||
|
||||
# IPv4: reject TCP port 443
|
||||
traffic_rule {
|
||||
proto: TCP
|
||||
dport: 443
|
||||
action: REJECT
|
||||
}
|
||||
|
||||
# IPv6: drop UDP port 53
|
||||
traffic_rule {
|
||||
ip_family: IPV6
|
||||
proto: UDP
|
||||
dport: 53
|
||||
action: DROP
|
||||
}
|
||||
|
||||
# IPv4: allow TCP port 80
|
||||
traffic_rule {
|
||||
proto: TCP
|
||||
dport: 80
|
||||
action: ALLOW
|
||||
}
|
||||
|
||||
exec_bin {
|
||||
path: "/bin/bash"
|
||||
arg0: "sh"
|
||||
arg: "-i"
|
||||
}
|
||||
49
tests/traffic-rules.cfg
Normal file
49
tests/traffic-rules.cfg
Normal file
@@ -0,0 +1,49 @@
|
||||
name: "traffic_rule"
|
||||
description: "Demonstrates the highly structured TrafficRule protobuf API for firewalling and NAT."
|
||||
|
||||
mode: ONCE
|
||||
|
||||
skip_setsid: true
|
||||
mount_proc: true
|
||||
|
||||
mount {
|
||||
src: "/"
|
||||
dst: "/"
|
||||
is_bind: true
|
||||
}
|
||||
|
||||
user_net {
|
||||
nat: true
|
||||
}
|
||||
|
||||
traffic_rule {
|
||||
proto: TCP
|
||||
dport: 443
|
||||
action: DROP
|
||||
}
|
||||
|
||||
traffic_rule {
|
||||
proto: TCP
|
||||
dport: 80
|
||||
dport_end: 85
|
||||
action: ENCAP
|
||||
encap_type: ENCAP_IP
|
||||
encap_dst: "127.0.0.100"
|
||||
encap_id: 100
|
||||
}
|
||||
|
||||
traffic_rule {
|
||||
ip_family: IPV6
|
||||
proto: UDP
|
||||
dport: 53
|
||||
action: ENCAP
|
||||
encap_type: ENCAP_MPLS
|
||||
encap_dst: "200"
|
||||
encap_id: 255
|
||||
}
|
||||
|
||||
exec_bin {
|
||||
path: "/bin/bash"
|
||||
arg0: "sh"
|
||||
arg: "-i"
|
||||
}
|
||||
Reference in New Issue
Block a user