def delete_user_chain(chain_id): """ Delete a user chain. You must remove it from the system chains before this will succeed. """ procutils.run([IPTABLES, "--flush", chain_id]) procutils.run([IPTABLES, "--delete-chain", chain_id])
def flush(chain_id=None): """ Flush iptables chains. Defaults to all chains. @param chain_id optionally limit flushing to given chain """ if chain_id: procutils.run([IPTABLES, "--flush", chain_id]) else: procutils.run([IPTABLES, "--flush"])
def create_gremlin_chain(ports_to_drop): """ Create a new iptables chain that drops all packets to the given list of ports. @param ports_to_drop: list of int port numbers to drop packets to @returns the name of the new chain """ chain_id = "gremlin_%d" % int(time.time()) # Create the chain procutils.run([IPTABLES, "-N", chain_id]) # Add the drop rules for port in ports_to_drop: procutils.run([ IPTABLES, "-A", chain_id, "-p", "tcp", "--dport", str(port), "-j", "DROP" ]) return chain_id
def create_gremlin_chain(ports_to_drop): """ Create a new iptables chain that drops all packets to the given list of ports. @param ports_to_drop: list of int port numbers to drop packets to @returns the name of the new chain """ chain_id = "gremlin_%d" % int(time.time()) # Create the chain procutils.run([IPTABLES, "-N", chain_id]) # Add the drop rules for port in ports_to_drop: procutils.run([IPTABLES, "-A", chain_id, "-p", "tcp", "--dport", str(port), "-j", "DROP"]) return chain_id
def guess_remote_host(): """ Attempt to find the host our current user last logged in from. """ user = os.environ.get("USER") sudo_user = os.environ.get("SUDO_USER") if sudo_user: user = sudo_user if user: last = procutils.run([LASTCMD, "-a", user, "-n", "1"]).splitlines()[0] return last.rpartition(' ')[2] else: return None
def remove_gremlin_chains(): """ Remove any gremlin chains that are found on the system. """ output_chains = map((lambda entry: entry.partition(" ")[0]), procutils.run([IPTABLES, "-L", "OUTPUT"]).splitlines()[2:]) for chain in list_chains(): if chain.startswith("gremlin_"): if chain in output_chains: remove_user_chain_from_output_chain(chain) else: remove_user_chain_from_input_chain(chain) delete_user_chain(chain)
def list_chains(): """Return a list of the names of all iptables chains.""" ret = procutils.run([IPTABLES, "-L"]) chains = re.findall(r'^Chain (\S+)', ret, re.MULTILINE) return chains
def add_user_chain_to_output_chain(chain_id): """Insert the given user chain into the system OUTPUT chain""" procutils.run([IPTABLES, "-A", "OUTPUT", "-j", chain_id])
def create_gremlin_network_failure(bastion_host): """ Create a new iptables chain that isolates the host we're on from all other hosts, save a single bastion. @param bastion_host: a hostname or ip to still allow ssh to/from @returns an array containing the name of the new chains [input, output] """ chain_prefix = "gremlin_%d" % int(time.time()) # Create INPUT chain chain_input = "%s_INPUT" % chain_prefix procutils.run([IPTABLES, "-N", chain_input]) # Add rules to allow ssh to/from bastion procutils.run([ IPTABLES, "-A", chain_input, "-p", "tcp", "--source", bastion_host, "--dport", "22", "-m", "state", "--state", "NEW,ESTABLISHED", "-j", "ACCEPT" ]) procutils.run([ IPTABLES, "-A", chain_input, "-p", "tcp", "--sport", "22", "-m", "state", "--state", "ESTABLISHED", "-j", "ACCEPT" ]) # Add rule to allow ICMP to/from bastion procutils.run([ IPTABLES, "-A", chain_input, "-p", "icmp", "--source", bastion_host, "-j", "ACCEPT" ]) # Drop everything else procutils.run([IPTABLES, "-A", chain_input, "-j", "DROP"]) # Create OUTPUT chain chain_output = "%s_OUTPUT" % chain_prefix procutils.run([IPTABLES, "-N", chain_output]) # Add rules to allow ssh to/from bastion procutils.run([ IPTABLES, "-A", chain_output, "-p", "tcp", "--sport", "22", "-m", "state", "--state", "ESTABLISHED", "-j", "ACCEPT" ]) procutils.run([ IPTABLES, "-A", chain_output, "-p", "tcp", "--destination", bastion_host, "--dport", "22", "-m", "state", "--state", "NEW,ESTABLISHED", "-j", "ACCEPT" ]) # Add rule to allow ICMP to/from bastion procutils.run([ IPTABLES, "-A", chain_output, "-p", "icmp", "--destination", bastion_host, "-j", "ACCEPT" ]) # Drop everything else procutils.run([IPTABLES, "-A", chain_output, "-j", "DROP"]) return [chain_input, chain_output]
def remove_user_chain_from_output_chain(chain_id): """Remove the given user chain from the system OUTPUT chain""" procutils.run([IPTABLES, "-D", "OUTPUT", "-j", chain_id])
def _add_fault(fault): """add a network fault""" logging.info("Adding network fault: %s" % (fault)) for iface in ['eth0']: procutils.run(("tc qdisc add dev %s root %s" % (iface, fault)).split(" "), assert_return_code_zero=False)
def clear_faults(): """undo all currently enabled faults""" logging.info("Clearing network faults") for iface in ['eth0']: procutils.run(("tc qdisc del dev %s root" % (iface)).split(" "), assert_return_code_zero=False)
def create_gremlin_network_failure(bastion_host): """ Create a new iptables chain that isolates the host we're on from all other hosts, save a single bastion. @param bastion_host: a hostname or ip to still allow ssh to/from @returns an array containing the name of the new chains [input, output] """ chain_prefix = "gremlin_%d" % int(time.time()) # Create INPUT chain chain_input = "%s_INPUT" % chain_prefix procutils.run([IPTABLES, "-N", chain_input]) # Add rules to allow ssh to/from bastion procutils.run([IPTABLES, "-A", chain_input, "-p", "tcp", "--source", bastion_host, "--dport", "22", "-m", "state", "--state", "NEW,ESTABLISHED", "-j", "ACCEPT"]) procutils.run([IPTABLES, "-A", chain_input, "-p", "tcp", "--sport", "22", "-m", "state", "--state", "ESTABLISHED", "-j", "ACCEPT"]) # Add rule to allow ICMP to/from bastion procutils.run([IPTABLES, "-A", chain_input, "-p", "icmp", "--source", bastion_host, "-j", "ACCEPT"]) # Drop everything else procutils.run([IPTABLES, "-A", chain_input, "-j", "DROP"]) # Create OUTPUT chain chain_output = "%s_OUTPUT" % chain_prefix procutils.run([IPTABLES, "-N", chain_output]) # Add rules to allow ssh to/from bastion procutils.run([IPTABLES, "-A", chain_output, "-p", "tcp", "--sport", "22", "-m", "state", "--state", "ESTABLISHED", "-j", "ACCEPT"]) procutils.run([IPTABLES, "-A", chain_output, "-p", "tcp", "--destination", bastion_host, "--dport", "22", "-m", "state", "--state", "NEW,ESTABLISHED", "-j", "ACCEPT"]) # Add rule to allow ICMP to/from bastion procutils.run([IPTABLES, "-A", chain_output, "-p", "icmp", "--destination", bastion_host, "-j", "ACCEPT"]) # Drop everything else procutils.run([IPTABLES, "-A", chain_output, "-j", "DROP"]) return [chain_input, chain_output]
from gremlins import faults, metafaults, triggers, procutils # TODO use an environment variable for paths.. no more absolutes # TODO make shutdown proper.. right now, bg processes are continuing ot run procutils.START_COMMANDS = { 'QuorumPeerMain': ["/Users/criccomi/Downloads/apache-zookeeper-ef198fc/bin/zkServer.sh", "start"], 'LoadBalancerEchoServer': ["/Users/criccomi/svn/pegasus/trunk/d2/scripts/lb-echo-server.sh", "2345", "prpc", "cluster-1", "service-1", "service-2"], 'LoadBalancerEchoClient': ["/Users/criccomi/svn/pegasus/trunk/d2/scripts/lb-echo-client.sh", "service-1", "service-2"], } # start zoo keeper procutils.start_daemon('QuorumPeerMain'); # put cluster and service properties procutils.run(["/Users/criccomi/svn/pegasus/trunk/d2/scripts/lb-tool.sh", "--put_cluster", "cluster-1", "--schemes", "prpc,http", "--banned", "http://www.google.com", "--store", "zk://localhost:2181/echo/lb/clusters"]) procutils.run(["/Users/criccomi/svn/pegasus/trunk/d2/scripts/lb-tool.sh", "--put_service", "service-1", "--cluster", "cluster-1", "--path", "/service-1", "--balancer", "degrader", "--store", "zk://localhost:2181/echo/lb/services"]) procutils.run(["/Users/criccomi/svn/pegasus/trunk/d2/scripts/lb-tool.sh", "--put_service", "service-2", "--cluster", "cluster-1", "--path", "/service-2", "--balancer", "degrader", "--store", "zk://localhost:2181/echo/lb/services"]) # start server and client procutils.start_daemon('LoadBalancerEchoServer'); procutils.start_daemon('LoadBalancerEchoClient'); # declare faults kill_short_zk = faults.kill_daemons(["QuorumPeerMain"], signal.SIGKILL, 5) kill_short_server = faults.kill_daemons(["LoadBalancerEchoServer"], signal.SIGKILL, 5) kill_short_client = faults.kill_daemons(["LoadBalancerEchoClient"], signal.SIGKILL, 5) kill_long_zk = faults.kill_daemons(["QuorumPeerMain"], signal.SIGKILL, 60) kill_long_server = faults.kill_daemons(["LoadBalancerEchoServer"], signal.SIGKILL, 60) kill_long_client = faults.kill_daemons(["LoadBalancerEchoClient"], signal.SIGKILL, 60)