iptables.py (salt-3002.1) | : | iptables.py (salt-3002.2) | ||
---|---|---|---|---|
# -*- coding: utf-8 -*- | ||||
""" | """ | |||
Support for iptables | Support for iptables | |||
Configuration Options | Configuration Options | |||
--------------------- | --------------------- | |||
The following options can be set in the minion config, grains, pillar, or | The following options can be set in the minion config, grains, pillar, or | |||
master config. The configuration is read using :py:func:`config.get | master config. The configuration is read using :py:func:`config.get | |||
<salt.modules.config.get>`. | <salt.modules.config.get>`. | |||
skipping to change at line 28 | skipping to change at line 27 | |||
.. code-block:: yaml | .. code-block:: yaml | |||
iptables.save_filters: | iptables.save_filters: | |||
- "-j CATTLE_PREROUTING" | - "-j CATTLE_PREROUTING" | |||
- "-j DOCKER" | - "-j DOCKER" | |||
- "-A POSTROUTING" | - "-A POSTROUTING" | |||
- "-A CATTLE_POSTROUTING" | - "-A CATTLE_POSTROUTING" | |||
- "-A FORWARD" | - "-A FORWARD" | |||
""" | """ | |||
from __future__ import absolute_import, print_function, unicode_literals | ||||
import logging | import logging | |||
# Import python libs | ||||
import os | import os | |||
import re | import re | |||
import string | import string | |||
import sys | import sys | |||
import uuid | import uuid | |||
# Import salt libs | ||||
import salt.utils.args | import salt.utils.args | |||
import salt.utils.files | import salt.utils.files | |||
import salt.utils.path | import salt.utils.path | |||
from salt.exceptions import SaltException | from salt.exceptions import SaltException | |||
from salt.ext import six | ||||
from salt.state import STATE_INTERNAL_KEYWORDS as _STATE_INTERNAL_KEYWORDS | from salt.state import STATE_INTERNAL_KEYWORDS as _STATE_INTERNAL_KEYWORDS | |||
log = logging.getLogger(__name__) | log = logging.getLogger(__name__) | |||
def __virtual__(): | def __virtual__(): | |||
""" | """ | |||
Only load the module if iptables is installed | Only load the module if iptables is installed | |||
""" | """ | |||
if not salt.utils.path.which("iptables"): | if not salt.utils.path.which("iptables"): | |||
return ( | return ( | |||
skipping to change at line 79 | skipping to change at line 73 | |||
def _has_option(option, family="ipv4"): | def _has_option(option, family="ipv4"): | |||
""" | """ | |||
Return truth of whether iptables has `option`. For example: | Return truth of whether iptables has `option`. For example: | |||
.. code-block:: python | .. code-block:: python | |||
_has_option('--wait') | _has_option('--wait') | |||
_has_option('--check', family='ipv6') | _has_option('--check', family='ipv6') | |||
""" | """ | |||
cmd = "{0} --help".format(_iptables_cmd(family)) | cmd = "{} --help".format(_iptables_cmd(family)) | |||
if option in __salt__["cmd.run"](cmd, output_loglevel="quiet"): | if option in __salt__["cmd.run"](cmd, output_loglevel="quiet"): | |||
return True | return True | |||
return False | return False | |||
def _conf(family="ipv4"): | def _conf(family="ipv4"): | |||
""" | """ | |||
Some distros have a specific location for config files | Some distros have a specific location for config files | |||
""" | """ | |||
if __grains__["os_family"] == "RedHat": | if __grains__["os_family"] == "RedHat": | |||
if family == "ipv6": | if family == "ipv6": | |||
skipping to change at line 121 | skipping to change at line 115 | |||
elif __grains__["os_family"] == "Void": | elif __grains__["os_family"] == "Void": | |||
if family == "ipv4": | if family == "ipv4": | |||
return "/etc/iptables/iptables.rules" | return "/etc/iptables/iptables.rules" | |||
else: | else: | |||
return "/etc/iptables/ip6tables.rules" | return "/etc/iptables/ip6tables.rules" | |||
elif __grains__["os"] == "Alpine": | elif __grains__["os"] == "Alpine": | |||
if family == "ipv6": | if family == "ipv6": | |||
return "/etc/iptables/rules6-save" | return "/etc/iptables/rules6-save" | |||
else: | else: | |||
return "/etc/iptables/rules-save" | return "/etc/iptables/rules-save" | |||
elif __grains__["os_family"] == "NILinuxRT": | ||||
if family == "ipv6": | ||||
return "/etc/natinst/share/ip6tables.conf" | ||||
else: | ||||
return "/etc/natinst/share/iptables.conf" | ||||
else: | else: | |||
raise SaltException( | raise SaltException( | |||
"Saving iptables to file is not" | "Saving iptables to file is not" | |||
+ " supported on {0}.".format(__grains__["os"]) | + " supported on {}.".format(__grains__["os"]) | |||
+ " Please file an issue with SaltStack" | + " Please file an issue with SaltStack" | |||
) | ) | |||
def _conf_save_filters(): | def _conf_save_filters(): | |||
""" | """ | |||
Return array of strings from `save_filters` in config. | Return array of strings from `save_filters` in config. | |||
This array will be pulled from minion config, minion grains, | This array will be pulled from minion config, minion grains, | |||
minion pillar, or master config. The default value returned is []. | minion pillar, or master config. The default value returned is []. | |||
skipping to change at line 188 | skipping to change at line 187 | |||
CLI Example: | CLI Example: | |||
.. code-block:: bash | .. code-block:: bash | |||
salt '*' iptables.version | salt '*' iptables.version | |||
IPv6: | IPv6: | |||
salt '*' iptables.version family=ipv6 | salt '*' iptables.version family=ipv6 | |||
""" | """ | |||
cmd = "{0} --version".format(_iptables_cmd(family)) | cmd = "{} --version".format(_iptables_cmd(family)) | |||
out = __salt__["cmd.run"](cmd).split() | out = __salt__["cmd.run"](cmd).split() | |||
return out[1] | return out[1] | |||
def build_rule( | def build_rule( | |||
table="filter", | table="filter", | |||
chain=None, | chain=None, | |||
command=None, | command=None, | |||
position="", | position="", | |||
full=None, | full=None, | |||
family="ipv4", | family="ipv4", | |||
skipping to change at line 287 | skipping to change at line 286 | |||
The prefix will be removed from the value in the kwargs dict. | The prefix will be removed from the value in the kwargs dict. | |||
""" | """ | |||
value = str(kwargs[arg]) | value = str(kwargs[arg]) | |||
if value.startswith("!") or value.startswith("not"): | if value.startswith("!") or value.startswith("not"): | |||
kwargs[arg] = re.sub(bang_not_pat, "", value) | kwargs[arg] = re.sub(bang_not_pat, "", value) | |||
return "! " | return "! " | |||
return "" | return "" | |||
if "if" in kwargs: | if "if" in kwargs: | |||
rule.append("{0}-i {1}".format(maybe_add_negation("if"), kwargs["if"])) | rule.append("{}-i {}".format(maybe_add_negation("if"), kwargs["if"])) | |||
del kwargs["if"] | del kwargs["if"] | |||
if "of" in kwargs: | if "of" in kwargs: | |||
rule.append("{0}-o {1}".format(maybe_add_negation("of"), kwargs["of"])) | rule.append("{}-o {}".format(maybe_add_negation("of"), kwargs["of"])) | |||
del kwargs["of"] | del kwargs["of"] | |||
if "proto" in kwargs and kwargs.get("match") != "policy": | if "proto" in kwargs and kwargs.get("match") != "policy": | |||
kwargs["protocol"] = kwargs["proto"] | kwargs["protocol"] = kwargs["proto"] | |||
del kwargs["proto"] | del kwargs["proto"] | |||
# Handle the case 'proto' in kwargs and kwargs.get('match') == 'policy' below | # Handle the case 'proto' in kwargs and kwargs.get('match') == 'policy' below | |||
if "protocol" in kwargs: | if "protocol" in kwargs: | |||
if not protocol: | if not protocol: | |||
rule.append( | rule.append( | |||
"{0}-p {1}".format(maybe_add_negation("protocol"), kwargs["proto col"]) | "{}-p {}".format(maybe_add_negation("protocol"), kwargs["protoco l"]) | |||
) | ) | |||
protocol = True | protocol = True | |||
del kwargs["protocol"] | del kwargs["protocol"] | |||
if "match" in kwargs: | if "match" in kwargs: | |||
match_value = kwargs["match"] | match_value = kwargs["match"] | |||
if not isinstance(match_value, list): | if not isinstance(match_value, list): | |||
match_value = match_value.split(",") | match_value = match_value.split(",") | |||
for match in match_value: | for match in match_value: | |||
rule.append("-m {0}".format(match)) | rule.append("-m {}".format(match)) | |||
if "name_" in kwargs and match.strip() in ("pknock", "quota2", "rece nt"): | if "name_" in kwargs and match.strip() in ("pknock", "quota2", "rece nt"): | |||
rule.append("--name {0}".format(kwargs["name_"])) | rule.append("--name {}".format(kwargs["name_"])) | |||
del kwargs["name_"] | del kwargs["name_"] | |||
if "proto" in kwargs and kwargs.get("match") == "policy": | if "proto" in kwargs and kwargs.get("match") == "policy": | |||
rule.append( | rule.append( | |||
"{0}--proto {1}".format(maybe_add_negation("proto"), kwargs["pro to"]) | "{}--proto {}".format(maybe_add_negation("proto"), kwargs["proto "]) | |||
) | ) | |||
del kwargs["proto"] | del kwargs["proto"] | |||
del kwargs["match"] | del kwargs["match"] | |||
if "match-set" in kwargs: | if "match-set" in kwargs: | |||
if isinstance(kwargs["match-set"], six.string_types): | if isinstance(kwargs["match-set"], str): | |||
kwargs["match-set"] = [kwargs["match-set"]] | kwargs["match-set"] = [kwargs["match-set"]] | |||
for match_set in kwargs["match-set"]: | for match_set in kwargs["match-set"]: | |||
negative_match_set = "" | negative_match_set = "" | |||
if match_set.startswith("!") or match_set.startswith("not"): | if match_set.startswith("!") or match_set.startswith("not"): | |||
negative_match_set = "! " | negative_match_set = "! " | |||
match_set = re.sub(bang_not_pat, "", match_set) | match_set = re.sub(bang_not_pat, "", match_set) | |||
rule.append( | rule.append("-m set {}--match-set {}".format(negative_match_set, mat | |||
"-m set {0}--match-set {1}".format(negative_match_set, match_set | ch_set)) | |||
) | ||||
) | ||||
del kwargs["match-set"] | del kwargs["match-set"] | |||
if "connstate" in kwargs: | if "connstate" in kwargs: | |||
if "-m state" not in rule: | if "-m state" not in rule: | |||
rule.append("-m state") | rule.append("-m state") | |||
rule.append( | rule.append( | |||
"{0}--state {1}".format( | "{}--state {}".format(maybe_add_negation("connstate"), kwargs["conns | |||
maybe_add_negation("connstate"), kwargs["connstate"] | tate"]) | |||
) | ||||
) | ) | |||
del kwargs["connstate"] | del kwargs["connstate"] | |||
if "dport" in kwargs: | if "dport" in kwargs: | |||
rule.append( | rule.append("{}--dport {}".format(maybe_add_negation("dport"), kwargs["d | |||
"{0}--dport {1}".format(maybe_add_negation("dport"), kwargs["dport"] | port"])) | |||
) | ||||
) | ||||
del kwargs["dport"] | del kwargs["dport"] | |||
if "sport" in kwargs: | if "sport" in kwargs: | |||
rule.append( | rule.append("{}--sport {}".format(maybe_add_negation("sport"), kwargs["s | |||
"{0}--sport {1}".format(maybe_add_negation("sport"), kwargs["sport"] | port"])) | |||
) | ||||
) | ||||
del kwargs["sport"] | del kwargs["sport"] | |||
for multiport_arg in ("dports", "sports"): | for multiport_arg in ("dports", "sports"): | |||
if multiport_arg in kwargs: | if multiport_arg in kwargs: | |||
if "-m multiport" not in rule: | if "-m multiport" not in rule: | |||
rule.append("-m multiport") | rule.append("-m multiport") | |||
if not protocol: | if not protocol: | |||
return "Error: protocol must be specified" | return "Error: protocol must be specified" | |||
mp_value = kwargs[multiport_arg] | mp_value = kwargs[multiport_arg] | |||
skipping to change at line 385 | skipping to change at line 376 | |||
] | ] | |||
rule.append("!") | rule.append("!") | |||
dports = ",".join(str(i) for i in mp_value) | dports = ",".join(str(i) for i in mp_value) | |||
else: | else: | |||
if str(mp_value).startswith("!") or str(mp_value).startswith("no t"): | if str(mp_value).startswith("!") or str(mp_value).startswith("no t"): | |||
dports = re.sub(bang_not_pat, "", mp_value) | dports = re.sub(bang_not_pat, "", mp_value) | |||
rule.append("!") | rule.append("!") | |||
else: | else: | |||
dports = mp_value | dports = mp_value | |||
rule.append("--{0} {1}".format(multiport_arg, dports)) | rule.append("--{} {}".format(multiport_arg, dports)) | |||
del kwargs[multiport_arg] | del kwargs[multiport_arg] | |||
if "comment" in kwargs: | if "comment" in kwargs: | |||
if "-m comment" not in rule: | if "-m comment" not in rule: | |||
rule.append("-m comment") | rule.append("-m comment") | |||
rule.append('--comment "{0}"'.format(kwargs["comment"])) | rule.append('--comment "{}"'.format(kwargs["comment"])) | |||
del kwargs["comment"] | del kwargs["comment"] | |||
# --set in ipset is deprecated, works but returns error. | # --set in ipset is deprecated, works but returns error. | |||
# rewrite to --match-set if not empty, otherwise treat as recent option | # rewrite to --match-set if not empty, otherwise treat as recent option | |||
if "set" in kwargs and kwargs["set"]: | if "set" in kwargs and kwargs["set"]: | |||
rule.append( | rule.append("{}--match-set {}".format(maybe_add_negation("set"), kwargs[ | |||
"{0}--match-set {1}".format(maybe_add_negation("set"), kwargs["set"] | "set"])) | |||
) | ||||
) | ||||
del kwargs["set"] | del kwargs["set"] | |||
# Jumps should appear last, except for any arguments that are passed to | # Jumps should appear last, except for any arguments that are passed to | |||
# jumps, which of course need to follow. | # jumps, which of course need to follow. | |||
after_jump = [] | after_jump = [] | |||
# All jump arguments as extracted from man iptables-extensions, man iptables , | # All jump arguments as extracted from man iptables-extensions, man iptables , | |||
# man xtables-addons and http://www.iptables.info/en/iptables-targets-and-ju mps.html | # man xtables-addons and http://www.iptables.info/en/iptables-targets-and-ju mps.html | |||
after_jump_arguments = ( | after_jump_arguments = ( | |||
"j", # j and jump needs to be first | "j", # j and jump needs to be first | |||
"jump", | "jump", | |||
skipping to change at line 531 | skipping to change at line 520 | |||
"shift", | "shift", | |||
"static", | "static", | |||
"tarpit", | "tarpit", | |||
"tname", | "tname", | |||
"ttl", | "ttl", | |||
) | ) | |||
for after_jump_argument in after_jump_arguments: | for after_jump_argument in after_jump_arguments: | |||
if after_jump_argument in kwargs: | if after_jump_argument in kwargs: | |||
value = kwargs[after_jump_argument] | value = kwargs[after_jump_argument] | |||
if value in (None, ""): # options without arguments | if value in (None, ""): # options without arguments | |||
after_jump.append("--{0}".format(after_jump_argument)) | after_jump.append("--{}".format(after_jump_argument)) | |||
elif any(ws_char in str(value) for ws_char in string.whitespace): | elif any(ws_char in str(value) for ws_char in string.whitespace): | |||
after_jump.append('--{0} "{1}"'.format(after_jump_argument, valu e)) | after_jump.append('--{} "{}"'.format(after_jump_argument, value) ) | |||
else: | else: | |||
after_jump.append("--{0} {1}".format(after_jump_argument, value) ) | after_jump.append("--{} {}".format(after_jump_argument, value)) | |||
del kwargs[after_jump_argument] | del kwargs[after_jump_argument] | |||
for key in kwargs: | for key in kwargs: | |||
negation = maybe_add_negation(key) | negation = maybe_add_negation(key) | |||
# don't use .items() since maybe_add_negation removes the prefix from | # don't use .items() since maybe_add_negation removes the prefix from | |||
# the value in the kwargs, thus we need to fetch it after that has run | # the value in the kwargs, thus we need to fetch it after that has run | |||
value = kwargs[key] | value = kwargs[key] | |||
flag = "-" if len(key) == 1 else "--" | flag = "-" if len(key) == 1 else "--" | |||
value = "" if value in (None, "") else " {0}".format(value) | value = "" if value in (None, "") else " {}".format(value) | |||
rule.append("{0}{1}{2}{3}".format(negation, flag, key, value)) | rule.append("{}{}{}{}".format(negation, flag, key, value)) | |||
rule += after_jump | rule += after_jump | |||
if full: | if full: | |||
if not table: | if not table: | |||
return "Error: Table needs to be specified" | return "Error: Table needs to be specified" | |||
if not chain: | if not chain: | |||
return "Error: Chain needs to be specified" | return "Error: Chain needs to be specified" | |||
if not command: | if not command: | |||
return "Error: Command needs to be specified" | return "Error: Command needs to be specified" | |||
if command in "ACDIRLSFZNXPE": | if command in "ACDIRLSFZNXPE": | |||
flag = "-" | flag = "-" | |||
else: | else: | |||
flag = "--" | flag = "--" | |||
wait = "--wait" if _has_option("--wait", family) else "" | wait = "--wait" if _has_option("--wait", family) else "" | |||
return "{0} {1} -t {2} {3}{4} {5} {6} {7}".format( | return "{} {} -t {} {}{} {} {} {}".format( | |||
_iptables_cmd(family), | _iptables_cmd(family), | |||
wait, | wait, | |||
table, | table, | |||
flag, | flag, | |||
command, | command, | |||
chain, | chain, | |||
position, | position, | |||
" ".join(rule), | " ".join(rule), | |||
) | ) | |||
skipping to change at line 676 | skipping to change at line 665 | |||
IPv6: | IPv6: | |||
salt '*' iptables.set_policy filter INPUT ACCEPT family=ipv6 | salt '*' iptables.set_policy filter INPUT ACCEPT family=ipv6 | |||
""" | """ | |||
if not chain: | if not chain: | |||
return "Error: Chain needs to be specified" | return "Error: Chain needs to be specified" | |||
if not policy: | if not policy: | |||
return "Error: Policy needs to be specified" | return "Error: Policy needs to be specified" | |||
wait = "--wait" if _has_option("--wait", family) else "" | wait = "--wait" if _has_option("--wait", family) else "" | |||
cmd = "{0} {1} -t {2} -P {3} {4}".format( | cmd = "{} {} -t {} -P {} {}".format( | |||
_iptables_cmd(family), wait, table, chain, policy | _iptables_cmd(family), wait, table, chain, policy | |||
) | ) | |||
out = __salt__["cmd.run"](cmd) | out = __salt__["cmd.run"](cmd) | |||
return out | return out | |||
def save(filename=None, family="ipv4"): | def save(filename=None, family="ipv4"): | |||
""" | """ | |||
Save the current in-memory rules to disk | Save the current in-memory rules to disk | |||
CLI Example: | CLI Example: | |||
skipping to change at line 703 | skipping to change at line 692 | |||
salt '*' iptables.save /etc/sysconfig/iptables family=ipv6 | salt '*' iptables.save /etc/sysconfig/iptables family=ipv6 | |||
""" | """ | |||
if _conf() and not filename: | if _conf() and not filename: | |||
filename = _conf(family) | filename = _conf(family) | |||
log.debug("Saving rules to %s", filename) | log.debug("Saving rules to %s", filename) | |||
parent_dir = os.path.dirname(filename) | parent_dir = os.path.dirname(filename) | |||
if not os.path.isdir(parent_dir): | if not os.path.isdir(parent_dir): | |||
os.makedirs(parent_dir) | os.makedirs(parent_dir) | |||
cmd = "{0}-save".format(_iptables_cmd(family)) | cmd = "{}-save".format(_iptables_cmd(family)) | |||
ipt = __salt__["cmd.run"](cmd) | ipt = __salt__["cmd.run"](cmd) | |||
# regex out the output if configured with filters | # regex out the output if configured with filters | |||
if _conf_save_filters(): | if _conf_save_filters(): | |||
ipt = _regex_iptables_save(ipt) | ipt = _regex_iptables_save(ipt) | |||
out = __salt__["file.write"](filename, ipt) | out = __salt__["file.write"](filename, ipt) | |||
return out | return out | |||
def check(table="filter", chain=None, rule=None, family="ipv4"): | def check(table="filter", chain=None, rule=None, family="ipv4"): | |||
skipping to change at line 741 | skipping to change at line 730 | |||
rule='-m state --state RELATED,ESTABLISHED -j ACCEPT' \\ | rule='-m state --state RELATED,ESTABLISHED -j ACCEPT' \\ | |||
family=ipv6 | family=ipv6 | |||
""" | """ | |||
if not chain: | if not chain: | |||
return "Error: Chain needs to be specified" | return "Error: Chain needs to be specified" | |||
if not rule: | if not rule: | |||
return "Error: Rule needs to be specified" | return "Error: Rule needs to be specified" | |||
ipt_cmd = _iptables_cmd(family) | ipt_cmd = _iptables_cmd(family) | |||
if _has_option("--check", family): | if _has_option("--check", family): | |||
cmd = "{0} -t {1} -C {2} {3}".format(ipt_cmd, table, chain, rule) | cmd = "{} -t {} -C {} {}".format(ipt_cmd, table, chain, rule) | |||
out = __salt__["cmd.run"](cmd, output_loglevel="quiet") | out = __salt__["cmd.run"](cmd, output_loglevel="quiet") | |||
else: | else: | |||
_chain_name = hex(uuid.getnode()) | _chain_name = hex(uuid.getnode()) | |||
# Create temporary table | # Create temporary table | |||
__salt__["cmd.run"]("{0} -t {1} -N {2}".format(ipt_cmd, table, _chain_na me)) | __salt__["cmd.run"]("{} -t {} -N {}".format(ipt_cmd, table, _chain_name) ) | |||
__salt__["cmd.run"]( | __salt__["cmd.run"]( | |||
"{0} -t {1} -A {2} {3}".format(ipt_cmd, table, _chain_name, rule) | "{} -t {} -A {} {}".format(ipt_cmd, table, _chain_name, rule) | |||
) | ) | |||
out = __salt__["cmd.run"]("{0}-save".format(ipt_cmd)) | out = __salt__["cmd.run"]("{}-save".format(ipt_cmd)) | |||
# Clean up temporary table | # Clean up temporary table | |||
__salt__["cmd.run"]("{0} -t {1} -F {2}".format(ipt_cmd, table, _chain_na | __salt__["cmd.run"]("{} -t {} -F {}".format(ipt_cmd, table, _chain_name) | |||
me)) | ) | |||
__salt__["cmd.run"]("{0} -t {1} -X {2}".format(ipt_cmd, table, _chain_na | __salt__["cmd.run"]("{} -t {} -X {}".format(ipt_cmd, table, _chain_name) | |||
me)) | ) | |||
for i in out.splitlines(): | for i in out.splitlines(): | |||
if i.startswith("-A {0}".format(_chain_name)): | if i.startswith("-A {}".format(_chain_name)): | |||
if i.replace(_chain_name, chain) in out.splitlines(): | if i.replace(_chain_name, chain) in out.splitlines(): | |||
return True | return True | |||
return False | return False | |||
if not out: | if not out: | |||
return True | return True | |||
return out | return out | |||
def check_chain(table="filter", chain=None, family="ipv4"): | def check_chain(table="filter", chain=None, family="ipv4"): | |||
skipping to change at line 788 | skipping to change at line 777 | |||
salt '*' iptables.check_chain filter INPUT | salt '*' iptables.check_chain filter INPUT | |||
IPv6: | IPv6: | |||
salt '*' iptables.check_chain filter INPUT family=ipv6 | salt '*' iptables.check_chain filter INPUT family=ipv6 | |||
""" | """ | |||
if not chain: | if not chain: | |||
return "Error: Chain needs to be specified" | return "Error: Chain needs to be specified" | |||
cmd = "{0}-save -t {1}".format(_iptables_cmd(family), table) | cmd = "{}-save -t {}".format(_iptables_cmd(family), table) | |||
out = __salt__["cmd.run"](cmd).find(":{0} ".format(chain)) | out = __salt__["cmd.run"](cmd).find(":{} ".format(chain)) | |||
if out != -1: | if out != -1: | |||
out = True | out = True | |||
else: | else: | |||
out = False | out = False | |||
return out | return out | |||
def new_chain(table="filter", chain=None, family="ipv4"): | def new_chain(table="filter", chain=None, family="ipv4"): | |||
""" | """ | |||
skipping to change at line 818 | skipping to change at line 807 | |||
salt '*' iptables.new_chain filter CUSTOM_CHAIN | salt '*' iptables.new_chain filter CUSTOM_CHAIN | |||
IPv6: | IPv6: | |||
salt '*' iptables.new_chain filter CUSTOM_CHAIN family=ipv6 | salt '*' iptables.new_chain filter CUSTOM_CHAIN family=ipv6 | |||
""" | """ | |||
if not chain: | if not chain: | |||
return "Error: Chain needs to be specified" | return "Error: Chain needs to be specified" | |||
wait = "--wait" if _has_option("--wait", family) else "" | wait = "--wait" if _has_option("--wait", family) else "" | |||
cmd = "{0} {1} -t {2} -N {3}".format(_iptables_cmd(family), wait, table, cha in) | cmd = "{} {} -t {} -N {}".format(_iptables_cmd(family), wait, table, chain) | |||
out = __salt__["cmd.run"](cmd) | out = __salt__["cmd.run"](cmd) | |||
if not out: | if not out: | |||
out = True | out = True | |||
return out | return out | |||
def delete_chain(table="filter", chain=None, family="ipv4"): | def delete_chain(table="filter", chain=None, family="ipv4"): | |||
""" | """ | |||
.. versionadded:: 2014.1.0 | .. versionadded:: 2014.1.0 | |||
skipping to change at line 845 | skipping to change at line 834 | |||
salt '*' iptables.delete_chain filter CUSTOM_CHAIN | salt '*' iptables.delete_chain filter CUSTOM_CHAIN | |||
IPv6: | IPv6: | |||
salt '*' iptables.delete_chain filter CUSTOM_CHAIN family=ipv6 | salt '*' iptables.delete_chain filter CUSTOM_CHAIN family=ipv6 | |||
""" | """ | |||
if not chain: | if not chain: | |||
return "Error: Chain needs to be specified" | return "Error: Chain needs to be specified" | |||
wait = "--wait" if _has_option("--wait", family) else "" | wait = "--wait" if _has_option("--wait", family) else "" | |||
cmd = "{0} {1} -t {2} -X {3}".format(_iptables_cmd(family), wait, table, cha in) | cmd = "{} {} -t {} -X {}".format(_iptables_cmd(family), wait, table, chain) | |||
out = __salt__["cmd.run"](cmd) | out = __salt__["cmd.run"](cmd) | |||
if not out: | if not out: | |||
out = True | out = True | |||
return out | return out | |||
def append(table="filter", chain=None, rule=None, family="ipv4"): | def append(table="filter", chain=None, rule=None, family="ipv4"): | |||
""" | """ | |||
Append a rule to the specified table/chain. | Append a rule to the specified table/chain. | |||
skipping to change at line 882 | skipping to change at line 871 | |||
""" | """ | |||
if not chain: | if not chain: | |||
return "Error: Chain needs to be specified" | return "Error: Chain needs to be specified" | |||
if not rule: | if not rule: | |||
return "Error: Rule needs to be specified" | return "Error: Rule needs to be specified" | |||
wait = "--wait" if _has_option("--wait", family) else "" | wait = "--wait" if _has_option("--wait", family) else "" | |||
returnCheck = check(table, chain, rule, family) | returnCheck = check(table, chain, rule, family) | |||
if isinstance(returnCheck, bool) and returnCheck: | if isinstance(returnCheck, bool) and returnCheck: | |||
return False | return False | |||
cmd = "{0} {1} -t {2} -A {3} {4}".format( | cmd = "{} {} -t {} -A {} {}".format(_iptables_cmd(family), wait, table, chai | |||
_iptables_cmd(family), wait, table, chain, rule | n, rule) | |||
) | ||||
out = __salt__["cmd.run"](cmd) | out = __salt__["cmd.run"](cmd) | |||
return not out | return not out | |||
def insert(table="filter", chain=None, position=None, rule=None, family="ipv4"): | def insert(table="filter", chain=None, position=None, rule=None, family="ipv4"): | |||
""" | """ | |||
Insert a rule into the specified table/chain, at the specified position. | Insert a rule into the specified table/chain, at the specified position. | |||
This function accepts a rule in a standard iptables command format, | This function accepts a rule in a standard iptables command format, | |||
starting with the chain. Trying to force users to adapt to a new | starting with the chain. Trying to force users to adapt to a new | |||
method of creating rules would be irritating at best, and we | method of creating rules would be irritating at best, and we | |||
skipping to change at line 932 | skipping to change at line 919 | |||
rules = get_rules(family=family) | rules = get_rules(family=family) | |||
size = len(rules[table][chain]["rules"]) | size = len(rules[table][chain]["rules"]) | |||
position = (size + position) + 1 | position = (size + position) + 1 | |||
if position == 0: | if position == 0: | |||
position = 1 | position = 1 | |||
wait = "--wait" if _has_option("--wait", family) else "" | wait = "--wait" if _has_option("--wait", family) else "" | |||
returnCheck = check(table, chain, rule, family) | returnCheck = check(table, chain, rule, family) | |||
if isinstance(returnCheck, bool) and returnCheck: | if isinstance(returnCheck, bool) and returnCheck: | |||
return False | return False | |||
cmd = "{0} {1} -t {2} -I {3} {4} {5}".format( | cmd = "{} {} -t {} -I {} {} {}".format( | |||
_iptables_cmd(family), wait, table, chain, position, rule | _iptables_cmd(family), wait, table, chain, position, rule | |||
) | ) | |||
out = __salt__["cmd.run"](cmd) | out = __salt__["cmd.run"](cmd) | |||
return out | return out | |||
def delete(table, chain=None, position=None, rule=None, family="ipv4"): | def delete(table, chain=None, position=None, rule=None, family="ipv4"): | |||
""" | """ | |||
Delete a rule from the specified table/chain, specifying either the rule | Delete a rule from the specified table/chain, specifying either the rule | |||
in its entirety, or the rule's position in the chain. | in its entirety, or the rule's position in the chain. | |||
skipping to change at line 970 | skipping to change at line 957 | |||
family=ipv6 | family=ipv6 | |||
""" | """ | |||
if position and rule: | if position and rule: | |||
return "Error: Only specify a position or a rule, not both" | return "Error: Only specify a position or a rule, not both" | |||
if position: | if position: | |||
rule = position | rule = position | |||
wait = "--wait" if _has_option("--wait", family) else "" | wait = "--wait" if _has_option("--wait", family) else "" | |||
cmd = "{0} {1} -t {2} -D {3} {4}".format( | cmd = "{} {} -t {} -D {} {}".format(_iptables_cmd(family), wait, table, chai | |||
_iptables_cmd(family), wait, table, chain, rule | n, rule) | |||
) | ||||
out = __salt__["cmd.run"](cmd) | out = __salt__["cmd.run"](cmd) | |||
return out | return out | |||
def flush(table="filter", chain="", family="ipv4"): | def flush(table="filter", chain="", family="ipv4"): | |||
""" | """ | |||
Flush the chain in the specified table, flush all chains in the specified | Flush the chain in the specified table, flush all chains in the specified | |||
table if not specified chain. | table if not specified chain. | |||
CLI Example: | CLI Example: | |||
.. code-block:: bash | .. code-block:: bash | |||
salt '*' iptables.flush filter INPUT | salt '*' iptables.flush filter INPUT | |||
IPv6: | IPv6: | |||
salt '*' iptables.flush filter INPUT family=ipv6 | salt '*' iptables.flush filter INPUT family=ipv6 | |||
""" | """ | |||
wait = "--wait" if _has_option("--wait", family) else "" | wait = "--wait" if _has_option("--wait", family) else "" | |||
cmd = "{0} {1} -t {2} -F {3}".format(_iptables_cmd(family), wait, table, cha in) | cmd = "{} {} -t {} -F {}".format(_iptables_cmd(family), wait, table, chain) | |||
out = __salt__["cmd.run"](cmd) | out = __salt__["cmd.run"](cmd) | |||
return out | return out | |||
def _parse_conf(conf_file=None, in_mem=False, family="ipv4"): | def _parse_conf(conf_file=None, in_mem=False, family="ipv4"): | |||
""" | """ | |||
If a file is not passed in, and the correct one for this OS is not | If a file is not passed in, and the correct one for this OS is not | |||
detected, return False | detected, return False | |||
""" | """ | |||
if _conf() and not conf_file and not in_mem: | if _conf() and not conf_file and not in_mem: | |||
conf_file = _conf(family) | conf_file = _conf(family) | |||
rules = "" | rules = "" | |||
if conf_file: | if conf_file: | |||
with salt.utils.files.fopen(conf_file, "r") as ifile: | with salt.utils.files.fopen(conf_file, "r") as ifile: | |||
rules = ifile.read() | rules = ifile.read() | |||
elif in_mem: | elif in_mem: | |||
cmd = "{0}-save".format(_iptables_cmd(family)) | cmd = "{}-save".format(_iptables_cmd(family)) | |||
rules = __salt__["cmd.run"](cmd) | rules = __salt__["cmd.run"](cmd) | |||
else: | else: | |||
raise SaltException("A file was not found to parse") | raise SaltException("A file was not found to parse") | |||
ret = {} | ret = {} | |||
table = "" | table = "" | |||
parser = _parser() | parser = _parser() | |||
for line in rules.splitlines(): | for line in rules.splitlines(): | |||
line = salt.utils.stringutils.to_unicode(line) | line = salt.utils.stringutils.to_unicode(line) | |||
if line.startswith("*"): | if line.startswith("*"): | |||
skipping to change at line 1050 | skipping to change at line 1035 | |||
if args[index].startswith("-"): | if args[index].startswith("-"): | |||
index += 1 | index += 1 | |||
if args[index].startswith("-") or (args[index] == "!" and no t swap): | if args[index].startswith("-") or (args[index] == "!" and no t swap): | |||
args.insert(index, "") | args.insert(index, "") | |||
else: | else: | |||
while ( | while ( | |||
index + 1 < len(args) | index + 1 < len(args) | |||
and args[index + 1] != "!" | and args[index + 1] != "!" | |||
and not args[index + 1].startswith("-") | and not args[index + 1].startswith("-") | |||
): | ): | |||
args[index] += " {0}".format(args.pop(index + 1)) | args[index] += " {}".format(args.pop(index + 1)) | |||
index += 1 | index += 1 | |||
if args[-1].startswith("-"): | if args[-1].startswith("-"): | |||
args.append("") | args.append("") | |||
parsed_args = [] | parsed_args = [] | |||
opts, _ = parser.parse_known_args(args) | opts, _ = parser.parse_known_args(args) | |||
parsed_args = vars(opts) | parsed_args = vars(opts) | |||
ret_args = {} | ret_args = {} | |||
chain = parsed_args["append"] | chain = parsed_args["append"] | |||
for arg in parsed_args: | for arg in parsed_args: | |||
if parsed_args[arg] and arg != "append": | if parsed_args[arg] and arg != "append": | |||
End of changes. 45 change blocks. | ||||
68 lines changed or deleted | 56 lines changed or added |