Skip to content

Commit

Permalink
Merge pull request #11 from longXboy/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
longxboy authored Apr 27, 2017
2 parents 2760882 + e53fdd1 commit aa0a146
Show file tree
Hide file tree
Showing 368 changed files with 70,916 additions and 405 deletions.
44 changes: 40 additions & 4 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ lunnel 是一款简单易用的内网NAT穿越、反向代理软件,支持 HTT
1. 隧道连接默认使用 TCP、KCP 自动切换模式,隧道传输协议可以任意替换。
2. 支持 AES、TLS 加密,客户端与服务器端建立隧道只需一次密钥交换握手,建立连接速度更快。
3. 自建隧道连接池,保证高并发下的访问通畅。
4. 单个连接支持多路并发(类似http 2.0),更节省资源
4. 单个连接支持多路并发(类似http 2.0),更节省资源

## QuickStart

Expand Down
3 changes: 3 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ func Main(configDetail []byte, configType string) {
log.Init(cliConf.Debug, nil)
}
raven.SetDSN(cliConf.DSN)
defer log.CapturePanic()

if cliConf.ClientId != "" {
u, err := uuid.FromString(string(cliConf.ClientId))
if err != nil {
Expand Down Expand Up @@ -211,6 +213,7 @@ func Main(configDetail []byte, configType string) {
tunnel.HttpHostRewrite = tc.HttpHostRewrite
tunnel.Local.Schema = localSchema
tunnel.Local.Host = localHost
tunnel.Local.InsecureSkipVerify = tc.HttpsSkipVerify
tunnel.Local.Port = uint16(localPort)
tunnel.Public.Schema = tc.Schema
tunnel.Public.Host = tc.Host
Expand Down
1 change: 1 addition & 0 deletions client/clientConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type TunnelConfig struct {
Port uint16 `yaml:"port,omitempty"`
LocalAddr string `yaml:"local,omitempty"`
HttpHostRewrite string `yaml:"http_host_rewrite,omitempty"`
HttpsSkipVerify bool `yaml:"https_skip_verify,omitempty"`
}

type Health struct {
Expand Down
22 changes: 18 additions & 4 deletions client/clientControl.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,20 @@ type writeReq struct {
}

type Control struct {
// To work on both ARM and x86-32,
// these two fields must be the first elements to keep 64-bit
// alignment for atomic access to the fields.
lastRead uint64
totalPipes int64

ClientID uuid.UUID

ctlConn net.Conn
tunnelsLock *sync.Mutex
tunnels map[string]msg.Tunnel
preMasterSecret []byte
lastRead uint64
encryptMode string
transportMode string
totalPipes int64

writeChan chan writeReq
cancel context.CancelFunc
Expand All @@ -84,6 +88,8 @@ func (c *Control) Close() {
}

func (c *Control) createPipe() {
defer log.CapturePanic()

log.WithFields(log.Fields{"time": time.Now().Unix(), "pipe_count": atomic.LoadInt64(&c.totalPipes)}).Debugln("create pipe to server!")
pipeConn, err := transport.CreateConn(cliConf.ServerAddr, c.transportMode, cliConf.HttpProxy)
if err != nil {
Expand Down Expand Up @@ -113,6 +119,8 @@ func (c *Control) createPipe() {
return
}
go func() {
defer log.CapturePanic()

defer stream.Close()
c.tunnelsLock.Lock()
tunnel, isok := c.tunnels[stream.TunnelName()]
Expand All @@ -136,8 +144,8 @@ func (c *Control) createPipe() {
log.WithFields(log.Fields{"err": err, "local": tunnel.LocalAddr()}).Warningln("pipe dial local failed!")
return
}
if tunnel.Local.Schema == "https" {
conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})
if tunnel.Public.Schema == "http" && tunnel.Local.Schema == "https" {
conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: tunnel.Local.InsecureSkipVerify, ServerName: tunnel.Local.Host})
}
} else if tunnel.Local.Schema == "unix" {
conn, err = net.Dial("unix", tunnel.Local.Host)
Expand Down Expand Up @@ -201,6 +209,8 @@ func (c *Control) ClientAddTunnels() error {
}

func (c *Control) recvLoop() {
defer log.CapturePanic()

atomic.StoreUint64(&c.lastRead, uint64(time.Now().UnixNano()))
for {
mType, body, err := msg.ReadMsgWithoutTimeout(c.ctlConn)
Expand Down Expand Up @@ -239,6 +249,8 @@ func (c *Control) recvLoop() {
}

func (c *Control) writeLoop() {
defer log.CapturePanic()

lastWrite := time.Now()
for {
select {
Expand Down Expand Up @@ -293,6 +305,8 @@ func (c *Control) AddTunnel(w http.ResponseWriter, r *http.Request) {
}

func (c *Control) serveHttp(lis net.Listener) {
defer log.CapturePanic()

m := http.NewServeMux()
m.HandleFunc("/tunnel", c.AddTunnel)
err := http.Serve(lis, m)
Expand Down
39 changes: 18 additions & 21 deletions cmd/lunnelCli/cacert-example.pem
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
-----BEGIN CERTIFICATE-----
MIID5TCCAs2gAwIBAgIJANcACfhNV/5hMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD
VQQGEwJDTjELMAkGA1UECAwCU0gxCzAJBgNVBAcMAlNIMRQwEgYDVQQKDAtEYW9j
bG91ZC5pbzELMAkGA1UECwwCSVQxFDASBgNVBAMMC2V4YW1wbGUuY29tMSYwJAYJ
KoZIhvcNAQkBFhdsb25neGlhLmNhb0BkYW9jbG91ZC5pbzAeFw0xNzAzMjgxMzQy
MTNaFw0xNzA0MjcxMzQyMTNaMIGIMQswCQYDVQQGEwJDTjELMAkGA1UECAwCU0gx
CzAJBgNVBAcMAlNIMRQwEgYDVQQKDAtEYW9jbG91ZC5pbzELMAkGA1UECwwCSVQx
FDASBgNVBAMMC2V4YW1wbGUuY29tMSYwJAYJKoZIhvcNAQkBFhdsb25neGlhLmNh
b0BkYW9jbG91ZC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFC
fFnzKgnXsMKb8wyfxk2su9OmvvTWBmn9+0N02M59k7NAJuI+7F6PKLVguLBPSUkY
DSEZ/gn7i/2Q/aCB6REWhxWqv+KNmq7LMNaIuJlf12f35r3SpdT6H2HDZn6F0q6b
FzeERPULdSzh/TlZijo7XZW09mMFfq/t8Fp+C/TqQIg28UOHlOBVMR8seAE/79zt
dqalki5jRqYQ5ZUh10JIK11/6m61fEgdG1PiDrBYWChHRUUafPbcWsqXONVJzEGj
Z3XJP9k8WBDRzqy7n4Peu96DBG06SwbA/Y8zjiBmKiPeIGoOGkiS7Gpb48jY/xOa
FvzP8YVzpnKtB8TBr1kCAwEAAaNQME4wHQYDVR0OBBYEFIFceIbp2poVl6XZzCV8
IF4iE4H4MB8GA1UdIwQYMBaAFIFceIbp2poVl6XZzCV8IF4iE4H4MAwGA1UdEwQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAKdeD1DR6D8FnrmeKbs0TIegifSZOag7
5xpIz3D+4rKuIY24z+v2sbqsoUN4mzkwlV37PSDxQMqlTWwu2FwRcs6AkRRu+rK6
G6a3kWUUCBkstCu574Q7hEg83H/3gvRL/D4okWFBwr+Vp8ZvIXewpROB8CpyJ2JI
CJ4Wqw7TJHHxQ5eq5ojKnzBFg+g4ukPGPO2GTKQvuZnw2w5F95sCkUYcJQ3wdhy0
VetRYiiBI8b28C5O4RNOH6GaoookgAeGu4Fombxvt3U87FEytgq1EuEVwHpTnx+O
bOsfKsWmI+s0E9waTt5ad33yP6t1NSI5a0GA8bFfHBIAW/abcPRc0HE=
MIIDPDCCAiQCCQDj8tij1T669zANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJD
TjELMAkGA1UECAwCU0gxCzAJBgNVBAcMAlNIMRQwEgYDVQQKDAtleGFtcGxlLmNv
bTELMAkGA1UECwwCSVQxFDASBgNVBAMMC2V4YW1wbGUuY29tMB4XDTE3MDQyNzE1
NTg1OVoXDTI3MDQyNTE1NTg1OVowYDELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNI
MQswCQYDVQQHDAJTSDEUMBIGA1UECgwLZXhhbXBsZS5jb20xCzAJBgNVBAsMAklU
MRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAL4M+9RpM5NNxCL0vDRIw8QorsdlCFNmLs79NU6Ps9sa9BtTN0BeJP+w
2I2ywdJkXkD87Q4cqF40PD7Sv6VqPC3xtRDGjbweEFlUOxTPLsQpk6gG9nNvGj2o
2bE3+VJhlwWI2tHiIh0n7bftHIyy0jz2q6sVkr5aoOJzWt7JjyymHT5+Lm0Lrr/Y
qfVxAuLoVHUuK7R99EfhrY1t1bbpqvgormLUeG9c0hBgtbwx4UqrYzqKzOsCt4KD
4V3fWQ8GmqO5iZNNdDPpAndNlVQ09pRNZ/OfKYpqJbjEG8AvEspAW1vWhKfciG8d
UOO7YZ3XcDZprKMyUfQ6AMa/PQ7evmkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
HGeFemG+kLkmNj6T3goWZQ/CQvhlhslo9SPi/TdHQaWQmk3kY7CxO6gx+toyAR3N
PTefGkAao7jH6yMw3jFke5MwB1hwV8x0fFE0ZTonq1+JiPmrfvJcW4wvaFSnOGT+
VO9SXDGuoSW1Qaigt5zhZ3lKfXMiIYtvVahP+6jETvLOxMIFmcfniiMHkDr7KKUl
Jy83KoJ2ake9XwWwKyfuviPqSbHd+4mp6HkiJRFWQLygozSUXr0crfnV7EfipuG4
Nez7G+NcVQOAVbmdOFLg12U/HVOIObJicPEfjSpqXBzpgfEpws4fjSNS7hPVoUFf
8DrI0nNy9Ayx2moyee/YGw==
-----END CERTIFICATE-----
11 changes: 8 additions & 3 deletions cmd/lunnelCli/config-full-example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ server_addr: 127.0.0.1:8080
tunnels:
#代理隧道的名字,必须唯一不可重复
2048:
#外网访问使用的协议,可以是http、https、tcp、udp
#外网访问时使用的协议,可以是http、https、tcp、udp
schema: http
#客户端代理的本地地址
#需要客户端代理的本地连接地址
local: http://127.0.0.1:32768
#外网公开访问的地址,当服务器中已经存在相同的host,则会报错(如果不填写则由服务器端自动分配)
host: 2048.example.com
Expand All @@ -18,7 +18,12 @@ tunnels:
local: http://127.0.0.1:32768
2048_https:
schema: https
local: http://127.0.0.1:32768
local: https://2048.example:443
2048_https_to_http:
schema: http
#当需要把本地的https转换为外网http访问时,并且本地https证书过期或非法的时候可以设置https_skip_verify为true
https_skip_verify: true
local: https://2048.example:443
docker:
schema: http
local: unix:///var/run/docker.sock
Expand Down
2 changes: 1 addition & 1 deletion cmd/lunnelSer/config-full-example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ health:
interval: 15
#心跳超时时间,单位秒
timeout: 40
#每个客户端的最大物理空闲连接数,不填写的话则默认为5
#每个客户端的最大物理空闲连接数,不填写的话则默认为4
max_idle_pipes: 5
#单个物理连接所能承载的最大并发请求数,不填写的话则默认为6
max_streams: 6
90 changes: 18 additions & 72 deletions cmd/lunnelSer/example.crt
Original file line number Diff line number Diff line change
@@ -1,74 +1,20 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=CN, ST=SH, L=SH, O=Daocloud.io, OU=IT, CN=example.com/[email protected]
Validity
Not Before: Mar 28 14:03:13 2017 GMT
Not After : Mar 8 14:03:13 2038 GMT
Subject: C=CN, ST=SH, O=example.com, OU=IT, CN=www.example.com/[email protected]
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:be:0c:fb:d4:69:33:93:4d:c4:22:f4:bc:34:48:
c3:c4:28:ae:c7:65:08:53:66:2e:ce:fd:35:4e:8f:
b3:db:1a:f4:1b:53:37:40:5e:24:ff:b0:d8:8d:b2:
c1:d2:64:5e:40:fc:ed:0e:1c:a8:5e:34:3c:3e:d2:
bf:a5:6a:3c:2d:f1:b5:10:c6:8d:bc:1e:10:59:54:
3b:14:cf:2e:c4:29:93:a8:06:f6:73:6f:1a:3d:a8:
d9:b1:37:f9:52:61:97:05:88:da:d1:e2:22:1d:27:
ed:b7:ed:1c:8c:b2:d2:3c:f6:ab:ab:15:92:be:5a:
a0:e2:73:5a:de:c9:8f:2c:a6:1d:3e:7e:2e:6d:0b:
ae:bf:d8:a9:f5:71:02:e2:e8:54:75:2e:2b:b4:7d:
f4:47:e1:ad:8d:6d:d5:b6:e9:aa:f8:28:ae:62:d4:
78:6f:5c:d2:10:60:b5:bc:31:e1:4a:ab:63:3a:8a:
cc:eb:02:b7:82:83:e1:5d:df:59:0f:06:9a:a3:b9:
89:93:4d:74:33:e9:02:77:4d:95:54:34:f6:94:4d:
67:f3:9f:29:8a:6a:25:b8:c4:1b:c0:2f:12:ca:40:
5b:5b:d6:84:a7:dc:88:6f:1d:50:e3:bb:61:9d:d7:
70:36:69:ac:a3:32:51:f4:3a:00:c6:bf:3d:0e:de:
be:69
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:*.example.com, DNS:example.com
Signature Algorithm: sha256WithRSAEncryption
8a:0c:82:bc:ba:63:28:66:86:19:85:52:a9:f9:28:cc:a1:ef:
b1:03:c4:64:ce:11:33:b0:a8:3c:28:17:f6:eb:3d:7d:46:be:
71:c6:04:4a:64:54:b7:d1:83:6d:ef:88:99:3d:94:ec:56:6a:
fe:3b:70:93:7d:35:24:4b:f7:a9:24:bb:d9:5f:51:62:fe:54:
ac:a9:ba:38:3b:87:f3:9c:4a:a4:02:3e:8b:3f:c0:c5:bf:d2:
da:64:72:7c:04:7c:5a:c3:53:3c:93:9b:fb:45:11:65:9c:ee:
c3:d2:d9:c1:2a:b2:67:c9:d6:f6:e4:f1:2b:b7:02:ea:5d:b4:
de:10:19:d7:77:21:a1:4f:91:a8:3b:2c:58:9e:97:c9:2d:d0:
f2:a8:ea:ec:11:81:6f:76:25:96:bf:98:46:58:0b:4e:5a:c7:
4b:d3:98:04:45:8c:53:c5:bc:c2:7d:74:e6:15:d4:99:c0:5e:
1a:56:11:95:df:a5:c7:5e:8a:97:bd:22:68:5f:52:c2:29:c6:
33:79:f6:03:92:2c:6d:b9:0e:40:bd:58:d1:61:3b:fe:8d:89:
3b:84:aa:05:02:ed:3d:ed:d7:1a:6c:2e:4e:fc:b5:15:2b:78:
7a:8c:c3:9b:eb:02:d6:90:fc:3f:7e:9c:63:7c:6c:db:99:27:
12:a5:d2:bb
-----BEGIN CERTIFICATE-----
MIIDpjCCAo6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCQ04x
CzAJBgNVBAgMAlNIMQswCQYDVQQHDAJTSDEUMBIGA1UECgwLRGFvY2xvdWQuaW8x
CzAJBgNVBAsMAklUMRQwEgYDVQQDDAtleGFtcGxlLmNvbTEmMCQGCSqGSIb3DQEJ
ARYXbG9uZ3hpYS5jYW9AZGFvY2xvdWQuaW8wHhcNMTcwMzI4MTQwMzEzWhcNMzgw
MzA4MTQwMzEzWjB5MQswCQYDVQQGEwJDTjELMAkGA1UECAwCU0gxFDASBgNVBAoM
C2V4YW1wbGUuY29tMQswCQYDVQQLDAJJVDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUu
Y29tMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAL4M+9RpM5NNxCL0vDRIw8QorsdlCFNmLs79
NU6Ps9sa9BtTN0BeJP+w2I2ywdJkXkD87Q4cqF40PD7Sv6VqPC3xtRDGjbweEFlU
OxTPLsQpk6gG9nNvGj2o2bE3+VJhlwWI2tHiIh0n7bftHIyy0jz2q6sVkr5aoOJz
Wt7JjyymHT5+Lm0Lrr/YqfVxAuLoVHUuK7R99EfhrY1t1bbpqvgormLUeG9c0hBg
tbwx4UqrYzqKzOsCt4KD4V3fWQ8GmqO5iZNNdDPpAndNlVQ09pRNZ/OfKYpqJbjE
G8AvEspAW1vWhKfciG8dUOO7YZ3XcDZprKMyUfQ6AMa/PQ7evmkCAwEAAaMpMCcw
JQYDVR0RBB4wHIINKi5leGFtcGxlLmNvbYILZXhhbXBsZS5jb20wDQYJKoZIhvcN
AQELBQADggEBAIoMgry6YyhmhhmFUqn5KMyh77EDxGTOETOwqDwoF/brPX1GvnHG
BEpkVLfRg23viJk9lOxWav47cJN9NSRL96kku9lfUWL+VKypujg7h/OcSqQCPos/
wMW/0tpkcnwEfFrDUzyTm/tFEWWc7sPS2cEqsmfJ1vbk8Su3AupdtN4QGdd3IaFP
kag7LFiel8kt0PKo6uwRgW92JZa/mEZYC05ax0vTmARFjFPFvMJ9dOYV1JnAXhpW
EZXfpcdeipe9ImhfUsIpxjN59gOSLG25DkC9WNFhO/6NiTuEqgUC7T3t1xpsLk78
tRUreHqMw5vrAtaQ/D9+nGN8bNuZJxKl0rs=
MIIDPDCCAiQCCQDj8tij1T669zANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJD
TjELMAkGA1UECAwCU0gxCzAJBgNVBAcMAlNIMRQwEgYDVQQKDAtleGFtcGxlLmNv
bTELMAkGA1UECwwCSVQxFDASBgNVBAMMC2V4YW1wbGUuY29tMB4XDTE3MDQyNzE1
NTg1OVoXDTI3MDQyNTE1NTg1OVowYDELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNI
MQswCQYDVQQHDAJTSDEUMBIGA1UECgwLZXhhbXBsZS5jb20xCzAJBgNVBAsMAklU
MRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAL4M+9RpM5NNxCL0vDRIw8QorsdlCFNmLs79NU6Ps9sa9BtTN0BeJP+w
2I2ywdJkXkD87Q4cqF40PD7Sv6VqPC3xtRDGjbweEFlUOxTPLsQpk6gG9nNvGj2o
2bE3+VJhlwWI2tHiIh0n7bftHIyy0jz2q6sVkr5aoOJzWt7JjyymHT5+Lm0Lrr/Y
qfVxAuLoVHUuK7R99EfhrY1t1bbpqvgormLUeG9c0hBgtbwx4UqrYzqKzOsCt4KD
4V3fWQ8GmqO5iZNNdDPpAndNlVQ09pRNZ/OfKYpqJbjEG8AvEspAW1vWhKfciG8d
UOO7YZ3XcDZprKMyUfQ6AMa/PQ7evmkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
HGeFemG+kLkmNj6T3goWZQ/CQvhlhslo9SPi/TdHQaWQmk3kY7CxO6gx+toyAR3N
PTefGkAao7jH6yMw3jFke5MwB1hwV8x0fFE0ZTonq1+JiPmrfvJcW4wvaFSnOGT+
VO9SXDGuoSW1Qaigt5zhZ3lKfXMiIYtvVahP+6jETvLOxMIFmcfniiMHkDr7KKUl
Jy83KoJ2ake9XwWwKyfuviPqSbHd+4mp6HkiJRFWQLygozSUXr0crfnV7EfipuG4
Nez7G+NcVQOAVbmdOFLg12U/HVOIObJicPEfjSpqXBzpgfEpws4fjSNS7hPVoUFf
8DrI0nNy9Ayx2moyee/YGw==
-----END CERTIFICATE-----
18 changes: 18 additions & 0 deletions log/sentry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package log

import (
"errors"
"fmt"
"runtime/debug"

"github.com/getsentry/raven-go"
)

func CapturePanic() {
if rval := recover(); rval != nil {
debug.PrintStack()
rvalStr := fmt.Sprint(rval)
packet := raven.NewPacket(rvalStr, raven.NewException(errors.New(rvalStr), raven.NewStacktrace(2, 3, nil)))
raven.Capture(packet, nil)
}
}
7 changes: 4 additions & 3 deletions msg/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ type Public struct {
}

type Local struct {
Schema string
Host string
Port uint16
Schema string
Host string
Port uint16
InsecureSkipVerify bool
}

type Tunnel struct {
Expand Down
Loading

0 comments on commit aa0a146

Please sign in to comment.