diff options
Diffstat (limited to 'pkg/linux/bitmask-root')
| -rwxr-xr-x | pkg/linux/bitmask-root | 143 | 
1 files changed, 142 insertions, 1 deletions
| diff --git a/pkg/linux/bitmask-root b/pkg/linux/bitmask-root index fa7fc92a..ba262a2c 100755 --- a/pkg/linux/bitmask-root +++ b/pkg/linux/bitmask-root @@ -25,6 +25,8 @@ USAGE:    bitmask-root firewall start [restart] GATEWAY1 GATEWAY2 ...    bitmask-root openvpn stop    bitmask-root openvpn start CONFIG1 CONFIG1 ... +  bitmask-root fw-email stop +  bitmask-root fw-email start uid  All actions return exit code 0 for success, non-zero otherwise. @@ -55,6 +57,11 @@ NAMESERVER = "10.42.0.1"  BITMASK_CHAIN = "bitmask"  BITMASK_CHAIN_NAT_OUT = "bitmask"  BITMASK_CHAIN_NAT_POST = "bitmask_postrouting" +BITMASK_CHAIN_EMAIL = "bitmask_email" +BITMASK_CHAIN_EMAIL_OUT = "bitmask_email_output" +LOCAL_INTERFACE = "lo" +IMAP_PORT = "1984" +SMTP_PORT = "2013"  IP = "/bin/ip"  IPTABLES = "/sbin/iptables" @@ -101,7 +108,8 @@ PARAM_FORMATS = {          "^[a-zA-Z0-9_\.\@][a-zA-Z0-9_\-\.\@]*\$?$", s),  # IEEE Std 1003.1-2001      "FILE": lambda s: os.path.isfile(s),      "DIR": lambda s: os.path.isdir(os.path.split(s)[0]), -    "UNIXSOCKET": lambda s: s == "unix" +    "UNIXSOCKET": lambda s: s == "unix", +    "UID": lambda s: re.match("^[a-zA-Z0-9]+$", s)  } @@ -740,6 +748,119 @@ def firewall_stop():                          "Please try `firewall stop` again.") +def fw_email_start(args): +    """ +    Bring up the email firewall. + +    :param args: the user uid of the bitmask process +    :type args: list +    """ +    # add custom chain "bitmask_email" to front of INPUT chain +    if not ipv4_chain_exists(BITMASK_CHAIN_EMAIL): +        ip4tables("--new-chain", BITMASK_CHAIN_EMAIL) +    if not ipv6_chain_exists(BITMASK_CHAIN_EMAIL): +        ip6tables("--new-chain", BITMASK_CHAIN_EMAIL) +    iptables("--insert", "INPUT", "--jump", BITMASK_CHAIN_EMAIL) + +    # add custom chain "bitmask_email_output" to front of OUTPUT chain +    if not ipv4_chain_exists(BITMASK_CHAIN_EMAIL_OUT): +        ip4tables("--new-chain", BITMASK_CHAIN_EMAIL_OUT) +    if not ipv6_chain_exists(BITMASK_CHAIN_EMAIL_OUT): +        ip6tables("--new-chain", BITMASK_CHAIN_EMAIL_OUT) +    iptables("--insert", "OUTPUT", "--jump", BITMASK_CHAIN_EMAIL_OUT) + +    # Disable the access to imap and smtp from outside +    iptables("--append", BITMASK_CHAIN_EMAIL, +             "--in-interface", LOCAL_INTERFACE, "--protocol", "tcp", +             "--dport", IMAP_PORT, "--jump", "ACCEPT") +    iptables("--append", BITMASK_CHAIN_EMAIL, +             "--in-interface", LOCAL_INTERFACE, "--protocol", "tcp", +             "--dport", SMTP_PORT, "--jump", "ACCEPT") +    iptables("--append", BITMASK_CHAIN_EMAIL, +             "--protocol", "tcp", "--dport", IMAP_PORT, "--jump", "REJECT") +    iptables("--append", BITMASK_CHAIN_EMAIL, +             "--protocol", "tcp", "--dport", SMTP_PORT, "--jump", "REJECT") + +    if not args or not PARAM_FORMATS["UID"](args[0]): +        raise Exception("No uid given") +    uid = args[0] + +    # Only the unix 'uid' have access to the email imap and smtp ports +    iptables("--append", BITMASK_CHAIN_EMAIL_OUT, +             "--out-interface", LOCAL_INTERFACE, +             "--match", "owner", "--uid-owner", uid, "--protocol", "tcp", +             "--dport", IMAP_PORT, "--jump", "ACCEPT") +    iptables("--append", BITMASK_CHAIN_EMAIL_OUT, +             "--out-interface", LOCAL_INTERFACE, +             "--match", "owner", "--uid-owner", uid, "--protocol", "tcp", +             "--dport", SMTP_PORT, "--jump", "ACCEPT") +    iptables("--append", BITMASK_CHAIN_EMAIL_OUT, +             "--out-interface", LOCAL_INTERFACE, +             "--protocol", "tcp", "--dport", IMAP_PORT, "--jump", "REJECT") +    iptables("--append", BITMASK_CHAIN_EMAIL_OUT, +             "--out-interface", LOCAL_INTERFACE, +             "--protocol", "tcp", "--dport", SMTP_PORT, "--jump", "REJECT") + + +def fw_email_stop(): +    """ +    Stop the email firewall. +    """ +    ok = True + +    try: +        iptables("--delete", "INPUT", "--jump", BITMASK_CHAIN_EMAIL, +                 throw=True) +    except subprocess.CalledProcessError as exc: +        debug("INFO: not able to remove bitmask email firewall from INPUT " +              "chain (maybe it is already removed?)", exc) +        ok = False + +    try: +        iptables("--delete", "OUTPUT", "--jump", BITMASK_CHAIN_EMAIL_OUT, +                 throw=True) +    except subprocess.CalledProcessError as exc: +        debug("INFO: not able to remove bitmask email firewall from OUTPUT " +              "chain (maybe it is already removed?)", exc) +        ok = False + +    try: +        ip4tables("--flush", BITMASK_CHAIN_EMAIL, throw=True) +        ip4tables("--delete-chain", BITMASK_CHAIN_EMAIL, throw=True) +    except subprocess.CalledProcessError as exc: +        debug("INFO: not able to flush and delete bitmask ipv4 email firewall " +              "chain (maybe it is already destroyed?)", exc) +        ok = False + +    try: +        ip6tables("--flush", BITMASK_CHAIN_EMAIL, throw=True) +        ip6tables("--delete-chain", BITMASK_CHAIN_EMAIL, throw=True) +    except subprocess.CalledProcessError as exc: +        debug("INFO: not able to flush and delete bitmask ipv6 email firewall " +              "chain (maybe it is already destroyed?)", exc) +        ok = False + +    try: +        ip4tables("--flush", BITMASK_CHAIN_EMAIL_OUT, throw=True) +        ip4tables("--delete-chain", BITMASK_CHAIN_EMAIL_OUT, throw=True) +    except subprocess.CalledProcessError as exc: +        debug("INFO: not able to flush and delete bitmask ipv4 email firewall " +              "chain (maybe it is already destroyed?)", exc) +        ok = False + +    try: +        ip6tables("--flush", BITMASK_CHAIN_EMAIL_OUT, throw=True) +        ip6tables("--delete-chain", BITMASK_CHAIN_EMAIL_OUT, throw=True) +    except subprocess.CalledProcessError as exc: +        debug("INFO: not able to flush and delete bitmask ipv6 email firewall " +              "chain (maybe it is already destroyed?)", exc) +        ok = False + +    if not (ok or ipv4_chain_exists or ipv6_chain_exists): +        raise Exception("email firewall might still be left up. " +                        "Please try `fw-email stop` again.") + +  #  # MAIN  # @@ -793,6 +914,26 @@ def main():              else:                  bail("INFO: bitmask firewall is down") +        elif command == "fw-email_start": +            try: +                fw_email_start(args) +            except Exception as ex: +                if not is_restart: +                    fw_email_stop() +                bail("ERROR: could not start email firewall", ex) + +        elif command == "fw-email_stop": +            try: +                fw_email_stop() +            except Exception as ex: +                bail("ERROR: could not stop email firewall", ex) + +        elif command == "fw-email_isup": +            if ipv4_chain_exists(BITMASK_CHAIN_EMAIL): +                log("%s: INFO: bitmask email firewall is up" % (SCRIPT,)) +            else: +                bail("INFO: bitmask email firewall is down") +          else:              bail("ERROR: No such command")      else: | 
