add ProxyJump function
This commit is contained in:
1 parent
56e20e5464
commit
7f0e0fdb23
48 files changed
+3875
-44
No files matched your search
@@ -3,6 +3,8 @@ package keymgr
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"ssh-access-tui/internal/model"
|
||||
)
|
||||
|
||||
// RenderClientConfig produces an OpenSSH client config (works identically on
|
||||
@@ -37,3 +39,58 @@ func RenderClientConfig(jumpHost string, jumpPort int, username, keyFileName str
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// RenderClientConfigProxyJump is the ProxyJump-mode counterpart of
|
||||
// RenderClientConfig: instead of one "jump" connection carrying a
|
||||
// LocalForward per service, each allowed service gets its own "Host <alias>"
|
||||
// block that reaches it by proxying through "jump" (ProxyJump), so the user
|
||||
// runs "ssh <alias>" directly per service rather than opening one
|
||||
// always-open tunnel and pointing local tools at 127.0.0.1:<port>.
|
||||
//
|
||||
// Same non-boundary caveat as RenderClientConfig: nothing here is enforced —
|
||||
// the actual restriction to these destinations is authorized_keys
|
||||
// permitopen= (see internal/sysadm/authorizedkeys.go), unaffected by which
|
||||
// client config style is handed out.
|
||||
func RenderClientConfigProxyJump(jumpHost string, jumpPort int, username, keyFileName string, forwards []model.Forward) string {
|
||||
var b strings.Builder
|
||||
fmt.Fprintf(&b, "# ssh-access-tui client config for %s\n", username)
|
||||
fmt.Fprintf(&b, "# Generated %s. Regenerated whenever your allowed services change.\n\n", genTimestamp())
|
||||
|
||||
fmt.Fprintf(&b, "Host jump\n")
|
||||
fmt.Fprintf(&b, " HostName %s\n", jumpHost)
|
||||
fmt.Fprintf(&b, " Port %d\n", jumpPort)
|
||||
fmt.Fprintf(&b, " User %s\n", username)
|
||||
fmt.Fprintf(&b, " IdentityFile ~/.ssh/%s\n", keyFileName)
|
||||
fmt.Fprintf(&b, " IdentitiesOnly yes\n\n")
|
||||
|
||||
aliases := hostAliases(forwards)
|
||||
for i, f := range forwards {
|
||||
fmt.Fprintf(&b, "Host %s\n", aliases[i])
|
||||
fmt.Fprintf(&b, " HostName %s\n", f.Address)
|
||||
fmt.Fprintf(&b, " Port %d\n", f.Port)
|
||||
fmt.Fprintf(&b, " User %s\n", username)
|
||||
fmt.Fprintf(&b, " ProxyJump jump\n")
|
||||
fmt.Fprintf(&b, " IdentityFile ~/.ssh/%s\n", keyFileName)
|
||||
fmt.Fprintf(&b, " IdentitiesOnly yes\n\n")
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// hostAliases assigns each forward a unique ssh_config "Host" alias: just
|
||||
// the host name when it's the only service of that host present, otherwise
|
||||
// "<host>-<service>" so multiple services on one host don't collide.
|
||||
func hostAliases(forwards []model.Forward) []string {
|
||||
countByHost := map[string]int{}
|
||||
for _, f := range forwards {
|
||||
countByHost[f.HostName]++
|
||||
}
|
||||
out := make([]string, len(forwards))
|
||||
for i, f := range forwards {
|
||||
if countByHost[f.HostName] > 1 {
|
||||
out[i] = f.HostName + "-" + f.ServiceName
|
||||
} else {
|
||||
out[i] = f.HostName
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in new issue
Block a user