mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 08:34:40 +01:00
fw: support for icmpv6 nftables in system rules
- Add support for all available nftables ICMPv6 types (ip6tables -m icmpv6 --help) - Build nftables ICMPv6 rules - Create a default outbound ICMPv6 echo-request/reply rule (currently outbound echo-request ICMPv6 is by default denied) Signed-off-by: Nico Berlee <nico.berlee@on2it.net>
This commit is contained in:
parent
96fbc8536a
commit
5721ca9479
6 changed files with 89 additions and 6 deletions
|
@ -170,4 +170,8 @@ const (
|
|||
ICMP_ROUTER_SOLICITATION = "router-solicitation"
|
||||
ICMP_ADDRESS_MASK_REQUEST = "address-mask-request"
|
||||
ICMP_ADDRESS_MASK_REPLY = "address-mask-reply"
|
||||
|
||||
ICMP_PACKET_TOO_BIG = "packet-too-big"
|
||||
ICMP_NEIGHBOUR_SOLICITATION = "neighbour-solicitation"
|
||||
ICMP_NEIGHBOUR_ADVERTISEMENT = "neighbour-advertisement"
|
||||
)
|
||||
|
|
|
@ -71,6 +71,16 @@ func NewExprProtocol(proto string) (*[]expr.Any, error) {
|
|||
},
|
||||
}, nil
|
||||
|
||||
case NFT_PROTO_ICMPv6:
|
||||
return &[]expr.Any{
|
||||
&expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1},
|
||||
&expr.Cmp{
|
||||
Op: expr.CmpOpEq,
|
||||
Register: 1,
|
||||
Data: []byte{unix.IPPROTO_ICMPV6},
|
||||
},
|
||||
}, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("Not valid protocol rule, invalid or not supported protocol: %s", proto)
|
||||
}
|
||||
|
|
|
@ -78,6 +78,35 @@ func GetICMPType(icmpType string) uint8 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// GetICMPv6Type returns an ICMPv6 type code
|
||||
func GetICMPv6Type(icmpType string) uint8 {
|
||||
switch icmpType {
|
||||
case ICMP_DEST_UNREACHABLE:
|
||||
return layers.ICMPv6TypeDestinationUnreachable
|
||||
case ICMP_PACKET_TOO_BIG:
|
||||
return layers.ICMPv6TypePacketTooBig
|
||||
case ICMP_TIME_EXCEEDED:
|
||||
return layers.ICMPv6TypeTimeExceeded
|
||||
case ICMP_PARAMETER_PROBLEM:
|
||||
return layers.ICMPv6TypeParameterProblem
|
||||
case ICMP_ECHO_REQUEST:
|
||||
return layers.ICMPv6TypeEchoRequest
|
||||
case ICMP_ECHO_REPLY:
|
||||
return layers.ICMPv6TypeEchoReply
|
||||
case ICMP_ROUTER_SOLICITATION:
|
||||
return layers.ICMPv6TypeRouterSolicitation
|
||||
case ICMP_ROUTER_ADVERTISEMENT:
|
||||
return layers.ICMPv6TypeRouterAdvertisement
|
||||
case ICMP_NEIGHBOUR_SOLICITATION:
|
||||
return layers.ICMPv6TypeNeighborSolicitation
|
||||
case ICMP_NEIGHBOUR_ADVERTISEMENT:
|
||||
return layers.ICMPv6TypeNeighborAdvertisement
|
||||
case ICMP_REDIRECT:
|
||||
return layers.ICMPv6TypeRedirect
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func getICMPv6RejectCode(reason string) uint8 {
|
||||
switch reason {
|
||||
case ICMP_HOST_UNREACHABLE, ICMP_NET_UNREACHABLE, ICMP_NO_ROUTE:
|
||||
|
|
|
@ -71,7 +71,7 @@ func (n *Nft) parseExpression(table, chain, family string, expression *config.Ex
|
|||
exprList = append(exprList, *exprIP...)
|
||||
|
||||
case exprs.NFT_PROTO_ICMP, exprs.NFT_PROTO_ICMPv6:
|
||||
exprICMP := n.buildICMPRule(table, family, expression.Statement.Values)
|
||||
exprICMP := n.buildICMPRule(table, family, expression.Statement.Name, expression.Statement.Values)
|
||||
if exprICMP == nil {
|
||||
log.Warning("%s icmp statement error", logTag)
|
||||
return nil
|
||||
|
|
|
@ -12,15 +12,25 @@ import (
|
|||
|
||||
// rules examples: https://github.com/google/nftables/blob/master/nftables_test.go
|
||||
|
||||
func (n *Nft) buildICMPRule(table, family string, icmpOptions []*config.ExprValues) *[]expr.Any {
|
||||
func (n *Nft) buildICMPRule(table, family string, icmpProtoVersion string, icmpOptions []*config.ExprValues) *[]expr.Any {
|
||||
tbl := getTable(table, family)
|
||||
if tbl == nil {
|
||||
return nil
|
||||
}
|
||||
offset := uint32(0)
|
||||
setType := nftables.TypeICMPType
|
||||
icmpType := uint8(0)
|
||||
setType := nftables.SetDatatype{}
|
||||
|
||||
exprICMP, _ := exprs.NewExprProtocol(exprs.NFT_PROTO_ICMP)
|
||||
switch icmpProtoVersion {
|
||||
case exprs.NFT_PROTO_ICMP:
|
||||
setType = nftables.TypeICMPType
|
||||
case exprs.NFT_PROTO_ICMPv6:
|
||||
setType = nftables.TypeICMP6Type
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
exprICMP, _ := exprs.NewExprProtocol(icmpProtoVersion)
|
||||
ICMPrule := []expr.Any{}
|
||||
ICMPrule = append(ICMPrule, *exprICMP...)
|
||||
|
||||
|
@ -29,10 +39,15 @@ func (n *Nft) buildICMPRule(table, family string, icmpOptions []*config.ExprValu
|
|||
for _, icmp := range icmpOptions {
|
||||
switch icmp.Key {
|
||||
case exprs.NFT_ICMP_TYPE:
|
||||
if exprs.NFT_PROTO_ICMPv6 == icmpProtoVersion {
|
||||
icmpType = exprs.GetICMPv6Type(icmp.Value)
|
||||
} else {
|
||||
icmpType = exprs.GetICMPType(icmp.Value)
|
||||
}
|
||||
exprCmp := &expr.Cmp{
|
||||
Op: expr.CmpOpEq,
|
||||
Register: 1,
|
||||
Data: []byte{exprs.GetICMPType(icmp.Value)},
|
||||
Data: []byte{icmpType},
|
||||
}
|
||||
ICMPtemp = append(ICMPtemp, []expr.Any{exprCmp}...)
|
||||
|
||||
|
@ -40,7 +55,7 @@ func (n *Nft) buildICMPRule(table, family string, icmpOptions []*config.ExprValu
|
|||
setElements = append(setElements,
|
||||
[]nftables.SetElement{
|
||||
{
|
||||
Key: []byte{exprs.GetICMPType(icmp.Value)},
|
||||
Key: []byte{icmpType},
|
||||
},
|
||||
}...)
|
||||
case exprs.NFT_ICMP_CODE:
|
||||
|
|
|
@ -175,6 +175,31 @@
|
|||
"Target": "accept",
|
||||
"TargetParameters": ""
|
||||
},
|
||||
{
|
||||
"Enabled": true,
|
||||
"Position": 0,
|
||||
"Description": "Allow ICMPv6",
|
||||
"Expressions": [
|
||||
{
|
||||
"Statement": {
|
||||
"Op": "",
|
||||
"Name": "icmpv6",
|
||||
"Values": [
|
||||
{
|
||||
"Key": "type",
|
||||
"Value": "echo-request"
|
||||
},
|
||||
{
|
||||
"Key": "type",
|
||||
"Value": "echo-reply"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"Target": "accept",
|
||||
"TargetParameters": ""
|
||||
},
|
||||
{
|
||||
"Enabled": false,
|
||||
"Position": "0",
|
||||
|
|
Loading…
Add table
Reference in a new issue