!feat(vless): IP restriction

Beta, only works for vless for now and it's not perfect needs a lot of testing.
This commit is contained in:
Devman 2023-06-30 13:13:36 +00:00
parent 34b68518fd
commit 3d692eb208
9 changed files with 94 additions and 22 deletions

View file

@ -76,7 +76,7 @@ type hasHandshakeAddress interface {
}
// Process implements proxy.Inbound.
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher) error {
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher, _ *map[session.ID]*stat.UserIpRestriction, _ *stat.UserIpRestriction) error {
newError("processing connection from: ", conn.RemoteAddr()).AtDebug().WriteToLog(session.ExportIDToError(ctx))
dest := net.Destination{
Network: network,

View file

@ -10,6 +10,7 @@ import (
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/features/routing"
"github.com/xtls/xray-core/transport"
"github.com/xtls/xray-core/transport/internet"
@ -22,7 +23,7 @@ type Inbound interface {
Network() []net.Network
// Process processes a connection of given network. If necessary, the Inbound can dispatch the connection to an Outbound.
Process(context.Context, net.Network, stat.Connection, routing.Dispatcher) error
Process(context.Context, net.Network, stat.Connection, routing.Dispatcher, *map[session.ID]*stat.UserIpRestriction, *stat.UserIpRestriction) error
}
// An Outbound process outbound connections.

View file

@ -178,7 +178,7 @@ func (*Handler) Network() []net.Network {
}
// Process implements proxy.Inbound.Process().
func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error {
func (h *Handler) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher, usrIpRstrct *map[session.ID]*stat.UserIpRestriction, connIp *stat.UserIpRestriction) error {
sid := session.ExportIDToError(ctx)
iConn := connection
@ -447,6 +447,27 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
// Flow: requestAddons.Flow,
}
if (request.User.IpLimit > 0) {
addr := connection.RemoteAddr().(*net.TCPAddr)
user := account.ID.String()
uniqueIps := make(map[string]bool)
// Iterate through the connections and find unique used IP addresses withing last 30 seconds.
for _, conn := range *usrIpRstrct {
if conn.User == user && !conn.IpAddress.Equal(addr.IP) && ((time.Now().Unix() - conn.Time) < 30) {
uniqueIps[conn.IpAddress.String()] = true
}
}
if (len(uniqueIps) >= int(request.User.IpLimit)) {
return newError("User ", user, " has exceeded their allowed IPs.").AtWarning()
}
connIp.IpAddress = addr.IP
connIp.User = user
connIp.Time = time.Now().Unix()
}
var netConn net.Conn
var rawConn syscall.RawConn
var input *bytes.Reader