1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-28 14:56:33 -04:00

tls config

This commit is contained in:
v2ray 2016-07-10 15:27:58 +02:00
parent 1e3ebeef59
commit 754e8b6e78
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
7 changed files with 119 additions and 83 deletions

View File

@ -1,42 +1,7 @@
package http package http
import "crypto/tls"
// CertificateConfig is the config for TLS certificates used in HTTP proxy.
type CertificateConfig struct {
Domain string
Certificate tls.Certificate
}
// TlsConfig is the config for TLS connections.
type TLSConfig struct {
Enabled bool
Certs []*CertificateConfig
}
// GetConfig returns corresponding tls.Config.
func (this *TLSConfig) GetConfig() *tls.Config {
if !this.Enabled {
return nil
}
config := &tls.Config{
InsecureSkipVerify: false,
}
config.Certificates = make([]tls.Certificate, len(this.Certs))
for index, cert := range this.Certs {
config.Certificates[index] = cert.Certificate
}
config.BuildNameToCertificate()
return config
}
// Config for HTTP proxy server. // Config for HTTP proxy server.
type Config struct { type Config struct {
TLSConfig *TLSConfig
} }
// ClientConfig for HTTP proxy client. // ClientConfig for HTTP proxy client.

View File

@ -3,62 +3,21 @@
package http package http
import ( import (
"crypto/tls"
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/v2ray/v2ray-core/proxy/internal" "github.com/v2ray/v2ray-core/proxy/internal"
) )
// UnmarshalJSON implements json.Unmarshaler
func (this *CertificateConfig) UnmarshalJSON(data []byte) error {
type JsonConfig struct {
Domain string `json:"domain"`
CertFile string `json:"cert"`
KeyFile string `json:"key"`
}
jsonConfig := new(JsonConfig)
if err := json.Unmarshal(data, jsonConfig); err != nil {
return errors.New("HTTP: Failed to parse certificate config: " + err.Error())
}
cert, err := tls.LoadX509KeyPair(jsonConfig.CertFile, jsonConfig.KeyFile)
if err != nil {
return err
}
this.Domain = jsonConfig.Domain
this.Certificate = cert
return nil
}
// UnmarshalJSON implements json.Unmarshaler
func (this *TLSConfig) UnmarshalJSON(data []byte) error {
type JsonConfig struct {
Enabled bool `json:"enable"`
Certs []*CertificateConfig `json:"certs"`
}
jsonConfig := new(JsonConfig)
if err := json.Unmarshal(data, jsonConfig); err != nil {
return errors.New("HTTP: Failed to parse TLS config: " + err.Error())
}
this.Enabled = jsonConfig.Enabled
this.Certs = jsonConfig.Certs
return nil
}
// UnmarshalJSON implements json.Unmarshaler // UnmarshalJSON implements json.Unmarshaler
func (this *Config) UnmarshalJSON(data []byte) error { func (this *Config) UnmarshalJSON(data []byte) error {
type JsonConfig struct { type JsonConfig struct {
Tls *TLSConfig `json:"tls"`
} }
jsonConfig := new(JsonConfig) jsonConfig := new(JsonConfig)
if err := json.Unmarshal(data, jsonConfig); err != nil { if err := json.Unmarshal(data, jsonConfig); err != nil {
return errors.New("HTTP: Failed to parse config: " + err.Error()) return errors.New("HTTP: Failed to parse config: " + err.Error())
} }
this.TLSConfig = jsonConfig.Tls
return nil return nil
} }

View File

@ -1,6 +1,7 @@
package internet package internet
import ( import (
"crypto/tls"
"net" "net"
) )
@ -13,14 +14,38 @@ type Reusable interface {
type StreamConnectionType int type StreamConnectionType int
var ( const (
StreamConnectionTypeRawTCP StreamConnectionType = 1 StreamConnectionTypeRawTCP StreamConnectionType = 1
StreamConnectionTypeTCP StreamConnectionType = 2 StreamConnectionTypeTCP StreamConnectionType = 2
StreamConnectionTypeKCP StreamConnectionType = 4 StreamConnectionTypeKCP StreamConnectionType = 4
) )
type StreamSecurityType int
const (
StreamSecurityTypeNone StreamSecurityType = 0
StreamSecurityTypeTLS StreamSecurityType = 1
)
type TLSSettings struct {
Certs []tls.Certificate
}
func (this *TLSSettings) GetTLSConfig() *tls.Config {
config := &tls.Config{
InsecureSkipVerify: true,
}
config.Certificates = this.Certs
config.BuildNameToCertificate()
return config
}
type StreamSettings struct { type StreamSettings struct {
Type StreamConnectionType Type StreamConnectionType
Security StreamSecurityType
TLSSettings *TLSSettings
} }
func (this *StreamSettings) IsCapableOf(streamType StreamConnectionType) bool { func (this *StreamSettings) IsCapableOf(streamType StreamConnectionType) bool {

View File

@ -3,14 +3,42 @@
package internet package internet
import ( import (
"crypto/tls"
"encoding/json" "encoding/json"
"errors"
"strings"
v2net "github.com/v2ray/v2ray-core/common/net" v2net "github.com/v2ray/v2ray-core/common/net"
) )
func (this *TLSSettings) UnmarshalJSON(data []byte) error {
type JSONCertConfig struct {
CertFile string `json:"certFile"`
KeyFile string `json:"keyFile"`
}
type JSONConfig struct {
Certs []*JSONCertConfig `json:"certs"`
}
jsonConfig := new(JSONConfig)
if err := json.Unmarshal(data, jsonConfig); err != nil {
return err
}
this.Certs = make([]tls.Certificate, len(jsonConfig.Certs))
for idx, certConf := range jsonConfig.Certs {
cert, err := tls.LoadX509KeyPair(certConf.CertFile, certConf.KeyFile)
if err != nil {
return errors.New("Internet|TLS: Failed to load certificate file: " + err.Error())
}
this.Certs[idx] = cert
}
return nil
}
func (this *StreamSettings) UnmarshalJSON(data []byte) error { func (this *StreamSettings) UnmarshalJSON(data []byte) error {
type JSONConfig struct { type JSONConfig struct {
Network v2net.NetworkList `json:"network"` Network v2net.NetworkList `json:"network"`
Security string `json:"security"`
TLSSettings *TLSSettings `json:"tlsSettings"`
} }
this.Type = StreamConnectionTypeRawTCP this.Type = StreamConnectionTypeRawTCP
jsonConfig := new(JSONConfig) jsonConfig := new(JSONConfig)
@ -23,5 +51,12 @@ func (this *StreamSettings) UnmarshalJSON(data []byte) error {
if jsonConfig.Network.HasNetwork(v2net.TCPNetwork) { if jsonConfig.Network.HasNetwork(v2net.TCPNetwork) {
this.Type |= StreamConnectionTypeTCP this.Type |= StreamConnectionTypeTCP
} }
this.Security = StreamSecurityTypeNone
if strings.ToLower(jsonConfig.Security) == "tls" {
this.Security = StreamSecurityTypeTLS
}
if jsonConfig.TLSSettings != nil {
this.TLSSettings = jsonConfig.TLSSettings
}
return nil return nil
} }

View File

@ -1,11 +1,13 @@
package internet package internet
import ( import (
"crypto/tls"
"errors" "errors"
"net" "net"
"time" "time"
v2net "github.com/v2ray/v2ray-core/common/net" v2net "github.com/v2ray/v2ray-core/common/net"
v2tls "github.com/v2ray/v2ray-core/transport/internet/tls"
) )
var ( var (
@ -22,16 +24,32 @@ var (
) )
func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (Connection, error) { func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (Connection, error) {
var connection Connection
var err error
if dest.IsTCP() { if dest.IsTCP() {
switch { switch {
case settings.IsCapableOf(StreamConnectionTypeTCP): case settings.IsCapableOf(StreamConnectionTypeTCP):
return TCPDialer(src, dest) connection, err = TCPDialer(src, dest)
case settings.IsCapableOf(StreamConnectionTypeKCP): case settings.IsCapableOf(StreamConnectionTypeKCP):
return KCPDialer(src, dest) connection, err = KCPDialer(src, dest)
case settings.IsCapableOf(StreamConnectionTypeRawTCP): case settings.IsCapableOf(StreamConnectionTypeRawTCP):
return RawTCPDialer(src, dest) connection, err = RawTCPDialer(src, dest)
default:
return nil, ErrUnsupportedStreamType
} }
return nil, ErrUnsupportedStreamType if err != nil {
return nil, err
}
if settings.Security == StreamSecurityTypeNone {
return connection, nil
}
config := settings.TLSSettings.GetTLSConfig()
if dest.Address().IsDomain() {
config.ServerName = dest.Address().Domain()
}
tlsConn := tls.Client(connection, config)
return v2tls.NewConnection(tlsConn), nil
} }
return UDPDialer(src, dest) return UDPDialer(src, dest)

View File

@ -1,12 +1,14 @@
package internet package internet
import ( import (
"crypto/tls"
"errors" "errors"
"net" "net"
"sync" "sync"
"github.com/v2ray/v2ray-core/common/log" "github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net" v2net "github.com/v2ray/v2ray-core/common/net"
v2tls "github.com/v2ray/v2ray-core/transport/internet/tls"
) )
var ( var (
@ -29,6 +31,7 @@ type TCPHub struct {
listener Listener listener Listener
connCallback ConnectionHandler connCallback ConnectionHandler
accepting bool accepting bool
tlsConfig *tls.Config
} }
func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandler, settings *StreamSettings) (*TCPHub, error) { func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandler, settings *StreamSettings) (*TCPHub, error) {
@ -51,9 +54,15 @@ func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandle
return nil, err return nil, err
} }
var tlsConfig *tls.Config
if settings.Security == StreamSecurityTypeTLS {
tlsConfig = settings.TLSSettings.GetTLSConfig()
}
hub := &TCPHub{ hub := &TCPHub{
listener: listener, listener: listener,
connCallback: callback, connCallback: callback,
tlsConfig: tlsConfig,
} }
go hub.start() go hub.start()
@ -76,6 +85,10 @@ func (this *TCPHub) start() {
} }
continue continue
} }
if this.tlsConfig != nil {
tlsConn := tls.Server(conn, this.tlsConfig)
conn = v2tls.NewConnection(tlsConn)
}
go this.connCallback(conn) go this.connCallback(conn)
} }
} }

View File

@ -0,0 +1,21 @@
package tls
import (
"crypto/tls"
)
type Connection struct {
*tls.Conn
}
func (this *Connection) Reusable() bool {
return false
}
func (this *Connection) SetReusable(bool) {}
func NewConnection(conn *tls.Conn) *Connection {
return &Connection{
Conn: conn,
}
}