Signed-off-by: Alessandro Boch <aboch@docker.com>
| ... | ... |
@@ -326,6 +326,21 @@ func (c *ChainInfo) Remove() error {
|
| 326 | 326 |
|
| 327 | 327 |
// Exists checks if a rule exists |
| 328 | 328 |
func Exists(table Table, chain string, rule ...string) bool {
|
| 329 |
+ return exists(false, table, chain, rule...) |
|
| 330 |
+} |
|
| 331 |
+ |
|
| 332 |
+// ExistsNative behaves as Exists with the difference it |
|
| 333 |
+// will always invoke `iptables` binary. |
|
| 334 |
+func ExistsNative(table Table, chain string, rule ...string) bool {
|
|
| 335 |
+ return exists(true, table, chain, rule...) |
|
| 336 |
+} |
|
| 337 |
+ |
|
| 338 |
+func exists(native bool, table Table, chain string, rule ...string) bool {
|
|
| 339 |
+ f := Raw |
|
| 340 |
+ if native {
|
|
| 341 |
+ f = raw |
|
| 342 |
+ } |
|
| 343 |
+ |
|
| 329 | 344 |
if string(table) == "" {
|
| 330 | 345 |
table = Filter |
| 331 | 346 |
} |
| ... | ... |
@@ -334,7 +349,7 @@ func Exists(table Table, chain string, rule ...string) bool {
|
| 334 | 334 |
|
| 335 | 335 |
if supportsCOpt {
|
| 336 | 336 |
// if exit status is 0 then return true, the rule exists |
| 337 |
- _, err := Raw(append([]string{"-t", string(table), "-C", chain}, rule...)...)
|
|
| 337 |
+ _, err := f(append([]string{"-t", string(table), "-C", chain}, rule...)...)
|
|
| 338 | 338 |
return err == nil |
| 339 | 339 |
} |
| 340 | 340 |
|
| ... | ... |
@@ -935,6 +935,14 @@ func redirecter() {
|
| 935 | 935 |
rule := strings.Fields(fmt.Sprintf("-t nat -A PREROUTING -d %s -p %s --dport %d -j REDIRECT --to-port %d",
|
| 936 | 936 |
eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort, iPort.TargetPort)) |
| 937 | 937 |
rules = append(rules, rule) |
| 938 |
+ // Allow only incoming connections to exposed ports |
|
| 939 |
+ iRule := strings.Fields(fmt.Sprintf("-I INPUT -d %s -p %s --dport %d -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT",
|
|
| 940 |
+ eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.TargetPort)) |
|
| 941 |
+ rules = append(rules, iRule) |
|
| 942 |
+ // Allow only outgoing connections from exposed ports |
|
| 943 |
+ oRule := strings.Fields(fmt.Sprintf("-I OUTPUT -s %s -p %s --sport %d -m conntrack --ctstate ESTABLISHED -j ACCEPT",
|
|
| 944 |
+ eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.TargetPort)) |
|
| 945 |
+ rules = append(rules, oRule) |
|
| 938 | 946 |
} |
| 939 | 947 |
|
| 940 | 948 |
ns, err := netns.GetFromPath(os.Args[1]) |
| ... | ... |
@@ -952,7 +960,31 @@ func redirecter() {
|
| 952 | 952 |
for _, rule := range rules {
|
| 953 | 953 |
if err := iptables.RawCombinedOutputNative(rule...); err != nil {
|
| 954 | 954 |
logrus.Errorf("setting up rule failed, %v: %v", rule, err)
|
| 955 |
- os.Exit(5) |
|
| 955 |
+ os.Exit(6) |
|
| 956 |
+ } |
|
| 957 |
+ } |
|
| 958 |
+ |
|
| 959 |
+ if len(ingressPorts) == 0 {
|
|
| 960 |
+ return |
|
| 961 |
+ } |
|
| 962 |
+ |
|
| 963 |
+ // Ensure blocking rules for anything else in/to ingress network |
|
| 964 |
+ for _, rule := range [][]string{
|
|
| 965 |
+ {"-d", eIP.String(), "-p", "udp", "-j", "DROP"},
|
|
| 966 |
+ {"-d", eIP.String(), "-p", "tcp", "-j", "DROP"},
|
|
| 967 |
+ } {
|
|
| 968 |
+ if !iptables.ExistsNative(iptables.Filter, "INPUT", rule...) {
|
|
| 969 |
+ if err := iptables.RawCombinedOutputNative(append([]string{"-A", "INPUT"}, rule...)...); err != nil {
|
|
| 970 |
+ logrus.Errorf("setting up rule failed, %v: %v", rule, err)
|
|
| 971 |
+ os.Exit(7) |
|
| 972 |
+ } |
|
| 973 |
+ } |
|
| 974 |
+ rule[0] = "-s" |
|
| 975 |
+ if !iptables.ExistsNative(iptables.Filter, "OUTPUT", rule...) {
|
|
| 976 |
+ if err := iptables.RawCombinedOutputNative(append([]string{"-A", "OUTPUT"}, rule...)...); err != nil {
|
|
| 977 |
+ logrus.Errorf("setting up rule failed, %v: %v", rule, err)
|
|
| 978 |
+ os.Exit(8) |
|
| 979 |
+ } |
|
| 956 | 980 |
} |
| 957 | 981 |
} |
| 958 | 982 |
} |