xtables

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 11, 2023 License: Apache-2.0 Imports: 4 Imported by: 2

README

GO-XTABLES

Go Reference Go License Go Report Card Platform

English | 简体中文

Overview

Background

Netfilter allows packets to be filtered, transformed, and modified across multiple tables and chains, it provides multiple socket options for setsockopt and getsockopt to allow upper-layer applications to add, delete, modify, and query rules. However, these socket options are not directly exposed to developers due to the lack of standard definition. For C/C++ developers, the libiptc library can be used to interact with Netfilter. But according to the official description, libiptc does not mean that it is open to the public. So, for Go developers, using system call to wrap socket or using cgo to wrap libiptc is not a good choice. According to the Netfilter instructions, it is recommended that developers use the iptables, ebtables, and arptables tools to operate on packets.

Go-xtables is a wrapper for the iptables, ebtables, and arptables tools. Compared to other libraries, it provides additional capabilities for ebtables and arptables, full feature support (wrapping all extension capabilities mentioned in the man pages), and offers chain and option modes for external use. It fully inherits several abstractions for users from the tables, making it very convenient to use.

Check out the iptables godoc and ebtables godoc to learn about the 70+ match capabilities, 50+ target capabilities, and 10+ option capabilities.

Design

Features
  • Easy to use.
  • Multiple tables(iptables, ebtables, arptables) to support.
  • Full featured matches, options, watchers and other extensions.
  • Chainable method and order free.
  • Dryrun commands to writer.
  • Log control(inner log, logrus etc.).

Usage

Getting Started
Only accep ssh, http and https ports for incoming traffic
package main

import (
	"log"

	"github.com/singchia/go-xtables/iptables"
	"github.com/singchia/go-xtables/pkg/network"
)

func main() {
	ipt := iptables.NewIPTables().
		Table(iptables.TableTypeFilter).
		Chain(iptables.ChainTypeINPUT).
		MatchProtocol(false, network.ProtocolTCP)

	// allow ssh
	err := ipt.MatchTCP(iptables.WithMatchTCPDstPort(false, 22)).TargetAccept().Insert()
	if err != nil {
		log.Fatal(err)
		return
	}
	// allow http
	err = ipt.MatchTCP(iptables.WithMatchTCPDstPort(false, 80)).TargetAccept().Insert()
	if err != nil {
		log.Fatal(err)
		return
	}
	// allow https
	err = ipt.MatchTCP(iptables.WithMatchTCPDstPort(false, 443)).TargetAccept().Insert()
	if err != nil {
		log.Fatal(err)
		return
	}
	// drop others
	err = iptables.NewIPTables().Table(iptables.TableTypeFilter).Chain(iptables.ChainTypeINPUT).Policy(iptables.TargetTypeDrop)
	if err != nil {
		log.Fatal(err)
		return
	}
}

Or

package main

import (
	"log"

	"github.com/singchia/go-xtables/iptables"
	"github.com/singchia/go-xtables/pkg/network"
)

func main() {
	ipt := iptables.NewIPTables().
		Table(iptables.TableTypeFilter).
		Chain(iptables.ChainTypeINPUT).
		MatchProtocol(false, network.ProtocolTCP)

	// allow ssh, http and https
	err := ipt.MatchMultiPort(
		iptables.WithMatchMultiPortDst(false, iptables.PortRange{Start: 22}, iptables.PortRange{Start: 80}, iptables.PortRange{Start: 443})).
		TargetAccept().Insert()
	if err != nil {
		log.Fatal(err)
		return
	}
	// drop others
	err = iptables.NewIPTables().Table(iptables.TableTypeFilter).Chain(iptables.ChainTypeINPUT).Policy(iptables.TargetTypeDrop)
	if err != nil {
		log.Fatal(err)
		return
	}
}
Simple Use
Drop all incoming traffic on specific port
iptables.NewIPTables().
	Table(iptables.TableTypeFilter).
	Chain(iptables.ChainTypeINPUT).
	MatchProtocol(false, network.ProtocolTCP).
	MatchTCP(iptables.WithMatchTCPDstPort(false, 2432)).
	TargetDrop().
	Append()
Accept all incoming traffic from a specific source IP address
iptables.NewIPTables().
	Table(iptables.TableTypeFilter).
	Chain(iptables.ChainTypeINPUT).
	MatchSource(false, "192.168.1.100").
	TargetAccept().
	Append()
rules, err := iptables.NewIPTables().
	Table(iptables.TableTypeFilter).
	Chain(iptables.ChainTypeINPUT).
	MatchSource(false, "192.168.1.100").
	TargetAccept().
	FindRules()
Delete all rules from all tables
iptables.NewIPTables().Flush()
Allow a maximum of 10 connections per minute to enter port 80
iptables.NewIPTables().
	Table(iptables.TableTypeFilter).
	Chain(iptables.ChainTypeINPUT).
	MatchProtocol(false, network.ProtocolTCP).
	MatchTCP(iptables.WithMatchTCPDstPort(false, 80)).
	MatchLimit(iptables.WithMatchLimit(xtables.Rate{10, xtables.Minute})).
	TargetAccept().
	Append()
Mirror traffic to the gateway
iptables.NewIPTables().
	Table(iptables.TableTypeMangle).
	Chain(iptables.ChainTypePREROUTING).
	MatchProtocol(false, network.ProtocolTCP).
	MatchTCP(iptables.WithMatchTCPDstPort(false, 2432)).
	TargetTEE(net.ParseIP("192.168.1.1")).
	Insert()
Deny access from a specific MAC address.

This example uses ebtables. Please note that this rule applies to the linux-bridge, so make sure that the network interface is being hosted by the bridge.

ebtables.NewEBTables().
	Table(ebtables.TableTypeFilter).
	Chain(ebtables.ChainTypeINPUT).
	MatchSource(false, "00:11:22:33:44:55").
	TargetDrop().
	Append()
Real-world scenario
Anti DDOS attack
custom := "SYN_FLOOD"
ipt := iptables.NewIPTables().Table(iptables.TableTypeFilter)
ipt.NewChain(custom)
ipt.Chain(iptables.ChainTypeINPUT).
	MatchProtocol(false, network.ProtocolTCP).
	MatchTCP(iptables.WithMatchTCPSYN(false)).
	TargetJumpChain(custom).
	Append()

userDefined := iptables.ChainTypeUserDefined
userDefined.SetName(custom)
rate := xtables.Rate{1, xtables.Second}
ipt.Chain(userDefined).
	MatchLimit(
		iptables.WithMatchLimit(rate),
		iptables.WithMatchLimitBurst(3)).
	TargetReturn().
	Append()
ipt.Chain(userDefined).
	TargetDrop().
	Append()
Disable PING
iptables.NewIPTables().
	Table(iptables.TableTypeFilter).
	Chain(iptables.ChainTypeINPUT).
	MatchProtocol(false, network.ProtocolICMP).
	MatchICMP(false, network.ICMPType(network.EchoRequest)).
	TargetDrop().
	Append()
Traffic outbound only except ssh port
ipt := iptables.NewIPTables().Table(iptables.TableTypeFilter)
ipt.Chain(iptables.ChainTypeINPUT).
	MatchInInterface(false, "lo").
	TargetAccept().
	Append()
ipt.Chain(iptables.ChainTypeINPUT).
	MatchState(iptables.ESTABLISHED | iptables.RELATED).
	TargetAccept().
	Append()
ipt.Chain(iptables.ChainTypeINPUT).
	MatchProtocol(false, network.ProtocolTCP).
	MatchTCP(iptables.WithMatchTCPDstPort(false, 22)).
	TargetAccept().
	Append()
ipt.Chain(iptables.ChainTypeINPUT).Policy(iptables.TargetTypeDrop)
ipt.Chain(iptables.ChainTypeFORWARD).Policy(iptables.TargetTypeDrop)
ipt.Chain(iptables.ChainTypeOUTPUT).Policy(iptables.TargetTypeAccept)

Note

Compatibility

Starting from Linux kernel version 4.18, nftables became part of the kernel and gradually replaced iptables. Therefore, distributions using Linux 4.18 and higher versions typically use nftables instead of iptables. Since nftables is not fully compatible with iptables, if you still want to continue using go-xtables, it is best to switch to iptables to continue using it when using these distributions.

The following distributions need to pay attention to compatibility:

  • Debian 10(Buster) and higher versions
  • Ubuntu 18.04(Bionic Beaver) and higher versions.
  • Centos 8 and higher versions.
  • Fedora 18 and higher versions.
  • OpenSUSE Leap 15.2 and higher versions.
  • Arch Linux

Contributing

Currently, go-xtables is in the proof-of-concept (POC) stage. If you find any bugs, please feel free to submit an issue, and the project maintainers will respond to the relevant issues promptly.

If you want to contribute new features or help solve project problems more quickly, please feel free to submit a PR that meets the following simple conditions:

  • Maintain consistent code style
  • Submit one feature at a time
  • Include unit tests with the code you submit
  • Pass the CI build

And after code review, it will be merged into the project.

License

© Austin Zhai, 2022-2025

Released under the Apache License 2.0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnsupportedAddress       = errors.New("unsupported address")
	ErrIllegalAddress           = errors.New("illegal address")
	ErrChainRequired            = errors.New("chain required")
	ErrCommandRequired          = errors.New("command required")
	ErrRulenumMustNot0          = errors.New("rulenum mustn't be 0")
	ErrChainLineTooShort        = errors.New("chain line too short")
	ErrChainAttrsNotRecognized  = errors.New("chain attrs not recognized")
	ErrArgs                     = errors.New("wrong args")
	ErrTargetNotFound           = errors.New("target not found")
	ErrMatchParams              = errors.New("illegal match params")
	ErrWatcherParams            = errors.New("illegal watcher params")
	ErrTargetParams             = errors.New("illegal target params")
	ErrAtLeastOneOptionRequired = errors.New("at least one option required")
	ErrTargetParseFailed        = errors.New("target parse failed")
	ErrIllegalTargetType        = errors.New("illegal target type")
	ErrArgsWithoutMAC           = errors.New("args without mac address")
)
View Source
var (
	Weekdays = map[string]Weekday{
		"Mon": Monday,
		"Tue": Tuesday,
		"Wed": Wednesday,
		"Thu": Thursday,
		"Fri": Friday,
		"Sat": Saturday,
		"Sun": Sunday,
	}
)

Functions

func ErrAndStdErr

func ErrAndStdErr(err error, stderr []byte) error

Types

type CommandError

type CommandError struct {
	Err     error
	Message string
}

func (*CommandError) Error

func (ce *CommandError) Error() string

func (*CommandError) IsRuleNotExistError

func (ce *CommandError) IsRuleNotExistError() bool

type Date

type Date struct {
	*Yeartime
	*Daytime
}

func ParseDate

func ParseDate(date string) (*Date, error)

func (*Date) String

func (date *Date) String() string

type Daytime

type Daytime struct {
	Hour   int8
	Minute int8
	Second int8
	// contains filtered or unexported fields
}

func ParseDaytime

func ParseDaytime(daytime string) (*Daytime, error)

func (*Daytime) String

func (dt *Daytime) String() string

type Direction

type Direction int
const (
	In Direction = 1 << iota
	Out
)

func (Direction) String

func (dir Direction) String() string

type LogLevel

type LogLevel int8
const (
	LogLevelEMERG   LogLevel = 0 /* system is unusable */
	LogLevelALERT   LogLevel = 1 /* action must be taken immediately */
	LogLevelCRIT    LogLevel = 2 /* critical conditions */
	LogLevelERR     LogLevel = 3 /* error conditions */
	LogLevelWARNING LogLevel = 4 /* warning conditions */
	LogLevelNOTICE  LogLevel = 5 /* normal but significant condition */
	LogLevelINFO    LogLevel = 6 /* informational */
	LogLevelDEBUG   LogLevel = 7 /* debug-level messages */
)

type Monthday

type Monthday int32

func (Monthday) String

func (monthday Monthday) String() string

type Operator

type Operator uint32
const (
	OperatorNull Operator = iota
	OperatorEQ            // ==
	OperatorNE            // !=
	OperatorLT            // <
	OperatorGT            // >
	OperatorINC           // +
	OperatorDEC           // -
	OperatorSET           // =
	OperatorXSET          // ^=
	OperatorAND           // &
	OperatorOR            // |
	OperatorXOR           // ^|
)

func (Operator) String

func (operator Operator) String() string

type Rate

type Rate struct {
	Rate int
	Unit Unit
}

func (Rate) String

func (rate Rate) String() string

type RateFloat

type RateFloat struct {
	Rate float64
	Unit Unit
}

func (RateFloat) Sting

func (rateFloat RateFloat) Sting() string

type Unit

type Unit int

time related

const (
	Microsecond Unit
	Millisecond
	Second
	Minute
	Hour
	Day
	BPS  // bytes per second
	KBPS // kilo bytes per second
	MBPS // million bytes per second
)

type Weekday

type Weekday int8
const (
	Monday Weekday = 1 << iota
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
	Sunday
)

func (Weekday) String

func (weekday Weekday) String() string

type Yeartime

type Yeartime struct {
	Year  int16
	Month int8
	Day   int8
	// contains filtered or unexported fields
}

func ParseYeartime

func ParseYeartime(yeartime string) (*Yeartime, error)

func (*Yeartime) String

func (yt *Yeartime) String() string

Directories

Path Synopsis
test command
examples
* Apache License 2.0 * * Copyright (c) 2022, Austin Zhai * All rights reserved.
* Apache License 2.0 * * Copyright (c) 2022, Austin Zhai * All rights reserved.
internal
test command
pkg
cmd
log
* Apache License 2.0 * * Copyright (c) 2022, Austin Zhai * All rights reserved.
* Apache License 2.0 * * Copyright (c) 2022, Austin Zhai * All rights reserved.
network
* Apache License 2.0 * * Copyright (c) 2022, Austin Zhai * All rights reserved.
* Apache License 2.0 * * Copyright (c) 2022, Austin Zhai * All rights reserved.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL