Skip to content

Commit

Permalink
Merge pull request #7 from askolesov/injector-fix
Browse files Browse the repository at this point in the history
Fix injector
  • Loading branch information
askolesov authored Nov 3, 2024
2 parents 16c502d + 9a6b14c commit c9f42e1
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 31 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

obfsproxy is a simple obfuscating proxy designed to provide a layer of obfuscation for network traffic. It works by applying multiple transformations to the data passing through it, making it harder for network monitors to identify the content of the communication.

```mermaid
graph LR
client[VPN Client] -->|Original Traffic| proxy1[obfsproxy client]
proxy1 -->|Obfuscated Traffic| proxy2[obfsproxy server]
proxy2 -->|Original Traffic| server[VPN Server]
style proxy1 fill:#ddd,stroke:#333
style proxy2 fill:#ddd,stroke:#333
```

## Features

- Multiple obfuscation methods:
Expand Down
3 changes: 3 additions & 0 deletions integration/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.PHONY: all
all: test

.PHONY: test
test:
# Start the containers
Expand Down
10 changes: 5 additions & 5 deletions integration/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
services:
obfuscating-proxy: # server
proxy-client:
build:
context: ./../
dockerfile: ./docker/Dockerfile
command: ["obfsproxy", "-l", "0.0.0.0:8080", "-t", "deobfuscating-proxy:8081", "-k", "test-key", "-r", "50", "-s"]
command: ["obfsproxy", "-l", "0.0.0.0:8080", "-t", "proxy-server:8081", "-k", "test-key", "-r", "50", "-c"]
ports:
- "8080:8080"

deobfuscating-proxy: # client
proxy-server:
build:
context: ./../
dockerfile: ./docker/Dockerfile
command: ["obfsproxy", "-l", "0.0.0.0:8081", "-t", "mock-server:80", "-k", "test-key", "-r", "50", "-c"]
command: ["obfsproxy", "-l", "0.0.0.0:8081", "-t", "mock-server:80", "-k", "test-key", "-r", "50", "-s"]
ports:
- "8081:8081"

mock-server: # target
mock-server:
image: nginx:alpine
volumes:
- ./mock-server.conf:/etc/nginx/conf.d/default.conf
Expand Down
28 changes: 5 additions & 23 deletions pkg/codec/injector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ func TestInjector(t *testing.T) {
data: []byte("hello world"),
},
{
name: "full rate",
name: "100% rate",
seed: 42,
rate: 100,
data: []byte("test data"),
},
{
name: "partial rate",
name: "500% rate",
seed: 42,
rate: 500,
data: []byte("partial injection test"),
data: generateRandomBytes(10000000, 42),
},
{
name: "empty input",
Expand All @@ -54,26 +54,8 @@ func TestInjector(t *testing.T) {
})

t.Run("Chunked encode/decode", func(t *testing.T) {
encodedChunks := make([]byte, 0)
for i := 0; i < len(tt.data); i += 2 {
end := i + 2
if end > len(tt.data) {
end = len(tt.data)
}
chunk := encoder(tt.data[i:end])
encodedChunks = append(encodedChunks, chunk...)
}

decodedChunks := make([]byte, 0)
for i := 0; i < len(encodedChunks); i += 3 {
end := i + 3
if end > len(encodedChunks) {
end = len(encodedChunks)
}
chunk := decoder(encodedChunks[i:end])
decodedChunks = append(decodedChunks, chunk...)
}

encodedChunks := transformByChunks(encoder, tt.data, 2)
decodedChunks := transformByChunks(decoder, encodedChunks, 3)
require.Equal(t, tt.data, decodedChunks, "Chunked encode/decode failed")
})
})
Expand Down
2 changes: 1 addition & 1 deletion pkg/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (p *Proxy) handleConnection(clientConn net.Conn) {
}
}

func (p *Proxy) proxy(dst, src net.Conn, t codec.Transformer) {
func (p *Proxy) proxy(src, dst net.Conn, t codec.Transformer) {
buf := make([]byte, 1024)
for {
n, err := src.Read(buf)
Expand Down
63 changes: 61 additions & 2 deletions pkg/proxy_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,74 @@
package pkg

import (
"bytes"
"io"
"net"
"net/http"
"net/http/httptest"
"testing"

"github.com/askolesov/obfsproxy/pkg/codec"
"github.com/stretchr/testify/require"
)

func TestProxy(t *testing.T) {
func TestProxyChain(t *testing.T) {
// Create a mock HTTP server that mirrors input
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = io.Copy(w, r.Body)
}))
defer mockServer.Close()

mockServerAddr := mockServer.Listener.Addr().String()

// Create codec for proxies
key := []byte("test-key")
xorer, err := codec.NewXorer(key)
require.NoError(t, err)

injector, err := codec.NewInjector(456, 20)
require.NoError(t, err)

chain, err := codec.NewChain([]codec.Codec{
codec.NewInverter(),
xorer,
injector,
})
require.NoError(t, err)

// Start proxy 1 (server)
proxyServer := NewProxy("localhost:50502", mockServerAddr, true, chain)
go func() {
_ = proxyServer.Start()
}()

// Start proxy 2 (client)
proxyClient := NewProxy("localhost:50503", proxyServer.ListenAddr, false, chain)
go func() {
_ = proxyClient.Start()
}()

// Generate test data (10MB)
dataSize := 10 * 1024 * 1024 // 10MB
testData := make([]byte, dataSize)
for i := range testData {
testData[i] = byte(i * 345876 % 256)
}

// Send data through proxy chain
resp, err := http.Post("http://"+proxyClient.ListenAddr, "application/octet-stream", bytes.NewReader(testData))
require.NoError(t, err)
defer resp.Body.Close()

// Read response
result, err := io.ReadAll(resp.Body)
require.NoError(t, err)

// Compare input and output
require.Equal(t, testData, result, "Response data should match input data")
}

func TestProxy_Proxy(t *testing.T) {
// Create a proxy instance
p := &Proxy{}

Expand All @@ -31,7 +90,7 @@ func TestProxy(t *testing.T) {
codec := codec.NewInverter()

// Run proxy in a goroutine
go p.proxy(in2, out1, codec.NewEncoder())
go p.proxy(out1, in2, codec.NewEncoder())

go func() {
// Write test data to server
Expand Down

0 comments on commit c9f42e1

Please sign in to comment.