update handler options
This commit is contained in:
parent
566e930010
commit
c428b37a36
@ -7,7 +7,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
"github.com/go-gost/gost/pkg/bypass"
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/config"
|
"github.com/go-gost/gost/pkg/config"
|
||||||
@ -71,7 +70,7 @@ func buildService(cfg *config.Config) (services []*service.Service) {
|
|||||||
})
|
})
|
||||||
ln := registry.GetListener(svc.Listener.Type)(
|
ln := registry.GetListener(svc.Listener.Type)(
|
||||||
listener.AddrOption(svc.Addr),
|
listener.AddrOption(svc.Addr),
|
||||||
listener.AuthenticatorOption(authFromConfig(svc.Listener.Auths...)),
|
listener.AuthsOption(authsFromConfig(svc.Listener.Auths...)...),
|
||||||
listener.LoggerOption(listenerLogger),
|
listener.LoggerOption(listenerLogger),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -91,15 +90,13 @@ func buildService(cfg *config.Config) (services []*service.Service) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
h := registry.GetHandler(svc.Handler.Type)(
|
h := registry.GetHandler(svc.Handler.Type)(
|
||||||
handler.LoggerOption(handlerLogger),
|
handler.RetriesOption(svc.Handler.Retries),
|
||||||
|
handler.ChainOption(chains[svc.Handler.Chain]),
|
||||||
|
handler.ResolverOption(resolvers[svc.Handler.Resolver]),
|
||||||
|
handler.HostsOption(hosts[svc.Handler.Hosts]),
|
||||||
handler.BypassOption(bypasses[svc.Handler.Bypass]),
|
handler.BypassOption(bypasses[svc.Handler.Bypass]),
|
||||||
handler.AuthenticatorOption(authFromConfig(svc.Handler.Auths...)),
|
handler.AuthsOption(authsFromConfig(svc.Handler.Auths...)...),
|
||||||
handler.RouterOption(&chain.Router{
|
handler.LoggerOption(handlerLogger),
|
||||||
Chain: chains[svc.Handler.Chain],
|
|
||||||
Resolver: resolvers[svc.Handler.Resolver],
|
|
||||||
Hosts: hosts[svc.Handler.Hosts],
|
|
||||||
Logger: handlerLogger,
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if forwarder, ok := h.(handler.Forwarder); ok {
|
if forwarder, ok := h.(handler.Forwarder); ok {
|
||||||
@ -331,17 +328,15 @@ func hostsFromConfig(cfg *config.HostsConfig) hostspkg.HostMapper {
|
|||||||
return hosts
|
return hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
func authFromConfig(cfgs ...config.AuthConfig) auth.Authenticator {
|
func authsFromConfig(cfgs ...config.AuthConfig) []*url.Userinfo {
|
||||||
auths := make(map[string]string)
|
var auths []*url.Userinfo
|
||||||
|
|
||||||
for _, cfg := range cfgs {
|
for _, cfg := range cfgs {
|
||||||
if cfg.Username == "" {
|
if cfg.Username == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
auths[cfg.Username] = cfg.Password
|
auths = append(auths, url.UserPassword(cfg.Username, cfg.Password))
|
||||||
}
|
|
||||||
if len(auths) > 0 {
|
|
||||||
return auth.NewMapAuthenticator(auths)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return auths
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,7 @@ type MapAuthenticator struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewMapAuthenticator creates an Authenticator that authenticates client by local infos.
|
// NewMapAuthenticator creates an Authenticator that authenticates client by local infos.
|
||||||
func NewMapAuthenticator(kvs map[string]string) *MapAuthenticator {
|
func NewMapAuthenticator(kvs map[string]string) Authenticator {
|
||||||
if kvs == nil {
|
|
||||||
kvs = make(map[string]string)
|
|
||||||
}
|
|
||||||
return &MapAuthenticator{
|
return &MapAuthenticator{
|
||||||
kvs: kvs,
|
kvs: kvs,
|
||||||
}
|
}
|
||||||
@ -22,11 +19,7 @@ func NewMapAuthenticator(kvs map[string]string) *MapAuthenticator {
|
|||||||
|
|
||||||
// Authenticate checks the validity of the provided user-password pair.
|
// Authenticate checks the validity of the provided user-password pair.
|
||||||
func (au *MapAuthenticator) Authenticate(user, password string) bool {
|
func (au *MapAuthenticator) Authenticate(user, password string) bool {
|
||||||
if au == nil {
|
if au == nil || len(au.kvs) == 0 {
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(au.kvs) == 0 {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
pkg/common/util/auth/auth.go
Normal file
24
pkg/common/util/auth/auth.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/go-gost/gost/pkg/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AuthFromUsers(users ...*url.Userinfo) auth.Authenticator {
|
||||||
|
kvs := make(map[string]string)
|
||||||
|
for _, v := range users {
|
||||||
|
if v == nil || v.Username() == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
kvs[v.Username()], _ = v.Password()
|
||||||
|
}
|
||||||
|
|
||||||
|
var authenticator auth.Authenticator
|
||||||
|
if len(kvs) > 0 {
|
||||||
|
authenticator = auth.NewMapAuthenticator(kvs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticator
|
||||||
|
}
|
@ -88,6 +88,7 @@ type ListenerConfig struct {
|
|||||||
|
|
||||||
type HandlerConfig struct {
|
type HandlerConfig struct {
|
||||||
Type string
|
Type string
|
||||||
|
Retries int `yaml:",omitempty"`
|
||||||
Chain string `yaml:",omitempty"`
|
Chain string `yaml:",omitempty"`
|
||||||
Bypass string `yaml:",omitempty"`
|
Bypass string `yaml:",omitempty"`
|
||||||
Resolver string `yaml:",omitempty"`
|
Resolver string `yaml:",omitempty"`
|
||||||
|
@ -15,7 +15,6 @@ type metadata struct {
|
|||||||
func (c *httpConnector) parseMetadata(md mdata.Metadata) (err error) {
|
func (c *httpConnector) parseMetadata(md mdata.Metadata) (err error) {
|
||||||
const (
|
const (
|
||||||
connectTimeout = "timeout"
|
connectTimeout = "timeout"
|
||||||
user = "user"
|
|
||||||
header = "header"
|
header = "header"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gosocks5"
|
"github.com/go-gost/gosocks5"
|
||||||
@ -24,20 +23,19 @@ func init() {
|
|||||||
|
|
||||||
type socks5Connector struct {
|
type socks5Connector struct {
|
||||||
selector gosocks5.Selector
|
selector gosocks5.Selector
|
||||||
user *url.Userinfo
|
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options connector.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConnector(opts ...connector.Option) connector.Connector {
|
func NewConnector(opts ...connector.Option) connector.Connector {
|
||||||
options := &connector.Options{}
|
options := connector.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &socks5Connector{
|
return &socks5Connector{
|
||||||
user: options.User,
|
options: options,
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,13 +44,15 @@ func (c *socks5Connector) Init(md md.Metadata) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.logger = c.options.Logger
|
||||||
|
|
||||||
selector := &clientSelector{
|
selector := &clientSelector{
|
||||||
methods: []uint8{
|
methods: []uint8{
|
||||||
gosocks5.MethodNoAuth,
|
gosocks5.MethodNoAuth,
|
||||||
gosocks5.MethodUserPass,
|
gosocks5.MethodUserPass,
|
||||||
},
|
},
|
||||||
logger: c.logger,
|
logger: c.logger,
|
||||||
User: c.user,
|
User: c.options.User,
|
||||||
TLSConfig: c.md.tlsConfig,
|
TLSConfig: c.md.tlsConfig,
|
||||||
}
|
}
|
||||||
if !c.md.noTLS {
|
if !c.md.noTLS {
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gosocks5"
|
"github.com/go-gost/gosocks5"
|
||||||
@ -22,20 +21,20 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ssConnector struct {
|
type ssConnector struct {
|
||||||
user *url.Userinfo
|
|
||||||
cipher core.Cipher
|
cipher core.Cipher
|
||||||
md metadata
|
md metadata
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
|
options connector.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConnector(opts ...connector.Option) connector.Connector {
|
func NewConnector(opts ...connector.Option) connector.Connector {
|
||||||
options := &connector.Options{}
|
options := connector.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ssConnector{
|
return &ssConnector{
|
||||||
user: options.User,
|
options: options,
|
||||||
logger: options.Logger,
|
logger: options.Logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,9 +44,9 @@ func (c *ssConnector) Init(md md.Metadata) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.user != nil {
|
if c.options.User != nil {
|
||||||
method := c.user.Username()
|
method := c.options.User.Username()
|
||||||
password, _ := c.user.Password()
|
password, _ := c.options.User.Password()
|
||||||
c.cipher, err = ss.ShadowCipher(method, password, c.md.key)
|
c.cipher, err = ss.ShadowCipher(method, password, c.md.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/common/util/socks"
|
"github.com/go-gost/gost/pkg/common/util/socks"
|
||||||
@ -21,20 +20,20 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ssuConnector struct {
|
type ssuConnector struct {
|
||||||
user *url.Userinfo
|
|
||||||
cipher core.Cipher
|
cipher core.Cipher
|
||||||
md metadata
|
md metadata
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
|
options connector.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConnector(opts ...connector.Option) connector.Connector {
|
func NewConnector(opts ...connector.Option) connector.Connector {
|
||||||
options := &connector.Options{}
|
options := connector.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ssuConnector{
|
return &ssuConnector{
|
||||||
user: options.User,
|
options: options,
|
||||||
logger: options.Logger,
|
logger: options.Logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,9 +43,9 @@ func (c *ssuConnector) Init(md md.Metadata) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.user != nil {
|
if c.options.User != nil {
|
||||||
method := c.user.Username()
|
method := c.options.User.Username()
|
||||||
password, _ := c.user.Password()
|
password, _ := c.options.User.Password()
|
||||||
c.cipher, err = ss.ShadowCipher(method, password, c.md.key)
|
c.cipher, err = ss.ShadowCipher(method, password, c.md.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/common/bufpool"
|
"github.com/go-gost/gost/pkg/common/bufpool"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
@ -30,27 +29,22 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type dnsHandler struct {
|
type dnsHandler struct {
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
|
||||||
exchangers []exchanger.Exchanger
|
exchangers []exchanger.Exchanger
|
||||||
cache *resolver_util.Cache
|
cache *resolver_util.Cache
|
||||||
|
router *chain.Router
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
cache := resolver_util.NewCache().WithLogger(options.Logger)
|
|
||||||
|
|
||||||
return &dnsHandler{
|
return &dnsHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
cache: cache,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +53,16 @@ func (h *dnsHandler) Init(md md.Metadata) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.cache = resolver_util.NewCache().WithLogger(h.options.Logger)
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
for _, server := range h.md.servers {
|
for _, server := range h.md.servers {
|
||||||
server = strings.TrimSpace(server)
|
server = strings.TrimSpace(server)
|
||||||
if server == "" {
|
if server == "" {
|
||||||
@ -89,6 +93,7 @@ func (h *dnsHandler) Init(md md.Metadata) (err error) {
|
|||||||
}
|
}
|
||||||
h.exchangers = append(h.exchangers, ex)
|
h.exchangers = append(h.exchangers, ex)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
@ -22,22 +21,20 @@ func init() {
|
|||||||
|
|
||||||
type forwardHandler struct {
|
type forwardHandler struct {
|
||||||
group *chain.NodeGroup
|
group *chain.NodeGroup
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &forwardHandler{
|
return &forwardHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +48,16 @@ func (h *forwardHandler) Init(md md.Metadata) (err error) {
|
|||||||
h.group = chain.NewNodeGroup(chain.NewNode("dummy", ":0"))
|
h.group = chain.NewNodeGroup(chain.NewNode("dummy", ":0"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward implements handler.Forwarder.
|
// Forward implements handler.Forwarder.
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
@ -21,26 +20,20 @@ func init() {
|
|||||||
|
|
||||||
type forwardHandler struct {
|
type forwardHandler struct {
|
||||||
group *chain.NodeGroup
|
group *chain.NodeGroup
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &forwardHandler{
|
return &forwardHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: &chain.Router{
|
|
||||||
Retries: options.Router.Retries,
|
|
||||||
Resolver: options.Resolver,
|
|
||||||
Logger: options.Logger,
|
|
||||||
},
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +41,16 @@ func (h *forwardHandler) Init(md md.Metadata) (err error) {
|
|||||||
if err = h.parseMetadata(md); err != nil {
|
if err = h.parseMetadata(md); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
|
auth_util "github.com/go-gost/gost/pkg/common/util/auth"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
ssh_util "github.com/go-gost/gost/pkg/internal/util/ssh"
|
ssh_util "github.com/go-gost/gost/pkg/internal/util/ssh"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
@ -32,24 +31,21 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type forwardHandler struct {
|
type forwardHandler struct {
|
||||||
bypass bypass.Bypass
|
|
||||||
config *ssh.ServerConfig
|
config *ssh.ServerConfig
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
authenticator auth.Authenticator
|
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &forwardHandler{
|
return &forwardHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,18 +54,28 @@ func (h *forwardHandler) Init(md md.Metadata) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
authenticator := auth_util.AuthFromUsers(h.options.Auths...)
|
||||||
|
|
||||||
config := &ssh.ServerConfig{
|
config := &ssh.ServerConfig{
|
||||||
PasswordCallback: ssh_util.PasswordCallback(h.authenticator),
|
PasswordCallback: ssh_util.PasswordCallback(authenticator),
|
||||||
PublicKeyCallback: ssh_util.PublicKeyCallback(h.md.authorizedKeys),
|
PublicKeyCallback: ssh_util.PublicKeyCallback(h.md.authorizedKeys),
|
||||||
}
|
}
|
||||||
|
|
||||||
config.AddHostKey(h.md.signer)
|
config.AddHostKey(h.md.signer)
|
||||||
|
|
||||||
if h.authenticator == nil && len(h.md.authorizedKeys) == 0 {
|
if authenticator == nil && len(h.md.authorizedKeys) == 0 {
|
||||||
config.NoClientAuth = true
|
config.NoClientAuth = true
|
||||||
}
|
}
|
||||||
|
|
||||||
h.config = config
|
h.config = config
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -161,7 +167,7 @@ func (h *forwardHandler) directPortForwardChannel(ctx context.Context, channel s
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(raddr) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(raddr) {
|
||||||
h.logger.Infof("bypass %s", raddr)
|
h.logger.Infof("bypass %s", raddr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ import (
|
|||||||
|
|
||||||
"github.com/asaskevich/govalidator"
|
"github.com/asaskevich/govalidator"
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
"github.com/go-gost/gost/pkg/auth"
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
|
auth_util "github.com/go-gost/gost/pkg/common/util/auth"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
md "github.com/go-gost/gost/pkg/metadata"
|
md "github.com/go-gost/gost/pkg/metadata"
|
||||||
@ -30,23 +30,21 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type httpHandler struct {
|
type httpHandler struct {
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
authenticator auth.Authenticator
|
authenticator auth.Authenticator
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &httpHandler{
|
return &httpHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +53,16 @@ func (h *httpHandler) Init(md md.Metadata) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.authenticator = auth_util.AuthFromUsers(h.options.Auths...)
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +149,7 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
|
|||||||
resp.Header = http.Header{}
|
resp.Header = http.Header{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(addr) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(addr) {
|
||||||
resp.StatusCode = http.StatusForbidden
|
resp.StatusCode = http.StatusForbidden
|
||||||
|
|
||||||
if h.logger.IsLevelEnabled(logger.DebugLevel) {
|
if h.logger.IsLevelEnabled(logger.DebugLevel) {
|
||||||
|
@ -64,7 +64,7 @@ func (h *httpHandler) handleUDP(ctx context.Context, conn net.Conn, network, add
|
|||||||
}
|
}
|
||||||
|
|
||||||
relay := handler.NewUDPRelay(socks.UDPTunServerConn(conn), pc).
|
relay := handler.NewUDPRelay(socks.UDPTunServerConn(conn), pc).
|
||||||
WithBypass(h.bypass).
|
WithBypass(h.options.Bypass).
|
||||||
WithLogger(h.logger)
|
WithLogger(h.logger)
|
||||||
|
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
|
@ -14,10 +14,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/asaskevich/govalidator"
|
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
"github.com/go-gost/gost/pkg/auth"
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
|
auth_util "github.com/go-gost/gost/pkg/common/util/auth"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
http2_util "github.com/go-gost/gost/pkg/internal/util/http2"
|
http2_util "github.com/go-gost/gost/pkg/internal/util/http2"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
@ -30,23 +29,21 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type http2Handler struct {
|
type http2Handler struct {
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
authenticator auth.Authenticator
|
authenticator auth.Authenticator
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &http2Handler{
|
return &http2Handler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +52,15 @@ func (h *http2Handler) Init(md md.Metadata) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.authenticator = auth_util.AuthFromUsers(h.options.Auths...)
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +139,7 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(addr) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(addr) {
|
||||||
w.WriteHeader(http.StatusForbidden)
|
w.WriteHeader(http.StatusForbidden)
|
||||||
h.logger.Info("bypass: ", addr)
|
h.logger.Info("bypass: ", addr)
|
||||||
return
|
return
|
||||||
@ -203,156 +209,6 @@ func (h *http2Handler) roundTrip(ctx context.Context, w http.ResponseWriter, req
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *http2Handler) handleRequest(ctx context.Context, conn net.Conn, req *http.Request) {
|
|
||||||
if req == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if h.md.sni && !req.URL.IsAbs() && govalidator.IsDNSName(req.Host) {
|
|
||||||
req.URL.Scheme = "http"
|
|
||||||
}
|
|
||||||
|
|
||||||
network := req.Header.Get("X-Gost-Protocol")
|
|
||||||
if network != "udp" {
|
|
||||||
network = "tcp"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to get the actual host.
|
|
||||||
// Compatible with GOST 2.x.
|
|
||||||
if v := req.Header.Get("Gost-Target"); v != "" {
|
|
||||||
if h, err := h.decodeServerName(v); err == nil {
|
|
||||||
req.Host = h
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.Header.Del("Gost-Target")
|
|
||||||
|
|
||||||
if v := req.Header.Get("X-Gost-Target"); v != "" {
|
|
||||||
if h, err := h.decodeServerName(v); err == nil {
|
|
||||||
req.Host = h
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.Header.Del("X-Gost-Target")
|
|
||||||
|
|
||||||
addr := req.Host
|
|
||||||
if _, port, _ := net.SplitHostPort(addr); port == "" {
|
|
||||||
addr = net.JoinHostPort(addr, "80")
|
|
||||||
}
|
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"dst": addr,
|
|
||||||
}
|
|
||||||
if u, _, _ := h.basicProxyAuth(req.Header.Get("Proxy-Authorization")); u != "" {
|
|
||||||
fields["user"] = u
|
|
||||||
}
|
|
||||||
h.logger = h.logger.WithFields(fields)
|
|
||||||
|
|
||||||
if h.logger.IsLevelEnabled(logger.DebugLevel) {
|
|
||||||
dump, _ := httputil.DumpRequest(req, false)
|
|
||||||
h.logger.Debug(string(dump))
|
|
||||||
}
|
|
||||||
h.logger.Infof("%s >> %s", conn.RemoteAddr(), addr)
|
|
||||||
|
|
||||||
resp := &http.Response{
|
|
||||||
ProtoMajor: 1,
|
|
||||||
ProtoMinor: 1,
|
|
||||||
Header: http.Header{},
|
|
||||||
}
|
|
||||||
|
|
||||||
if h.md.proxyAgent != "" {
|
|
||||||
resp.Header.Add("Proxy-Agent", h.md.proxyAgent)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if !Can("tcp", host, h.options.Whitelist, h.options.Blacklist) {
|
|
||||||
log.Logf("[http] %s - %s : Unauthorized to tcp connect to %s",
|
|
||||||
conn.RemoteAddr(), conn.LocalAddr(), host)
|
|
||||||
resp.StatusCode = http.StatusForbidden
|
|
||||||
|
|
||||||
if Debug {
|
|
||||||
dump, _ := httputil.DumpResponse(resp, false)
|
|
||||||
log.Logf("[http] %s <- %s\n%s", conn.RemoteAddr(), conn.LocalAddr(), string(dump))
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Write(conn)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(addr) {
|
|
||||||
resp.StatusCode = http.StatusForbidden
|
|
||||||
|
|
||||||
if h.logger.IsLevelEnabled(logger.DebugLevel) {
|
|
||||||
dump, _ := httputil.DumpResponse(resp, false)
|
|
||||||
h.logger.Debug(string(dump))
|
|
||||||
}
|
|
||||||
h.logger.Info("bypass: ", addr)
|
|
||||||
|
|
||||||
resp.Write(conn)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !h.authenticate(conn, req, resp) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Method == "PRI" ||
|
|
||||||
(req.Method != http.MethodConnect && req.URL.Scheme != "http") {
|
|
||||||
resp.StatusCode = http.StatusBadRequest
|
|
||||||
resp.Write(conn)
|
|
||||||
|
|
||||||
if h.logger.IsLevelEnabled(logger.DebugLevel) {
|
|
||||||
dump, _ := httputil.DumpResponse(resp, false)
|
|
||||||
h.logger.Debug(string(dump))
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Del("Proxy-Authorization")
|
|
||||||
|
|
||||||
cc, err := h.router.Dial(ctx, network, addr)
|
|
||||||
if err != nil {
|
|
||||||
resp.StatusCode = http.StatusServiceUnavailable
|
|
||||||
resp.Write(conn)
|
|
||||||
|
|
||||||
if h.logger.IsLevelEnabled(logger.DebugLevel) {
|
|
||||||
dump, _ := httputil.DumpResponse(resp, false)
|
|
||||||
h.logger.Debug(string(dump))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer cc.Close()
|
|
||||||
|
|
||||||
if req.Method == http.MethodConnect {
|
|
||||||
resp.StatusCode = http.StatusOK
|
|
||||||
resp.Status = "200 Connection established"
|
|
||||||
|
|
||||||
if h.logger.IsLevelEnabled(logger.DebugLevel) {
|
|
||||||
dump, _ := httputil.DumpResponse(resp, false)
|
|
||||||
h.logger.Debug(string(dump))
|
|
||||||
}
|
|
||||||
if err = resp.Write(conn); err != nil {
|
|
||||||
h.logger.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
req.Header.Del("Proxy-Connection")
|
|
||||||
if err = req.Write(cc); err != nil {
|
|
||||||
h.logger.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
start := time.Now()
|
|
||||||
h.logger.Infof("%s <-> %s", conn.RemoteAddr(), addr)
|
|
||||||
handler.Transport(conn, cc)
|
|
||||||
h.logger.
|
|
||||||
WithFields(map[string]interface{}{
|
|
||||||
"duration": time.Since(start),
|
|
||||||
}).
|
|
||||||
Infof("%s >-< %s", conn.RemoteAddr(), addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *http2Handler) decodeServerName(s string) (string, error) {
|
func (h *http2Handler) decodeServerName(s string) (string, error) {
|
||||||
b, err := base64.RawURLEncoding.DecodeString(s)
|
b, err := base64.RawURLEncoding.DecodeString(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,26 +1,48 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
"net/url"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
"github.com/go-gost/gost/pkg/bypass"
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
|
"github.com/go-gost/gost/pkg/hosts"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
"github.com/go-gost/gost/pkg/resolver"
|
"github.com/go-gost/gost/pkg/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Router *chain.Router
|
Retries int
|
||||||
Bypass bypass.Bypass
|
Chain *chain.Chain
|
||||||
Resolver resolver.Resolver
|
Resolver resolver.Resolver
|
||||||
Authenticator auth.Authenticator
|
Hosts hosts.HostMapper
|
||||||
|
Bypass bypass.Bypass
|
||||||
|
Auths []*url.Userinfo
|
||||||
Logger logger.Logger
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(opts *Options)
|
type Option func(opts *Options)
|
||||||
|
|
||||||
func RouterOption(router *chain.Router) Option {
|
func RetriesOption(retries int) Option {
|
||||||
return func(opts *Options) {
|
return func(opts *Options) {
|
||||||
opts.Router = router
|
opts.Retries = retries
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChainOption(chain *chain.Chain) Option {
|
||||||
|
return func(opts *Options) {
|
||||||
|
opts.Chain = chain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResolverOption(resolver resolver.Resolver) Option {
|
||||||
|
return func(opts *Options) {
|
||||||
|
opts.Resolver = resolver
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HostsOption(hosts hosts.HostMapper) Option {
|
||||||
|
return func(opts *Options) {
|
||||||
|
opts.Hosts = hosts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,9 +52,9 @@ func BypassOption(bypass bypass.Bypass) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AuthenticatorOption(auth auth.Authenticator) Option {
|
func AuthsOption(auths ...*url.Userinfo) Option {
|
||||||
return func(opts *Options) {
|
return func(opts *Options) {
|
||||||
opts.Authenticator = auth
|
opts.Auths = auths
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
@ -22,27 +21,38 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type redirectHandler struct {
|
type redirectHandler struct {
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &redirectHandler{
|
return &redirectHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *redirectHandler) Init(md md.Metadata) (err error) {
|
func (h *redirectHandler) Init(md md.Metadata) (err error) {
|
||||||
return h.parseMetadata(md)
|
if err = h.parseMetadata(md); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn) {
|
func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn) {
|
||||||
@ -84,7 +94,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn) {
|
|||||||
|
|
||||||
h.logger.Infof("%s >> %s", conn.RemoteAddr(), dstAddr)
|
h.logger.Infof("%s >> %s", conn.RemoteAddr(), dstAddr)
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(dstAddr.String()) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(dstAddr.String()) {
|
||||||
h.logger.Info("bypass: ", dstAddr)
|
h.logger.Info("bypass: ", dstAddr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ func (h *relayHandler) tunnelServerUDP(tunnel, c net.PacketConn) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(raddr.String()) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(raddr.String()) {
|
||||||
h.logger.Warn("bypass: ", raddr)
|
h.logger.Warn("bypass: ", raddr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ func (h *relayHandler) tunnelServerUDP(tunnel, c net.PacketConn) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(raddr.String()) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(raddr.String()) {
|
||||||
h.logger.Warn("bypass: ", raddr)
|
h.logger.Warn("bypass: ", raddr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(address) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(address) {
|
||||||
h.logger.Info("bypass: ", address)
|
h.logger.Info("bypass: ", address)
|
||||||
resp.Status = relay.StatusForbidden
|
resp.Status = relay.StatusForbidden
|
||||||
resp.WriteTo(conn)
|
resp.WriteTo(conn)
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
"github.com/go-gost/gost/pkg/auth"
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
|
auth_util "github.com/go-gost/gost/pkg/common/util/auth"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
md "github.com/go-gost/gost/pkg/metadata"
|
md "github.com/go-gost/gost/pkg/metadata"
|
||||||
@ -22,23 +22,21 @@ func init() {
|
|||||||
|
|
||||||
type relayHandler struct {
|
type relayHandler struct {
|
||||||
group *chain.NodeGroup
|
group *chain.NodeGroup
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
authenticator auth.Authenticator
|
authenticator auth.Authenticator
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &relayHandler{
|
return &relayHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +45,15 @@ func (h *relayHandler) Init(md md.Metadata) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.authenticator = auth_util.AuthFromUsers(h.options.Auths...)
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/common/bufpool"
|
"github.com/go-gost/gost/pkg/common/bufpool"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
@ -27,16 +26,16 @@ func init() {
|
|||||||
|
|
||||||
type sniHandler struct {
|
type sniHandler struct {
|
||||||
httpHandler handler.Handler
|
httpHandler handler.Handler
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
log := options.Logger
|
log := options.Logger
|
||||||
@ -45,8 +44,7 @@ func NewHandler(opts ...handler.Option) handler.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h := &sniHandler{
|
h := &sniHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: log,
|
logger: log,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +70,14 @@ func (h *sniHandler) Init(md md.Metadata) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +138,7 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn) {
|
|||||||
})
|
})
|
||||||
h.logger.Infof("%s >> %s", conn.RemoteAddr(), target)
|
h.logger.Infof("%s >> %s", conn.RemoteAddr(), target)
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(target) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(target) {
|
||||||
h.logger.Info("bypass: ", target)
|
h.logger.Info("bypass: ", target)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
|
|
||||||
"github.com/go-gost/gosocks4"
|
"github.com/go-gost/gosocks4"
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
"github.com/go-gost/gost/pkg/auth"
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
|
auth_util "github.com/go-gost/gost/pkg/common/util/auth"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
md "github.com/go-gost/gost/pkg/metadata"
|
md "github.com/go-gost/gost/pkg/metadata"
|
||||||
@ -21,23 +21,21 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type socks4Handler struct {
|
type socks4Handler struct {
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
authenticator auth.Authenticator
|
authenticator auth.Authenticator
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &socks4Handler{
|
return &socks4Handler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +44,16 @@ func (h *socks4Handler) Init(md md.Metadata) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.authenticator = auth_util.AuthFromUsers(h.options.Auths...)
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +113,7 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g
|
|||||||
})
|
})
|
||||||
h.logger.Infof("%s >> %s", conn.RemoteAddr(), addr)
|
h.logger.Infof("%s >> %s", conn.RemoteAddr(), addr)
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(addr) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(addr) {
|
||||||
resp := gosocks4.NewReply(gosocks4.Rejected, nil)
|
resp := gosocks4.NewReply(gosocks4.Rejected, nil)
|
||||||
resp.Write(conn)
|
resp.Write(conn)
|
||||||
h.logger.Debug(resp)
|
h.logger.Debug(resp)
|
||||||
|
@ -17,7 +17,7 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ
|
|||||||
})
|
})
|
||||||
h.logger.Infof("%s >> %s", conn.RemoteAddr(), address)
|
h.logger.Infof("%s >> %s", conn.RemoteAddr(), address)
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(address) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(address) {
|
||||||
resp := gosocks5.NewReply(gosocks5.NotAllowed, nil)
|
resp := gosocks5.NewReply(gosocks5.NotAllowed, nil)
|
||||||
resp.Write(conn)
|
resp.Write(conn)
|
||||||
h.logger.Debug(resp)
|
h.logger.Debug(resp)
|
||||||
|
@ -6,9 +6,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gosocks5"
|
"github.com/go-gost/gosocks5"
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
|
auth_util "github.com/go-gost/gost/pkg/common/util/auth"
|
||||||
"github.com/go-gost/gost/pkg/common/util/socks"
|
"github.com/go-gost/gost/pkg/common/util/socks"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
@ -23,23 +22,20 @@ func init() {
|
|||||||
|
|
||||||
type socks5Handler struct {
|
type socks5Handler struct {
|
||||||
selector gosocks5.Selector
|
selector gosocks5.Selector
|
||||||
bypass bypass.Bypass
|
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
authenticator auth.Authenticator
|
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &socks5Handler{
|
return &socks5Handler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,8 +44,17 @@ func (h *socks5Handler) Init(md md.Metadata) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
|
||||||
h.selector = &serverSelector{
|
h.selector = &serverSelector{
|
||||||
Authenticator: h.authenticator,
|
Authenticator: auth_util.AuthFromUsers(h.options.Auths...),
|
||||||
TLSConfig: h.md.tlsConfig,
|
TLSConfig: h.md.tlsConfig,
|
||||||
logger: h.logger,
|
logger: h.logger,
|
||||||
noTLS: h.md.noTLS,
|
noTLS: h.md.noTLS,
|
||||||
|
@ -67,7 +67,7 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
relay := handler.NewUDPRelay(socks.UDPConn(cc, h.md.udpBufferSize), pc).
|
relay := handler.NewUDPRelay(socks.UDPConn(cc, h.md.udpBufferSize), pc).
|
||||||
WithBypass(h.bypass).
|
WithBypass(h.options.Bypass).
|
||||||
WithLogger(h.logger)
|
WithLogger(h.logger)
|
||||||
relay.SetBufferSize(h.md.udpBufferSize)
|
relay.SetBufferSize(h.md.udpBufferSize)
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network
|
|||||||
}
|
}
|
||||||
|
|
||||||
relay := handler.NewUDPRelay(socks.UDPTunServerConn(conn), pc).
|
relay := handler.NewUDPRelay(socks.UDPTunServerConn(conn), pc).
|
||||||
WithBypass(h.bypass).
|
WithBypass(h.options.Bypass).
|
||||||
WithLogger(h.logger)
|
WithLogger(h.logger)
|
||||||
relay.SetBufferSize(h.md.udpBufferSize)
|
relay.SetBufferSize(h.md.udpBufferSize)
|
||||||
|
|
||||||
|
@ -8,13 +8,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gosocks5"
|
"github.com/go-gost/gosocks5"
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/common/util/ss"
|
"github.com/go-gost/gost/pkg/common/util/ss"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
md "github.com/go-gost/gost/pkg/metadata"
|
md "github.com/go-gost/gost/pkg/metadata"
|
||||||
"github.com/go-gost/gost/pkg/registry"
|
"github.com/go-gost/gost/pkg/registry"
|
||||||
|
"github.com/shadowsocks/go-shadowsocks2/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -22,31 +22,47 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ssHandler struct {
|
type ssHandler struct {
|
||||||
bypass bypass.Bypass
|
cipher core.Cipher
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ssHandler{
|
return &ssHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ssHandler) Init(md md.Metadata) (err error) {
|
func (h *ssHandler) Init(md md.Metadata) (err error) {
|
||||||
if err := h.parseMetadata(md); err != nil {
|
if err = h.parseMetadata(md); err != nil {
|
||||||
return err
|
return
|
||||||
|
}
|
||||||
|
if len(h.options.Auths) > 0 {
|
||||||
|
method := h.options.Auths[0].Username()
|
||||||
|
password, _ := h.options.Auths[0].Password()
|
||||||
|
h.cipher, err = ss.ShadowCipher(method, password, h.md.key)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ssHandler) Handle(ctx context.Context, conn net.Conn) {
|
func (h *ssHandler) Handle(ctx context.Context, conn net.Conn) {
|
||||||
@ -65,8 +81,8 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn) {
|
|||||||
}).Infof("%s >< %s", conn.RemoteAddr(), conn.LocalAddr())
|
}).Infof("%s >< %s", conn.RemoteAddr(), conn.LocalAddr())
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if h.md.cipher != nil {
|
if h.cipher != nil {
|
||||||
conn = ss.ShadowConn(h.md.cipher.StreamConn(conn), nil)
|
conn = ss.ShadowConn(h.cipher.StreamConn(conn), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.md.readTimeout > 0 {
|
if h.md.readTimeout > 0 {
|
||||||
@ -86,7 +102,7 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn) {
|
|||||||
|
|
||||||
h.logger.Infof("%s >> %s", conn.RemoteAddr(), addr)
|
h.logger.Infof("%s >> %s", conn.RemoteAddr(), addr)
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(addr.String()) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(addr.String()) {
|
||||||
h.logger.Info("bypass: ", addr.String())
|
h.logger.Info("bypass: ", addr.String())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,23 @@
|
|||||||
package ss
|
package ss
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/common/util/ss"
|
|
||||||
mdata "github.com/go-gost/gost/pkg/metadata"
|
mdata "github.com/go-gost/gost/pkg/metadata"
|
||||||
"github.com/shadowsocks/go-shadowsocks2/core"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type metadata struct {
|
type metadata struct {
|
||||||
cipher core.Cipher
|
key string
|
||||||
readTimeout time.Duration
|
readTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ssHandler) parseMetadata(md mdata.Metadata) (err error) {
|
func (h *ssHandler) parseMetadata(md mdata.Metadata) (err error) {
|
||||||
const (
|
const (
|
||||||
users = "users"
|
|
||||||
key = "key"
|
key = "key"
|
||||||
readTimeout = "readTimeout"
|
readTimeout = "readTimeout"
|
||||||
)
|
)
|
||||||
|
|
||||||
var method, password string
|
h.md.key = mdata.GetString(md, key)
|
||||||
if auths := mdata.GetStrings(md, users); len(auths) > 0 {
|
|
||||||
auth := auths[0]
|
|
||||||
ss := strings.SplitN(auth, ":", 2)
|
|
||||||
if len(ss) == 1 {
|
|
||||||
method = ss[0]
|
|
||||||
} else {
|
|
||||||
method, password = ss[0], ss[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h.md.cipher, err = ss.ShadowCipher(method, password, mdata.GetString(md, key))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
h.md.readTimeout = mdata.GetDuration(md, readTimeout)
|
h.md.readTimeout = mdata.GetDuration(md, readTimeout)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/common/bufpool"
|
"github.com/go-gost/gost/pkg/common/bufpool"
|
||||||
"github.com/go-gost/gost/pkg/common/util/socks"
|
"github.com/go-gost/gost/pkg/common/util/socks"
|
||||||
@ -14,6 +13,7 @@ import (
|
|||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
md "github.com/go-gost/gost/pkg/metadata"
|
md "github.com/go-gost/gost/pkg/metadata"
|
||||||
"github.com/go-gost/gost/pkg/registry"
|
"github.com/go-gost/gost/pkg/registry"
|
||||||
|
"github.com/shadowsocks/go-shadowsocks2/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -21,31 +21,48 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ssuHandler struct {
|
type ssuHandler struct {
|
||||||
bypass bypass.Bypass
|
cipher core.Cipher
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ssuHandler{
|
return &ssuHandler{
|
||||||
bypass: options.Bypass,
|
options: options,
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ssuHandler) Init(md md.Metadata) (err error) {
|
func (h *ssuHandler) Init(md md.Metadata) (err error) {
|
||||||
if err := h.parseMetadata(md); err != nil {
|
if err = h.parseMetadata(md); err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if len(h.options.Auths) > 0 {
|
||||||
|
method := h.options.Auths[0].Username()
|
||||||
|
password, _ := h.options.Auths[0].Password()
|
||||||
|
h.cipher, err = ss.ShadowCipher(method, password, h.md.key)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ssuHandler) Handle(ctx context.Context, conn net.Conn) {
|
func (h *ssuHandler) Handle(ctx context.Context, conn net.Conn) {
|
||||||
@ -66,14 +83,14 @@ func (h *ssuHandler) Handle(ctx context.Context, conn net.Conn) {
|
|||||||
|
|
||||||
pc, ok := conn.(net.PacketConn)
|
pc, ok := conn.(net.PacketConn)
|
||||||
if ok {
|
if ok {
|
||||||
if h.md.cipher != nil {
|
if h.cipher != nil {
|
||||||
pc = h.md.cipher.PacketConn(pc)
|
pc = h.cipher.PacketConn(pc)
|
||||||
}
|
}
|
||||||
// standard UDP relay.
|
// standard UDP relay.
|
||||||
pc = ss.UDPServerConn(pc, conn.RemoteAddr(), h.md.bufferSize)
|
pc = ss.UDPServerConn(pc, conn.RemoteAddr(), h.md.bufferSize)
|
||||||
} else {
|
} else {
|
||||||
if h.md.cipher != nil {
|
if h.cipher != nil {
|
||||||
conn = ss.ShadowConn(h.md.cipher.StreamConn(conn), nil)
|
conn = ss.ShadowConn(h.cipher.StreamConn(conn), nil)
|
||||||
}
|
}
|
||||||
// UDP over TCP
|
// UDP over TCP
|
||||||
pc = socks.UDPTunServerConn(conn)
|
pc = socks.UDPTunServerConn(conn)
|
||||||
@ -116,7 +133,7 @@ func (h *ssuHandler) relayPacket(pc1, pc2 net.PacketConn) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(addr.String()) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(addr.String()) {
|
||||||
h.logger.Warn("bypass: ", addr)
|
h.logger.Warn("bypass: ", addr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -148,7 +165,7 @@ func (h *ssuHandler) relayPacket(pc1, pc2 net.PacketConn) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.bypass != nil && h.bypass.Contains(raddr.String()) {
|
if h.options.Bypass != nil && h.options.Bypass.Contains(raddr.String()) {
|
||||||
h.logger.Warn("bypass: ", raddr)
|
h.logger.Warn("bypass: ", raddr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2,43 +2,25 @@ package ss
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/common/util/ss"
|
|
||||||
mdata "github.com/go-gost/gost/pkg/metadata"
|
mdata "github.com/go-gost/gost/pkg/metadata"
|
||||||
"github.com/shadowsocks/go-shadowsocks2/core"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type metadata struct {
|
type metadata struct {
|
||||||
cipher core.Cipher
|
key string
|
||||||
readTimeout time.Duration
|
readTimeout time.Duration
|
||||||
bufferSize int
|
bufferSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ssuHandler) parseMetadata(md mdata.Metadata) (err error) {
|
func (h *ssuHandler) parseMetadata(md mdata.Metadata) (err error) {
|
||||||
const (
|
const (
|
||||||
users = "users"
|
|
||||||
key = "key"
|
key = "key"
|
||||||
readTimeout = "readTimeout"
|
readTimeout = "readTimeout"
|
||||||
bufferSize = "bufferSize"
|
bufferSize = "bufferSize"
|
||||||
)
|
)
|
||||||
|
|
||||||
var method, password string
|
h.md.key = mdata.GetString(md, key)
|
||||||
if auths := mdata.GetStrings(md, users); len(auths) > 0 {
|
|
||||||
auth := auths[0]
|
|
||||||
ss := strings.SplitN(auth, ":", 2)
|
|
||||||
if len(ss) == 1 {
|
|
||||||
method = ss[0]
|
|
||||||
} else {
|
|
||||||
method, password = ss[0], ss[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h.md.cipher, err = ss.ShadowCipher(method, password, mdata.GetString(md, key))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
h.md.readTimeout = mdata.GetDuration(md, readTimeout)
|
h.md.readTimeout = mdata.GetDuration(md, readTimeout)
|
||||||
|
|
||||||
if bs := mdata.GetInt(md, bufferSize); bs > 0 {
|
if bs := mdata.GetInt(md, bufferSize); bs > 0 {
|
||||||
|
@ -10,14 +10,15 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/common/bufpool"
|
"github.com/go-gost/gost/pkg/common/bufpool"
|
||||||
|
"github.com/go-gost/gost/pkg/common/util/ss"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
tap_util "github.com/go-gost/gost/pkg/internal/util/tap"
|
tap_util "github.com/go-gost/gost/pkg/internal/util/tap"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
md "github.com/go-gost/gost/pkg/metadata"
|
md "github.com/go-gost/gost/pkg/metadata"
|
||||||
"github.com/go-gost/gost/pkg/registry"
|
"github.com/go-gost/gost/pkg/registry"
|
||||||
|
"github.com/shadowsocks/go-shadowsocks2/core"
|
||||||
"github.com/shadowsocks/go-shadowsocks2/shadowaead"
|
"github.com/shadowsocks/go-shadowsocks2/shadowaead"
|
||||||
"github.com/songgao/water/waterutil"
|
"github.com/songgao/water/waterutil"
|
||||||
)
|
)
|
||||||
@ -28,34 +29,51 @@ func init() {
|
|||||||
|
|
||||||
type tapHandler struct {
|
type tapHandler struct {
|
||||||
group *chain.NodeGroup
|
group *chain.NodeGroup
|
||||||
bypass bypass.Bypass
|
|
||||||
routes sync.Map
|
routes sync.Map
|
||||||
exit chan struct{}
|
exit chan struct{}
|
||||||
|
cipher core.Cipher
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tapHandler{
|
return &tapHandler{
|
||||||
bypass: options.Bypass,
|
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
exit: make(chan struct{}, 1),
|
exit: make(chan struct{}, 1),
|
||||||
|
options: options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *tapHandler) Init(md md.Metadata) (err error) {
|
func (h *tapHandler) Init(md md.Metadata) (err error) {
|
||||||
if err := h.parseMetadata(md); err != nil {
|
if err = h.parseMetadata(md); err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if len(h.options.Auths) > 0 {
|
||||||
|
method := h.options.Auths[0].Username()
|
||||||
|
password, _ := h.options.Auths[0].Password()
|
||||||
|
h.cipher, err = ss.ShadowCipher(method, password, h.md.key)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward implements handler.Forwarder.
|
// Forward implements handler.Forwarder.
|
||||||
@ -132,8 +150,8 @@ func (h *tapHandler) handleLoop(ctx context.Context, conn net.Conn, addr net.Add
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.md.cipher != nil {
|
if h.cipher != nil {
|
||||||
pc = h.md.cipher.PacketConn(pc)
|
pc = h.cipher.PacketConn(pc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.transport(conn, pc, addr)
|
return h.transport(conn, pc, addr)
|
||||||
|
@ -1,42 +1,21 @@
|
|||||||
package tap
|
package tap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/common/util/ss"
|
|
||||||
mdata "github.com/go-gost/gost/pkg/metadata"
|
mdata "github.com/go-gost/gost/pkg/metadata"
|
||||||
"github.com/shadowsocks/go-shadowsocks2/core"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type metadata struct {
|
type metadata struct {
|
||||||
cipher core.Cipher
|
key string
|
||||||
retryCount int
|
|
||||||
bufferSize int
|
bufferSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *tapHandler) parseMetadata(md mdata.Metadata) (err error) {
|
func (h *tapHandler) parseMetadata(md mdata.Metadata) (err error) {
|
||||||
const (
|
const (
|
||||||
users = "users"
|
|
||||||
key = "key"
|
key = "key"
|
||||||
readTimeout = "readTimeout"
|
|
||||||
bufferSize = "bufferSize"
|
bufferSize = "bufferSize"
|
||||||
)
|
)
|
||||||
|
|
||||||
var method, password string
|
h.md.key = mdata.GetString(md, key)
|
||||||
if auths := mdata.GetStrings(md, users); len(auths) > 0 {
|
|
||||||
auth := auths[0]
|
|
||||||
ss := strings.SplitN(auth, ":", 2)
|
|
||||||
if len(ss) == 1 {
|
|
||||||
method = ss[0]
|
|
||||||
} else {
|
|
||||||
method, password = ss[0], ss[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h.md.cipher, err = ss.ShadowCipher(method, password, mdata.GetString(md, key))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
h.md.bufferSize = mdata.GetInt(md, bufferSize)
|
h.md.bufferSize = mdata.GetInt(md, bufferSize)
|
||||||
if h.md.bufferSize <= 0 {
|
if h.md.bufferSize <= 0 {
|
||||||
h.md.bufferSize = 1024
|
h.md.bufferSize = 1024
|
||||||
|
@ -10,14 +10,15 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/bypass"
|
|
||||||
"github.com/go-gost/gost/pkg/chain"
|
"github.com/go-gost/gost/pkg/chain"
|
||||||
"github.com/go-gost/gost/pkg/common/bufpool"
|
"github.com/go-gost/gost/pkg/common/bufpool"
|
||||||
|
"github.com/go-gost/gost/pkg/common/util/ss"
|
||||||
"github.com/go-gost/gost/pkg/handler"
|
"github.com/go-gost/gost/pkg/handler"
|
||||||
tun_util "github.com/go-gost/gost/pkg/internal/util/tun"
|
tun_util "github.com/go-gost/gost/pkg/internal/util/tun"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
md "github.com/go-gost/gost/pkg/metadata"
|
md "github.com/go-gost/gost/pkg/metadata"
|
||||||
"github.com/go-gost/gost/pkg/registry"
|
"github.com/go-gost/gost/pkg/registry"
|
||||||
|
"github.com/shadowsocks/go-shadowsocks2/core"
|
||||||
"github.com/shadowsocks/go-shadowsocks2/shadowaead"
|
"github.com/shadowsocks/go-shadowsocks2/shadowaead"
|
||||||
"github.com/songgao/water/waterutil"
|
"github.com/songgao/water/waterutil"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
@ -30,34 +31,51 @@ func init() {
|
|||||||
|
|
||||||
type tunHandler struct {
|
type tunHandler struct {
|
||||||
group *chain.NodeGroup
|
group *chain.NodeGroup
|
||||||
bypass bypass.Bypass
|
|
||||||
routes sync.Map
|
routes sync.Map
|
||||||
exit chan struct{}
|
exit chan struct{}
|
||||||
|
cipher core.Cipher
|
||||||
router *chain.Router
|
router *chain.Router
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options handler.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := &handler.Options{}
|
options := handler.Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(options)
|
opt(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tunHandler{
|
return &tunHandler{
|
||||||
bypass: options.Bypass,
|
|
||||||
router: options.Router,
|
|
||||||
logger: options.Logger,
|
|
||||||
exit: make(chan struct{}, 1),
|
exit: make(chan struct{}, 1),
|
||||||
|
options: options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *tunHandler) Init(md md.Metadata) (err error) {
|
func (h *tunHandler) Init(md md.Metadata) (err error) {
|
||||||
if err := h.parseMetadata(md); err != nil {
|
if err = h.parseMetadata(md); err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if len(h.options.Auths) > 0 {
|
||||||
|
method := h.options.Auths[0].Username()
|
||||||
|
password, _ := h.options.Auths[0].Password()
|
||||||
|
h.cipher, err = ss.ShadowCipher(method, password, h.md.key)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h.router = &chain.Router{
|
||||||
|
Retries: h.options.Retries,
|
||||||
|
Chain: h.options.Chain,
|
||||||
|
Resolver: h.options.Resolver,
|
||||||
|
Hosts: h.options.Hosts,
|
||||||
|
Logger: h.options.Logger,
|
||||||
|
}
|
||||||
|
h.logger = h.options.Logger
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward implements handler.Forwarder.
|
// Forward implements handler.Forwarder.
|
||||||
@ -133,8 +151,8 @@ func (h *tunHandler) handleLoop(ctx context.Context, conn net.Conn, addr net.Add
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.md.cipher != nil {
|
if h.cipher != nil {
|
||||||
pc = h.md.cipher.PacketConn(pc)
|
pc = h.cipher.PacketConn(pc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.transport(conn, pc, addr)
|
return h.transport(conn, pc, addr)
|
||||||
|
@ -1,41 +1,21 @@
|
|||||||
package tun
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/common/util/ss"
|
|
||||||
mdata "github.com/go-gost/gost/pkg/metadata"
|
mdata "github.com/go-gost/gost/pkg/metadata"
|
||||||
"github.com/shadowsocks/go-shadowsocks2/core"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type metadata struct {
|
type metadata struct {
|
||||||
cipher core.Cipher
|
key string
|
||||||
bufferSize int
|
bufferSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *tunHandler) parseMetadata(md mdata.Metadata) (err error) {
|
func (h *tunHandler) parseMetadata(md mdata.Metadata) (err error) {
|
||||||
const (
|
const (
|
||||||
users = "users"
|
|
||||||
key = "key"
|
key = "key"
|
||||||
readTimeout = "readTimeout"
|
|
||||||
bufferSize = "bufferSize"
|
bufferSize = "bufferSize"
|
||||||
)
|
)
|
||||||
|
|
||||||
var method, password string
|
h.md.key = mdata.GetString(md, key)
|
||||||
if auths := mdata.GetStrings(md, users); len(auths) > 0 {
|
|
||||||
auth := auths[0]
|
|
||||||
ss := strings.SplitN(auth, ":", 2)
|
|
||||||
if len(ss) == 1 {
|
|
||||||
method = ss[0]
|
|
||||||
} else {
|
|
||||||
method, password = ss[0], ss[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h.md.cipher, err = ss.ShadowCipher(method, password, mdata.GetString(md, key))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
h.md.bufferSize = mdata.GetInt(md, bufferSize)
|
h.md.bufferSize = mdata.GetInt(md, bufferSize)
|
||||||
if h.md.bufferSize <= 0 {
|
if h.md.bufferSize <= 0 {
|
||||||
h.md.bufferSize = 1024
|
h.md.bufferSize = 1024
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package listener
|
package listener
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
"net/url"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Addr string
|
Addr string
|
||||||
Authenticator auth.Authenticator
|
Auths []*url.Userinfo
|
||||||
Logger logger.Logger
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,9 +20,9 @@ func AddrOption(addr string) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AuthenticatorOption(auth auth.Authenticator) Option {
|
func AuthsOption(auths ...*url.Userinfo) Option {
|
||||||
return func(opts *Options) {
|
return func(opts *Options) {
|
||||||
opts.Authenticator = auth
|
opts.Auths = auths
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/go-gost/gost/pkg/auth"
|
auth_util "github.com/go-gost/gost/pkg/common/util/auth"
|
||||||
ssh_util "github.com/go-gost/gost/pkg/internal/util/ssh"
|
ssh_util "github.com/go-gost/gost/pkg/internal/util/ssh"
|
||||||
"github.com/go-gost/gost/pkg/listener"
|
"github.com/go-gost/gost/pkg/listener"
|
||||||
"github.com/go-gost/gost/pkg/logger"
|
"github.com/go-gost/gost/pkg/logger"
|
||||||
@ -21,11 +21,11 @@ type sshListener struct {
|
|||||||
addr string
|
addr string
|
||||||
net.Listener
|
net.Listener
|
||||||
config *ssh.ServerConfig
|
config *ssh.ServerConfig
|
||||||
authenticator auth.Authenticator
|
|
||||||
cqueue chan net.Conn
|
cqueue chan net.Conn
|
||||||
errChan chan error
|
errChan chan error
|
||||||
logger logger.Logger
|
logger logger.Logger
|
||||||
md metadata
|
md metadata
|
||||||
|
options listener.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewListener(opts ...listener.Option) listener.Listener {
|
func NewListener(opts ...listener.Option) listener.Listener {
|
||||||
@ -51,14 +51,13 @@ func (l *sshListener) Init(md md.Metadata) (err error) {
|
|||||||
|
|
||||||
l.Listener = ln
|
l.Listener = ln
|
||||||
|
|
||||||
|
authenticator := auth_util.AuthFromUsers(l.options.Auths...)
|
||||||
config := &ssh.ServerConfig{
|
config := &ssh.ServerConfig{
|
||||||
PasswordCallback: ssh_util.PasswordCallback(l.authenticator),
|
PasswordCallback: ssh_util.PasswordCallback(authenticator),
|
||||||
PublicKeyCallback: ssh_util.PublicKeyCallback(l.md.authorizedKeys),
|
PublicKeyCallback: ssh_util.PublicKeyCallback(l.md.authorizedKeys),
|
||||||
}
|
}
|
||||||
|
|
||||||
config.AddHostKey(l.md.signer)
|
config.AddHostKey(l.md.signer)
|
||||||
|
if authenticator == nil && len(l.md.authorizedKeys) == 0 {
|
||||||
if l.authenticator == nil && len(l.md.authorizedKeys) == 0 {
|
|
||||||
config.NoClientAuth = true
|
config.NoClientAuth = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user