Skip to content

Commit

Permalink
feat: support tor network (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
DVKunion authored Jan 29, 2024
1 parent ea7da38 commit f91855d
Show file tree
Hide file tree
Showing 16 changed files with 190 additions and 36 deletions.
7 changes: 6 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,10 @@ FROM alpine:3.19
LABEL maintainer="[email protected]"
WORKDIR /app
COPY --from=build /tmp/seamoon /app/seamoon
COPY ./entrypoint.sh /app/entrypoint.sh
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
apk add tor && \
echo -e "RunAsDaemon 1\n\nAssumeReachable 1\n\nLog notice file /var/log/tor/tor.log" > /etc/tor/torrc &&\
chmod +x /app/entrypoint.sh && chmod +x /app/seamoon
EXPOSE 1080 8080 7777 9000
ENTRYPOINT ["/app/seamoon"]
ENTRYPOINT ["/app/entrypoint.sh"]
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,50 @@
月海(Sea Moon) 是一款 FaaS/BaaS 实现的 Serverless 网络工具集,期望利用云原生的优势,实现更简单、更便宜的网络功能。
</p>
<p align="center">
月海之名取自于苏轼的《西江月·顷在黄州》,寓意月海取自于传统安全工具,用之于云,最终达到隐匿于海的效果。
月海之名取自于苏轼的《西江月·顷在黄州》,寓意月海取自于传统工具,用之于云,最终达到隐匿于海的效果。
</p>

## ☁️ 什么是月海

> 🌕 月出于云却隐于海
> 🔥 新增 seamoon 支持 tor 网络访问 onion 域名
月海(Sea Moon) 是一款 FaaS/BaaS 实现的 Serverless 网络工具集,期望利用云原生的优势,实现更简单、更便宜的网络功能。

月海之名取自于苏轼的《西江月·顷在黄州》,寓意月海取自于传统工具,用之于云,最终达到隐匿于海的效果。

月海基于 Serverless 的动态特性、分别从网络层、应用层实现对应的安全能力,并利用serverless-devs工具来实现快捷的部署/跨厂商操作。
月海基于 Serverless 的动态特性、分别从网络层、应用层实现对应的能力,并利用serverless-devs工具来实现快捷的部署/跨厂商操作。

想要了解更多,请移步 [官方手册](https://seamoon.dvkunion.cn)

觉得项目不错的话,[还请给一个star ✨](https://github.com/DVKunion/SeaMoon), 你的支持是更新的最大动力~

## 🔨 功能简要


**网络隧道**

| 隧道类型 | 技术文档 | 支持情况 |
|-----------|------|:------:|
| websockst | []() ||
| grpc | []() ||


**网络代理**

| 代理类型 | 技术文档 | Seamoon 客户端支持 | 其他客户端支持 |
|-------------|-----------------------------------------------------------|:-------------:|:-------:|
| HTTP(S) | [HTTP.md](https://seamoon.dvkunion.cn/tech/net/http/) |||
| Socks5 | [Socks5.md](https://seamoon.dvkunion.cn/tech/net/socks5/) |||
| Socks4 | []() |||
| shadowsocks | []() |||

**其他**

+ 🧅 Tor 网络 .onion 支持. [如何开启 Tor 代理](https://seamoon.dvkunion.cn/guide/client/tor/)
+ ......

## 🔥 使用展示

![client](https://seamoon.oss-cn-hangzhou.aliyuncs.com/0dd37f5600364e59a9457e38eaf77b1f.png)
Expand Down
2 changes: 2 additions & 0 deletions cmd/client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func (c *clientConfig) Addr(t transfer.Type) string {
type controlConfig struct {
ConfigAddr string `toml:"addr"`
LogPath string `toml:"logPath"`
TorEnable bool `toml:"tor_enable"`
}

type proxyConfig struct {
Expand Down Expand Up @@ -58,6 +59,7 @@ func defaultConfig() *clientConfig {
// is dangerous to open Control page for everyone, do not set value like: ":7777" / "0.0.0.0:7777"
ConfigAddr: ":7777",
LogPath: "web.log",
TorEnable: false,
},
Http: proxyConfig{
false, ":9000", "inactive",
Expand Down
2 changes: 1 addition & 1 deletion cmd/client/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func listen(ctx context.Context, server net.Listener, pa string, pt tunnel.Type,
slog.Error(consts.ACCEPT_ERROR, "err", err)
}
if srv, ok := service.Factory.Load(pt); ok {
destConn, err := srv.(service.Service).Conn(ctx, t, service.WithAddr(pa))
destConn, err := srv.(service.Service).Conn(ctx, t, service.WithAddr(pa), service.WithTorFlag(Config().Control.TorEnable))
if err != nil {
slog.Error(consts.CONNECT_RMOET_ERROR, "err", err)
continue
Expand Down
5 changes: 5 additions & 0 deletions cmd/client/static/public/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function post() {
Control: {
ConfigAddr: $("#controlAddr").val(),
LogPath: $("#controlLog").val(),
TorEnable: $(".tor.ui.toggle.checkbox").hasClass("checked"),
},
Http: {
Enabled: $(".http.ui.toggle.checkbox").hasClass("checked"),
Expand Down Expand Up @@ -70,6 +71,10 @@ function setValue(config) {
console.log(config.Control.ConfigAddr)
$('#controlAddr').attr("value", config.Control.ConfigAddr)
$('#controlLog').attr("value", config.Control.LogPath)
if (config.Control.TorEnable) {
$('.tor.ui.toggle.checkbox').addClass("checked")
$("#torEnable").attr("checked", "checked")
}
if (config.Http.Enabled) {
$('.http.ui.toggle.checkbox').addClass("checked")
$(".http.two.fields").attr("style", "display: block;")
Expand Down
38 changes: 18 additions & 20 deletions cmd/client/static/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ <h1 class="ui center inverted aligned icon header">
<div class="content center">
<p>SeaMoon - 月海</p>
<p align="center">
<img src="https://goreportcard.com/badge/github.com/DVKunion/SeaMoon" />
<img src="https://img.shields.io/github/stars/DVKunion/SeaMoon.svg" alt="stars"/>
<img src="https://img.shields.io/github/downloads/dvkunion/seamoon/total?color=orange" alt="downloads" />
<img src="https://img.shields.io/github/languages/top/DVKunion/SeaMoon.svg?&color=blueviolet" alt="languages">
<img src="https://img.shields.io/badge/LICENSE-MIT-777777.svg" alt="license"/>
<img src="https://goreportcard.com/badge/github.com/DVKunion/SeaMoon"/>
<img src="https://img.shields.io/github/stars/DVKunion/SeaMoon.svg" alt="stars"/>
<img src="https://img.shields.io/github/downloads/dvkunion/seamoon/total?color=orange"
alt="downloads"/>
<img src="https://img.shields.io/github/languages/top/DVKunion/SeaMoon.svg?&color=blueviolet"
alt="languages">
<img src="https://img.shields.io/badge/LICENSE-MIT-777777.svg" alt="license"/>
<a href='https://github.com/DVKunion/SeaMoon'><img
src="https://img.shields.io/github/watchers/dvkunion/seamoon?style=social"/></a>
src="https://img.shields.io/github/watchers/dvkunion/seamoon?style=social"/></a>
</p>
<div class="sub header">
🌕 月出于云却隐于海
Expand Down Expand Up @@ -84,6 +86,13 @@ <h4 class="ui inverted dividing header"><i class="cloud icon"></i>工具配置</
<input id="controlLog" placeholder="日志路径" type="text">
</div>
</div>
<br />
<div class="field">
<div class="tor ui toggle checkbox">
<input id="torEnable" type="checkbox" tabindex="0" class="hidden">
<label>开启 tor 网络(仅支持 socks5 代理 + websocket 隧道)</label>
</div>
</div>
<h4 class="ui inverted dividing header"><i class="cloud icon"></i>云端配置</h4>
<div class="fifteen wide field">
<label>代理地址: </label>
Expand Down Expand Up @@ -118,19 +127,8 @@ <h4 class="ui inverted dividing header"><i class="paper plane icon"></i>代理
<input id="socksAddr" placeholder="socks代理地址" type="text">
</div>
</div>
<h4 class="ui dividing inverted header"><i class="ellipsis horizontal icon"></i>高级功能</h4>
{{/* <div class="inline field">*/}}
{{/* <div class="ui checkbox">*/}}
{{/* <input type="checkbox" tabindex="0" class="hidden">*/}}
{{/* <label>开启webshell动态代理功能(待实现)</label>*/}}
{{/* </div>*/}}
{{/* </div>*/}}
<!-- <div class="inline field">-->
<!-- <div class="ui checkbox">-->
<!-- <input type="checkbox" tabindex="0" class="hidden">-->
<!-- <label>其他一些乱七八糟的功能,占个位置</label>-->
<!-- </div>-->
<!-- </div>-->
{{/* <h4 class="ui dividing inverted header"><i class="ellipsis horizontal icon"></i>高级功能</h4>*/}}

</form>
</div>
<div class="actions">
Expand Down Expand Up @@ -159,6 +157,6 @@ <h4 class="ui dividing inverted header"><i class="ellipsis horizontal icon"></i>
<script src="/static/public/js/index.js"></script>
<script>
const config = {{ . }}
setValue(config);
setValue(config);
</script>
</html>
6 changes: 3 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ bannerBg: none
postList: none
features:
- title: 🫥 隐匿
details: 基于 FaaS/BaaS 实现动态IP代理,云上无痕。
details: 基于 FaaS/BaaS 实现动态IP代理,支持Tor网络,云上无痕。
- title: 🗃️ 集成
details: 适配大量云服务商和知名客户端,拒绝服务绑架。
details: 适配大量云服务商与知名客户端,拒绝服务绑架。
- title: 🚀 便携
details: 以 Serverless Devs为基础,实现跨平台快速部署。
details: 以 Serverless Devs 为基础,实现跨平台快速部署。
---
9 changes: 6 additions & 3 deletions docs/guide/00.概述/00.introduce.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ article: false

月海之名取自于苏轼的《西江月·顷在黄州》,寓意月海取自于传统工具,用之于云,最终达到隐匿于海的效果。

月海基于 Serverless 的动态特性、分别从网络层、应用层实现对应的安全能力,并利用serverless-devs工具来实现快捷的部署/跨厂商操作。
月海基于 Serverless 的动态特性、分别从网络层、应用层实现对应的能力,并利用serverless-devs工具来实现快捷的部署/跨厂商操作。

觉得项目不错的话,[还请给一个star ✨](https://github.com/DVKunion/SeaMoon), 你的支持是更新的最大动力~

Expand All @@ -34,6 +34,8 @@ article: false

利用云函数的动态实例不同的出口IP,从而获取到了干净(非威胁情报黑名单)、随机的外网IP代理来进行测试。

同时月海集成了 Tor 网桥,实现了服务端 Tor 网络的访问。

目前网络层功能支持如下:

**网络隧道**
Expand All @@ -53,9 +55,10 @@ article: false
| Socks4 | []() |||
| shadowsocks | []() |||

**端口转发**
**其他**

**NAT穿透**
+ 🧅 Tor 网络 .onion 支持. [如何开启 Tor 代理](https://seamoon.dvkunion.cn/guide/client/tor/)
+ ......

更多特性相关请移步: [技术文档](https://seamoon.dvkunion.cn/tech/feature/)

Expand Down
4 changes: 2 additions & 2 deletions docs/guide/03.客户端部署/03.gost.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ gost -L socks5://:1080 -F socks5+wss://<seamoon-server>:<seamoon-port>?path=/soc
# 通过 gost 启动一个其他协议代理,这里以 socks4 代理为例,利用 websocket 转发,并指定转发的流量 以 socks5 形式。
gost -L socks4://:1080 -F socks5+wss://<seamoon-server>:<seamoon-port>?path=/socks5
```

</code-block>

<code-block title="gost-shadowsocks + seamoon-websocket(socks5)">

```shell
# 通过 gost 启动一个其他协议代理,这里以 shadowsocks 代理为例,利用 websocket 转发,并指定转发的流量 以 socks5 形式。
gost -L ss://:1080 -F socks5+wss://<seamoon-server>:<seamoon-port>?path=/socks5
gost -L ss://<cipher>:<pass>@:1080 -F socks5+wss://<seamoon-server>:<seamoon-port>?path=/socks5
# 如:ss://AEAD_AES_128_GCM:password@:1080
```

</code-block>
Expand Down
38 changes: 38 additions & 0 deletions docs/guide/03.客户端部署/04.tor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: Tor
date: 2022-09-29 23:45:03
permalink: /guide/client/tor
article: false
---

## 🧅 Tor 网络开启

::: warning 注意
tor 服务比较吃内存,经测试 内存至少需要配置在 100MB 以上才能发挥稳定的效果。
:::

为了防止普通流量过 Tor 导致的速率下降,在客户端做了个开关。

客户端会根据这个这个开关来选择是否给服务端发送 Tor 代理标识。

服务端接收到 Tor 代理标识后,会将流量直接转发给本地服务。

![tor](https://seamoon.oss-cn-hangzhou.aliyuncs.com/ec26347f298a4f9d81f7068eb3c0e4dc.png)

注意,tor 网络目前仅支持: 本地 socks5 代理 + websocket 隧道 的模式。

然后本地的 socks5 代理即可访问一些 .onion 结尾的域名了。如:

`https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/`


![onion](https://seamoon.oss-cn-hangzhou.aliyuncs.com/09626bede56b4c18b6cd4d41d3e11c00.png)


::: tips
在当前版本内,seamoon 实现了最简单的 tor 接入方式 -- 通过 tor cli 自带的 s5 协议做了一层转发,因为 v2ray 也是这样玩的。

实际上,这种方案,有很多不足,出去开头的资源占用较高 warning,通过 binary 的集成力度也不是非常合适,但是在这个阶段暂时用该方案来减少代码开发的工作量。

因此,此方案仅用于证明 seamoon 的扩展性,距离真正 "便宜" 可能还需要一段的距离。
:::
8 changes: 7 additions & 1 deletion docs/guide/03.客户端部署/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ SeaMoon 客户端同样支持多模式部署
+ [docker](https://seamoon.dvkunion.cn/guide/client/docker/)
+ [binary](https://seamoon.dvkunion.cn/guide/deploy/binary/)

Seamoon 客户端还支持了 Tor 网桥的接入

+ [tor](https://seamoon.dvkunion.cn/guide/client/tor/)

除此之外,你还可以选择其他客户端,seamoon做了部分的协议适配支持,这样可以选择仅部署服务端,然后使用已有的成品客户端。

成品客户端通常会支持更多协议类型,比如 gost,基本上所有可以监听的类型都可以通过 seamoon 隧道协议转发出来。

+ [gost:优雅简便的go代理](https://seamoon.dvkunion.cn/guide/client/gost/)
+ [gost:优雅简便的go代理](https://seamoon.dvkunion.cn/guide/client/gost/)

[//]: # (+ [v2ray: 时代战神]&#40;https://seamoon.dvkunion.cn/guide/client/v2ray/&#41;)
8 changes: 8 additions & 0 deletions docs/tech/01.网络/03.TOR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: TOR
date: 2024-01-29 11:05:23
permalink: /tech/net/tor/
article: false
---
# TOR

7 changes: 7 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

if [ "$TOR" = "true" ]; then
tor
fi

/app/seamoon "$@"
7 changes: 7 additions & 0 deletions pkg/service/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
type Options struct {
addr string

tor bool
tlsConf *tls.Config
keepalive *KeepAliveOpt
buffers *BufferOpt
Expand Down Expand Up @@ -37,6 +38,12 @@ func WithAddr(addr string) Option {
}
}

func WithTorFlag(tor bool) Option {
return func(o *Options) {
o.tor = tor
}
}

func WithTLSConf(t *tls.Config) Option {
return func(o *Options) {
o.tlsConf = t
Expand Down
20 changes: 17 additions & 3 deletions pkg/service/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ func (s *WSService) Conn(ctx context.Context, t transfer.Type, sOpts ...Option)
wsDialer.EnableCompression = srvOpts.buffers.EnableCompression
}

wsConn, _, err := wsDialer.Dial(t.Path(srvOpts.addr), nil)
var requestHeader = http.Header{}

if srvOpts.tor {
requestHeader.Add("SM-ONION", "enable")
}

wsConn, _, err := wsDialer.Dial(t.Path(srvOpts.addr), requestHeader)

if err != nil {
return nil, err
Expand Down Expand Up @@ -115,15 +121,23 @@ func (s *WSService) http(w http.ResponseWriter, r *http.Request) {
}

func (s *WSService) socks5(w http.ResponseWriter, r *http.Request) {
onion := r.Header.Get("SM-ONION")
// means use socks5 to connector
conn, err := s.upGrader.Upgrade(w, r, nil)
if err != nil {
return
}
t := tunnel.WsWrapConn(conn)
go func() {
if err := transfer.Socks5Transport(t); err != nil {
slog.Error("connection error", "msg", err)
// 检测是否存在 onion 标识,代表着是否要开启 tor 转发
if onion != "" {
if err := transfer.TorTransport(t); err != nil {
slog.Error("connection error", "msg", err)
}
} else {
if err := transfer.Socks5Transport(t); err != nil {
slog.Error("connection error", "msg", err)
}
}
}()
}
Expand Down
Loading

0 comments on commit f91855d

Please sign in to comment.