{"id":13491409,"url":"https://github.com/mefellows/muxy","last_synced_at":"2025-04-04T22:08:00.649Z","repository":{"id":53397184,"uuid":"41590877","full_name":"mefellows/muxy","owner":"mefellows","description":"Chaos engineering tool for simulating real-world distributed system failures","archived":false,"fork":false,"pushed_at":"2021-01-13T12:31:12.000Z","size":1727,"stargazers_count":823,"open_issues_count":8,"forks_count":31,"subscribers_count":26,"default_branch":"master","last_synced_at":"2024-11-15T11:07:14.002Z","etag":null,"topics":["chaos","chaos-engineering","golang","hacktoberfest","hacktoberfest2021","proxy","resilience","testing"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mefellows.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-29T11:13:21.000Z","updated_at":"2024-10-11T15:41:35.000Z","dependencies_parsed_at":"2022-08-13T02:40:15.002Z","dependency_job_id":null,"html_url":"https://github.com/mefellows/muxy","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mefellows%2Fmuxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mefellows%2Fmuxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mefellows%2Fmuxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mefellows%2Fmuxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mefellows","download_url":"https://codeload.github.com/mefellows/muxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256112,"owners_count":20909240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chaos","chaos-engineering","golang","hacktoberfest","hacktoberfest2021","proxy","resilience","testing"],"created_at":"2024-07-31T19:00:56.796Z","updated_at":"2025-04-04T22:08:00.631Z","avatar_url":"https://github.com/mefellows.png","language":"Go","funding_links":[],"categories":["Go","Network"],"sub_categories":[],"readme":"# \u003cimg src=\"https://cloud.githubusercontent.com/assets/53900/26097013/7c930660-3a66-11e7-9b5c-780b0630d5a4.gif\" alt=\"Muxy Logo\" style=\"height: 80px;\" height=\"80px\"/\u003e\n\nProxy for simulating real-world distributed system failures to improve resilience in your applications.\n\n[![wercker status](https://app.wercker.com/status/e45703ebafd48632db56f022cc54546b/s \"wercker status\")](https://app.wercker.com/project/bykey/e45703ebafd48632db56f022cc54546b)\n[![Go Report Card](https://goreportcard.com/badge/github.com/mefellows/muxy)](https://goreportcard.com/report/github.com/mefellows/muxy)\n[![GoDoc](https://godoc.org/github.com/mefellows/muxy?status.svg)](https://godoc.org/github.com/mefellows/muxy)\n[![Coverage Status](https://coveralls.io/repos/github/mefellows/muxy/badge.svg?branch=HEAD)](https://coveralls.io/github/mefellows/muxy?branch=HEAD)\n\n## Introduction\n\nMuxy 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.\n\nIf you are building a distributed system, Muxy can help you test your resilience and fault tolerance patterns.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"880\" src=\"https://cdn.rawgit.com/mefellows/muxy/master/images/muxy.svg\"\u003e\n\u003c/p\u003e\n\n### Contents\n\n\u003c!-- TOC depthFrom:2 depthTo:4 withLinks:1 updateOnSave:1 orderedList:0 --\u003e\n\n- [Introduction](#introduction) - [Contents](#contents)\n- [Features](#features)\n- [Installation](#installation) - [On Mac OSX using Homebrew](#on-mac-osx-using-homebrew) - [Using Go Get](#using-go-get)\n- [Using Muxy](#using-muxy) - [5-minute example](#5-minute-example) - [Muxy as part of a test suite](#muxy-as-part-of-a-test-suite) - [Notes](#notes)\n- [Proxies and Middlewares](#proxies-and-middlewares) - [Proxies](#proxies) - [HTTP Proxy](#http-proxy) - [TCP Proxy](#tcp-proxy) - [Middleware](#middleware) - [Delay](#delay) - [HTTP Tamperer](#http-tamperer) - [Network Shaper](#network-shaper) - [TCP Tamperer](#tcp-tamperer) - [Logger](#logger)\n- [Configuration Reference](#configuration-reference)\n- [Examples](#examples) - [Hystrix](#hystrix)\n- [Usage with Docker](#usage-with-docker)\n- [Extending Muxy](#extending-muxy) - [Proxies](#proxies) - [Middleware](#middleware)\n- [Contributing](#contributing)\n\n\u003c!-- /TOC --\u003e\n\n## Features\n\n- Ability to tamper with network devices at the transport level (Layer 4)\n- Ability to tamper with the TCP session layer (Layer 5)\n- ...and HTTP requests/responses at the HTTP protocol level (Layer 7)\n  - Supports custom proxy routing (aka basic reverse proxy)\n  - Advanced matching rules allow you to target specific requests\n  - Introduce randomness into symptoms\n- Simulate real-world network connectivity problems/partitions for mobile devices, distributed systems etc.\n- Ideal for use in CI/Test Suites to test resilience across languages/technologies\n- Simple native binary installation with no dependencies\n- Extensible and modular architecture\n- An official Docker [container](https://github.com/mefellows/docker-muxy) to simplify uses cases such as Docker Compose\n\n## Installation\n\nDownload a [release](https://github.com/mefellows/muxy/releases) for your platform\nand put it somewhere on the `PATH`.\n\n### On Mac OSX using Homebrew\n\nIf you are using [Homebrew](http://brew.sh) you can follow these steps to install Muxy:\n\n```bash\nbrew install https://raw.githubusercontent.com/mefellows/muxy/master/scripts/muxy.rb\n```\n\n### Using Go Get\n\n```\ngo get github.com/mefellows/muxy\n```\n\n## Using Muxy\n\nMuxy is typically used in two ways:\n\n1. In local development to see how your application responds\n   under certain conditions\n1. In test suites to automate resilience testing\n\n### 5-minute example\n\n1. Install Muxy\n1. Create configuration file `config.yml`:\n\n   ```yaml\n   # Configures a proxy to forward/mess with your requests\n   # to/from www.onegeek.com.au. This example adds a 5s delay\n   # to the response.\n   proxy:\n     - name: http_proxy\n       config:\n         host: 0.0.0.0\n         port: 8181\n         proxy_host: www.onegeek.com.au\n         proxy_port: 80\n\n   # Proxy plugins\n   middleware:\n     - name: http_tamperer\n       config:\n         request:\n           host: \"www.onegeek.com.au\"\n\n     # Message Delay request/response plugin\n     - name: delay\n       config:\n         request_delay: 1000\n         response_delay: 500\n\n     # Log in/out messages\n     - name: logger\n   ```\n\n1. Run Muxy with your config: `muxy proxy --config ./config.yml`\n1. 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.\n\nThat's it - running Muxy is a matter of configuring one or more [Proxies](#proxies), with 1 or more [Middleware](#middleware) components defined in a simple [YAML file](/examples/config.yml).\n\n### Muxy as part of a test suite\n\n1. Create an application\n2. Build in fault tolerence (e.g. using something like [Hystrix](https://github.com/Netflix/Hystrix))\n3. Create integration tests\n4. Run Muxy configuring a _proxy_ such as HTTP, and one or more *symptom*s such as network latency, partition or HTTP error\n5. Point your app at Muxy\n6. Run tests and check if system behaved as expected\n7. Profit!\n\n### Notes\n\nMuxy is a stateful system, and mucks with your low-level (system) networking interfaces and therefore cannot be run in parallel with other tests.\nIt is also recommended to run within a container/virtual machine to avoid unintended consequences (like breaking Internet access from the host).\n\n## Proxies and Middlewares\n\n### Proxies\n\n#### HTTP Proxy\n\nSimple HTTP(s) Proxy that starts up on a local IP/Hostname and Port.\n\nExample configuration snippet:\n\n```yaml\nproxy:\n  - name: http_proxy\n    config:\n      ## Proxy host details\n      host: 0.0.0.0\n      protocol: http\n      port: 8181\n\n      ## Proxy target details\n      proxy_host: 0.0.0.0\n      proxy_port: 8282\n      proxy_protocol: https\n\n      ## Certificate to present to Muxy clients (i.e. server certs)\n      proxy_ssl_key: proxy-server/test.key\n      proxy_ssl_cert: proxy-server/test.crt\n\n      ## Certificate to present to Muxy proxy targets (i.e. client certs)\n      proxy_client_ssl_key: client-certs/cert-key.pem\n      proxy_client_ssl_cert: client-certs/cert.pem\n      proxy_client_ssl_ca: client-certs/ca.pem\n\n      ## Enable this to proxy targets we don't trust\n      # insecure: true # allow insecure https\n\n      # Specify additional proxy rules. Default catch-all proxy still\n      # applies with lowest matching precedence.\n      # Request matchers are specified as valid regular expressions\n      # and must be properly YAML escaped.\n      # See https://github.com/mefellows/muxy/issues/11 for behaviour.\n      - request:\n          method: 'GET|DELETE'\n          path: '^\\/foo'\n          host: '.*foo\\.com'\n        pass:\n          path: '/bar'\n          scheme: 'http'\n          host: 'bar.com'\n\n```\n\n#### TCP Proxy\n\nSimple TCP Proxy that starts up on a local IP/Hostname and Port, forwarding traffic to the specified `proxy_host` on `proxy_port`.\n\nExample configuration snippet:\n\n```yaml\nproxy:\n  - name: tcp_proxy\n    config:\n      host: 0.0.0.0 # Local ip/hostname to bind to and accept connections.\n      port: 8080 # Local port to bind to\n      proxy_host: 0.0.0.0\n      proxy_port: 2000\n      nagles_algorithm: true\n      packet_size: 64\n```\n\n### Middleware\n\nMiddleware have the ability to intervene upon receiving a request (Pre-Dispatch) or before sending the response back to the client (Post-Dispatch).\nIn 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).\n\n#### Delay\n\nA basic middleware that simply adds a delay of `delay` milliseconds to the request\nor response.\n\nExample configuration snippet:\n\n```yaml\nmiddleware:\n  - name: delay\n    config:\n      request_delay: 1000 # Delay in ms to apply to request to target\n      response_delay: 500 # Delay in ms to apply to response from target\n\n      # Specify additional matching rules. Default is to apply delay to all\n      # requests on all http proxies.\n      # Request matchers are specified as valid regular expressions\n      # and must be properly YAML escaped.\n      # See https://github.com/mefellows/muxy/issues/11 for behaviour.\n      matching_rules:\n        - method: \"GET|DELETE\"\n          path: \"^/boo\"\n          host: 'foo\\.com'\n```\n\n#### HTTP Tamperer\n\nA Layer 7 tamperer, this plugin allows you to modify response headers, status code or the body itself.\n\nExample configuration snippet:\n\n```yaml\nmiddleware:\n  - name: http_tamperer\n    config:\n      request:\n        host: \"somehost\" # Override Host header that's sent to target\n        path: \"/\" # Override the request path\n        method: \"GET\" # Override request method\n        headers:\n          x_my_request: \"foo\" # Override request header\n          content_type: \"application/x-www-form-urlencoded\"\n          content_length: \"5\"\n        cookies: # Custom request cookies\n          - name: \"fooreq\"\n            value: \"blahaoeuaoeu\"\n            domain: \"localhost\"\n            path: \"/foopath\"\n            secure: true\n            rawexpires: \"Sat, 12 Sep 2015 09:19:48 UTC\"\n            maxage: 200\n            httponly: true\n        body: \"wow, new body!\" # Override request body\n      response:\n        status: 201 # Override HTTP Status code\n        headers: # Override response headers\n          content_length: \"27\"\n          x_foo_bar: \"baz\"\n        body: \"my new body\" # Override response body\n        cookies: # Custom response cookies\n          - name: \"foo\"\n            value: \"blahaoeuaoeu\"\n            domain: \"localhost\"\n            path: \"/foopath\"\n            secure: true\n            rawexpires: \"Sat, 12 Sep 2015 09:19:48 UTC\"\n            maxage: 200\n            httponly: true\n\n      # Specify additional matching rules. Default is to apply delay to all\n      # requests on all http proxies.\n      # Request matchers are specified as valid regular expressions\n      # and must be properly YAML escaped.\n      # See https://github.com/mefellows/muxy/issues/11 for behaviour.\n      matching_rules:\n        - method: \"GET|DELETE\"\n          path: \"^/boo\"\n          host: 'foo\\.com'\n```\n\n#### Network Shaper\n\nThe 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.\nUsing the excellent [Comcast](https://github.com/tylertreat/comcast) library, it can shape and interfere with network traffic,\nincluding bandwidth, latency, packet loss and jitter on specified ports, IPs and protocols.\n\nNOTE: This component only works on MacOSX, FreeBSD, Linux and common \\*nix flavours.\n\nExample configuration snippet:\n\n```yaml\nmiddleware:\n  - name: network_shape\n    config:\n      latency: 250 # Latency to add in ms\n      target_bw: 750 # Bandwidth in kbits/s\n      packet_loss: 0.5 # Packet loss, as a %\n      target_ips: # Target ipv4 IP addresses\n        - 0.0.0.0\n      target_ips6: # Target ipv6 IP addresses\n        - \"::1/128\"\n      target_ports: # Target destination ports\n        - \"80\"\n      target_protos: # Target protocols\n        - \"tcp\"\n        - \"udp\"\n        - \"icmp\"\n      device: \"lo\" # defaults to eth0\n```\n\n#### TCP Tamperer\n\nThe TCP Tamperer is a Layer 5 tamperer, modifying the messages in and around TCP\nsessions. Crudely, you can set the body of inbound and outbound TCP packets, truncate\nthe last character of messages or randomise the text over the wire.\n\n```yaml\n- name: tcp_tamperer\n  config:\n    request:\n      body: \"wow, new request!\" # Override request body\n      randomize: true # Replaces input message with a random string\n      truncate: true # Removes last character from the request message\n    response:\n      body: \"wow, new response!\" # Override response body\n      randomize: true # Replaces response message with a random string\n      truncate: true # Removes last character from the response message\n```\n\n#### Logger\n\nLog the in/out messages, optionally requesting the output to be hex encoded.\n\nExample configuration snippet:\n\n```yaml\nmiddleware:\n  - name: logger\n    config:\n      hex_output: false # Display output as Hex instead of a string\n```\n\n## Configuration Reference\n\nRefer to the [example](/examples/config.yml) YAML file for a full reference.\n\n## Examples\n\n### Hystrix\n\nUsing the [Hystrix Go](https://github.com/afex/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](examples/hystrix).\n\n## Usage with Docker\n\nDownload the [Docker image](https://github.com/mefellows/docker-muxy) by running:\n\n```\ndocker pull mefellows/muxy\n```\n\nAfter 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:\n\n```\ndocker run \\\n  -d \\\n  -p 80:80 \\\n  -v \"$PWD/conf\":/opt/muxy/conf \\\n  --privileged \\\n  mefellows/muxy\n```\n\nYou should now be able to hit this Docker container and simulate any failures as per usual. e.g. `curl docker:80/some/endpoint`.\n\nThe [Hystrix](#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.\n\n## Extending Muxy\n\nMuxy is built as a series of configurable plugins (using [Plugo](https://github.com/mefellows/plugo)) that must be specified in the configuration\nfile to be activated. Start with a quick tour of Plugo before progressing.\n\n### Proxies\n\nProxies must implement the [Proxy](/muxy/proxy.go) interface, and register themselves via `PluginFactories.register` to be available at runtime.\nTake a look at the [HTTP Proxy](protocol/http.go) for a good working example.\n\n### Middleware\n\nMiddlewares implement the [Middleware](/muxy/middle.go) interface and register themselves via `PluginFactories.register` to be available at runtime.\nTake a look at the [HTTP Delay](symptom/http_delay.go) for a good working example.\n\n## Contributing\n\nSee [CONTRIBUTING](CONTRIBUTING.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmefellows%2Fmuxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmefellows%2Fmuxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmefellows%2Fmuxy/lists"}