Skip to content

Commit

Permalink
TLS and Session ID Improvements
Browse files Browse the repository at this point in the history
- Added detailed TLS debugging information including:
  - Client handshake details
  - Connection state changes
  - TLS version and cipher negotiations
  - SNI hostname requests
  - ALPN protocol selection

- Enhanced session ID handling:
  - Added support for Cloudflare headers (Cf-Ray)
  - Fallback to Cf-Connecting-Ip if needed
  - Maintained backward compatibility with X-Ephemeral
  - Improved error messaging for missing session IDs

- Improved TLS configuration:
  - Added explicit version range (TLS 1.2 - 1.3)
  - Added HTTP/2 support via ALPN
  - Added SNI certificate handling
  - Removed unnecessary cipher restrictions

- Enhanced debug logging:
  - Added connection state tracking
  - Added detailed header logging
  - Added TLS configuration details at startup
  - Added client capability logging
  • Loading branch information
doxx authored and doxx committed Nov 27, 2024
1 parent ad6755c commit 5cb069c
Show file tree
Hide file tree
Showing 13 changed files with 310 additions and 83 deletions.
32 changes: 23 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Add your new proxy hostname into a free Cloudflare account.

Setup your origin rules to send that host to the origin server (darkflare-server) via the proxy port you choose.

I used 8080.
I used 8080 with a Cloudflare proxy via HTTP for the firs test. Less overhead.

## ✨ Features

Expand All @@ -95,9 +95,6 @@ I used 8080.
- **Session Management**: Keeps your connections organized like a Type A personality
- **TLS Security**: Because we're sneaky, not reckless

## ☠️ Pending Features
- **Include Spoofed Headers for Files**: Add real headers to the jpegs and php files to appear to be exactly and they are to be. Add more support for PDF, MOV, and MP4 files to make the traffic looks more realistic.

## 🚀 Quick Start

### Installation
Expand All @@ -116,18 +113,35 @@ chmod +x darkflare-client darkflare-server
Add `-debug` flag for debug mode

### Notes
Make the host.domain.net you use is configured in Cloudflare to point to the darkflare-server. If you want to debug and go directly to the psudo server you can use the `-o` flag.
Make the host.domain.net you use is configured in Cloudflare to point to the darkflare-server. If you want to debug and go directly to the psudo server you can use the `-allow-direct` flag on the server.

### Running the Server

```bash
./darkflare-server -d localhost:22 -p 8080 -debug
# HTTPS Server (recommended for production)
./darkflare-server -o https://0.0.0.0:443 -d localhost:22 -c /path/to/cert.pem -k /path/to/key.pem

# HTTP Server (for testing)
./darkflare-server -o http://0.0.0.0:8080 -d localhost:22
```
Add `-debug` for server debug messages

### Notes
- You must specify either `-d` (destination) or `-a` (application) mode, but not both
- The `-o` flag (open) allows direct connections without Cloudflare headers (not recommended for production). Good for debugging so you can go from the client directly to the server.
- You must specify either `-d` (network destination) or `-a` (application) mode, but not both
- The `-allow-direct` flag allows direct connections without Cloudflare headers (not recommended for production)
- Debug mode (`-debug`) provides verbose logging of connections and data transfers
- Under SSL/TLS configuration in Cloudflare you need to set ssl encryption mode to Full.

### SSL/TLS Certificates

For HTTPS mode, you'll need to obtain origin certificates from Cloudflare:

1. Log into your Cloudflare dashboard
2. Go to SSL/TLS > Origin Server
3. Create a new certificate (or use an existing one)
4. Download both the certificate and private key
5. When starting the server in HTTPS mode, provide both certificate files:

Note: Keep your private key secure and never share it. The certificate provided by Cloudflare is specifically for securing the connection between Cloudflare and your origin server.

### Testing the Connection
```bash
Expand Down
20 changes: 10 additions & 10 deletions bin/checksums.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# DarkFlare Binary Checksums
# Generated: Wed Nov 27 17:17:28 UTC 2024
# Generated: Wed Nov 27 18:28:12 UTC 2024

c71a5cf86a1280d00dd460046718ccfeee7a8aabbac3241b344bb87705bc7933 checksums.txt
55acba659aa2e0fe1b6d1926c32988d7e33e53ad87582a0e547922fdcccfcedd darkflare-client-darwin-amd64
de1ef97574fe9a6310dd76df938ae0436d1b321f16218b6a142a4915f6ffc144 darkflare-client-darwin-arm64
bf887e178d20dc7f97e0984032afefefad41568a4a0c7a68f2fd67a5df1e314e darkflare-client-linux-amd64
5ba3cf40b182968195e7df419ffe3a5d02567256b529badd6bd9dd32f2ed49ea darkflare-client-windows-amd64.exe
635e6593ac287be49cded64674a24a262fc1ae77047ec7beb0e2732a58d8fb52 darkflare-server-darwin-amd64
af68cf706364049dad8848d6f0bd1a24daae5d5e60db343057482622533df28b darkflare-server-darwin-arm64
57a529665b1a3ca0c7ef633afff3ec6a04020918f05e77203c91cb97ae6313ad darkflare-server-linux-amd64
62477e5d843ee7c33e2a99f42dcc7c7f34fb369fdced4d90570623accdb8f381 darkflare-server-windows-amd64.exe
bef55901802edf53cfbf3bdd2db0e50202c67ee14c77f46fa2242c154617d3bc checksums.txt
58c1df4743072ec1691378b65eac7e66beaaec60572f724e62eaf5be104dfea3 darkflare-client-darwin-amd64
17cf1c0b0c7e4bfba8602499e760b25ed37833f88c2e8afa68122408be3a881b darkflare-client-darwin-arm64
1a4a0539b645e6a9fef5eb3a633c4fabe9952bf1655ee402ca8f870f6c8655c3 darkflare-client-linux-amd64
260fcf233f40628347f8c6c7197d6549e2fc2b9079866e9cc25cb9d676b42eb6 darkflare-client-windows-amd64.exe
df474dd2277f2fe4668c9c3d569a8cf8c2b6761f04a5c7a4212ac50dfb195c16 darkflare-server-darwin-amd64
b9b9e4475ba6055a33a9ce1c6ed605725afbd1a997b1508b1b0cbfb78fff3b13 darkflare-server-darwin-arm64
ada672ccb9ad4cb78499d640d233fcc3d052d7eb1a05c149a0485f74dd0ed1eb darkflare-server-linux-amd64
feedeb09aa65c81c1024122a25dd408bbe7e7ad4f1bfe42476af7a64665b4202 darkflare-server-windows-amd64.exe
Binary file modified bin/darkflare-client-darwin-amd64
Binary file not shown.
Binary file modified bin/darkflare-client-darwin-arm64
Binary file not shown.
Binary file modified bin/darkflare-client-linux-amd64
Binary file not shown.
Binary file modified bin/darkflare-client-windows-amd64.exe
Binary file not shown.
Binary file modified bin/darkflare-server-darwin-amd64
Binary file not shown.
Binary file modified bin/darkflare-server-darwin-arm64
Binary file not shown.
Binary file modified bin/darkflare-server-linux-amd64
Binary file not shown.
Binary file modified bin/darkflare-server-windows-amd64.exe
Binary file not shown.
62 changes: 62 additions & 0 deletions cert/cert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package cert

import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"net"
"time"
)

func GenerateSelfSignedCert() (certPEM []byte, keyPEM []byte, err error) {
// Generate private key
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return nil, nil, err
}

// Create certificate template
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
Organization: []string{"DarkFlare Server"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour),

KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
DNSNames: []string{"localhost"},
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
}

// Create certificate
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
if err != nil {
return nil, nil, err
}

// Encode certificate
certPEM = pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: derBytes,
})

// Encode private key
privBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
return nil, nil, err
}

keyPEM = pem.EncodeToMemory(&pem.Block{
Type: "PRIVATE KEY",
Bytes: privBytes,
})

return certPEM, keyPEM, nil
}
103 changes: 69 additions & 34 deletions client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,37 +310,7 @@ func (c *Client) handleConnection(conn net.Conn) {

if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(io.LimitReader(resp.Body, c.maxBodySize))
errorMsg := fmt.Sprintf("CDN returned status %d (%s)", resp.StatusCode, resp.Status)

// Try to extract more detailed error information
if len(body) > 0 {
// Check if it's HTML (common for CDN error pages)
if bytes.Contains(body, []byte("<!DOCTYPE html>")) || bytes.Contains(body, []byte("<html>")) {
errorMsg += " - CDN returned an HTML error page"
} else {
// Add the response body if it's not too long
if len(body) > 200 {
errorMsg += fmt.Sprintf("\nResponse: %s...", string(body[:200]))
} else {
errorMsg += fmt.Sprintf("\nResponse: %s", string(body))
}
}
}

// Add common CDN error code explanations
switch resp.StatusCode {
case http.StatusBadGateway:
errorMsg += "\nPossible cause: Origin server (darkflare-server) is unreachable"
case http.StatusForbidden:
errorMsg += "\nPossible cause: Request blocked by CDN security rules"
case http.StatusServiceUnavailable:
errorMsg += "\nPossible cause: CDN temporary error or rate limiting"
case http.StatusGatewayTimeout:
errorMsg += "\nPossible cause: Origin server (darkflare-server) timed out"
}

c.debugLog("CDN Error: %s", errorMsg)
resp.Body.Close()
c.handleResponse(resp, body)
time.Sleep(time.Second)
continue
}
Expand All @@ -354,9 +324,24 @@ func (c *Client) handleConnection(conn net.Conn) {
}

if len(data) > 0 {
if bytes.HasPrefix(data, []byte("<")) {
c.debugLog("Received HTML response instead of hex data")
time.Sleep(time.Second)
// Check for Cloudflare directory listing or error pages
if bytes.Contains(data, []byte("<!DOCTYPE html>")) || bytes.Contains(data, []byte("<html>")) {
// Check for common indicators
switch {
case bytes.Contains(data, []byte("Index of /")):
c.debugLog("Error: Origin server returned a directory listing - Server may be misconfigured")
case bytes.Contains(data, []byte("Error 521")):
c.debugLog("Error: Origin server is down or not responding (Cloudflare Error 521)")
case bytes.Contains(data, []byte("Error 522")):
c.debugLog("Error: Connection timed out to origin server (Cloudflare Error 522)")
case bytes.Contains(data, []byte("Error 523")):
c.debugLog("Error: Origin server is unreachable (Cloudflare Error 523)")
case bytes.Contains(data, []byte("Error 524")):
c.debugLog("Error: Connection timed out waiting for origin server (Cloudflare Error 524)")
default:
c.debugLog("Error: Received HTML response instead of tunnel data - Origin server may be down or misconfigured")
}
time.Sleep(time.Second * 5) // Increased backoff for server errors
continue
}

Expand Down Expand Up @@ -387,6 +372,56 @@ func (c *Client) handleConnection(conn net.Conn) {
}
}

func (c *Client) handleResponse(resp *http.Response, body []byte) {
if resp.StatusCode != http.StatusOK {
// Format error message
errorMsg := fmt.Sprintf("\n╭─ CDN Error ─────────────────────────────────────────────────\n")
errorMsg += fmt.Sprintf("│ Status: %d (%s)\n", resp.StatusCode, resp.Status)

// Add common CDN error explanations
switch resp.StatusCode {
case http.StatusBadGateway:
errorMsg += "│ Cause: Origin server (darkflare-server) is unreachable\n"
case http.StatusForbidden:
errorMsg += "│ Cause: Request blocked by CDN security rules\n"
case http.StatusServiceUnavailable:
errorMsg += "│ Cause: CDN temporary error or rate limiting\n"
case http.StatusGatewayTimeout:
errorMsg += "│ Cause: Origin server (darkflare-server) timed out\n"
case http.StatusNotFound:
errorMsg += "│ Cause: Origin server not responding or incorrect path\n"
}

// If we got HTML content, parse it for specific errors
if bytes.Contains(body, []byte("<!DOCTYPE html>")) || bytes.Contains(body, []byte("<html>")) {
switch {
case bytes.Contains(body, []byte("Index of /")):
errorMsg += "│ Detail: Origin server returned directory listing\n"
errorMsg += "│ Server is misconfigured or not running darkflare\n"
case bytes.Contains(body, []byte("Error 521")):
errorMsg += "│ Detail: Origin server is down (Cloudflare Error 521)\n"
case bytes.Contains(body, []byte("Error 522")):
errorMsg += "│ Detail: Connection timed out (Cloudflare Error 522)\n"
case bytes.Contains(body, []byte("Error 523")):
errorMsg += "│ Detail: Origin unreachable (Cloudflare Error 523)\n"
case bytes.Contains(body, []byte("Error 524")):
errorMsg += "│ Detail: Origin timeout (Cloudflare Error 524)\n"
default:
errorMsg += "│ Detail: Received HTML instead of tunnel data\n"
errorMsg += "│ Server may be down or misconfigured\n"
}
} else if len(body) > 0 {
// If we got binary data, just indicate it
errorMsg += "│ Detail: Received unexpected binary response\n"
}

errorMsg += "╰───────────────────────────────────────────────────────────\n"
c.debugLog(errorMsg)
return
}
// ... handle successful response ...
}

func main() {
var localPort int
var targetURL string
Expand Down
Loading

0 comments on commit 5cb069c

Please sign in to comment.