SkillAgentSearch skills...

Pichi

Flexible Rule-Based Proxy

Install / Use

/learn @pichi-router/Pichi

README

Pichi License

Pichi is a flexible rule-based proxy.

Build Status

Server/Desktop

| OS | Ubuntu 22.04 | macOS 14 | Windows Server 2022 | |:---:|:---:|:---:|:---:| | Toolchain | GCC 12.1.0 | Xcode 16.0 | Visual Studio 2022 | | Status | Linux | macOS | Windows |

Mobile

| OS | Android | iOS | |:---:|:---:|:---:| | Toolchain | Android NDK 27c | Xcode 16.0 | | Status | Android | iOS |

Security Alert

According to the report, the TLS fingerprint can be used to recognize the type of TLS client for some censorship. If you want to avoid being censored, please make sure:

  • Version 1.5.0 or later is used.
  • On TLS client side,
    • CMake option TLS_FINGERPRINT was enabled while building, and
    • sni field is set for each TLS egress.
  • On TLS server side,
    • CMake option TLS_FINGERPRINT was disabled while building.

Pichi 1.5.0 is trying to emulate TLS fingerprint e47eae8f8c4887b6, which is the fingerprint of Google Chrome lower than 109.

On the other hand, Pichi 1.5.1 or later would randomise TLS extension order to emulate normailised TLS fingerprint N/ffa2ee96ff7b42d4, which is the default behavior of Google Chrome since version 109.

Overview

Pichi is designed

  1. to support common proxy protocols: HTTP(S)/Socks5(s)/Shadowsocks;
  2. to dynamically and flexibly control the proxy route: just use RESTful APIs;
  3. developer oriented: NO GUI, but can be easily integrated into other GUIs;
  4. for personal usage: performance is important, but not the first priority;
  5. for multiple platforms: at least Windows, POSIX-compatible, Android and iOS.
<img src="images/overview.png" alt="Overview" width="1024"/>

Motivation

Proxy is widely applied to traverse through the firewall, hide or change the original address, expose internal service port, etc. But if we iterate some famous proxy tools, it's easily recognized that each of them has at least one of these cons list below:

  • Not support all of HTTP, Socks5, Shadowsocks
  • Not support multiple ingresses or egresses
  • No rule-based routing

As a result, the motivation of pichi is to provide a tool, which can

  1. support sufficient proxy protocols,
  2. be easily integrated with GUIs/APPs/scripts, which might have their own rule database,
  3. control rule-based routing at runtime.

Use cases

Alternative to PAC

If an individual user is using a proxy, it's very common that the network traffic is probably split into 2 pieces of flow, one going through the proxy and another going directly. PAC is a good choice if web browsing is heavily used. But unfortunately, not all applications support PAC, such as most of MUA, IM, and so on.

Pichi is an alternative choice for this situation. It separates routing rules from every application.

<img src="images/use_case_0.png" alt="Use Case 0" width="1024"/>

Unify proxy configuration

If the configuration for remote proxies is volatile, such as changing IP/Port periodically, it's a nightmare that lots of clients are using it. Pichi can centralize the varies, rather than editing the configuration client by client.

<img src="images/use_case_1.png" alt="Use Case 1" width="1024"/>

TCP Tunnel for DNS

TCP tunnel is very useful if you want to use some DNS servers which might be already poisoned or blocked. Pichi provides tunnel ingress to act as a tunnel. Furthermore, the outgoing egress for each destination will be chosen by following the user-defined rules.

<img src="images/use_case_2.png" alt="Use Case 2" width="1024"/>

Transparent proxy

The transparent proxies are usually deployed on some internet exit router in the intranet. The difference between the transparent proxy and others is that the clients use no explicit proxy settings. It is engaging for the devices that can't use proxy settings. On the other hand, the con of the transparent proxy is that it usually requires the root privilege of the router. The proxy can also use rule-based routing to forward the requests from the transparent ingress. And it is easy to understand that the domain rules don't make any sense because the transparent ingress can't provide the domain information.

<img src="images/use_case_3.png" alt="Use Case 3" width="1024"/>

To enable the transparent proxy, it's necessary to enable the IP packet redirection on the router. When a redirected packet received, the transparent ingress can read its original destination IP address and TCP port from the firewall, if pichi has enough privilege. Pichi supports netfilter/iptables on Linux and PF on macOS/FreeBSD/OpenBSD. For instance, if pichi is running with the transparent ingress configured as below:

# curl -s http://pichi-router/ingresses | jq .example
{
  "type": "transparent",
  "bind": [
    {
      "host": "0.0.0.0",
      "port": 1726
    }
  ]
}

we can configure the firewall on Linux like:

# iptables -t nat -A PREROUTING -i eth0 -p tcp -j REDIRECT --to-ports 1726

, on macOS/FreeBSD like:

rdr pass on fxp0 inet proto tcp from fxp0:network to any -> 127.0.0.1 port 1726

, on OpenBSD like:

pass in on fxp0 inet proto tcp from fxp0:network to any rdr-to 127.0.0.1 port 1726

BTW, Here's an assumption that pichi is running on the host enabling the packet redirection with the correct privilege.

Supported protocols

Ingress protocols

  • Tunnel: TCP tunnel to multiple destinations to be chosen by pre-defined load balance algorithms
  • Transparent: Transparent proxy for TCP
  • HTTP Proxy: defined by RFC 2068
  • HTTP Tunnel: defined by RFC 2616
  • SOCKS5: defined by RFC 1928
  • Shadowsocks: defined by shadowsocks.org
  • Trojan: defined by trojan-gfw and its websocket extension defined by trojan-go

Egress protocols

  • Direct: connecting to destination directly
  • Reject: rejecting request immediately or after a fixed/random delay
  • HTTP Proxy: defined by RFC 2068
  • HTTP Tunnel: defined by RFC 2616
  • SOCKS5: defined by RFC 1928
  • Shadowsocks: defined by shadowsocks.org
  • Trojan: defined by trojan-gfw and its websocket extension defined by trojan-go

NOTE: HTTP egress would like to try HTTP CONNECT first. HTTP proxy will be chosen if the previous handshake is failed.

Get started

Installation

Linux

Please use Docker:

$ docker pull ghcr.io/pichi-router/pichi:latest
$ docker run -d ghcr.io/pichi-router/pichi:latest <options>

macOS

Please use Homebrew:

$ brew tap pichi-router/pichi
$ brew install pichi
$ pichi <options>

FreeBSD

Please use FreeBSD ports.

$ pkg install pichi

Windows or others

Please refer to Build section.

Run

$ pichi -h
Allow options:
  -h [ --help ]              produce help message
  -l [ --listen ] arg (=::1) API server address
  -p [ --port ] arg          API server port
  -g [ --geo ] arg           GEO file
  --json arg                 Initail configration(JSON format)
  -d [ --daemon ]            daemonize
  -u [ --user ] arg          run as user
  --group arg                run as group

--port and --geo are mandatory. --json option can take a JSON file as an Initial configuration to specify ingresses/egresses/rules/route. The initial configuration format looks like:

{
  "ingresses": {
    "ingress-0": {/* ingress configuration */},
    "ingress-1": {/* ingress configuration */}
  },
  "egresses": {
    "egress-0": {/* egress configuration */},
    "egress-1": {/* egress configuration */}
  },
  "rules": {
    "rule-0": {/* rule configuration */},
    "rule-1": {/* rule configuration */}
  },
  "route": {/* route configuration */}
}

Please refer to Using Pichi API section for the details of configurations of ingress/egress/rule/route.

Furthermore, Pichi server reloads JSON configuration on SIGHUP received if OS supports

View on GitHub
GitHub Stars179
CategoryDevelopment
Updated1mo ago
Forks20

Languages

C++

Security Score

100/100

Audited on Feb 22, 2026

No findings