Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@trimsj

trimsj/README Secret

Created March 18, 2020 10:59
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save trimsj/da37da55994a07bc1c602a22f13cbdb4 to your computer and use it in GitHub Desktop.
Save trimsj/da37da55994a07bc1c602a22f13cbdb4 to your computer and use it in GitHub Desktop.
SOCKS5 proxy server with HAProxy and Lua
SOCKS5 proxy server with HAProxy and Lua
requires haproxy (>1.9) and lua-socket
global
maxconn 1000
lua-load socks5.lua
defaults
mode tcp
maxconn 1000
timeout connect 10s
timeout client 10m
timeout server 10m
listen proxy
bind *:1080
tcp-request inspect-delay 1s
tcp-request content lua.socks5
tcp-request content set-dst var(txn.dst)
tcp-request content set-dst-port var(txn.port)
tcp-request content reject if { var(txn.dst) -m ip 127.0.0.0/8 ::1 }
server clear 0.0.0.0:0 weight 0
server clear6 [::]:0 weight 0
use-server clear if { var(txn.family) inet }
use-server clear6 if { var(txn.family) inet6 }
local socket = require("socket")
function string.toport(str)
return (str:byte(1)*256+str:byte(2))
end
function string.to4(str)
return (str:gsub('.', function (c) return string.format('%d.', string.byte(c)) end):sub(1,-2))
end
function string.to6(str)
return (str:gsub('..', function (c) return string.format('%02x%02x:', string.byte(c), string.byte(c,2)) end):sub(1,-2))
end
function string.tohex(str)
return (str:gsub('.', function (c) return string.format('%02x', string.byte(c)) end))
end
local function socks5(txn)
local c = txn.req:get()
if c:byte(1) ~= 5 then return end
txn.res:send('\5\0')
local c = txn.req:get()
if c:byte(1) ~= 5 or c:byte(2) ~= 1 then return end
if c:byte(4) == 1 then
dst = c:sub(5,8):to4()
port = c:sub(9,10):toport()
family = 'inet'
elseif c:byte(4) == 4 then
dst = c:sub(5,20):to6()
port = c:sub(21,22):toport()
family = 'inet6'
elseif c:byte(4) == 3 then
len = c:byte(5)
host = c:sub(6,5+len)
port = c:sub(6+len,7+len):toport()
core.Debug(string.format('resolving %s', host))
addr = socket.dns.getaddrinfo(host)
if not addr then return end
dst = addr[1].addr
family = addr[1].family
else return end
txn:set_var('txn.dst', dst)
txn:set_var('txn.port', port)
txn:set_var('txn.family', family)
txn.res:send('\5\0\0\1\0\0\0\0\0\0')
core.Debug(string.format('dst=%s, port=%d', dst, port))
end
core.register_action("socks5", { 'tcp-req', 'tcp-res' }, socks5, 0)
@shashidharrao
Copy link

getting error when i use the above configuration.

I am using dst,port and family info like below.

   txn:set_var('txn.dst', inputs1.enforcer.splunkcloud.com)
    txn:set_var('txn.port', 9997)
    txn:set_var('txn.family', family)
    txn.res:send('\5\0\0\1\0\0\0\0\0\0')
    core.Debug(string.format('dst=%s, port=%d', dst, port))

ERROR :

Mar 30 14:11:23 xxxx.yyy.zzz systemd[1]: Unit haproxy.service entered failed state.
Mar 30 14:11:23 xxxx.yyy.zzz systemd[1]: haproxy.service failed.
Mar 30 14:12:46 xxxx.yyy.zzz systemd[1]: Started HAProxy Load Balancer.
Mar 30 14:12:46 xxxx.yyy.zzz systemd[1]: Starting HAProxy Load Balancer...
Mar 30 14:12:46 xxxx.yyy.zzz haproxy-systemd-wrapper[13847]: haproxy-systemd-wrapper: executing /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
Mar 30 14:12:46 xxxx.yyy.zzz haproxy-systemd-wrapper[13847]: [ALERT] 089/141246 (13848) : parsing [/etc/haproxy/haproxy.cfg:3] : unknown keyword 'lua-load' in 'global' section
Mar 30 14:12:46 xxxx.yyy.zzz haproxy-systemd-wrapper[13847]: [ALERT] 089/141246 (13848) : parsing [/etc/haproxy/haproxy.cfg:15] : 'tcp-request content' expects 'accept', 'reject', 'track-sc0' ... 'track-sc2' in proxy 'proxy' (got 'lua.socks5')
Mar 30 14:12:46 xxxx.yyy.zzz haproxy-systemd-wrapper[13847]: [ALERT] 089/141246 (13848) : parsing [/etc/haproxy/haproxy.cfg:16] : 'tcp-request content' expects 'accept', 'reject', 'track-sc0' ... 'track-sc2' in proxy 'proxy' (got 'set-dst')
Mar 30 14:12:46 xxxx.yyy.zzz haproxy-systemd-wrapper[13847]: [ALERT] 089/141246 (13848) : parsing [/etc/haproxy/haproxy.cfg:17] : 'tcp-request content' expects 'accept', 'reject', 'track-sc0' ... 'track-sc2' in proxy 'proxy' (got 'set-dst-port')
Mar 30 14:12:46 xxxx.yyy.zzz haproxy-systemd-wrapper[13847]: [ALERT] 089/141246 (13848) : parsing [/etc/haproxy/haproxy.cfg:19] : error detected while parsing switching rule : unknown fetch method 'var' in ACL expression 'var(txn.family)'.
Mar 30 14:12:46 xxxx.yyy.zzz haproxy-systemd-wrapper[13847]: [ALERT] 089/141246 (13848) : Error(s) found in configuration file : /etc/haproxy/haproxy.cfg
Mar 30 14:12:46 xxxx.yyy.zzz haproxy-systemd-wrapper[13847]: [ALERT] 089/141246 (13848) : Fatal errors found in configuration.
Mar 30 14:12:46 xxxx.yyy.zzz systemd[1]: haproxy.service: main process exited, code=exited, status=1/FAILURE
Mar 30 14:12:46 xxxx.yyy.zzz haproxy-systemd-wrapper[13847]: haproxy-systemd-wrapper: exit, haproxy RC=1
Mar 30 14:12:46 xxxx.yyy.zzz systemd[1]: Unit haproxy.service entered failed state.
Mar 30 14:12:46 xxxx.yyy.zzz systemd[1]: haproxy.service failed.
~

@trimsj
Copy link
Author

trimsj commented Mar 31, 2020

@shashidharrao

It appears your haproxy is not recent enough (It requires at least version 1.9)

@bgrooot
Copy link

bgrooot commented Nov 15, 2022

In my case, I had to implement it like blocking as a loop in the second txn.req:get() to work.

...
repeat
    c = c .. txn.req:get()
    if os.clock() - clock > timeout then break end
until string.len(c) >= len
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment