sos
Version, currently 0.1.01 version
- 0.1.0latestNov 7, 2018
github.com/jkthorne/sox
SOCKS client and server for Crystal
28 stars
0 dependents
License: LGPLv3
Installation
# Add this to your shard.yml
dependencies:
sos:
github: jkthorne/sox
version: ~> 0.1.0Then run:
shards installshard.yml
- Crystal
0.27.0- License
- LGPLv3
- Author
- Jack Thorne <jack@kilmer.co>
Dependencies
This version declares no dependencies.
README
# socks
Socks is a library for creating SOCKS clients and servers. Socks is a network proxy and can proxy connections like HTTP requests or ssh connections.
## Documentation
For more documentation on the specs, this implementation is based on please read documents at `./docs/specs.`
For more documentation on the implementations of SOCKS, please read documents at `./docs/`.
## FEATURES
- SOCKS5
- addr type
- [x] IPv4 connection
- [x] IPv6 connection
- [x] Domain connection
- Authentication
- [x] unauthentication
- [ ] GSS connection
- [ ] username and password
- [x] IANA unimplented in ssh
- command types
- [x] connect
- [x] bind
- [x] udp associate
- reply / response
- [x] reply server messages
- [x] connection response server messages
- SOCKS4
- SOCKS5 server
## Installation
Add this to your application's `shard.yml`:
```yaml
dependencies:
socks:
gitlab: wontruefree/socks
```
## Usage
A SOCKS Client so to make a connection you have to have a corresponding SOCKS server. The easiest one to use is ssh.
To start up a local ssh SOCKS server you can connect to yourself.
```bash
# Setup SOCKS on localhost
ssh -D 1080 -C -N 127.0.0.1
```
Have a local SOCKS server directing its connection to a remote host.
```bash
# Setup SOCKS connecting to remote host
ssh -D 1080 -C -N user@remote.com
```
### Basic Usage
#### Basic Socket
To open a socks connection and send a basic HTTP request and get a response.
```crystal
require "socks"
socket = Socks.new(addr: "52.85.89.35")
request = HTTP::Request.new("GET", "/", HTTP::Headers{"Host" => "crystal-lang.org"})
request.to_io(socket)
socket.flush
response = HTTP::Client::Response.from_io?(socket)
if response.success?
puts "Got to crystal through SOCKS5!!!"
end
```
#### Basic Client
`Socks::Client` functions almost like the Crystal (HTTP::Client)[https://crystal-lang.org/api/latest/HTTP/Client.html]
```crystal
client = Socks::Client.new("www.example.com", host_addr: "127.0.0.1", host_port: 1080)
response = client.get("/")
puts response.status_code # => 200
puts response.body.lines.first # => "<!doctype html>"
client.close
```
#### Basic UDP
`Socks::UDP` functions almost like the Crystal (UDPSocket)[https://crystal-lang.org/api/latest/UDPSocket.html]
```crystal
server = UDPSocket.new
server.bind "localhost", 9999
client = Socks::UDP.new(host_addr: "127.0.0.1", host_port: 1080)
client.connect "localhost", 9999
client.send "message"
message, client_addr = server.receive
message # => "message"
client_addr # => Socket::IPAddress(127.0.0.1:50516)
client.close
server.close
```
you can use `Socks::Client` almost like the Crystal (HTTP::Client)[https://crystal-lang.org/api/latest/HTTP/Client.html]
```crystal
client = Socks::Client.new("www.example.com", host_addr: "127.0.0.1", host_port: 1080)
response = client.get("/")
puts response.status_code # => 200
puts response.body.lines.first # => "<!doctype html>"
client.close
```
### Remote server connnection
To open a connection to a remote SOCKS5 Server.
```crystal
require "socks"
socket = Socks.new(host_addr: "gateway.com", addr: "52.85.89.35")
request = HTTP::Request.new("GET", "/", HTTP::Headers{"Host" => "crystal-lang.org"})
request.to_io(socket)
socket.flush
response = HTTP::Client::Response.from_io?(socket)
if response.success?
puts "Got to crystal through SOCKS5!!!"
end
```
### Connection using none default ports
Sometimes you connect to web servers or remote SOCKS servers on ports that are not default. This is built into the top level interface no having to deal with requests or connection requests directly.
```crystal
require "socks"
socket = Socks.new(host_addr: "gateway.com" host_port: 8010, addr: "52.85.89.35", port: 3000)
request = HTTP::Request.new("GET", "/", HTTP::Headers{"Host" => "crystal-lang.org"})
request.to_io(socket)
socket.flush
response = HTTP::Client::Response.from_io?(socket)
if response.success?
puts "Got to crystal through SOCKS5!!!"
end
```
### Use the raw socket
sending some raw data over the socket.
```crystal
require "socks"
socket = Socks.new(addr: "127.0.0.1")
socket << "ping"
if socket.gets == "pong"
puts "hello SOCKS!!"
end
```
## Specs
Before running specs you should add your public key to the authorized keys. Please read below if you have not previously set up a socks server for testing. Although I like Unit Test Spec SOCKS only use tools in the stdlib so this is written in spec style syntax.
### Runnning specs
To run the test suite use the spec command built into crystal.
```bash
crystal spec
```
### Setup SOCKS Server
enable key based authentication for testing
```bash
# enable key based localhost authentication
cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys
```
### TOR
There are some basic tests for a commonly used SOCKS5 server tor.
#### Debian
Install tor via apt.
```bash
sudo apt install tor
```
Optional: Start tor at login and keep tor running in the background.
```bash
systemctl start tor
```
#### MAC
Use homebrew to install tor on your mac.
```bash
brew install tor
```
Optional: Use brew services to keep tor running in the background.
```bash
brew services start tor
```
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.1.0- Tagged
- Nov 7, 2018
- Commit
13646612f102- Crystal
0.27.0- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/jkthorne/sox
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 12, 2026
- Synced
- Aug 12, 2026
- Versions
- 1