mirror of
https://github.com/jpillora/chisel
synced 2026-06-08 15:07:02 +00:00
server: add reverse port forwarding restrictions
Although reverse port forwarding (sharing client ports with the server) should not generally leak any resources from the server to the client, the facility may nevertheless be abused if the client is able to open a server port which is otherwise meant for some other purpose on the server. (This might happen, for instance, if a service on the server has crashed or becomes somehow disabled, thus freeing the port which would otherwise be occupied by the service.) To mitigate such potential abuse, disable reverse port forwarding by default and introduce server option --reverse to enable it explicitly. Additionally, subject reverse port forwarding remotes to server-side --authfile restrictions (for instance, "^R:0.0.0.0:7000$").
This commit is contained in:
@@ -104,7 +104,9 @@ $ chisel server --help
|
||||
when <user> connects, their <pass> will be verified and then
|
||||
each of the remote addresses will be compared against the list
|
||||
of address regular expressions for a match. Addresses will
|
||||
always come in the form "<host/ip>:<port>".
|
||||
always come in the form "<remote-host>:<remote-port>" for normal remotes
|
||||
and "R:<local-interface>:<local-port>" for reverse port forwarding
|
||||
remotes. This file will be automatically reloaded on change.
|
||||
|
||||
--auth, An optional string representing a single user with full
|
||||
access, in the form of <user:pass>. This is equivalent to creating an
|
||||
@@ -117,6 +119,9 @@ $ chisel server --help
|
||||
--socks5, Allows client to access the internal SOCKS5 proxy. See
|
||||
chisel client --help for more information.
|
||||
|
||||
--reverse, Allows client to specify reverse port forwarding remotes
|
||||
in addition to normal remotes.
|
||||
|
||||
--pid Generate pid file in current directory
|
||||
|
||||
-v, Enable verbose logging
|
||||
|
||||
+3
-2
@@ -7,6 +7,7 @@
|
||||
],
|
||||
"ping:pong": [
|
||||
"^0.0.0.0:[45]000$",
|
||||
"^example.com:80$"
|
||||
"^example.com:80$",
|
||||
"^R:0.0.0.0:7000$"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,8 +107,9 @@ var serverHelp = `
|
||||
when <user> connects, their <pass> will be verified and then
|
||||
each of the remote addresses will be compared against the list
|
||||
of address regular expressions for a match. Addresses will
|
||||
always come in the form "<host/ip>:<port>". This file will be
|
||||
automatically reloaded on change.
|
||||
always come in the form "<remote-host>:<remote-port>" for normal remotes
|
||||
and "R:<local-interface>:<local-port>" for reverse port forwarding
|
||||
remotes. This file will be automatically reloaded on change.
|
||||
|
||||
--auth, An optional string representing a single user with full
|
||||
access, in the form of <user:pass>. This is equivalent to creating an
|
||||
@@ -120,6 +121,9 @@ var serverHelp = `
|
||||
|
||||
--socks5, Allows client to access the internal SOCKS5 proxy. See
|
||||
chisel client --help for more information.
|
||||
|
||||
--reverse, Allows client to specify reverse port forwarding remotes
|
||||
in addition to normal remotes.
|
||||
` + commonHelp
|
||||
|
||||
func server(args []string) {
|
||||
@@ -134,6 +138,7 @@ func server(args []string) {
|
||||
auth := flags.String("auth", "", "")
|
||||
proxy := flags.String("proxy", "", "")
|
||||
socks5 := flags.Bool("socks5", false, "")
|
||||
reverse := flags.Bool("reverse", false, "")
|
||||
pid := flags.Bool("pid", false, "")
|
||||
verbose := flags.Bool("v", false, "")
|
||||
|
||||
@@ -167,6 +172,7 @@ func server(args []string) {
|
||||
Auth: *auth,
|
||||
Proxy: *proxy,
|
||||
Socks5: *socks5,
|
||||
Reverse: *reverse,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
+11
-2
@@ -95,14 +95,23 @@ func (s *Server) handleWebsocket(w http.ResponseWriter, req *http.Request) {
|
||||
clog.Infof("Client version (%s) differs from server version (%s)",
|
||||
v, chshare.BuildVersion)
|
||||
}
|
||||
for _, r := range c.Remotes {
|
||||
if r.Reverse && !s.reverseOk {
|
||||
clog.Debugf("Denied reverse port forwarding request, please enable --reverse")
|
||||
failed(s.Errorf("Reverse port forwaring not enabled on server"))
|
||||
return
|
||||
}
|
||||
}
|
||||
//if user is provided, ensure they have
|
||||
//access to the desired remotes
|
||||
if user != nil {
|
||||
for _, r := range c.Remotes {
|
||||
var addr string
|
||||
if r.Reverse {
|
||||
continue
|
||||
addr = "R:" + r.LocalHost + ":" + r.LocalPort
|
||||
} else {
|
||||
addr = r.RemoteHost + ":" + r.RemotePort
|
||||
}
|
||||
addr := r.RemoteHost + ":" + r.RemotePort
|
||||
if !user.HasAccess(addr) {
|
||||
failed(s.Errorf("access to '%s' denied", addr))
|
||||
return
|
||||
|
||||
@@ -25,6 +25,7 @@ type Config struct {
|
||||
Auth string
|
||||
Proxy string
|
||||
Socks5 bool
|
||||
Reverse bool
|
||||
}
|
||||
|
||||
// Server respresent a chisel service
|
||||
@@ -39,6 +40,7 @@ type Server struct {
|
||||
socksServer *socks5.Server
|
||||
sshConfig *ssh.ServerConfig
|
||||
users *chshare.UserIndex
|
||||
reverseOk bool
|
||||
}
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
@@ -53,6 +55,7 @@ func NewServer(config *Config) (*Server, error) {
|
||||
httpServer: chshare.NewHTTPServer(),
|
||||
Logger: chshare.NewLogger("server"),
|
||||
sessions: chshare.Users{},
|
||||
reverseOk: config.Reverse,
|
||||
}
|
||||
s.Info = true
|
||||
s.users = chshare.NewUserIndex(s.Logger)
|
||||
|
||||
Reference in New Issue
Block a user