defmodule GSMLG.Tor do
@moduledoc """
Documentation for `GSMLG.Tor`.
"""
@doc """
Start tor server at
- `127.0.0.1:9050`
- `[::1]:9050`
Accept accesss from `127.0.0.1/8`
Start server with
```
GSMLG.Tor.start()
```
To start server, libevent must be installed.
"""
def start() do
File.mkdir_p(Application.app_dir(:gsmlg_tor, "priv") <> "/etc")
f = Application.app_dir(:gsmlg_tor, "priv") <> "/etc/torrc"
File.write!(f, torrc())
System.cmd(cmd(), ["-f", f],
into: IO.stream(),
cd: Application.app_dir(:gsmlg_tor, "priv") <> "/tor"
)
end
def torrc() do
"""
##
## OPNsense autogenerated config file.
## Don't change it because your changes get lost.
##
##
SOCKSPort 127.0.0.1:9050 # localhost IPv4
SOCKSPort [::1]:9050 # localhost IPv6
SOCKSPolicy accept 127.0.0.1/8
SOCKSPolicy reject *
SOCKSPolicy reject6 *
Scheduler KISTLite,Vanilla
DataDirectory #{Application.app_dir(:gsmlg_tor, "priv")}/data
FascistFirewall 0
## Client Authentication
HardwareAccel 1
"""
end
def cmd() do
p = Application.app_dir(:gsmlg_tor, "priv")
tor_cmd = p <> "/tor/tor"
unless File.exists?(tor_cmd) do
IO.puts("cmd not exists, downloading...")
case download() do
0 -> tor_cmd
_ -> :error
end
else
tor_cmd
end
end
@doc """
Download tor from website.
https://www.torproject.org/download/tor/
linux x86_64 is `https://www.torproject.org/dist/torbrowser/12.0/tor-expert-bundle-12.0-linux-x86_64.tar.gz`
## Examples
iex> GSMLG.Tor.download()
0
"""
def download do
body =
case System.fetch_env("HTTP_PROXY") do
{:ok, proxy} ->
%HTTPoison.Response{status_code: 200, body: body} =
download_url() |> HTTPoison.get!([], proxy: proxy, follow_redirect: true)
body
:error ->
%HTTPoison.Response{status_code: 200, body: body} =
download_url() |> HTTPoison.get!([], follow_redirect: true)
body
end
p = Application.app_dir(:gsmlg_tor, "priv")
f = p <> "/" <> filename()
File.write!(f, body)
{_, code} = System.cmd("tar", ["zxf", f, "-C", p])
code
end
def download_url() do
"https://dist.torproject.org/torbrowser/12.0/" <> filename()
end
def filename() do
{os, arch} = os_arch()
"tor-expert-bundle-12.0-#{os}-#{arch}.tar.gz"
end
def os_arch() do
{arch, os_str} =
case :erlang.system_info(:system_architecture) |> to_string() do
"aarch64-" <> os_info ->
{"aarch64", os_info}
"x86_64-" <> os_info ->
{"x86_64", os_info}
_ ->
IO.puts("unsupported")
:error
end
{ostype} =
cond do
String.contains?(os_str, "darwin") -> {"macos"}
String.contains?(os_str, "linux") -> {"linux"}
true -> :error
end
{ostype, arch}
end
end