--[[ @object-name: tor @object-desc: tor设置 --]] local M = {} local uci = require "uci" local lnet = require "oui.network" local fs = require "oui.fs" local function replace_ip() local c = uci.cursor() local org_ip = io.popen("cat /etc/tor/torrc | grep TransPort|awk -F '[ :]' '{print $2}'") local res_org_ip = org_ip:read() org_ip:close() if res_org_ip then local new_ip = c:get("network", "lan", "ipaddr") if res_org_ip ~= new_ip then local cmd = "sed -i -e \"s/" .. res_org_ip .. "/" .. new_ip .. "/g\" /etc/tor/torrc" os.execute(cmd) return 1 end end return 0 end local function replace_country() local c = uci.cursor() local country = c:get("tor", "global", "countries") local manual = c:get("tor", "global", "manual") or 0 if tonumber(manual) == 0 then os.execute("sed -i \"/StrictNodes/d;/ExitNodes/d\" /etc/tor/torrc") else os.execute("sed -i \"/StrictNodes/d;/ExitNodes/d\" /etc/tor/torrc") os.execute("echo \"StrictNodes 1\" >> /etc/tor/torrc") local result = country:gsub(" ", "},{") local countries = "{" .. result .. "}" os.execute("echo \"ExitNodes " .. countries .. "\" >> /etc/tor/torrc") end end local function tor_on() local c = uci.cursor() c:delete("firewall", "tor_dhcp") c:set("firewall", "tor_dhcp", "rule") c:set("firewall", "tor_dhcp", "name", "Allow-Tor-DHCP") c:set("firewall", "tor_dhcp", "src", "lan") c:set("firewall", "tor_dhcp", "proto", "udp") c:set("firewall", "tor_dhcp", "dest_port", "67") c:set("firewall", "tor_dhcp", "family", "ipv4") c:set("firewall", "tor_dhcp", "target", "ACCEPT") c:delete("firewall", "tor_dns") c:set("firewall", "tor_dns", "rule") c:set("firewall", "tor_dns", "name", "Allow-Tor-DNS") c:set("firewall", "tor_dns", "src", "lan") c:set("firewall", "tor_dns", "proto", "udp") c:set("firewall", "tor_dns", "dest_port", "9053") c:set("firewall", "tor_dns", "family", "ipv4") c:set("firewall", "tor_dns", "target", "ACCEPT") c:delete("firewall", "tor_tras") c:set("firewall", "tor_tras", "rule") c:set("firewall", "tor_tras", "name", "Allow-Tor-Transparent") c:set("firewall", "tor_tras", "src", "lan") c:set("firewall", "tor_tras", "proto", "tcp") c:set("firewall", "tor_tras", "dest_port", "9040") c:set("firewall", "tor_tras", "family", "ipv4") c:set("firewall", "tor_tras", "target", "ACCEPT") c:delete("firewall", "tor_socks") c:set("firewall", "tor_socks", "rule") c:set("firewall", "tor_socks", "name", "Allow-Tor-SOCKS") c:set("firewall", "tor_socks", "src", "lan") c:set("firewall", "tor_socks", "proto", "tcp") c:set("firewall", "tor_socks", "dest_port", "9050") c:set("firewall", "tor_socks", "family", "ipv4") c:set("firewall", "tor_socks", "target", "ACCEPT") local lan_ip = c:get("network", "lan", "ipaddr") local lan_mask = c:get("network", "lan", "netmask") local lan_info = lnet.ipcalc({lan_ip,lan_mask}) local src_ip = lan_ip .. "/" .. lan_info.prefix if lan_ip and src_ip then c:delete("firewall", "tor_allow_http") c:set("firewall", "tor_allow_http", "redirect") c:set("firewall", "tor_allow_http", "name", "Allow access http") c:set("firewall", "tor_allow_http", "src", "lan") c:set("firewall", "tor_allow_http", "src_ip", src_ip) c:set("firewall", "tor_allow_http", "src_dip", lan_ip) c:set("firewall", "tor_allow_http", "src_dport", "80") c:set("firewall", "tor_allow_http", "family", "ipv4") c:set("firewall", "tor_allow_http", "proto", "tcp") c:set("firewall", "tor_allow_http", "target", "ACCEPT") c:delete("firewall", "tor_allow_https") c:set("firewall", "tor_allow_https", "redirect") c:set("firewall", "tor_allow_https", "name", "Allow access https") c:set("firewall", "tor_allow_https", "src", "lan") c:set("firewall", "tor_allow_https", "src_ip", src_ip) c:set("firewall", "tor_allow_https", "src_dip", lan_ip) c:set("firewall", "tor_allow_https", "src_dport", "443") c:set("firewall", "tor_allow_https", "family", "ipv4") c:set("firewall", "tor_allow_https", "proto", "tcp") c:set("firewall", "tor_allow_https", "target", "ACCEPT") c:delete("firewall", "tor_allow_ssh") c:set("firewall", "tor_allow_ssh", "redirect") c:set("firewall", "tor_allow_ssh", "name", "Allow access ssh") c:set("firewall", "tor_allow_ssh", "src", "lan") c:set("firewall", "tor_allow_ssh", "src_ip", src_ip) c:set("firewall", "tor_allow_ssh", "src_dip", lan_ip) c:set("firewall", "tor_allow_ssh", "src_dport", "22") c:set("firewall", "tor_allow_ssh", "family", "ipv4") c:set("firewall", "tor_allow_ssh", "proto", "tcp") c:set("firewall", "tor_allow_ssh", "target", "ACCEPT") end c:delete("firewall", "tor_allow") c:set("firewall", "tor_allow", "redirect") c:set("firewall", "tor_allow", "name", "Allow access tor domain") c:set("firewall", "tor_allow", "src", "lan") c:set("firewall", "tor_allow", "src_dport", "9050") c:set("firewall", "tor_allow", "family", "ipv4") c:set("firewall", "tor_allow", "proto", "tcp") c:set("firewall", "tor_allow", "target", "ACCEPT") c:delete("firewall", "dns_int") c:set("firewall", "dns_int", "redirect") c:set("firewall", "dns_int", "name", "Intercept-DNS") c:set("firewall", "dns_int", "src", "lan") c:set("firewall", "dns_int", "src_dport", "53") c:set("firewall", "dns_int", "dest_port", "9053") c:set("firewall", "dns_int", "family", "ipv4") c:set("firewall", "dns_int", "proto", "udp") c:set("firewall", "dns_int", "target", "DNAT") c:delete("firewall", "tcp_int") if fs.access("/sbin/fw4") then c:set("firewall", "tcp_int", "include") c:set("firewall", "tcp_int", "type", "nftables") c:set("firewall", "tcp_int", "path", "/etc/firewall.tor.nft") c:set("firewall", "tcp_int", "position", "table-post") else c:set("firewall", "tcp_int", "redirect") c:set("firewall", "tcp_int", "name", "Intercept-TCP") c:set("firewall", "tcp_int", "src", "lan") c:set("firewall", "tcp_int", "dest_port", "9040") c:set("firewall", "tcp_int", "family", "ipv4") c:set("firewall", "tcp_int", "proto", "tcp") c:set("firewall", "tcp_int", "extra", "--syn") c:set("firewall", "tcp_int", "target", "DNAT") end c:set("firewall", "@forwarding[0]", "enabled", "0") c:set("firewall", "guestzone_fwd", "enabled", "0") c:set("tor", "global", "enable", "1") c:commit("firewall") c:commit("tor") ngx.pipe.spawn({"/etc/init.d/firewall", "reload"}):wait() local replace_ip_status = replace_ip() local run = ngx.pipe.spawn("ps | grep /usr/sbin/tor | grep -v grep") local run_data = run:stdout_read_all() if run_data == "" or replace_ip_status == 1 then replace_country() ngx.pipe.spawn({"/etc/init.d/tor", "enable"}):wait() ngx.pipe.spawn({"/etc/init.d/tor", "restart"}):wait() end os.execute("echo y >/proc/net/nf_conntrack") os.execute("killall -16 e750-mcu") local force_dns = c:get("glconfig", "general", "force_dns") if force_dns == "yes" then local _, _, tcp_status = ngx.pipe.spawn("iptables -t nat -C PREROUTING -i br-lan -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 9053") if tcp_status ~= 0 then ngx.pipe.spawn("iptables -t nat -I PREROUTING -i br-lan -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 9053") end local _, _, udp_status = ngx.pipe.spawn("iptables -t nat -C PREROUTING -i br-lan -p udp -m udp --dport 53 -j REDIRECT --to-ports 9053") if udp_status ~= 0 then ngx.pipe.spawn("iptables -t nat -I PREROUTING -i br-lan -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 9053") end end end local function tor_exit() local c = uci.cursor() c:delete("firewall", "tor_dhcp") c:delete("firewall", "tor_dns") c:delete("firewall", "tor_tras") c:delete("firewall", "tor_socks") c:delete("firewall", "tor_allow_http") c:delete("firewall", "tor_allow_https") c:delete("firewall", "tor_allow_ssh") c:delete("firewall", "tor_allow") c:delete("firewall", "dns_int") c:delete("firewall", "tcp_int") c:set("firewall", "@forwarding[0]", "enabled" , "1") c:set("firewall", "guestzone_fwd", "enabled", "1") c:set("tor", "global", "enable", "0") c:commit("firewall") c:commit("tor") ngx.pipe.spawn({"/etc/init.d/firewall", "reload"}):wait() ngx.pipe.spawn({"/etc/init.d/tor", "stop"}):wait() ngx.pipe.spawn({"/etc/init.d/tor", "disable"}):wait() os.execute("killall -16 e750-mcu") ngx.pipe.spawn("iptables -t nat -D PREROUTING -i br-lan -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 9053") ngx.pipe.spawn("iptables -t nat -D PREROUTING -i br-lan -p udp -m udp --dport 53 -j REDIRECT --to-ports 9053") end --[[ @method-type: call @method-name: get_config @method-desc: 获取tor的配置信息 @out bool manual 手动选择开关: false: 关闭, true:开启 @out bool enable tor 状态:false :关闭, true :开启 @out array countries 获取手动选择的国家 @out number ?err_code Error code,-1:获取信息失败. @out string ?err_msg Error message @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","tor","get_config"]} @out-example: {"jsonrpc": "2.0", "id": 1, "result": {"manual": true, "enable": true, "countries": "cn"}} --]] function M.get_config() local c = uci.cursor() local tor = {} local countries = {} local manual = c:get("tor", "global", "manual") == "1" tor.enable = c:get("tor", "global", "enable") == "1" local country_info = c:get("tor", "global", "countries") if country_info ~= "all" then for info in country_info:gmatch('%S+') do countries[#countries + 1] = info end end tor.countries = countries tor.manual = manual return tor end --[[ @method-type: call @method-name: set_config @method-desc: 设置tor的配置信息 @in bool manual 手动选择开关: false: 关闭, true:开启 @in bool enable tor 状态:false :关闭, true :开启 @in array countries 设置手动选择的国家(可选择多个国家) @out number ?err_code Error code,-1:非法参数. @out string ?err_msg Error message @in-example: {"jsonrpc":"2.0","method":"call","params":["","tor","set_config",{"enable":true,"manual":true,"countries":"cn"}],"id":1} @out-example: {"jsonrpc": "2.0", "id": 1, "result": null} --]] function M.set_config(params) local c = uci.cursor() local enable = params.enable local manual = params.manual and 1 or 0 local countries = params.countries or {} local countries_info = {} if manual == 1 then for _, v in ipairs(countries) do countries_info[#countries_info + 1] = v end c:set("tor", "global", "countries", table.concat(countries_info, " ")) end c:set("tor", "global", "manual", manual) if enable == true then c:set("tor", "global", "enable", "1") c:commit("tor") ngx.pipe.spawn({"/etc/init.d/tor", "stop"}):wait() os.execute("rm /var/lib/tor/control.log") tor_on() else c:set("tor", "global", "enable", "0") c:commit("tor") tor_exit() os.execute("rm /var/lib/tor/control.log") end end --[[ @method-type: call @method-name: get_status @method-desc: 获取 tor 状态 @out number status tor连接状态:0:未连接,1 :连接成功, 2 :连接中 @out string log 当前连接信息日志 @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","tor","get_status"]} @out-example: {"id":null,"jsonrpc":"2.0","result":{"tor_status":[{"status":2,"log":"Initialization tor configuration"]}} --]] function M.get_status() local c = uci.cursor() local tor_status = {} local enable = c:get("tor", "global", "enable") == "1" if enable then local rs_file = assert(io.popen("cat /var/lib/tor/control.log |grep Bootstrapped|tail -n 1")) local percent = rs_file:read() rs_file:close() if percent then if percent:match("100") then tor_status.status = 1 tor_status.log = "tor connection succeeded" else tor_status.status = 2 tor_status.log = percent end else tor_status.status = 0 tor_status.log = "Initialization tor configuration" end end return tor_status end return M