Chaos engineering tool for simulating real-world distributed system failures

Overview

Muxy Logo

Proxy for simulating real-world distributed system failures to improve resilience in your applications.

wercker status Go Report Card GoDoc Coverage Status

Introduction

Muxy is a proxy that mucks with your system and application context, operating at Layers 4, 5 and 7, allowing you to simulate common failure scenarios from the perspective of an application under test; such as an API or a web application.

If you are building a distributed system, Muxy can help you test your resilience and fault tolerance patterns.

Contents

Features

  • Ability to tamper with network devices at the transport level (Layer 4)
  • Ability to tamper with the TCP session layer (Layer 5)
  • ...and HTTP requests/responses at the HTTP protocol level (Layer 7)
    • Supports custom proxy routing (aka basic reverse proxy)
    • Advanced matching rules allow you to target specific requests
    • Introduce randomness into symptoms
  • Simulate real-world network connectivity problems/partitions for mobile devices, distributed systems etc.
  • Ideal for use in CI/Test Suites to test resilience across languages/technologies
  • Simple native binary installation with no dependencies
  • Extensible and modular architecture
  • An official Docker container to simplify uses cases such as Docker Compose

Installation

Download a release for your platform and put it somewhere on the PATH.

On Mac OSX using Homebrew

If you are using Homebrew you can follow these steps to install Muxy:

brew install https://raw.githubusercontent.com/mefellows/muxy/master/scripts/muxy.rb

Using Go Get

go get github.com/mefellows/muxy

Using Muxy

Muxy is typically used in two ways:

  1. In local development to see how your application responds under certain conditions
  2. In test suites to automate resilience testing

5-minute example

  1. Install Muxy

  2. Create configuration file config.yml:

    # Configures a proxy to forward/mess with your requests
    # to/from www.onegeek.com.au. This example adds a 5s delay
    # to the response.
    proxy:
      - name: http_proxy
        config:
          host: 0.0.0.0
          port: 8181
          proxy_host: www.onegeek.com.au
          proxy_port: 80
    
    # Proxy plugins
    middleware:
      - name: http_tamperer
        config:
          request:
            host: "www.onegeek.com.au"
    
      # Message Delay request/response plugin
      - name: delay
        config:
          request_delay: 1000
          response_delay: 500
    
      # Log in/out messages
      - name: logger
  3. Run Muxy with your config: muxy proxy --config ./config.yml

  4. Make a request to www.onegeek.com via the proxy: time curl -v -H"Host: www.onegeek.com.au" http://localhost:8181/. Compare that with a request direct to the website: time curl -v www.onegeek.com.au - it should be approximately 5s faster.

That's it - running Muxy is a matter of configuring one or more Proxies, with 1 or more Middleware components defined in a simple YAML file.

Muxy as part of a test suite

  1. Create an application
  2. Build in fault tolerence (e.g. using something like Hystrix)
  3. Create integration tests
  4. Run Muxy configuring a proxy such as HTTP, and one or more symptoms such as network latency, partition or HTTP error
  5. Point your app at Muxy
  6. Run tests and check if system behaved as expected
  7. Profit!

Notes

Muxy is a stateful system, and mucks with your low-level (system) networking interfaces and therefore cannot be run in parallel with other tests. It is also recommended to run within a container/virtual machine to avoid unintended consequences (like breaking Internet access from the host).

Proxies and Middlewares

Proxies

HTTP Proxy

Simple HTTP(s) Proxy that starts up on a local IP/Hostname and Port.

Example configuration snippet:

proxy:
  - name: http_proxy
    config:
      ## Proxy host details
      host: 0.0.0.0
      protocol: http
      port: 8181

      ## Proxy target details
      proxy_host: 0.0.0.0
      proxy_port: 8282
      proxy_protocol: https

      ## Certificate to present to Muxy clients (i.e. server certs)
      proxy_ssl_key: proxy-server/test.key
      proxy_ssl_cert: proxy-server/test.crt

      ## Certificate to present to Muxy proxy targets (i.e. client certs)
      proxy_client_ssl_key: client-certs/cert-key.pem
      proxy_client_ssl_cert: client-certs/cert.pem
      proxy_client_ssl_ca: client-certs/ca.pem

      ## Enable this to proxy targets we don't trust
      # insecure: true # allow insecure https

      # Specify additional proxy rules. Default catch-all proxy still
      # applies with lowest matching precedence.
      # Request matchers are specified as valid regular expressions
      # and must be properly YAML escaped.
      # See https://github.com/mefellows/muxy/issues/11 for behaviour.
      - request:
          method: 'GET|DELETE'
          path: '^\/foo'
          host: '.*foo\.com'
        pass:
          path: '/bar'
          scheme: 'http'
          host: 'bar.com'

TCP Proxy

Simple TCP Proxy that starts up on a local IP/Hostname and Port, forwarding traffic to the specified proxy_host on proxy_port.

Example configuration snippet:

proxy:
  - name: tcp_proxy
    config:
      host: 0.0.0.0 # Local ip/hostname to bind to and accept connections.
      port: 8080 # Local port to bind to
      proxy_host: 0.0.0.0
      proxy_port: 2000
      nagles_algorithm: true
      packet_size: 64

Middleware

Middleware have the ability to intervene upon receiving a request (Pre-Dispatch) or before sending the response back to the client (Post-Dispatch). In some cases, such as the Network Shaper, the effect is applied before any request is made (e.g. if the local network device configuration is altered).

Delay

A basic middleware that simply adds a delay of delay milliseconds to the request or response.

Example configuration snippet:

middleware:
  - name: delay
    config:
      request_delay: 1000 # Delay in ms to apply to request to target
      response_delay: 500 # Delay in ms to apply to response from target

      # Specify additional matching rules. Default is to apply delay to all
      # requests on all http proxies.
      # Request matchers are specified as valid regular expressions
      # and must be properly YAML escaped.
      # See https://github.com/mefellows/muxy/issues/11 for behaviour.
      matching_rules:
        - method: "GET|DELETE"
          path: "^/boo"
          host: 'foo\.com'

HTTP Tamperer

A Layer 7 tamperer, this plugin allows you to modify response headers, status code or the body itself.

Example configuration snippet:

middleware:
  - name: http_tamperer
    config:
      request:
        host: "somehost" # Override Host header that's sent to target
        path: "/" # Override the request path
        method: "GET" # Override request method
        headers:
          x_my_request: "foo" # Override request header
          content_type: "application/x-www-form-urlencoded"
          content_length: "5"
        cookies: # Custom request cookies
          - name: "fooreq"
            value: "blahaoeuaoeu"
            domain: "localhost"
            path: "/foopath"
            secure: true
            rawexpires: "Sat, 12 Sep 2015 09:19:48 UTC"
            maxage: 200
            httponly: true
        body: "wow, new body!" # Override request body
      response:
        status: 201 # Override HTTP Status code
        headers: # Override response headers
          content_length: "27"
          x_foo_bar: "baz"
        body: "my new body" # Override response body
        cookies: # Custom response cookies
          - name: "foo"
            value: "blahaoeuaoeu"
            domain: "localhost"
            path: "/foopath"
            secure: true
            rawexpires: "Sat, 12 Sep 2015 09:19:48 UTC"
            maxage: 200
            httponly: true

      # Specify additional matching rules. Default is to apply delay to all
      # requests on all http proxies.
      # Request matchers are specified as valid regular expressions
      # and must be properly YAML escaped.
      # See https://github.com/mefellows/muxy/issues/11 for behaviour.
      matching_rules:
        - method: "GET|DELETE"
          path: "^/boo"
          host: 'foo\.com'

Network Shaper

The network shaper plugin is a Layer 4 tamperer, and requires root access to work, as it needs to configure the local firewall and network devices. Using the excellent Comcast library, it can shape and interfere with network traffic, including bandwidth, latency, packet loss and jitter on specified ports, IPs and protocols.

NOTE: This component only works on MacOSX, FreeBSD, Linux and common *nix flavours.

Example configuration snippet:

middleware:
  - name: network_shape
    config:
      latency: 250 # Latency to add in ms
      target_bw: 750 # Bandwidth in kbits/s
      packet_loss: 0.5 # Packet loss, as a %
      target_ips: # Target ipv4 IP addresses
        - 0.0.0.0
      target_ips6: # Target ipv6 IP addresses
        - "::1/128"
      target_ports: # Target destination ports
        - "80"
      target_protos: # Target protocols
        - "tcp"
        - "udp"
        - "icmp"
      device: "lo" # defaults to eth0

TCP Tamperer

The TCP Tamperer is a Layer 5 tamperer, modifying the messages in and around TCP sessions. Crudely, you can set the body of inbound and outbound TCP packets, truncate the last character of messages or randomise the text over the wire.

- name: tcp_tamperer
  config:
    request:
      body: "wow, new request!" # Override request body
      randomize: true # Replaces input message with a random string
      truncate: true # Removes last character from the request message
    response:
      body: "wow, new response!" # Override response body
      randomize: true # Replaces response message with a random string
      truncate: true # Removes last character from the response message

Logger

Log the in/out messages, optionally requesting the output to be hex encoded.

Example configuration snippet:

middleware:
  - name: logger
    config:
      hex_output: false # Display output as Hex instead of a string

Configuration Reference

Refer to the example YAML file for a full reference.

Examples

Hystrix

Using the Hystrix Go library, we use Muxy to trigger a circuit breaker and return a canned response, ensuring we don't have downtime. View the example.

Usage with Docker

Download the Docker image by running:

docker pull mefellows/muxy

After creating a [config](#configuration-reference] file (let's assume it's at ./conf/config.yml), and assuming you are proxying something on port 80, you can now run the image locally:

docker run \
  -d \
  -p 80:80 \
  -v "$PWD/conf":/opt/muxy/conf \
  --privileged \
  mefellows/muxy

You should now be able to hit this Docker container and simulate any failures as per usual. e.g. curl docker:80/some/endpoint.

The Hystrix example above has a detailed example on how to use Muxy with a more complicated system, using Docker Compose to orchestrate a number of containers.

Extending Muxy

Muxy is built as a series of configurable plugins (using Plugo) that must be specified in the configuration file to be activated. Start with a quick tour of Plugo before progressing.

Proxies

Proxies must implement the Proxy interface, and register themselves via PluginFactories.register to be available at runtime. Take a look at the HTTP Proxy for a good working example.

Middleware

Middlewares implement the Middleware interface and register themselves via PluginFactories.register to be available at runtime. Take a look at the HTTP Delay for a good working example.

Contributing

See CONTRIBUTING.

Comments
  • Can not start muxy proxy with a network_shape configuration.

    Can not start muxy proxy with a network_shape configuration.

    My muxy.config:

    proxy:
      - name: http_proxy
        config:
          host: 0.0.0.0
          port: 8527
          protocol: http
          proxy_host: 192.168.8.228
          proxy_port: 8527
          proxy_protocol: http
      - name: tcp_proxy
        config:
          host: 0.0.0.0           # Local address to bind to and accept connections. May be an IP/hostname
          port: 9527              # Local port to bind to
          proxy_host: 192.168.8.228     # Proxy server port
          proxy_port: 9527        # Proxied server port
          nagles_algorithm: true  # Use Nagles algorithm?
          packet_size: 64         # Size of each contiguous network packet to proxy
    middleware:
      - name: logger
        config:
          hex_output: false
      - name: delay
        config:
          request_delay: 2000
          response_delay: 1500
      - name: network_shape
        config:
          latency:     1000        # Latency to add in ms
          target_bw:   10         # Bandwidth in kbits/s
          packet_loss: 0.9         # Packet loss, as a %
          target_ips:              # Target ipv4 IP addresses/CIDRs
            - "0.0.0.0/0"
          target_ips6:             # Target ipv6 IP addresses
            - "::1/128"
          target_ports:            # Target destination ports
            - "9527"               # - "1:65535"            # Ranges also valid
          target_protos:           # Target protocols
            - "tcp"
            - "udp"
            - "imp"
    

    command

    sudo ./muxy_bin proxy --config muxy_middleware.yml
    

    logs

    2018/08/21 10:38:45.999520 [INFO]		Loading plugin 	logger
    2018/08/21 10:38:45.999540 [INFO]		Loading plugin 	delay
    2018/08/21 10:38:45.999549 [INFO]		Loading plugin 	network_shape
    2018/08/21 10:38:45.999706 [INFO]		Loading proxy 	http_proxy
    2018/08/21 10:38:45.999733 [INFO]		Loading proxy 	tcp_proxy
    2018/08/21 10:38:45.999741 [DEBUG]		Delay Symptom - Setup()
    2018/08/21 10:38:45.999748 [DEBUG]		NetworkShaperSymptom - Setup()
    

    and Muxy process exited.

    I viewed the source code, I think that this code will has a panic:

    network_shape.go - 62

    executeThrottler(&s.config)
    

    how can I solve this problem? thanks.

    Triage 
    opened by yangyongzhi7 18
  • network_shape middleware crashes Muxy

    network_shape middleware crashes Muxy

    I'm trying to use Muxy to test a TCP protocol and it crashes as soon as I turn on the network_shape middleware (tried copying the default settings).

    There is nothing in the program output that would point to the problem, this is what I get before the program exits:

    2018/03/07 10:28:37.633260 [INFO]               Loading plugin  logger
    2018/03/07 10:28:37.633277 [INFO]               Loading plugin  network_shape
    2018/03/07 10:28:37.633391 [INFO]               Loading proxy   tcp_proxy
    2018/03/07 10:28:37.633399 [INFO]               Loading proxy   tcp_proxy
    2018/03/07 10:28:37.633404 [INFO]               Loading proxy   http_proxy
    2018/03/07 10:28:37.633411 [DEBUG]              NetworkShaperSymptom - Setup()
    

    I'm running Muxy 0.05 on an OpenSuse Linux with kernel version 3.12. I downloaded the binary release from Github and also tried the 0.06 pre-release, with the same result.

    Triage 
    opened by gregopet 4
  • Addition of hacktoberfest topic to the project

    Addition of hacktoberfest topic to the project

    I feel adding the hacktoberfest topic to the list of labels in the project would greatly increase the visibility of this awesome project in my opinion

    More info on hacktoberfest: https://hacktoberfest.digitalocean.com/

    Current topics

    Screenshot 2021-10-26 at 1 35 00 PM
    opened by kishaningithub 1
  • Support randomness in symptoms

    Support randomness in symptoms

    Ability to add randomness to when a symptom (any symptom) fires, e.g.

      - name: delay
        config:
          request_delay:  100              # Delay in ms to apply to request
          response_delay: 500              # Delay in ms to apply to response
          matching_rules:
            probability: 20                # Probability of delay  
    
    opened by mefellows 0
  • Feat/routing

    Feat/routing

    Fixes #11 and adds a bunch of tests that were desperately required - given I was under the hood, it felt a good time to address the related missing tests.

    opened by mefellows 0
  • SSL, TCP Tamperer and more

    SSL, TCP Tamperer and more

    SSL

    • Run Proxy with HTTPS enabled
    • Run Proxy with HTTPS enabled + custom certificate
    • Proxy HTTPS target
    • Proxy HTTPS target with invalid (untrusted) certificate
    • Proxy HTTPS target requiring client certificates

    TCP

    • Ability to tamper with TCP messages
    • Modify request/response packets with canned responses
    • Randomize request/response packets
    • Truncate last char of request/response packets

    HTTP Proxy

    • Ability to set request Host
    • Ability to set request Path

    Delay Symptom

    • Set delay on request and response
    • Convert to millisecond granularity

    Other

    • Bunch of formatting fun

    Fixes #13, #10, #9, #7.

    opened by mefellows 0
  • Add ability to tamper with TCP messages

    Add ability to tamper with TCP messages

    Currently, the TCP Proxy has the capability for Middleware to render chaos, but no such middlewares exist. Create one.

    Requirements:

    • Ability to send a canned request to the target, overriding the initial request
    • Ability to send a canned response to the client, overriding the targets message
    • Random entropy - just add random bits here and there
    opened by mefellows 0
  • Add ability to match based on paths regex in HTTP Proxy

    Add ability to match based on paths regex in HTTP Proxy

    It would be great to be able to differentiate symptoms in the HTTP proxy and symptoms based on the incoming path. Middleware components should skip if the path does not match the incoming request.

    This should allow some extra flexibility when proxying multiple endpoints on a single target (e.g. an Nginx server or API gateway).

    Requirements:

    HTTP Proxy

    1. Specify zero or more Proxy Rules on the http_proxy symptom. The rules may include the following details:
      1. Matching path, host and method as a regular expression
      2. Specifying proxy target rules (path, host and method as strings)
        1. All options replace existing request details, except for path which is prepended to the existing request path e.g. if path was /baz and request http://foo.com/foo/bar => http://foo.com/baz/foo/bar
    2. If no Proxy Rules are provided, default is to proxy as per current behaviour (all requests to proxy are sent to proxy target)
    3. If one or more Proxy Rules are specified, they will take precedence over a default catch-all proxy (existing behaviour)
    4. Proxy Rules are evaluated in the order they are specified (precedence)
    5. Performance is not a consideration

    HTTP Symptom

    1. Specify zero or more Matching Rules on the http_tamperer and http_delay symptoms. The rules may include the following details:
      1. Matching path, host and method as a regular expression
    2. If no Matching Rules are provided, default is to apply symptoms as per current behaviour (all requests to proxy are mucked)
    3. If one or more Matching Rules are specified, unmatched rules do not have any symptom applied
    4. Proxy Rule precedence is FIFO
    enhancement 
    opened by mefellows 0
  • Support full request/response tampering features in 'http_tamperer'

    Support full request/response tampering features in 'http_tamperer'

    Support full tampering feature set for the 'http_tamperer' middleware:

    Request:

    • Headers
    • Cookies
    • Method
    • Body

    Response

    • Headers
    • Cookies
    • Body
    • Status Code
    opened by mefellows 0
  • Migrate to go modules

    Migrate to go modules

    I see the project still uses go dep (https://github.com/mefellows/muxy/tree/master/Godeps)

    Any specific reason for the same?

    I recommend moving to go modules, I am happy to help

    opened by kishaningithub 1
  • Support environment variables in templates

    Support environment variables in templates

    In use cases such as Docker, it's common to move around things like hostnames and ports - this makes configuration files brittle and less flexible.

    Supporting e.g. the ability for environment variables to change values would be super handy.

    enhancement 
    opened by mefellows 0
  • Network shape symptom does not discriminate port range on OSX

    Network shape symptom does not discriminate port range on OSX

    Given a Muxy configuration as follows, we expect only ports 8181 and 8282 to be shaped.

    However, it does in fact still slow down other ports.

      - name: network_shape
        config:
          latency:     250         # Latency to add in ms
          target_bw:   750         # Bandwidth in kbits/s
          packet_loss: 0.5         # Packet loss, as a %
          target_ips:              # Target ipv4 IP addresses/CIDRs
            - "0.0.0.0/0"
          target_ips6:             # Target ipv6 IP addresses
            - "::1/128"
          target_ports:            # Target destination ports
            - "8181"
            - "8282"
            # - "8080:9000"          # Ranges also valid
          target_protos:           # Target protocols
            - "tcp"
            - "udp"
            - "icmp"
    
    bug 
    opened by mefellows 0
  • Add ability to send back a stub response

    Add ability to send back a stub response

    In some cases, we don't want the proxy to send the request downstream at all - the ability to return a controlled stub could be useful.

    Need to think about this as we don't want to build a stubbing engine either. But in some cases this is much simpler (e.g. send a 401 response)

    enhancement question 
    opened by mefellows 0
Releases(v0.0.6)
Owner
Matt Fellows
Matt Fellows
Simulating shitty network connections so you can build better systems.

Comcast Testing distributed systems under hard failures like network partitions and instance termination is critical, but it's also important we test

Tyler Treat 9.8k Dec 30, 2022
BAIN Social is a Fully Decentralized Server/client system that utilizes Concepts pioneered by I2P, ToR, and PGP to create a system which bypasses singular hosts for data while keeping that data secure.

SYNOPSIS ---------------------------------------------------------------------------------------------------- Welcome to B.A.I.N - Barren's A.I. Natio

Barren A.I. Wolfsbane 14 Jan 11, 2022
Distributed WebSocket Server

Keeper 分布式 WebSocket 服务器。 注意事项 IO 线程和业务线程分离:对于小业务,依旧放到 worker 线程中处理,对于需要和中间件交互的丢到业务线程池处理,避免 worker 阻塞。 WebSocket 握手阶段支持参数列表。 插件 本服务功能插件化。

岚 1 Dec 15, 2022
A Linux packet crafting tool.

Pig Pig (which can be understood as Packet intruder generator) is a Linux packet crafting tool. You can use Pig to test your IDS/IPS among other stuff

Rafael Santiago 431 Dec 24, 2022
JNetcat : a tool to debug network issues or simulate servers

JNetcat A tool to easily debug or monitor traffic on TCP/UDP and simulate a server or client No need of telnet anymore to test for a remote connection

io-panic 3 Jul 26, 2022
Remote Support Tool is an easy single click solution for remote maintenance.

Remote Support Tool is an easy single click solution for remote maintenance.

OpenIndex.de 74 Jun 13, 2022
Intra is an experimental tool that allows you to test new DNS-over-HTTPS services that encrypt domain name lookups and prevent manipulation by your network

Intra Intra is an experimental tool that allows you to test new DNS-over-HTTPS services that encrypt domain name lookups and prevent manipulation by y

Jigsaw 1.2k Jan 1, 2023
CustomRPC - a tool that allows you to change your discord rich presence (RPC) to a custom one

CustomRPC is a tool that allows you to change your discord rich presence (RPC) to a custom one. It also allows creating sentence sequences

null 2 May 3, 2022
Simple & Lightweight Netty packet library + event system

Minimalistic Netty-Packet library Create packets with ease Bind events to packets Example Packet: public class TestPacket extends Packet { privat

Pierre Maurice Schwang 17 Dec 7, 2022
Nzyme is a free and open next-generation WiFi defense system.

Nzyme is a free and open next-generation WiFi defense system.

Lennart Koopmann 1.1k Jan 1, 2023
Tools for keeping your cloud operating in top form. Chaos Monkey is a resiliency tool that helps applications tolerate random instance failures.

PROJECT STATUS: RETIRED The Simian Army project is no longer actively maintained. Some of the Simian Army functionality has been moved to other Netfli

Netflix, Inc. 7.9k Jan 6, 2023
Sniffy - interactive profiler, testing and chaos engineering tool for Java

Sniffy Sniffy is a Java profiler which shows the results directly in your browser. It also brings profiling to your unit (or rather component) tests a

Sniffy 139 Dec 23, 2022
BungeeCord/Spigot plugin that fixes Multi-world detection by simulating mod presence on the server side

Companion for map mods Unofficial BungeeCord and Spigot (Paper) companion plugin for Xaero's Minimap (and their World Map), JourneyMap and VoxelMap. T

Artur Khusainov 3 Sep 18, 2022
Simulating shitty network connections so you can build better systems.

Comcast Testing distributed systems under hard failures like network partitions and instance termination is critical, but it's also important we test

Tyler Treat 9.8k Dec 30, 2022
Logisim-evolution is educational software for designing and simulating digital logic circuits

Branch master: Branch develop: Logisim-evolution Table of contents Features Requirements Downloads Nightly builds (unstable) Pictures of Logisim-evolu

null 3k Jan 4, 2023
A tool for reverse engineering Android apk files

Apktool This is the repository for Apktool. If you are looking for the Apktool website. Click here. It is a tool for reverse engineering 3rd party, cl

Connor Tumbleson 15.4k Jan 4, 2023
chaos-platform

Chaosblade-box: An chaos engineering platform with rich scenes Introduction Chaosblade-box is an chaos engineering platform with rich scenes, the scen

null 179 Dec 22, 2022
Pandaemonium-Fabric - Unleash the chaos.

Pandaemonium Unleash the chaos. Pandaemonium is a Fabric-based mod for Minecraft. I am creating this primarily to learn Fabric modding and Java. Cavea

Chris Shoeman 1 Jan 6, 2022
Clone of real world Chatting application Whatsapp built on Android Studio and Firebase

WhatsappChatApp About This Project Clone of real world Chatting application Whatsapp built on Android Studio and Firebase Programming Language Used :

Aditya Bonde 11 May 23, 2022