# UA3F: an HTTP(S) rewriting proxy for User-Agent and header control

> UA3F is a Go program that sits on HTTP(S) traffic and rewrites request and response headers, bodies and URLs, offered as an HTTP, SOCKS5, TPROXY, REDIRECT or NFQUEUE service with rule-based rewriting. It targets people who need to control what their traffic looks like to servers and to middleboxes.

**SunBK201/UA3F** — Advanced HTTP(S) Rewriting Proxy

- Repository: https://github.com/SunBK201/UA3F
- Website: https://ua3f.sunbk201.site
- Stars: 679 · Forks: 37
- Language: Go
- License: GPL-3.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/sunbk201-ua3f

## A rewriting proxy, not a filtering proxy

UA3F is described as an advanced HTTP(S) rewriting proxy. Its job is to sit in the path of traffic and change what that traffic looks like: request headers, response headers, bodies, and URLs, in both directions.

The best known case is the User-Agent. The default value for the rewritten User-Agent is FFF, and the tool ships a command line option for a custom value plus a regular expression option that selects which User-Agents get rewritten. By default the regular expression is empty, which the documentation states means every User-Agent is rewritten. A partial replacement option limits the change to the matched part of the string rather than the whole value.

That framing matters, because UA3F is not a content filter and not a privacy tool in the usual sense. It does not block ads, it does not decrypt for inspection as its primary purpose, and it does not decide what a user may see. It changes the identity your traffic presents. The repository topics list http, mitm, netfilter, nfqueue, proxy, socks5 and user-agent, which matches that description: the mitm support exists so HTTPS traffic can be decrypted and rewritten, not so it can be scanned.

The implementation is Go, with a repository layout that has a cmd directory for the command surface, an internal directory for the implementation, a configs directory, a Dockerfile, an openwrt directory, and docs. The module requires Go 1.23.0. The licence is GPL-3.0, with the licence file at the repository root.

The audience is a network operator or a technically confident user on a home router, which is why the whole tool is shaped around netfilter modes and a LuCI web page.

## Five service modes and what each one costs you

The same rewriting engine can be exposed in five different ways, and the documentation tabulates them by how they work, whether they depend on Clash or a similar proxy, compatibility, and whether they can run alongside one.

HTTP and SOCKS5 are application layer modes. They are the classic proxy forms, the documentation marks their compatibility as high, and they depend on Clash or a comparable proxy being in the picture.

TPROXY and REDIRECT are transport layer modes built on netfilter. Neither depends on Clash. Compatibility is marked as medium. REDIRECT is the classic approach for redirecting TCP traffic into a local listener, and TPROXY preserves the original client address, which is why both appear as separate choices: one is easier to set up, the other keeps information that some applications need.

NFQUEUE is the network layer mode, and the documentation marks its compatibility as low. NFQUEUE means packets are queued for a userspace program to accept or drop, which is why the project points at UA2F as the related tool for that mode. The cost is that every packet takes a detour through userspace.

All five can run alongside Clash or a similar tool, which is the point of the table. A deployment where Clash handles the routing decision and UA3F handles the header rewriting is a supported arrangement rather than a conflict, and the project has a separate documentation page on cooperating with other proxies.

The three rewriting strategies cut across the modes. GLOBAL rewrites every request and only touches the User-Agent header. DIRECT does no rewriting at all and is a pure forwarder, which is useful as a mode switch without changing the deployment. RULE applies a custom rule set, and this is the mode where the full rule vocabulary applies, which the documentation lists as working with HTTP, SOCKS5, TPROXY and REDIRECT.

## Rule types and actions give fine control but need care

The rule system is where the real configuration effort goes, and the documentation breaks it into three tables: rule types, rewrite actions, and URL redirect actions.

Matching covers domains and domain shapes, IP ranges, ports, source addresses and headers. DOMAIN matches a domain, DOMAIN-SUFFIX matches on a suffix, DOMAIN-KEYWORD matches on a keyword, and DOMAIN-SET matches against a set of domains. IP-CIDR matches an address range, SRC-IP matches the source address, DST-PORT matches the destination port, HEADER-KEYWORD and HEADER-REGEX match on request headers, and URL-REGEX matches on the request URL.

Actions then decide what happens. DIRECT passes the request through untouched. DELETE removes a specified header, ADD adds a header with given content, REPLACE swaps a header's value, and REPLACE-REGEX replaces only the part of a value matching a regular expression. There are also two refusal actions, REJECT, which refuses the request, and DROP, which discards it.

URL redirection is separate, with three options. REDIRECT-302 and REDIRECT-307 return a redirect response to the client, and REDIRECT-HEADER performs the redirect by modifying the request header so the client does not notice.

Here is the practical warning. The RULE strategy is the only one that accepts a custom rule set, and the CLI flag that supplies it is documented as a json string that takes effect only in RULE mode. A rule set that misfires does not produce an error, it produces traffic that has been silently modified in ways the target service may reject, and the failure will look like a service problem rather than a proxy problem. This is where the statistics panel and the logging level options earn their keep, and it is the reason to build up rules incrementally rather than pasting a large set at once.

## Install paths: opkg and apk, Docker, or a Go build

Three installation routes are documented, and the choice depends mostly on where the tool runs.

Binary packages are the fastest route. The releases page provides binaries and opkg and apk installation packages for common architectures, and the documentation says to download the package for your platform and install it manually.

Docker deployment is the second route, and the example given is running it as a SOCKS5 proxy:

```bash
  docker run -p 1080:1080 sunbk201/ua3f -f FFF
```

That single command publishes port 1080 and sets the rewritten User-Agent to FFF. The image is built from a Go builder stage on Alpine, and the final stage sets defaults through environment variables rather than command line flags. The entrypoint binds to 0.0.0.0 and passes a bind address of 0.0.0.0 explicitly, so the container listens on all interfaces and the port has to be published, as the example does.

Building from source is the third route:

```bash
  git clone https://github.com/SunBK201/UA3F.git && cd UA3F
  go build -o ua3f main.go
```

The dependencies tell you what the tool is made of. cobra and viper provide the command line and the configuration file handling, the Go regexp2 fork provides regular expressions with features the standard library lacks, go-nfqueue and the netlink packages provide the network layer modes, gopacket handles packet work, cilium's ebpf library is there for the eBPF offload path, and websocket and chi support the API server and its live panel.

There is also a documented OpenWrt build path that clones the OpenWrt tree, checks out the 24.10 branch, installs the UA3F repository as a package and builds it. That route targets routers running OpenWrt, which is where the netfilter modes make the most sense.

## The command line is small, and the defaults are opinionated

Three invocations cover most needs. Running the binary with no arguments starts it with the default configuration:

```bash
ua3f
```

Pointing it at a configuration file is the second:

```bash
ua3f -c /path/to/config.yaml
```

And generating a template configuration file in the current directory is the third, which is the sensible first action for anyone deploying this:

```bash
ua3f -g
```

The rest of the flags are documented individually. The service mode flag takes HTTP, SOCKS5, TPROXY or REDIRECT, and defaults to SOCKS5. The bind address defaults to 127.0.0.1, and the port defaults to 1080. The log level defaults to info, with debug available, and the default log file location is /var/log/ua3f.log. The rewrite strategy flag takes GLOBAL, DIRECT or RULE and defaults to GLOBAL. The User-Agent flag defaults to FFF, the User-Agent regular expression flag defaults to empty, and the partial replacement flag limits rewriting to the matched portion.

The defaults are chosen for a safe first run. SOCKS5 on 127.0.0.1:1080 with GLOBAL rewriting and a FFF User-Agent is a local, inspectable configuration. Note that the documented mode list for the flag lists four modes, while the service mode table lists five, with NFQUEUE appearing in the table. The documentation does not explain that difference, so treat NFQUEUE as something to confirm in the configuration guide rather than assume from the flag description.

The CLI also carries a JSON string flag for the rewrite rules, which the documentation notes applies only when the strategy is RULE.

## Beyond the User-Agent: bodies, redirects, L3 rewriting and Desync

The feature list extends well past header swapping, and the interesting entries are the ones that operate below HTTP.

Bidirectional rewriting of headers and bodies is supported, so responses can be modified as well as requests. URL redirection is supported through the 302, 307 and header methods described earlier. And HTTPS traffic can be decrypted and rewritten, which is the mitm capability the topics tag refers to.

At the network layer, L3 rewriting covers TTL, IPID, TCP timestamps and the TCP initial window. These are fields a middlebox can inspect, and changing them is a different game from changing a User-Agent string: a mismatch in TCP timestamps or an odd IPID can be a signal in itself.

The Desync feature is the one to read the documentation on before enabling. The description says it supports fragmented out-of-order emission and obfuscation, used against deep packet inspection. In other words, it deliberately makes the traffic pattern on the wire not match a clean TCP stream, so that a DPI device reconstructing the stream sees something different from what the endpoint reassembles. This is a deliberate interoperability feature aimed at middleboxes, and it is a legitimate technique in the same family as the fragmentation and out-of-order handling that TLS stacks and CDNs use. It is also the feature with the most operational risk, since anything that reassembles and reorders traffic in the path may break the connection rather than merely inspect it.

The eBPF offload path is the performance counterweight. The feature list says traffic can be offloaded to eBPF to accelerate forwarding, and cilium's ebpf library is in the dependency list to support it. Which traffic takes that path, and under what conditions, is a question for the configuration guide rather than the README.

## Operating it: LuCI, the API server and the statistics panel

On OpenWrt, the tool exposes a LuCI web page under Services, so configuration does not require a text editor on the router. A separate tutorial page is linked from the README for people who want a guided introduction. The OpenWrt manual command line startup is documented too, and it runs the binary as an unprivileged user rather than as root:

```bash
opkg install sudo
sudo -u nobody /usr/bin/ua3f
```

For users of shellclash or shellcrash, the documentation suggests running the binary as that specific user instead, so that the rewritten traffic and the proxy's own state stay in the same account:

```bash
sudo -u shellclash /usr/bin/ua3f
```

The built-in API server is enabled with a flag and an address:

```bash
ua3f --api-server <addr:port>
```

It exposes the running state and the configured rules, with query and control interfaces, and it has its own documentation page. The gorilla websocket dependency and the chi router are what make that possible, and the websocket side is what backs the real-time statistics panel described in the feature list, where traffic modifications can be monitored and analysed.

One security note that follows from the design rather than the documentation. The service mode defaults to binding 127.0.0.1, and the Docker image deliberately binds 0.0.0.0 because a container needs to be reachable from the host. A proxy that rewrites traffic and exposes an API for reading and changing rules should not be exposed to an untrusted network, and the documentation does not describe authentication for the API server, so treat the address you pass to --api-server as a privileged endpoint.

## Release pace, licence and what a new maintainer inherits

The release history is brisk. Version 3.5.0 was published on 2026-05-09, 3.6.0 on 2026-05-30, and 3.7.0 on 2026-10-02. The last push to the repository was on 2026-10-06, and the repository is not archived, so work is ongoing.

The project carries a CodeQL badge for code scanning, a golangci configuration, and a Dockerfile built with pinned dependency versions. The go.mod file pins every direct dependency to an exact version, from the ebpf library through the cobra and viper command line and configuration stack down to the YAML library and the x/net and x/sys modules. That is a well-maintained dependency posture, and for a tool that sits in the network path of a router, it is the difference between a predictable upgrade and a surprise.

The licence is GPL-3.0. For a tool you run on your own network that is not restrictive in practice. It does constrain redistribution: if you package UA3F into a commercial product or a modified image, the copyleft terms apply to that distribution. That is an observation about the licence terms, not advice.

What a new user inherits is a Go program with a config file format, a fairly deep rule vocabulary, and features that reach down to packet level. The documentation on the project site is the real documentation: the configuration guide, the config examples, the Desync overview, the API reference and the proxy integration page. The README is an index to those pages rather than a substitute for them.

## Conclusion

UA3F fits an operator who needs precise control over the headers and URLs their traffic presents, on a router or a single host, and who is comfortable with netfilter, TPROXY and a Go build. It is the wrong tool for TLS inspection at scale on a corporate network, for anyone who needs a general purpose filtering proxy, and for deployments where a rewritten User-Agent would break the target service. Before adopting it, read the configuration guide on the project site, run `ua3f -g` to see the generated template before editing anything, and confirm your kernel supports the netfilter mode you intend to use.

## FAQ

### What does UA3F do to HTTP(S) traffic?

It rewrites request and response headers and bodies, and can redirect URLs, with the default behaviour being to replace every User-Agent with the value FFF.

### Which service modes does UA3F support?

The documentation tabulates five: HTTP, SOCKS5, TPROXY, REDIRECT and NFQUEUE, with TPROXY, REDIRECT and NFQUEUE built on netfilter and the first two depending on a proxy such as Clash.

### How do I generate a config file for UA3F?

Run ua3f -g, which writes a template config.yaml in the current directory, and start the service afterwards with ua3f -c /path/to/config.yaml.

### Can UA3F run on OpenWrt?

Yes, the README documents a LuCI web page under Services, a package build route inside an OpenWrt tree, and opkg installation of the binary.

### Does UA3F have an API for inspecting and changing rules?

It has a built-in API server enabled with the --api-server flag and an address, documented separately on the project site, alongside a real-time statistics panel for monitoring traffic modifications.

## Sources

- [License: GPL-3.0](https://github.com/SunBK201/UA3F/blob/master/LICENSE)
- [Project website](https://ua3f.sunbk201.site)
- [README](https://github.com/SunBK201/UA3F/blob/master/README.md)
- [Releases](https://github.com/SunBK201/UA3F/releases)
- [SunBK201/UA3F on GitHub](https://github.com/SunBK201/UA3F)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sunbk201-ua3f
