-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproxy.go
140 lines (116 loc) · 3.11 KB
/
proxy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
Proxy Socks5 Golang Websocket By Farell Aditya
Date Thu Feb 13 06:36:21 UTC 2025
Only For Linux Usage
*/
package main
import (
"flag"
"fmt"
"io"
"log"
"net"
"os"
"time"
"golang.org/x/crypto/ssh"
"golang.org/x/net/proxy"
)
// Application version
const Version = "1.0.0"
// Config structure
type Config struct {
SOCKS5Port string
SSHPort string
}
// Function to authenticate SSH credentials
func authenticateSSH(username, password, sshPort string) bool {
sshAddress := fmt.Sprintf("127.0.0.1:%s", sshPort)
config := &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: 5 * time.Second,
}
conn, err := ssh.Dial("tcp", sshAddress, config)
if err != nil {
return false
}
defer conn.Close()
return true
}
// Custom SSH Authentication struct
type sshAuth struct {
SSHPort string
}
// Implement proxy.Authenticator for SSH authentication
func (s *sshAuth) Authenticate(username, password string) error {
if authenticateSSH(username, password, s.SSHPort) {
return nil // Authentication successful
}
return fmt.Errorf("authentication failed")
}
func main() {
// Command-line flags
socks5Port := flag.String("p", "1080", "Port for SOCKS5 Proxy (default: 1080)")
sshPort := flag.String("f", "22", "Port for SSH Server (default: 22)")
version := flag.Bool("version", false, "Show application version")
help := flag.Bool("h", false, "Show help menu")
flag.Parse()
// Handle --version
if *version {
fmt.Printf("SOCKS5 Proxy with SSH Auth - Version %s\n", Version)
os.Exit(0)
}
// Handle --help or -h
if *help {
fmt.Println("Usage:")
fmt.Println(" socks5_proxy [OPTIONS]")
fmt.Println("\nOptions:")
fmt.Println(" -p <port> Port for SOCKS5 Proxy (default: 1080)")
fmt.Println(" -f <port> Port for SSH Server (default: 22)")
fmt.Println(" --version Show application version")
fmt.Println(" -h, --help Show this help menu")
os.Exit(0)
}
config := Config{
SOCKS5Port: *socks5Port,
SSHPort: *sshPort,
}
// Start SOCKS5 proxy server
listener, err := net.Listen("tcp", ":"+config.SOCKS5Port)
if err != nil {
log.Fatal("Failed to start SOCKS5 server:", err)
}
defer listener.Close()
log.Printf("SOCKS5 proxy server running on port %s (SSH auth on port %s)\n", config.SOCKS5Port, config.SSHPort)
for {
conn, err := listener.Accept()
if err != nil {
log.Println("Failed to accept connection:", err)
continue
}
go handleClient(conn, config)
}
}
// Function to handle SOCKS5 authentication and proxying
func handleClient(client net.Conn, config Config) {
defer client.Close()
// Setup authentication
auth := &proxy.Auth{}
dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:"+config.SOCKS5Port, auth, proxy.Direct)
if err != nil {
log.Println("Failed to create SOCKS5 dialer:", err)
return
}
target, err := dialer.Dial("tcp", client.RemoteAddr().String())
if err != nil {
log.Println("Failed to connect to target:", err)
return
}
defer target.Close()
// Relay data between client and target
go io.Copy(target, client)
io.Copy(client, target)
}