|
@@ -13,24 +13,24 @@ import (
|
|
|
"github.com/Sirupsen/logrus"
|
|
|
)
|
|
|
|
|
|
-//Action signifies the iptable action.
|
|
|
+// Action signifies the iptable action.
|
|
|
type Action string
|
|
|
|
|
|
-//Table refers to Nat, Filter or Mangle.
|
|
|
+// Table refers to Nat, Filter or Mangle.
|
|
|
type Table string
|
|
|
|
|
|
const (
|
|
|
- //Append appends the rule at the end of the chain.
|
|
|
+ // Append appends the rule at the end of the chain.
|
|
|
Append Action = "-A"
|
|
|
- //Delete deletes the rule from the chain.
|
|
|
+ // Delete deletes the rule from the chain.
|
|
|
Delete Action = "-D"
|
|
|
- //Insert inserts the rule at the top of the chain.
|
|
|
+ // Insert inserts the rule at the top of the chain.
|
|
|
Insert Action = "-I"
|
|
|
- //Nat table is used for nat translation rules.
|
|
|
+ // Nat table is used for nat translation rules.
|
|
|
Nat Table = "nat"
|
|
|
- //Filter table is used for filter rules.
|
|
|
+ // Filter table is used for filter rules.
|
|
|
Filter Table = "filter"
|
|
|
- //Mangle table is used for mangling the packet.
|
|
|
+ // Mangle table is used for mangling the packet.
|
|
|
Mangle Table = "mangle"
|
|
|
)
|
|
|
|
|
@@ -39,18 +39,18 @@ var (
|
|
|
supportsXlock = false
|
|
|
// used to lock iptables commands if xtables lock is not supported
|
|
|
bestEffortLock sync.Mutex
|
|
|
- //ErrIptablesNotFound is returned when the rule is not found.
|
|
|
+ // ErrIptablesNotFound is returned when the rule is not found.
|
|
|
ErrIptablesNotFound = errors.New("Iptables not found")
|
|
|
)
|
|
|
|
|
|
-//Chain defines the iptables chain.
|
|
|
+// Chain defines the iptables chain.
|
|
|
type Chain struct {
|
|
|
Name string
|
|
|
Bridge string
|
|
|
Table Table
|
|
|
}
|
|
|
|
|
|
-//ChainError is returned to represent errors during ip table operation.
|
|
|
+// ChainError is returned to represent errors during ip table operation.
|
|
|
type ChainError struct {
|
|
|
Chain string
|
|
|
Output []byte
|
|
@@ -73,8 +73,8 @@ func initCheck() error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-//NewChain adds a new chain to ip table.
|
|
|
-func NewChain(name, bridge string, table Table) (*Chain, error) {
|
|
|
+// NewChain adds a new chain to ip table.
|
|
|
+func NewChain(name, bridge string, table Table, hairpinMode bool) (*Chain, error) {
|
|
|
c := &Chain{
|
|
|
Name: name,
|
|
|
Bridge: bridge,
|
|
@@ -106,8 +106,10 @@ func NewChain(name, bridge string, table Table) (*Chain, error) {
|
|
|
}
|
|
|
output := []string{
|
|
|
"-m", "addrtype",
|
|
|
- "--dst-type", "LOCAL",
|
|
|
- "!", "--dst", "127.0.0.0/8"}
|
|
|
+ "--dst-type", "LOCAL"}
|
|
|
+ if !hairpinMode {
|
|
|
+ output = append(output, "!", "--dst", "127.0.0.0/8")
|
|
|
+ }
|
|
|
if !Exists(Nat, "OUTPUT", output...) {
|
|
|
if err := c.Output(Append, output...); err != nil {
|
|
|
return nil, fmt.Errorf("Failed to inject docker in OUTPUT chain: %s", err)
|
|
@@ -129,7 +131,7 @@ func NewChain(name, bridge string, table Table) (*Chain, error) {
|
|
|
return c, nil
|
|
|
}
|
|
|
|
|
|
-//RemoveExistingChain removes existing chain from the table.
|
|
|
+// RemoveExistingChain removes existing chain from the table.
|
|
|
func RemoveExistingChain(name string, table Table) error {
|
|
|
c := &Chain{
|
|
|
Name: name,
|
|
@@ -141,7 +143,7 @@ func RemoveExistingChain(name string, table Table) error {
|
|
|
return c.Remove()
|
|
|
}
|
|
|
|
|
|
-//Forward adds forwarding rule to 'filter' table and corresponding nat rule to 'nat' table
|
|
|
+// Forward adds forwarding rule to 'filter' table and corresponding nat rule to 'nat' table.
|
|
|
func (c *Chain) Forward(action Action, ip net.IP, port int, proto, destAddr string, destPort int) error {
|
|
|
daddr := ip.String()
|
|
|
if ip.IsUnspecified() {
|
|
@@ -154,7 +156,6 @@ func (c *Chain) Forward(action Action, ip net.IP, port int, proto, destAddr stri
|
|
|
"-p", proto,
|
|
|
"-d", daddr,
|
|
|
"--dport", strconv.Itoa(port),
|
|
|
- "!", "-i", c.Bridge,
|
|
|
"-j", "DNAT",
|
|
|
"--to-destination", net.JoinHostPort(destAddr, strconv.Itoa(destPort))); err != nil {
|
|
|
return err
|
|
@@ -188,7 +189,7 @@ func (c *Chain) Forward(action Action, ip net.IP, port int, proto, destAddr stri
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-//Link adds reciprocal ACCEPT rule for two supplied IP addresses.
|
|
|
+// Link adds reciprocal ACCEPT rule for two supplied IP addresses.
|
|
|
// Traffic is allowed from ip1 to ip2 and vice-versa
|
|
|
func (c *Chain) Link(action Action, ip1, ip2 net.IP, port int, proto string) error {
|
|
|
if output, err := Raw("-t", string(Filter), string(action), c.Name,
|
|
@@ -216,7 +217,7 @@ func (c *Chain) Link(action Action, ip1, ip2 net.IP, port int, proto string) err
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-//Prerouting adds linking rule to nat/PREROUTING chain.
|
|
|
+// Prerouting adds linking rule to nat/PREROUTING chain.
|
|
|
func (c *Chain) Prerouting(action Action, args ...string) error {
|
|
|
a := []string{"-t", string(Nat), string(action), "PREROUTING"}
|
|
|
if len(args) > 0 {
|
|
@@ -230,7 +231,7 @@ func (c *Chain) Prerouting(action Action, args ...string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-//Output adds linking rule to an OUTPUT chain
|
|
|
+// Output adds linking rule to an OUTPUT chain.
|
|
|
func (c *Chain) Output(action Action, args ...string) error {
|
|
|
a := []string{"-t", string(c.Table), string(action), "OUTPUT"}
|
|
|
if len(args) > 0 {
|
|
@@ -244,7 +245,7 @@ func (c *Chain) Output(action Action, args ...string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// Remove removes the chain
|
|
|
+// Remove removes the chain.
|
|
|
func (c *Chain) Remove() error {
|
|
|
// Ignore errors - This could mean the chains were never set up
|
|
|
if c.Table == Nat {
|
|
@@ -260,7 +261,7 @@ func (c *Chain) Remove() error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-//Exists checks if a rule exists
|
|
|
+// Exists checks if a rule exists
|
|
|
func Exists(table Table, chain string, rule ...string) bool {
|
|
|
if string(table) == "" {
|
|
|
table = Filter
|
|
@@ -291,7 +292,7 @@ func Exists(table Table, chain string, rule ...string) bool {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
-//Raw calls 'iptables' system command, passing supplied arguments
|
|
|
+// Raw calls 'iptables' system command, passing supplied arguments.
|
|
|
func Raw(args ...string) ([]byte, error) {
|
|
|
if firewalldRunning {
|
|
|
output, err := Passthrough(Iptables, args...)
|