mirror of https://github.com/fatedier/frp
Kevin Crawley
4 years ago
committed by
GitHub
3 changed files with 151 additions and 1 deletions
@ -0,0 +1,138 @@ |
|||||||
|
// Copyright 2019 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package plugin |
||||||
|
|
||||||
|
import ( |
||||||
|
"crypto/tls" |
||||||
|
"fmt" |
||||||
|
"io" |
||||||
|
"net" |
||||||
|
"net/http" |
||||||
|
"net/http/httputil" |
||||||
|
"strings" |
||||||
|
|
||||||
|
frpNet "github.com/fatedier/frp/pkg/util/net" |
||||||
|
) |
||||||
|
|
||||||
|
const PluginHTTPS2HTTPS = "https2https" |
||||||
|
|
||||||
|
func init() { |
||||||
|
Register(PluginHTTPS2HTTPS, NewHTTPS2HTTPSPlugin) |
||||||
|
} |
||||||
|
|
||||||
|
type HTTPS2HTTPSPlugin struct { |
||||||
|
crtPath string |
||||||
|
keyPath string |
||||||
|
hostHeaderRewrite string |
||||||
|
localAddr string |
||||||
|
headers map[string]string |
||||||
|
|
||||||
|
l *Listener |
||||||
|
s *http.Server |
||||||
|
} |
||||||
|
|
||||||
|
func NewHTTPS2HTTPSPlugin(params map[string]string) (Plugin, error) { |
||||||
|
crtPath := params["plugin_crt_path"] |
||||||
|
keyPath := params["plugin_key_path"] |
||||||
|
localAddr := params["plugin_local_addr"] |
||||||
|
hostHeaderRewrite := params["plugin_host_header_rewrite"] |
||||||
|
headers := make(map[string]string) |
||||||
|
for k, v := range params { |
||||||
|
if !strings.HasPrefix(k, "plugin_header_") { |
||||||
|
continue |
||||||
|
} |
||||||
|
if k = strings.TrimPrefix(k, "plugin_header_"); k != "" { |
||||||
|
headers[k] = v |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if crtPath == "" { |
||||||
|
return nil, fmt.Errorf("plugin_crt_path is required") |
||||||
|
} |
||||||
|
if keyPath == "" { |
||||||
|
return nil, fmt.Errorf("plugin_key_path is required") |
||||||
|
} |
||||||
|
if localAddr == "" { |
||||||
|
return nil, fmt.Errorf("plugin_local_addr is required") |
||||||
|
} |
||||||
|
|
||||||
|
listener := NewProxyListener() |
||||||
|
|
||||||
|
p := &HTTPS2HTTPSPlugin{ |
||||||
|
crtPath: crtPath, |
||||||
|
keyPath: keyPath, |
||||||
|
localAddr: localAddr, |
||||||
|
hostHeaderRewrite: hostHeaderRewrite, |
||||||
|
headers: headers, |
||||||
|
l: listener, |
||||||
|
} |
||||||
|
|
||||||
|
tr := &http.Transport{ |
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, |
||||||
|
} |
||||||
|
|
||||||
|
rp := &httputil.ReverseProxy{ |
||||||
|
Director: func(req *http.Request) { |
||||||
|
req.URL.Scheme = "https" |
||||||
|
req.URL.Host = p.localAddr |
||||||
|
if p.hostHeaderRewrite != "" { |
||||||
|
req.Host = p.hostHeaderRewrite |
||||||
|
} |
||||||
|
for k, v := range p.headers { |
||||||
|
req.Header.Set(k, v) |
||||||
|
} |
||||||
|
}, |
||||||
|
Transport: tr, |
||||||
|
} |
||||||
|
|
||||||
|
p.s = &http.Server{ |
||||||
|
Handler: rp, |
||||||
|
} |
||||||
|
|
||||||
|
tlsConfig, err := p.genTLSConfig() |
||||||
|
if err != nil { |
||||||
|
return nil, fmt.Errorf("gen TLS config error: %v", err) |
||||||
|
} |
||||||
|
ln := tls.NewListener(listener, tlsConfig) |
||||||
|
|
||||||
|
go p.s.Serve(ln) |
||||||
|
return p, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (p *HTTPS2HTTPSPlugin) genTLSConfig() (*tls.Config, error) { |
||||||
|
cert, err := tls.LoadX509KeyPair(p.crtPath, p.keyPath) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
config := &tls.Config{Certificates: []tls.Certificate{cert}} |
||||||
|
return config, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (p *HTTPS2HTTPSPlugin) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) { |
||||||
|
wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn) |
||||||
|
p.l.PutConn(wrapConn) |
||||||
|
} |
||||||
|
|
||||||
|
func (p *HTTPS2HTTPSPlugin) Name() string { |
||||||
|
return PluginHTTPS2HTTP |
||||||
|
} |
||||||
|
|
||||||
|
func (p *HTTPS2HTTPSPlugin) Close() error { |
||||||
|
if err := p.s.Close(); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
Loading…
Reference in new issue