### Install h2i Source: https://github.com/wi1dcard/fingerproxy/blob/master/pkg/http2/h2i/README.md Install the h2i tool using the go install command. Then, run h2i with the target hostname. ```bash go install golang.org/x/net/http2/h2i@latest h2i ``` -------------------------------- ### Generate Fake Certificates and Run TLS Server Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/my-fingerprint/README.md This snippet shows how to generate self-signed TLS certificates and start the Fingerproxy TLS server. It forwards requests to a specified URL and listens on a given port. Ensure you have OpenSSL and Go installed. ```bash openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -days 3650 \ -nodes -keyout tls.key -out tls.crt -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost,DNS:*.localhost,IP:127.0.0.1" go run . -listen-addr :8443 -forward-url https://httpbin.org ``` -------------------------------- ### Example: Get Fingerprints in JSON via Curl Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/echo-server/README.md Request fingerprints in JSON format from the echo server using curl. The output is piped to `jq` for pretty-printing. This provides a structured view of JA3, JA4, and HTTP2 fingerprints. ```bash $ curl https://localhost:8443/json --insecure | jq ``` -------------------------------- ### Example Server Response with Custom Fingerprints Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/my-fingerprint/README.md This is an example of the JSON output received from the server after a successful request. It includes various headers, notably custom fingerprints like X-Http2-Fingerprint, X-Ja3-Fingerprint, X-Ja4-Fingerprint, and X-My-Fingerprint. ```yaml { "headers": { "Accept": "*/*", "Accept-Encoding": "gzip", "Host": "httpbin.org", "User-Agent": "curl/8.6.0", "X-Amzn-Trace-Id": "Root=1-664c08ef-4efb8ea50d0d59181a2b1565", "X-Forwarded-Host": "localhost:8443", "X-Http2-Fingerprint": "3:100;4:10485760;2:0|1048510465|0|m,s,a,p", "X-Ja3-Fingerprint": "0149f47eabf9a20d0893e2a44e5a6323", "X-Ja4-Fingerprint": "t13d3112h2_e8f1e7e78f70_6bebaf5329ac", "X-My-Fingerprint": "alpn:h2,http/1.1|supported_versions:772,771" } } ``` -------------------------------- ### Example Output with Raw JA3 Fingerprint Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/ja3-raw/README.md The output shows the headers received by the backend, including the raw JA3 fingerprint under the X-Ja3-Raw-Fingerprint key. ```yaml { \ "headers": { \ "Accept": "*/*", \ "Accept-Encoding": "gzip", \ "Host": "httpbin.org", \ "User-Agent": "curl/8.6.0", \ "X-Amzn-Trace-Id": "Root=1-664c0810-09f1e3a03376e930030b20f7", \ "X-Forwarded-Host": "localhost:8443", \ "X-Http2-Fingerprint": "3:100;4:10485760;2:0|1048510465|0|m,s,a,p", \ "X-Ja3-Fingerprint": "0149f47eabf9a20d0893e2a44e5a6323", \ "X-Ja3-Raw-Fingerprint": "771,4866-4867-4865-49196-49200-159-52393-52392-52394-49195-49199-158-49188-49192-107-49187-49191-103-49162-49172-57-49161-49171-51-157-156-61-60-53-47-255,0-11-10-16-22-23-49-13-43-45-51-21,29-23-30-25-24-256-257-258-259-260,0-1-2", \ "X-Ja4-Fingerprint": "t13d3112h2_e8f1e7e78f70_6bebaf5329ac" \ } \ } ``` -------------------------------- ### Run Fingerproxy Server Source: https://github.com/wi1dcard/fingerproxy/blob/master/README.md Starts the Fingerproxy server listening on port 8443 and forwards requests to the specified URL. Ensure the binary is downloaded and executable. ```bash ./fingerproxy -listen-addr :8443 -forward-url https://httpbin.org ``` -------------------------------- ### Example: Get Fingerprints via Curl Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/echo-server/README.md Use curl to request fingerprints from the echo server. The `--insecure` flag is used because the server may be using self-signed certificates. The response includes User-Agent, TLS ClientHello record, JA3, JA4, and HTTP2 fingerprints. ```bash $ curl https://localhost:8443/ --insecure ``` -------------------------------- ### Example: Get Detailed Fingerprints in JSON via Curl Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/echo-server/README.md Retrieve detailed fingerprint information, including raw data, in JSON format from the echo server. This endpoint is useful for in-depth analysis of client connection details. The response includes metadata like TLS ClientHelloRecord, ConnectionState, and HTTP2Frames. ```bash $ curl https://localhost:8443/json/detail --insecure | jq ``` -------------------------------- ### Run Fingerproxy Server Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/ja3-sorted-extensions/README.md Starts the Fingerproxy TLS server on port 8443, forwarding requests to a specified URL. Ensure the generated certificates are in the same directory. ```bash go run . -listen-addr :8443 -forward-url https://httpbin.org ``` -------------------------------- ### Fingerproxy Output with Sorted JA3 Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/ja3-sorted-extensions/README.md Example output from the `curl` command, showing the headers processed by Fingerproxy. Note the `X-Sorted-Ja3-Fingerprint` which remains consistent across connections, unlike `X-Ja3-Fingerprint`. ```yaml { "headers": { "Accept": "*/*", "Accept-Encoding": "gzip", "Host": "httpbin.org", "User-Agent": "curl/8.6.0", "X-Amzn-Trace-Id": "Root=1-664c0b9c-4f89ce9c411f2cf22acd59bb", "X-Forwarded-Host": "localhost:8443", "X-Http2-Fingerprint": "3:100;4:10485760;2:0|1048510465|0|m,s,a,p", "X-Ja3-Fingerprint": "0149f47eabf9a20d0893e2a44e5a6323", "X-Ja4-Fingerprint": "t13d3112h2_e8f1e7e78f70_6bebaf5329ac", ## HERE ## "X-Sorted-Ja3-Fingerprint": "22441e3edb4a151c17462a438c7a10a5" } } ``` -------------------------------- ### Fingerproxy Output Headers Source: https://github.com/wi1dcard/fingerproxy/blob/master/README.md Example of the request headers received by the backend when using Fingerproxy. These include JA3, JA4, and HTTP2 fingerprints, along with forwarded information. ```yaml { "headers": { # ... "X-Forwarded-Host": "localhost:8443", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https", "X-Http2-Fingerprint": "3:100;4:10485760;2:0|1048510465|0|m,s,a,p", "X-Ja3-Fingerprint": "0149f47eabf9a20d0893e2a44e5a6323", "X-Ja4-Fingerprint": "t13d3112h2_e8f1e7e78f70_6bebaf5329ac" }, # ... } ``` -------------------------------- ### Get Fingerprints Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/echo-server/README.md Retrieves the client's fingerprints in a raw, human-readable format. This includes User-Agent, TLS details, and JA3/JA4 fingerprints. ```APIDOC ## GET / ### Description Get the fingerprints. ### Method GET ### Endpoint / ### Response #### Success Response (200) - **User-Agent** (string) - The User-Agent string of the client. - **TLS ClientHello Record** (string) - The raw TLS ClientHello record. - **JA3 fingerprint** (string) - The JA3 fingerprint of the client. - **JA4 fingerprint** (string) - The JA4 fingerprint of the client. - **HTTP2 fingerprint** (string) - The HTTP2 fingerprint of the client. ### Request Example ```bash curl https://localhost:8443/ --insecure ``` ### Response Example ``` User-Agent: curl/8.6.0 TLS ClientHello Record: 1603010200010001fc030343e508c0a4676da67fe2f68a0f045d56f0504b9f572828189c020f3773ef838120225f9cf0a9a1a6ec2a5ae5987dc80e57ebb2d9cc60384d8664b3b47b01c3cf9f003e130213031301c02cc030009fcca9cca8ccaac02bc02f009ec024c028006bc023c0270067c00ac0140039c009c0130033009d009c003d003c0035002f00ff010001750000000e000c0000096c6f63616c686f7374000b000403000102000a00160014001d0017001e00190018010001010102010301040010000e000c02683208687474702f312e31001600000017000000310000000d0030002e04030503060308070808081a081b081c0809080a080b080408050806040105010601030303010302040205020602002b00050403040303002d00020101003300260024001d00208f0de8a643605177c1d9b09b5e65325d3834da5b7d608d2d27f4ffe784ce883b001500b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "JA3 fingerprint": "0149f47eabf9a20d0893e2a44e5a6323" "JA4 fingerprint": "t13d3112h2_e8f1e7e78f70_6bebaf5329ac" "HTTP2 fingerprint": "3:100;4:10485760;2:0|1048510465|0|m,s,a,p" ``` ``` -------------------------------- ### Get Fingerprints in JSON Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/echo-server/README.md Retrieves the client's fingerprints in a JSON format. This endpoint is useful for programmatic access to fingerprint data. ```APIDOC ## GET /json ### Description Get the fingerprints in JSON format. ### Method GET ### Endpoint /json ### Response #### Success Response (200) - **ja3** (string) - The JA3 fingerprint of the client. - **ja4** (string) - The JA4 fingerprint of the client. - **http2** (string) - The HTTP2 fingerprint of the client. ### Request Example ```bash curl https://localhost:8443/json --insecure | jq ``` ### Response Example ```json { "ja3": "0149f47eabf9a20d0893e2a44e5a6323", "ja4": "t13d3112h2_e8f1e7e78f70_6bebaf5329ac", "http2": "3:100;4:10485760;2:0|1048510465|0|m,s,a,p" } ``` ``` -------------------------------- ### Get Detailed Fingerprints in JSON Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/echo-server/README.md Retrieves detailed fingerprint information, including the raw data used for fingerprint generation, in JSON format. ```APIDOC ## GET /json/detail ### Description Get the fingerprints, as well as the detailed raw data that has been used for creating fingerprints. ### Method GET ### Endpoint /json/detail ### Response #### Success Response (200) - **detail** (object) - An object containing detailed fingerprint information. - **metadata** (object) - Contains raw data used for fingerprinting. - **ClientHelloRecord** (string) - Base64 encoded ClientHello record. - **ConnectionState** (object) - Details about the TLS connection state. - **Version** (integer) - TLS version. - **HandshakeComplete** (boolean) - Indicates if the handshake was completed. - **DidResume** (boolean) - Indicates if the session was resumed. - **CipherSuite** (integer) - The negotiated cipher suite. - **NegotiatedProtocol** (string) - The negotiated application protocol (e.g., "h2"). - **NegotiatedProtocolIsMutual** (boolean) - Indicates if the protocol negotiation was mutual. - **ServerName** (string) - The server name indicated by the client. - **PeerCertificates** (array) - List of peer certificates (null if not available). - **VerifiedChains** (array) - List of verified certificate chains (null if not available). - **SignedCertificateTimestamps** (array) - List of Signed Certificate Timestamps (null if not available). - **OCSPResponse** (string) - OCSP response data (null if not available). - **TLSUnique** (string) - TLS unique data (null if not available). - **HTTP2Frames** (object) - Details about HTTP/2 frames. - **Settings** (array) - List of HTTP/2 settings. - **Id** (integer) - Setting ID. - **Val** (integer) - Setting value. - **WindowUpdateIncrement** (integer) - The increment value for window updates. - **Priorities** (array) - List of HTTP/2 priorities (null if not available). - **Headers** (array) - List of HTTP/2 headers. - **Name** (string) - Header name. - **Value** (string) - Header value. - **Sensitive** (boolean) - Indicates if the header is sensitive. ### Request Example ```bash curl https://localhost:8443/json/detail --insecure | jq ``` ### Response Example ```json { "detail": { "metadata": { "ClientHelloRecord": "FgMBAgABAAH8AwPz9vlIElIYMFW/b8YdGNPpSH1f23HqsIo77l0x7x7X6SDSErd5AuwakOQG59gMX2UVmQDD/MU3Y7C3GQ2bCglrKQA+EwITAxMBwCzAMACfzKnMqMyqwCvALwCewCTAKABrwCPAJwBnwArAFAA5wAnAEwAzAJ0AnAA9ADwANQAvAP8BAAF1AAAADgAMAAAJbG9jYWxob3N0AAsABAMAAQIACgAWABQAHQAXAB4AGQAYAQABAQECAQMBBAAQAA4ADAJoMghodHRwLzEuMQAWAAAAFwAAADEAAAANADAALgQDBQMGAwgHCAgIGggbCBwICQgKCAsIBAgFCAYEAQUBBgEDAwMBAwIEAgUCBgIAKwAFBAMEAwMALQACAQEAMwAmACQAHQAgJVr45fQu/Scp1rR44ICssKYhbqJ/ebI+Mrqz5ezxrnAAFQCyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", "ConnectionState": { "Version": 772, "HandshakeComplete": true, "DidResume": false, "CipherSuite": 4865, "NegotiatedProtocol": "h2", "NegotiatedProtocolIsMutual": true, "ServerName": "localhost", "PeerCertificates": null, "VerifiedChains": null, "SignedCertificateTimestamps": null, "OCSPResponse": null, "TLSUnique": null }, "HTTP2Frames": { "Settings": [ { "Id": 3, "Val": 100 }, { "Id": 4, "Val": 10485760 }, { "Id": 2, "Val": 0 } ], "WindowUpdateIncrement": 1048510465, "Priorities": null, "Headers": [ { "Name": ":method", "Value": "GET", "Sensitive": false }, { "Name": ":scheme", "Value": "https", "Sensitive": false }, { "Name": ":authority", "Value": "localhost:8443", "Sensitive": false }, { "Name": ":path", "Value": "/json/detail", "Sensitive": false }, { "Name": "user-agent", "Value": "curl/8.6.0", "Sensitive": false } ] } } } } ``` ``` -------------------------------- ### h2i Usage and Demo Source: https://github.com/wi1dcard/fingerproxy/blob/master/pkg/http2/h2i/README.md Demonstrates the usage of h2i, including command-line flags and an interactive session. Shows how to connect to a host, negotiate protocols, send PING and HEADERS frames, and observe responses. ```bash h2i -insecure Whether to skip TLS cert validation -nextproto string Comma-separated list of NPN/ALPN protocol names to negotiate. (default "h2,h2-14") h2i google.com Connecting to google.com:443 ... Connected to 74.125.224.41:443 Negotiated protocol "h2-14" [FrameHeader SETTINGS len=18] [MAX_CONCURRENT_STREAMS = 100] [INITIAL_WINDOW_SIZE = 1048576] [MAX_FRAME_SIZE = 16384] [FrameHeader WINDOW_UPDATE len=4] Window-Increment = 983041 h2i> PING h2iSayHI [FrameHeader PING flags=ACK len=8] Data = "h2iSayHI" h2i> headers (as HTTP/1.1)> GET / HTTP/1.1 (as HTTP/1.1)> Host: ip.appspot.com (as HTTP/1.1)> User-Agent: h2i/brad-n-blake (as HTTP/1.1)> Opening Stream-ID 1: :authority = ip.appspot.com :method = GET :path = / :scheme = https user-agent = h2i/brad-n-blake [FrameHeader HEADERS flags=END_HEADERS stream=1 len=77] :status = "200" alternate-protocol = "443:quic,p=1" content-length = "15" content-type = "text/html" date = "Fri, 01 May 2015 23:06:56 GMT" server = "Google Frontend" [FrameHeader DATA flags=END_STREAM stream=1 len=15] "173.164.155.78\n" [FrameHeader PING len=8] Data = "\x00\x00\x00\x00\x00\x00\x00\x00" h2i> ping [FrameHeader PING flags=ACK len=8] Data = "h2i_ping" h2i> ping [FrameHeader PING flags=ACK len=8] Data = "h2i_ping" h2i> ping [FrameHeader GOAWAY len=22] Last-Stream-ID = 1; Error-Code = PROTOCOL_ERROR (1) ReadFrame: EOF ``` -------------------------------- ### Kubernetes Liveness Probe Configuration Source: https://github.com/wi1dcard/fingerproxy/blob/master/README.md Configure a Kubernetes liveness probe for the fingerproxy container. This ensures that Kubernetes can monitor the health of the fingerproxy instance and restart it if it becomes unresponsive. The probe checks the root path over HTTPS on port 443. ```yaml apiVersion: v1 kind: Pod metadata: name: fingerproxy spec: containers: - name: fingerproxy image: fingerproxy livenessProbe: httpGet: path: / port: 443 scheme: https ``` -------------------------------- ### Generate TLS Certificates Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/ja3-sorted-extensions/README.md Generates self-signed TLS certificates and keys required for the Fingerproxy server. Use this command to create `tls.crt` and `tls.key`. ```bash openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -days 3650 \ -nodes -keyout tls.key -out tls.crt -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost,DNS:*.localhost,IP:127.0.0.1" ``` -------------------------------- ### Access Prometheus Metrics Source: https://github.com/wi1dcard/fingerproxy/blob/master/README.md Retrieve available Prometheus metrics from the default metrics server. This endpoint can be accessed locally when the fingerproxy is running. ```bash curl http://localhost:9035/ ``` -------------------------------- ### Test TLS Server with Curl Source: https://github.com/wi1dcard/fingerproxy/blob/master/example/my-fingerprint/README.md This command tests the running TLS server by sending a request to the /headers endpoint. The --insecure flag is used because the certificates are self-signed. ```bash curl "https://localhost:8443/headers" --insecure ``` -------------------------------- ### Send HTTPS Request to Fingerproxy Source: https://github.com/wi1dcard/fingerproxy/blob/master/README.md Sends an HTTPS request to the running Fingerproxy instance using curl. The --insecure flag is used to bypass certificate validation for local testing. The output shows environment details including the generated fingerprint headers. ```bash curl "https://localhost:8443/anything?show_env=1" --insecure ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.