{"id":13775940,"url":"https://github.com/paulzql/shadowsocks-ex","last_synced_at":"2025-07-18T22:38:25.402Z","repository":{"id":57547351,"uuid":"95182851","full_name":"paulzql/shadowsocks-ex","owner":"paulzql","description":"elixir port of shadowsocks","archived":false,"fork":false,"pushed_at":"2018-12-18T15:02:28.000Z","size":75,"stargazers_count":45,"open_issues_count":0,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-26T06:34:27.926Z","etag":null,"topics":["elixir","erlang","proxy","shadowsocks"],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paulzql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-23T04:23:44.000Z","updated_at":"2024-06-03T13:00:03.000Z","dependencies_parsed_at":"2022-09-26T18:40:47.577Z","dependency_job_id":null,"html_url":"https://github.com/paulzql/shadowsocks-ex","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulzql%2Fshadowsocks-ex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulzql%2Fshadowsocks-ex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulzql%2Fshadowsocks-ex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulzql%2Fshadowsocks-ex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paulzql","download_url":"https://codeload.github.com/paulzql/shadowsocks-ex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248564384,"owners_count":21125407,"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":["elixir","erlang","proxy","shadowsocks"],"created_at":"2024-08-03T17:01:55.254Z","updated_at":"2025-04-12T11:45:17.929Z","avatar_url":"https://github.com/paulzql.png","language":"Elixir","funding_links":[],"categories":["\u003ca id=\"d03d494700077f6a65092985c06bf8e8\"\u003e\u003c/a\u003e工具"],"sub_categories":["\u003ca id=\"cb16466a31a167bb61f39e2a4a85f449\"\u003e\u003c/a\u003eShadowsocks"],"readme":"\n# Shadowsocks-ex\n\nshadowsocks-ex is a elixir port of [shadowsocks](https://github.com/shadowsocks/shadowsocks)\n\nA fast tunnel proxy that helps you bypass firewalls.\n\nFeatures:\n- TCP  support\n- UDP  support (only server)\n- Client support (socks5 and http proxy)\n- Server support\n- OTA    support\n- Mulit user support\n- Transparent Proxy Client support\n- Anti protocol detection\n- IP blacklist support\n- Simple obfs support\n\nEncryption methods\n- rc4-md5\n- aes-128-cfb\n- aes-192-cfb\n- aes-256-cfb\n- aes-128-ctr\n- aes-192-ctr\n- aes-256-ctr\n- aes-128-gcm\n- aes-192-gcm\n- aes-256-gcm\n\n## Installation\n\nThe package can be installed\nby adding `shadowsocks` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [{:shadowsocks, \"~\u003e 0.5\"}]\nend\n```\n\n## Documentation\nThe online docs can\nbe found at [https://hexdocs.pm/shadowsocks](https://hexdocs.pm/shadowsocks).\n\n## Usage\n### start a listener\n\n```elixir\nShadowsocks.start(args)\n```\n\nthe `args` is a keyword list, fields:\n\n * `type` required `atom` - the connection type, `:client` or `:server` or custom module name\n\n    There are currently four built-in `type`:\n\n    1. `Shadowsocks.Conn.Client` - general client, alias is `:client`\n    2. `Shadowsocks.Conn.Server` - general server, alias is `:server`\n    3. `Shadowsocks.Conn.TransparentClient` - transparent client, use iptables forward to this port instead socks5 client\n    4. `Shadowsocks.Conn.ObfsServer` - simple http obfs server (Compatible with raw protocol, It means that can both accept http obfs client and original shadowsocks client. see: [https://github.com/shadowsocks/simple-obfs](https://github.com/shadowsocks/simple-obfs))\n\n * `port` required `integer` - listen port\n * `ip`   optional `tuple` - listen ip, example: `{127,0,0,1}`\n * `method` optional `string` - encode method, default: `\"rc4-md5\"`\n * `password` required `string` - encode password\n * `ota` optional `bool` - is force open one time auth, default: `false`\n * `server` optional `tuple` - required if `type` is `:client`, example: `{\"la.ss.org\", 8388}`\n * `udp`   optional `bool` - enable udp relay (only support server side)\n\n### stop a listener\n\n```elixir\nShadowsocks.stop(port)\n```\n\n  stop listener by listen port, always return `:ok`\n\n### update listener args\n\n```elixir\nShadowsocks.update(port, args)\n```\n\n  the `args` is a keyword list, *see `Shadowsocks.start/1` method*\n\n## IP blacklist\n### block ip\n\n```elixir\n# block ipv4 address (also will add a ipv6 rule when ipv4 rule added)\nShadowsocks.BlackList.add({127,0,0,1})\n# block ipv6 address\nShadowsocks.BlackList.add({0,0,0,0,0,0,0,1})\n```\n\n### unblock ip\n\n```elixir\nShadowsocks.BlackList.del({127,0,0,1})\n```\n\n### clear blacklist\n\n```elixir\n# clear all rules\nShadowsocks.BlackList.clear(:all)\n# clear static rules\nShadowsocks.BlackList.clear(:static)\n# clear dynamic rules\nShadowsocks.BlackList.clear(:dynamic)\n```\n\n### list blacklist\n\n```elixir\nShadowsocks.BlackList.list()\n```\n\n## Configuration\n\n### startup listeners example:\n\n```elixir\nconfig :shadowsocks, :listeners,\n  [\n    [\n      type: :server,\n      method: \"aes-192-cfb\",\n      password: \"pass\",\n      port: 8888,\n      ota: true,\n      ip: {127, 0, 0, 1}\n    ],\n    [\n      type: Shadowsocks.Conn.Http302,\n      method: \"rc4-md5\",\n      password: \"pass\",\n      port: 8889,\n      ota: false,\n      ip: {0, 0, 0, 0},\n      redirect_url: \"https://google.com\"\n    ],\n    [\n      type: :client,\n      method: \"aes-192-cfb\",\n      password: \"pass\",\n      server: {\"localhost\", 8888},\n      port: 1080,\n      ota: true,\n      ip: {127, 0, 0, 1}\n    ],\n  ]\n\n```\n\n\n### compile time configs\n\n```elixir\nconfig :shadowsocks, :report,\n    port_min_flow: 5 * 1024 * 1024, # report flow when cached flow exceed :port_min_flow\n    port_min_time: 60 * 1000,       # report flow when cached flow after :port_min_time\n    conn_min_flow: 5 * 1024 * 1024  # send flow to listener when cached flow exceed :conn_min_flow\n\nconfig :shadowsocks, :protocol,\n  recv_timeout: 180000,             # timeout for receive header\n  anti_max_time: 10000,             # anti max delay time (ms), random sleep time before close connection\n  anti_max_bytes: 500,              # anti max reply bytes, random bytes send to client\n  anti_detect: true                 # on / off anti protocol detection\nconfig :shadowsocks,:skip_localhost, true # skip local lookback address(remote address), prevent attacks\n```\n\n### runtime configs\n\n```elixir\n# dynamic block attack ip\nconfig :shadowsocks, :dynamic_blocklist,\n  enable: true,\n  attack_times: 30, # block ip when attack times more than attack_times in attack_time\n  collect_duration: 3600 * 1000, # collect attack times every collect_duration\n  block_expire: 7 * 3600 * 1000 # how long to block ip\n```\n\n## Connection Events\n\nEvent name: `Shadowsocks.Event`\n\nevents:\n\n```elixir\n{:port, :open, port}                       # when start listener on port\n{:conn, :open, {port, pid, addr}}  # when received connection request\n{:conn, :close, {port, pid, reason, flow}} # when connection process exited\n{:conn, :connect, {port, pid, {ret, addr, port}}} # connect to remote addr result\n{:port, :flow, {port, down, up}}           # flow report on the port\n{:bad_request, port, addr} # bad client connection detected (`port` is listener port, `addr` is client addr)\n{:dynamic_blocked, addr} # the addr was blocked by dynamic block rules\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulzql%2Fshadowsocks-ex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulzql%2Fshadowsocks-ex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulzql%2Fshadowsocks-ex/lists"}