Run two chained Proxies in protected environments

Developed In: Lua — Contributed by: Giuseppe Maxia

This script will accept two Lua scripts and start two instances of MySQL Proxy, the first one chained to the second one. Each instance is run inside a 'screen' application, to have a separate output environment.

MySQL Proxy is a tool that sits between MySQL client and server.


Giuseppe Maxia
Lua
  1. #!/opt/local/bin/lua
  2.  
  3. local PROXY_BINPATH = os.getenv("PROXY_BINPATH") or "/usr/local/sbin/mysql-proxy"
  4. local MYSQL_HOST = os.getenv("MYSQL_HOST") or "127.0.0.1"
  5. local MYSQL_PORT = os.getenv("MYSQL_PORT") or "3306"
  6. local PROXY_HOST = os.getenv("PROXY_HOST") or "127.0.0.1"
  7. local PROXY_PORT = os.getenv("PROXY_PORT") or "4040"
  8. local ADMIN_PORT = os.getenv("ADMIN_PORT") or "4041"
  9. local PROXY_CHAIN_PORT = os.getenv("PROXY_CHAIN_PORT") or "15070"
  10. local PROXY_MASTER_PORT = os.getenv("PROXY_MASTER_PORT") or "15050"
  11. local PROXY_SLAVE_PORT = os.getenv("PROXY_SLAVE_PORT") or "15060"
  12. local ADMIN_MASTER_PORT = os.getenv("ADMIN_MASTER_PORT") or "15051"
  13. local ADMIN_SLAVE_PORT = os.getenv("ADMIN_SLAVE_PORT") or "15061"
  14. local ADMIN_CHAIN_PORT = os.getenv("ADMIN_CHAIN_PORT") or "15071"
  15. local PROXY_PID_DIRECTORY = os.getenv("PROXY_PID_DIRECTORY") or "/tmp"
  16. local PROXY_PID_FILE = os.getenv("PROXY_PID_FILE") or "proxy1.pid"
  17. local PROXY_CHAIN_PID_FILE = os.getenv("PROXY_CHAIN_PID_FILE") or "proxy_chain1.pid"
  18. local PROXY_MASTER_PID_FILE = os.getenv("PROXY_MASTER_PID_FILE") or "proxy_master1.pid"
  19. local PROXY_SLAVE_PID_FILE = os.getenv("PROXY_SLAVE_PID_FILE") or "proxy_slave1.pid"
  20. local PROXY_STOP_SCRIPT = os.getenv("PROXY_STOP_SCRIPT") or 'proxy_chain_stop'
  21.  
  22. -- this is the path containing the global Lua modules
  23. local GLOBAL_LUA_PATH = os.getenv('LUA_LDIR') or '/usr/share/lua/5.1/?.lua'
  24.  
  25. -- this is the path containing the Proxy libraries
  26. local PROXY_LUA_PATH = os.getenv('LUA_PATH') or '/usr/local/share/?.lua'
  27.  
  28. -- Building the final include path
  29. local INCLUDE_PATH =
  30. GLOBAL_LUA_PATH .. ';' ..
  31. PROXY_LUA_PATH
  32.  
  33. local proxy_list = {}
  34.  
  35. ---
  36. -- chain_proxy()
  37. --[[
  38.   starts two proxy instances, with the first one pointing to the
  39.   default backend server, and the second one (with default ports)
  40.   is pointing at the first proxy
  41.  
  42.   @param first_lua_script
  43.   @param second_lua_script
  44.   @param use_replication uses a master proxy as backend
  45. --]]
  46. function chain_proxy (first_lua_script, second_lua_script, use_replication, env_opts)
  47. first_proxy_options = {
  48. ["proxy-backend-addresses"] = MYSQL_HOST .. ":" .. MYSQL_PORT,
  49. ["proxy-address"] = PROXY_HOST .. ":" .. PROXY_CHAIN_PORT,
  50. ["admin-address"] = PROXY_HOST .. ":" .. ADMIN_CHAIN_PORT,
  51. ["pid-file"] = PROXY_CHAIN_PID_FILE,
  52. ["proxy-lua-script"] = first_lua_script ,
  53. }
  54. --
  55. -- if replication was not started, then it is started here
  56. --
  57. if use_replication and (use_replication == true) then
  58. if (proxy_list['master'] == nil) then
  59. simulate_replication()
  60. end
  61. first_proxy_options["proxy-backend-addresses"] = PROXY_HOST .. ':' .. PROXY_MASTER_PORT
  62. end
  63. second_proxy_options = {
  64. ["proxy-backend-addresses"] = MYSQL_HOST .. ":" .. PROXY_CHAIN_PORT ,
  65. ["proxy-address"] = PROXY_HOST .. ":" .. PROXY_PORT,
  66. ["admin-address"] = PROXY_HOST .. ":" .. ADMIN_PORT,
  67. ["pid-file"] = PROXY_PID_FILE,
  68. ["proxy-lua-script"] = second_lua_script ,
  69. }
  70. if not env_opts then
  71. env_opts = { }
  72. end
  73. start_proxy('first_proxy', first_proxy_options, env_opts['first'] or '')
  74. start_proxy('second_proxy',second_proxy_options, env_opts['second'] or '' )
  75. end
  76.  
  77. ---
  78. -- simulate_replication()
  79. --[[
  80.   creates a fake master/slave by having two proxies
  81.   pointing at the same backend
  82.  
  83.   you can alter those backends by changing
  84.   the starting parameters
  85.  
  86.   @param master_options options for master
  87.   @param slave_options options for slave
  88. --]]
  89. function simulate_replication(master_options, slave_options)
  90. if not master_options then
  91. master_options = default_master_options
  92. end
  93. if not master_options['pid-file'] then
  94. master_options['pid-file'] = PROXY_MASTER_PID_FILE
  95. end
  96. if not slave_options then
  97. slave_options = default_slave_options
  98. end
  99. if not slave_options['pid-file'] then
  100. slave_options['pid-file'] = PROXY_SLAVE_PID_FILE
  101. end
  102. start_proxy('master', master_options)
  103. start_proxy('slave', slave_options)
  104. end
  105.  
  106. ---
  107. -- turn a option-table into a string
  108. --
  109. -- the values are encoded and quoted for the shell
  110. --
  111. -- @param tbl a option table
  112. -- @param sep the seperator, defaults to a space
  113. function options_tostring(tbl, sep)
  114. -- default value for sep
  115. sep = sep or " "
  116.  
  117. assert(type(tbl) == "table")
  118. assert(type(sep) == "string")
  119.  
  120. local s = ""
  121. for k, v in pairs(tbl) do
  122. local enc_value = v:gsub("\\", "\\\\"):gsub("\"", "\\\"")
  123. s = s .. "--" .. k .. "=\"" .. enc_value .. "\" "
  124. end
  125.  
  126. return s
  127. end
  128.  
  129. ---
  130. -- file_exists()
  131. --
  132. -- checks if a file exists
  133. --
  134. -- @param fname the name of the file being checked
  135. function file_exists(fname)
  136. local fh=io.open( fname, 'r')
  137. if fh then
  138. fh:close()
  139. return true
  140. else
  141. return false
  142. end
  143. end
  144.  
  145. ---
  146. -- start_proxy()
  147. --
  148. -- starts an instance of MySQL Proxy
  149. --
  150. -- @param proxy_name internal name of the proxy instance, for retrieval
  151. -- @param proxy_options the options to start the Proxy
  152. function start_proxy(proxy_name, proxy_options, env_opts)
  153. -- start the proxy
  154. assert(type(proxy_options) == 'table')
  155. assert(file_exists(proxy_options['proxy-lua-script']) )
  156. proxy_options['pid-file'] = PROXY_PID_DIRECTORY ..
  157. '/' .. proxy_options['pid-file']
  158.  
  159. assert(os.execute(
  160. env_opts ..
  161. ' LUA_PATH="' ..
  162. INCLUDE_PATH .. '" ' ..
  163. ' screen -d -m -S ' ..
  164. proxy_name .. ' ' ..
  165. PROXY_BINPATH .. " " ..
  166. options_tostring( proxy_options) .. " &"
  167. ))
  168. proxy_list[proxy_name] = proxy_options
  169. end
  170.  
  171. --
  172. -- PROGRAM STARTS HERE
  173. --
  174.  
  175. local lua_scripts = {arg[1], arg[2] }
  176.  
  177. for i, v in pairs( lua_scripts ) do
  178. if not v:match('.lua$') then
  179. v = v .. '.lua'
  180. end
  181. lua_scripts[i] = v
  182. if not file_exists(v) then
  183. print( "file " .. v .. " does not exist")
  184. os.exit(1)
  185. end
  186. end
  187.  
  188.  
  189. chain_proxy(lua_scripts[1], lua_scripts[2]) -- , false, {first = arg[3], second = arg[4]} )
  190.  
  191. local stop_script_name = PROXY_PID_DIRECTORY .. '/' .. PROXY_STOP_SCRIPT
  192.  
  193. local fh = assert(io.open(stop_script_name, 'w'), "can't open " .. stop_script_name)
  194.  
  195. --
  196. -- creates a customized script to stop the chained proxies
  197. -- and close the support 'screen' applications
  198. --
  199.  
  200. fh:write("#!" .. arg[-1] .. "\n")
  201. fh:write([[
  202. function get_pid(pid_file_name)
  203. local fh = assert(io.open(pid_file_name, 'r'),
  204. "error opening " .. pid_file_name)
  205. local pid = assert(fh:read() ,
  206. "PID not found in " .. pid_file_name)
  207. fh:close()
  208. return pid
  209. end
  210.  
  211. os.execute('screen -list')
  212.  
  213. ]] )
  214.  
  215. --
  216. -- prints information about the chained proxies
  217. --
  218. for name,data in pairs(proxy_list) do
  219. print (string.format('proxy started on screen "%s" using script "%s" - pid_file : %s ',
  220. name, data['proxy-lua-script'], data['pid-file']
  221. ))
  222. fh:write("os.execute('kill -TERM ' .. get_pid('" .. data['pid-file'] .. "'))\n")
  223. fh:write("os.remove('" .. data['pid-file'] .. "' )\n")
  224. end
  225.  
  226. fh:write("os.execute('sleep 1')\n")
  227. fh:write("os.execute('screen -list')\n")
  228.  
  229. fh:close()
  230. os.execute('chmod +x ' .. stop_script_name)
  231. print ('stop script is '.. stop_script_name)
  232. os.execute('screen -list')
  233.  
  234.  

Current Tags

You must be logged in to tag this tool

One simple way to "chain" proxies is to enter the information for one proxy directly into your browser's proxy configuration setup. Then connect to a web anonymizer which is also a proxy, and from there, to the site you want to view. Anyone trying to trace your actual IP would now have to subpoena the logs from two proxy servers. Download Games website

I previously blogged on the publication of my article JEE and Flex: A Compelling Combination, Part 1 on JavaWorld. As I explained in that blog post, the article focuses primarily on why Java developers might be interested in Flex for RIA development and on communication between Flex and Java EE. masters degree business AND get diploma AND High school diploma online

With mining projects in the region, as well as any implementations of new energy, that are being proposed, both Calder and Lipinski expect they will be contacted by various industry professionals shortly. Online highschool AND homeschool

Votes

  • Rated 5.00 out of 5
Rated 5.00 out of 5 with 2 votes cast.
You must be logged in to vote.

Watches

2 members are watching this tool
You must be logged in to track this tool.

Provide Feedback

Please note:
HTML will be purified, but we allow for a number of HTML tags so that you have the flexibility to decorate your comment text to some extent. The comments allow the following HTML tags:

strong, b, em, blockquote, a, code, pre

To put code into your comment, simply encapsulate your code with
[code language="XXX"][/code], where XXX is any common language, for instance "PHP", "SQL", "C", etc.



You must be logged in to comment