Some checks failed
ci/woodpecker/push/build/1 Pipeline was canceled
ci/woodpecker/push/build/3 Pipeline was canceled
ci/woodpecker/push/build/2 Pipeline was canceled
ci/woodpecker/tag/build/2 Pipeline is pending
ci/woodpecker/tag/build/3 Pipeline is pending
ci/woodpecker/tag/build/1 Pipeline was canceled
80 lines
2.5 KiB
Markdown
80 lines
2.5 KiB
Markdown
# l4p
|
|
|
|
> Hey, now we are on level 4!
|
|
|
|

|
|
|
|
`l4p` is a layer 4 proxy implemented by Rust to listen on specific ports and transfer TCP data to remote addresses (only TCP) according to the configuration.
|
|
|
|
## Features
|
|
|
|
- Listen on specific port and proxy to local or remote port
|
|
- SNI-based rule without terminating TLS connection
|
|
- DNS-based backend with periodic resolution
|
|
|
|
## Installation
|
|
|
|
To gain best performance on your computer's architecture, please consider build the source code. First, you may need [Rust tool chain](https://rustup.rs/).
|
|
|
|
```bash
|
|
$ cd l4p
|
|
$ cargo build --release
|
|
```
|
|
|
|
Binary file will be generated at `target/release/l4p`, or you can use `cargo install --path .` to install.
|
|
|
|
Or you can use Cargo to install `l4p`:
|
|
|
|
```bash
|
|
$ cargo install l4p
|
|
```
|
|
|
|
Or you can download binary file form the Release page.
|
|
|
|
## Features
|
|
|
|
- Listen on specific port and proxy to local or remote port
|
|
- SNI-based rule without terminating TLS connection
|
|
- Wildcard SNI matching with DNS-style longest-suffix-match
|
|
- DNS-based backend with periodic resolution
|
|
|
|
## Configuration
|
|
|
|
`l4p` will read yaml format configuration file from `/etc/l4p/l4p.yaml`, and you can set custom path to environment variable `L4P_CONFIG`, here is an minimal viable example:
|
|
|
|
```yaml
|
|
version: 1
|
|
log: info
|
|
|
|
servers:
|
|
proxy_server:
|
|
listen:
|
|
- "127.0.0.1:8081"
|
|
default: remote
|
|
|
|
upstream:
|
|
remote: "tcp://www.remote.example.com:8082" # proxy to remote address
|
|
```
|
|
|
|
There are two upstreams built in:
|
|
* Ban, which terminates the connection immediately
|
|
* Echo, which reflects back with the input
|
|
|
|
For detailed configuration, check [this example](./config.yaml.example).
|
|
|
|
### SNI Matching
|
|
|
|
The proxy supports both exact and wildcard SNI patterns in the `sni` config. Wildcards use DNS-style longest-suffix-match: more specific patterns take precedence. For example, with `*.example.com` and `*.api.example.com`, request `api.example.com` matches the first, while `v2.api.example.com` matches the second.
|
|
|
|
Wildcards are validated against the Public Suffix List (PSL). Known suffixes (`.com`, `.org`) require at least one label below the suffix (`*.example.com` OK, `*.com` rejected). Unknown suffixes (`.local`, `.lan`) are allowed without restriction.
|
|
|
|
Invalid wildcard patterns are rejected at config load time with clear error messages.
|
|
|
|
## Thanks
|
|
|
|
- [`fourth`](https://crates.io/crates/fourth), of which this is a heavily modified fork.
|
|
|
|
## License
|
|
|
|
`l4p` is available under terms of Apache-2.0.
|