mic

command module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 20, 2026 License: MIT Imports: 1 Imported by: 0

README

mic

mic (mina-is-cute) is a modular Go proxy for controlling outbound TLS fingerprints. It lets you pick a browser fingerprint profile and the proxy will use the corresponding uTLS preset when connecting to upstream servers, making your traffic look like a specific browser to any fingerprinting system.

Two modes are supported:

  • client-front — HTTP CONNECT proxy with optional MitM TLS interception. The proxy generates a local CA, issues per-host leaf certs on the fly, terminates TLS from the client, and re-dials the target with the configured uTLS fingerprint. Standard tools (curl, browsers) work after importing the CA once.
  • server-front — the proxy terminates incoming TLS (with your own cert/key), then re-dials the backend with the configured fingerprint. Useful when the client cannot be configured to use a CONNECT proxy.

How it works

sequenceDiagram
    participant C as Client
    participant P as mic proxy
    participant T as Target

    rect rgb(30, 30, 60)
        note over C,T: client-front mode (MitM TLS)
        C->>P: HTTP CONNECT target:443
        P->>T: TCP + uTLS handshake (configured fingerprint)
        P-->>C: 200 Connection Established
        C->>P: TLS handshake (mic-issued cert for target)
        P-->>C: TLS established
        C->>P: HTTP request (decrypted by proxy)
        P->>T: request bytes (through uTLS tunnel)
        T-->>P: HTTP response (through uTLS)
        P-->>C: HTTP response (re-encrypted for client)
    end

    rect rgb(30, 60, 30)
        note over C,T: server-front mode
        C->>P: TLS handshake (proxy cert)
        P-->>C: TLS established
        P->>T: TCP + uTLS handshake (configured fingerprint)
        C->>P: HTTP request (decrypted by proxy)
        P->>T: request bytes (through uTLS tunnel)
        T-->>P: HTTP response (through uTLS)
        P-->>C: HTTP response (re-encrypted for client)
    end

In both modes the target sees a TLS handshake that matches the configured fingerprint, not the default Go TLS fingerprint.


Build

go build -o mic .

Running

client-front
mic client --listen :8080 --fingerprint chrome-120 \
           --intercept-cert ca.pem --intercept-key ca-key.pem

--intercept-cert and --intercept-key enable MitM interception. mic generates the CA files on first run and reuses them. Import the cert once, then all traffic through the proxy is transparently intercepted and re-dialled with the configured fingerprint.

Trust the CA (pick whichever applies):

# curl — pass on every call, or set CURL_CA_BUNDLE
curl --cacert ca.pem -x http://localhost:8080 https://tlsinfo.me/json

# Debian / Ubuntu / Kali
sudo cp ca.pem /usr/local/share/ca-certificates/mic-ca.crt && sudo update-ca-certificates

# macOS
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca.pem

After trusting, standard tools work without extra flags:

curl -x http://localhost:8080 https://tlsinfo.me/json
# check the "ja4" field — it should match the fingerprint you configured

Omit --intercept-* to run as a plain CONNECT proxy (no MitM, raw tunnel only).

server-front

Generate a cert for the proxy to present to clients:

go run $(go env GOROOT)/src/crypto/tls/generate_cert.go --host="localhost,127.0.0.1"
# produces cert.pem and key.pem
mic server --listen :8080 --backend 10.0.0.1:443 \
           --cert cert.pem --key key.pem \
           --fingerprint chrome-120

--backend, --cert, and --key are required. --fingerprint is optional; without it the proxy falls back to a randomised uTLS preset.

Available fingerprint profiles

Hashes are measured by cmd/probe against tlsinfo.me and reflect what each utls preset actually emits. Re-run the probe after upgrading the utls dependency.

Profile JA4 hash
chrome-120 t13d1516h2_8daaf6152771_02713d6af862
chrome-120-pq same as chrome-120¹
firefox-120 t13d1715h2_5b57614c22b0_5c2c66f702b0
safari-16 t13d2014h2_a09f3c656075_14788d8d241b
edge-106 t13d1516h2_8daaf6152771_e5627efa2ab1

¹ chrome-120-pq (post-quantum) produces the same JA4 because JA4 does not distinguish the X25519MLKEM768 key share. Use it when you specifically need the PQ key exchange behaviour regardless of fingerprint visibility.


Testing

# unit tests
go test ./...

# integration tests — spin up in-process TLS servers, no network required
go test -tags integration -v ./proxy/... ./fingerprint/...

The integration suite includes JA4 fingerprint verification tests: for each profile, both TestClientFront_JA4 and TestServerFront_JA4 capture the raw ClientHello sent by the proxy's uTLS engine and assert the computed JA4 hash matches the expected value. This is the offline equivalent of running cmd/probe against tlsinfo.me.

CI runs both suites on every push via .github/workflows/ci.yml.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd
probe command
probe dials tlsinfo.me/json with each known utls preset and prints the JA4 hash that the server observes.
probe dials tlsinfo.me/json with each known utls preset and prints the JA4 hash that the server observes.
Package fingerprint provides interfaces and implementations for controlling outbound TLS connection fingerprints.
Package fingerprint provides interfaces and implementations for controlling outbound TLS connection fingerprints.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL