{"action":"created","comment":{"url":"https://api.github.com/repos/gravitational/teleport/pulls/comments/222421135","pull_request_review_id":161300503,"id":222421135,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyMjQyMTEzNQ==","diff_hunk":"@@ -577,58 +577,92 @@ func (client *NodeClient) ExecuteSCP(cmd scp.Command) error {\n \treturn trace.Wrap(err)\n }\n \n-// listenAndForward listens on a given socket and forwards all incoming connections\n-// to the given remote address via\n-func (client *NodeClient) listenAndForward(socket net.Listener, remoteAddr string) {\n-\tdefer socket.Close()\n-\tdefer client.Close()\n-\tproxyConnection := func(incoming net.Conn) {\n-\t\tdefer incoming.Close()\n-\t\tvar (\n-\t\t\tconn net.Conn\n-\t\t\terr  error\n-\t\t)\n-\t\tlog.Debugf(\"nodeClient.listenAndForward(%v -> %v) started\", incoming.RemoteAddr(), remoteAddr)\n-\t\tfor attempt := 1; attempt <= 5; attempt++ {\n-\t\t\tconn, err = client.Client.Dial(\"tcp\", remoteAddr)\n-\t\t\tif err != nil {\n-\t\t\t\tlog.Errorf(\"Connection attempt %v: %v\", attempt, err)\n-\t\t\t\t// failed to establish an outbound connection? try again:\n-\t\t\t\ttime.Sleep(time.Millisecond * time.Duration(100*attempt))\n-\t\t\t\tcontinue\n-\t\t\t}\n-\t\t\t// connection established: continue:\n-\t\t\tbreak\n+func (client *NodeClient) proxyConnection(incoming net.Conn, remoteAddr string) {\n+\tdefer incoming.Close()\n+\n+\tvar (\n+\t\tconn net.Conn\n+\t\terr  error\n+\t)\n+\tlog.Debugf(\"nodeClient.proxyConnection(%v -> %v) started\", incoming.RemoteAddr(), remoteAddr)\n+\n+\tfor attempt := 1; attempt <= 5; attempt++ {\n+\t\tconn, err = client.Client.Dial(\"tcp\", remoteAddr)\n+\t\tif err != nil {\n+\t\t\tlog.Errorf(\"Connection attempt %v: %v\", attempt, err)\n+\t\t\t// failed to establish an outbound connection? try again:\n+\t\t\ttime.Sleep(time.Millisecond * time.Duration(100*attempt))\n+\t\t\tcontinue\n \t\t}\n-\t\t// permanent failure establishing connection\n+\t\t// connection established: continue:\n+\t\tbreak\n+\t}\n+\t// permanent failure establishing connection\n+\tif err != nil {\n+\t\tlog.Errorf(\"Failed to connect to node %v\", remoteAddr)\n+\t\treturn\n+\t}\n+\tdefer conn.Close()\n+\t// start proxying:\n+\tdoneC := make(chan interface{}, 2)\n+\tgo func() {\n+\t\tio.Copy(incoming, conn)\n+\t\tdoneC <- true\n+\t}()\n+\tgo func() {\n+\t\tio.Copy(conn, incoming)\n+\t\tdoneC <- true\n+\t}()\n+\t<-doneC\n+\t<-doneC\n+\tlog.Debugf(\"nodeClient.proxyConnection(%v -> %v) exited\", incoming.RemoteAddr(), remoteAddr)\n+}\n+\n+// listenAndForward listens on a given socket and forwards all incoming\n+// commands to the remote address through the SSH tunnel.\n+func (c *NodeClient) listenAndForward(ln net.Listener, remoteAddr string) {\n+\tdefer ln.Close()\n+\tdefer c.Close()\n+\n+\tfor {\n+\t\t// Accept connections from the client.\n+\t\tconn, err := ln.Accept()\n \t\tif err != nil {\n-\t\t\tlog.Errorf(\"Failed to connect to node %v\", remoteAddr)\n-\t\t\treturn\n+\t\t\tlog.Errorf(\"Port forwarding failed: %v.\", err)\n+\t\t\tbreak\n \t\t}\n-\t\tdefer conn.Close()\n-\t\t// start proxying:\n-\t\tdoneC := make(chan interface{}, 2)\n-\t\tgo func() {\n-\t\t\tio.Copy(incoming, conn)\n-\t\t\tdoneC <- true\n-\t\t}()\n-\t\tgo func() {\n-\t\t\tio.Copy(conn, incoming)\n-\t\t\tdoneC <- true\n-\t\t}()\n-\t\t<-doneC\n-\t\t<-doneC\n-\t\tlog.Debugf(\"nodeClient.listenAndForward(%v -> %v) exited\", incoming.RemoteAddr(), remoteAddr)\n-\t}\n-\t// request processing loop: accept incoming requests to be connected to nodes\n-\t// and proxy them to 'remoteAddr'\n+\n+\t\t// Proxy the connection to the remote address.\n+\t\tgo c.proxyConnection(conn, remoteAddr)\n+\t}\n+}\n+\n+// dynamicListenAndForward listens for connections, performs a SOCKS5\n+// handshake, and then proxies the connection to the requested address.\n+func (c *NodeClient) dynamicListenAndForward(ln net.Listener) {\n+\tdefer ln.Close()\n+\tdefer c.Close()\n+\n \tfor {\n-\t\tincoming, err := socket.Accept()\n+\t\t// Accept connection from the client. Here the client is typically\n+\t\t// something like a web browser or other SOCKS5 aware application.\n+\t\tconn, err := ln.Accept()\n \t\tif err != nil {\n-\t\t\tlog.Error(err)\n+\t\t\tlog.Errorf(\"Dynamic port forwarding (SOCKS5) failed: %v.\", err)\n \t\t\tbreak\n \t\t}\n-\t\tgo proxyConnection(incoming)\n+\n+\t\t// Perform the SOCKS5 handshake with the client to find out the remote\n+\t\t// address to proxy.\n+\t\tremoteAddr, err := socks.Handshake(conn)\n+\t\tif err != nil {\n+\t\t\tlog.Errorf(\"SOCKS5 handshake failed: %v.\", err)\n+\t\t\tbreak\n+\t\t}\n+\t\tlog.Debugf(\"SOCKS5 proxy forwarding requests to %v.\", remoteAddr)\n+\n+\t\t// Proxy the connection.\n+\t\tgo c.proxyConnection(conn, remoteAddr)","path":"lib/client/client.go","position":163,"original_position":163,"commit_id":"01c2f4577e11984606f043254a4df128ff6befe4","original_commit_id":"01c2f4577e11984606f043254a4df128ff6befe4","user":{"login":"klizhentas","id":13717,"node_id":"MDQ6VXNlcjEzNzE3","avatar_url":"https://avatars1.githubusercontent.com/u/13717?v=4","gravatar_id":"","url":"https://api.github.com/users/klizhentas","html_url":"https://github.com/klizhentas","followers_url":"https://api.github.com/users/klizhentas/followers","following_url":"https://api.github.com/users/klizhentas/following{/other_user}","gists_url":"https://api.github.com/users/klizhentas/gists{/gist_id}","starred_url":"https://api.github.com/users/klizhentas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/klizhentas/subscriptions","organizations_url":"https://api.github.com/users/klizhentas/orgs","repos_url":"https://api.github.com/users/klizhentas/repos","events_url":"https://api.github.com/users/klizhentas/events{/privacy}","received_events_url":"https://api.github.com/users/klizhentas/received_events","type":"User","site_admin":false},"body":"use context.","created_at":"2018-10-03T18:36:17Z","updated_at":"2018-10-03T18:39:37Z","html_url":"https://github.com/gravitational/teleport/pull/2261#discussion_r222421135","pull_request_url":"https://api.github.com/repos/gravitational/teleport/pulls/2261","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/gravitational/teleport/pulls/comments/222421135"},"html":{"href":"https://github.com/gravitational/teleport/pull/2261#discussion_r222421135"},"pull_request":{"href":"https://api.github.com/repos/gravitational/teleport/pulls/2261"}}},"pull_request":{"url":"https://api.github.com/repos/gravitational/teleport/pulls/2261","id":219480884,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE5NDgwODg0","html_url":"https://github.com/gravitational/teleport/pull/2261","diff_url":"https://github.com/gravitational/teleport/pull/2261.diff","patch_url":"https://github.com/gravitational/teleport/pull/2261.patch","issue_url":"https://api.github.com/repos/gravitational/teleport/issues/2261","number":2261,"state":"open","locked":false,"title":"Dynamic Port Forwarding","user":{"login":"russjones","id":5017502,"node_id":"MDQ6VXNlcjUwMTc1MDI=","avatar_url":"https://avatars0.githubusercontent.com/u/5017502?v=4","gravatar_id":"","url":"https://api.github.com/users/russjones","html_url":"https://github.com/russjones","followers_url":"https://api.github.com/users/russjones/followers","following_url":"https://api.github.com/users/russjones/following{/other_user}","gists_url":"https://api.github.com/users/russjones/gists{/gist_id}","starred_url":"https://api.github.com/users/russjones/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/russjones/subscriptions","organizations_url":"https://api.github.com/users/russjones/orgs","repos_url":"https://api.github.com/users/russjones/repos","events_url":"https://api.github.com/users/russjones/events{/privacy}","received_events_url":"https://api.github.com/users/russjones/received_events","type":"User","site_admin":false},"body":"**Purpose**\r\n\r\nBuild off the work of @steven-aerts in https://github.com/gravitational/teleport/pull/1694 and add support for dynamic port forwarding (SOCKS5).\r\n\r\n**Implementation**\r\n\r\n* Add the `-D` flag to tsh.\r\n* Add support for a SOCKS5 handshake to discover the remote address to proxy.\r\n* Proxy connections using a `direct-tcpip` channel.\r\n\r\n**Related Issues**\r\n\r\nFixes https://github.com/gravitational/teleport/issues/1693\r\nFixes https://github.com/gravitational/teleport/pull/1694","created_at":"2018-10-01T19:01:02Z","updated_at":"2018-10-03T18:39:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3346a7b9292de3cc501718775631257830100c79","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/gravitational/teleport/pulls/2261/commits","review_comments_url":"https://api.github.com/repos/gravitational/teleport/pulls/2261/comments","review_comment_url":"https://api.github.com/repos/gravitational/teleport/pulls/comments{/number}","comments_url":"https://api.github.com/repos/gravitational/teleport/issues/2261/comments","statuses_url":"https://api.github.com/repos/gravitational/teleport/statuses/01c2f4577e11984606f043254a4df128ff6befe4","head":{"label":"gravitational:rjones/socks5","ref":"rjones/socks5","sha":"01c2f4577e11984606f043254a4df128ff6befe4","user":{"login":"gravitational","id":10781132,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNzgxMTMy","avatar_url":"https://avatars2.githubusercontent.com/u/10781132?v=4","gravatar_id":"","url":"https://api.github.com/users/gravitational","html_url":"https://github.com/gravitational","followers_url":"https://api.github.com/users/gravitational/followers","following_url":"https://api.github.com/users/gravitational/following{/other_user}","gists_url":"https://api.github.com/users/gravitational/gists{/gist_id}","starred_url":"https://api.github.com/users/gravitational/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gravitational/subscriptions","organizations_url":"https://api.github.com/users/gravitational/orgs","repos_url":"https://api.github.com/users/gravitational/repos","events_url":"https://api.github.com/users/gravitational/events{/privacy}","received_events_url":"https://api.github.com/users/gravitational/received_events","type":"Organization","site_admin":false},"repo":{"id":31558937,"node_id":"MDEwOlJlcG9zaXRvcnkzMTU1ODkzNw==","name":"teleport","full_name":"gravitational/teleport","private":false,"owner":{"login":"gravitational","id":10781132,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNzgxMTMy","avatar_url":"https://avatars2.githubusercontent.com/u/10781132?v=4","gravatar_id":"","url":"https://api.github.com/users/gravitational","html_url":"https://github.com/gravitational","followers_url":"https://api.github.com/users/gravitational/followers","following_url":"https://api.github.com/users/gravitational/following{/other_user}","gists_url":"https://api.github.com/users/gravitational/gists{/gist_id}","starred_url":"https://api.github.com/users/gravitational/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gravitational/subscriptions","organizations_url":"https://api.github.com/users/gravitational/orgs","repos_url":"https://api.github.com/users/gravitational/repos","events_url":"https://api.github.com/users/gravitational/events{/privacy}","received_events_url":"https://api.github.com/users/gravitational/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/gravitational/teleport","description":"Privileged access management for elastic infrastructure.","fork":false,"url":"https://api.github.com/repos/gravitational/teleport","forks_url":"https://api.github.com/repos/gravitational/teleport/forks","keys_url":"https://api.github.com/repos/gravitational/teleport/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gravitational/teleport/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gravitational/teleport/teams","hooks_url":"https://api.github.com/repos/gravitational/teleport/hooks","issue_events_url":"https://api.github.com/repos/gravitational/teleport/issues/events{/number}","events_url":"https://api.github.com/repos/gravitational/teleport/events","assignees_url":"https://api.github.com/repos/gravitational/teleport/assignees{/user}","branches_url":"https://api.github.com/repos/gravitational/teleport/branches{/branch}","tags_url":"https://api.github.com/repos/gravitational/teleport/tags","blobs_url":"https://api.github.com/repos/gravitational/teleport/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gravitational/teleport/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gravitational/teleport/git/refs{/sha}","trees_url":"https://api.github.com/repos/gravitational/teleport/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gravitational/teleport/statuses/{sha}","languages_url":"https://api.github.com/repos/gravitational/teleport/languages","stargazers_url":"https://api.github.com/repos/gravitational/teleport/stargazers","contributors_url":"https://api.github.com/repos/gravitational/teleport/contributors","subscribers_url":"https://api.github.com/repos/gravitational/teleport/subscribers","subscription_url":"https://api.github.com/repos/gravitational/teleport/subscription","commits_url":"https://api.github.com/repos/gravitational/teleport/commits{/sha}","git_commits_url":"https://api.github.com/repos/gravitational/teleport/git/commits{/sha}","comments_url":"https://api.github.com/repos/gravitational/teleport/comments{/number}","issue_comment_url":"https://api.github.com/repos/gravitational/teleport/issues/comments{/number}","contents_url":"https://api.github.com/repos/gravitational/teleport/contents/{+path}","compare_url":"https://api.github.com/repos/gravitational/teleport/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gravitational/teleport/merges","archive_url":"https://api.github.com/repos/gravitational/teleport/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gravitational/teleport/downloads","issues_url":"https://api.github.com/repos/gravitational/teleport/issues{/number}","pulls_url":"https://api.github.com/repos/gravitational/teleport/pulls{/number}","milestones_url":"https://api.github.com/repos/gravitational/teleport/milestones{/number}","notifications_url":"https://api.github.com/repos/gravitational/teleport/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gravitational/teleport/labels{/name}","releases_url":"https://api.github.com/repos/gravitational/teleport/releases{/id}","deployments_url":"https://api.github.com/repos/gravitational/teleport/deployments","created_at":"2015-03-02T19:36:00Z","updated_at":"2018-10-03T16:16:44Z","pushed_at":"2018-10-03T18:20:48Z","git_url":"git://github.com/gravitational/teleport.git","ssh_url":"git@github.com:gravitational/teleport.git","clone_url":"https://github.com/gravitational/teleport.git","svn_url":"https://github.com/gravitational/teleport","homepage":"https://gravitational.com/teleport","size":56059,"stargazers_count":6608,"watchers_count":6608,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":383,"mirror_url":null,"archived":false,"open_issues_count":172,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":383,"open_issues":172,"watchers":6608,"default_branch":"master"}},"base":{"label":"gravitational:master","ref":"master","sha":"dcb9ccfd517cc909c2ab411cf99b4379eeabea21","user":{"login":"gravitational","id":10781132,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNzgxMTMy","avatar_url":"https://avatars2.githubusercontent.com/u/10781132?v=4","gravatar_id":"","url":"https://api.github.com/users/gravitational","html_url":"https://github.com/gravitational","followers_url":"https://api.github.com/users/gravitational/followers","following_url":"https://api.github.com/users/gravitational/following{/other_user}","gists_url":"https://api.github.com/users/gravitational/gists{/gist_id}","starred_url":"https://api.github.com/users/gravitational/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gravitational/subscriptions","organizations_url":"https://api.github.com/users/gravitational/orgs","repos_url":"https://api.github.com/users/gravitational/repos","events_url":"https://api.github.com/users/gravitational/events{/privacy}","received_events_url":"https://api.github.com/users/gravitational/received_events","type":"Organization","site_admin":false},"repo":{"id":31558937,"node_id":"MDEwOlJlcG9zaXRvcnkzMTU1ODkzNw==","name":"teleport","full_name":"gravitational/teleport","private":false,"owner":{"login":"gravitational","id":10781132,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNzgxMTMy","avatar_url":"https://avatars2.githubusercontent.com/u/10781132?v=4","gravatar_id":"","url":"https://api.github.com/users/gravitational","html_url":"https://github.com/gravitational","followers_url":"https://api.github.com/users/gravitational/followers","following_url":"https://api.github.com/users/gravitational/following{/other_user}","gists_url":"https://api.github.com/users/gravitational/gists{/gist_id}","starred_url":"https://api.github.com/users/gravitational/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gravitational/subscriptions","organizations_url":"https://api.github.com/users/gravitational/orgs","repos_url":"https://api.github.com/users/gravitational/repos","events_url":"https://api.github.com/users/gravitational/events{/privacy}","received_events_url":"https://api.github.com/users/gravitational/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/gravitational/teleport","description":"Privileged access management for elastic infrastructure.","fork":false,"url":"https://api.github.com/repos/gravitational/teleport","forks_url":"https://api.github.com/repos/gravitational/teleport/forks","keys_url":"https://api.github.com/repos/gravitational/teleport/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gravitational/teleport/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gravitational/teleport/teams","hooks_url":"https://api.github.com/repos/gravitational/teleport/hooks","issue_events_url":"https://api.github.com/repos/gravitational/teleport/issues/events{/number}","events_url":"https://api.github.com/repos/gravitational/teleport/events","assignees_url":"https://api.github.com/repos/gravitational/teleport/assignees{/user}","branches_url":"https://api.github.com/repos/gravitational/teleport/branches{/branch}","tags_url":"https://api.github.com/repos/gravitational/teleport/tags","blobs_url":"https://api.github.com/repos/gravitational/teleport/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gravitational/teleport/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gravitational/teleport/git/refs{/sha}","trees_url":"https://api.github.com/repos/gravitational/teleport/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gravitational/teleport/statuses/{sha}","languages_url":"https://api.github.com/repos/gravitational/teleport/languages","stargazers_url":"https://api.github.com/repos/gravitational/teleport/stargazers","contributors_url":"https://api.github.com/repos/gravitational/teleport/contributors","subscribers_url":"https://api.github.com/repos/gravitational/teleport/subscribers","subscription_url":"https://api.github.com/repos/gravitational/teleport/subscription","commits_url":"https://api.github.com/repos/gravitational/teleport/commits{/sha}","git_commits_url":"https://api.github.com/repos/gravitational/teleport/git/commits{/sha}","comments_url":"https://api.github.com/repos/gravitational/teleport/comments{/number}","issue_comment_url":"https://api.github.com/repos/gravitational/teleport/issues/comments{/number}","contents_url":"https://api.github.com/repos/gravitational/teleport/contents/{+path}","compare_url":"https://api.github.com/repos/gravitational/teleport/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gravitational/teleport/merges","archive_url":"https://api.github.com/repos/gravitational/teleport/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gravitational/teleport/downloads","issues_url":"https://api.github.com/repos/gravitational/teleport/issues{/number}","pulls_url":"https://api.github.com/repos/gravitational/teleport/pulls{/number}","milestones_url":"https://api.github.com/repos/gravitational/teleport/milestones{/number}","notifications_url":"https://api.github.com/repos/gravitational/teleport/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gravitational/teleport/labels{/name}","releases_url":"https://api.github.com/repos/gravitational/teleport/releases{/id}","deployments_url":"https://api.github.com/repos/gravitational/teleport/deployments","created_at":"2015-03-02T19:36:00Z","updated_at":"2018-10-03T16:16:44Z","pushed_at":"2018-10-03T18:20:48Z","git_url":"git://github.com/gravitational/teleport.git","ssh_url":"git@github.com:gravitational/teleport.git","clone_url":"https://github.com/gravitational/teleport.git","svn_url":"https://github.com/gravitational/teleport","homepage":"https://gravitational.com/teleport","size":56059,"stargazers_count":6608,"watchers_count":6608,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":383,"mirror_url":null,"archived":false,"open_issues_count":172,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":383,"open_issues":172,"watchers":6608,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/gravitational/teleport/pulls/2261"},"html":{"href":"https://github.com/gravitational/teleport/pull/2261"},"issue":{"href":"https://api.github.com/repos/gravitational/teleport/issues/2261"},"comments":{"href":"https://api.github.com/repos/gravitational/teleport/issues/2261/comments"},"review_comments":{"href":"https://api.github.com/repos/gravitational/teleport/pulls/2261/comments"},"review_comment":{"href":"https://api.github.com/repos/gravitational/teleport/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/gravitational/teleport/pulls/2261/commits"},"statuses":{"href":"https://api.github.com/repos/gravitational/teleport/statuses/01c2f4577e11984606f043254a4df128ff6befe4"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"klizhentas"}}