v0.2.0
This commit is contained in:
1 parent
23c7133fa9
commit
8c1b93c14e
16 files changed
+1187
-295
No files matched your search
@@ -19,20 +19,23 @@ const managedMarker = "# ssh-access-tui managed key — do not edit by hand, use
|
||||
// actual security boundary for a jump/forward-only account:
|
||||
// - restrict disables pty, X11, agent-forwarding, user-rc, etc.
|
||||
// - port-forwarding re-enables (only) local/dynamic forwarding
|
||||
// - permitopen=... whitelists exactly the host:port pairs this key
|
||||
// may forward to — this is what makes "only these hosts" a protocol-level
|
||||
// guarantee rather than a client-side convention.
|
||||
// - permitopen=... whitelists exactly the address:port pairs this key
|
||||
// may forward to — this is what makes "only these destinations" a
|
||||
// protocol-level guarantee rather than a client-side convention. Every
|
||||
// service on every host the user's groups grant becomes one
|
||||
// permitopen= entry here, independent of how many services share a
|
||||
// host or how many hosts share a port number.
|
||||
//
|
||||
// Reverse forwarding (-R) is intentionally never granted here.
|
||||
func BuildKeyOptions(hosts []model.Host) string {
|
||||
if len(hosts) == 0 {
|
||||
// No hosts assigned yet: restrict everything, permit nothing, so the
|
||||
// key authenticates but cannot open forwarding channels anywhere.
|
||||
func BuildKeyOptions(forwards []model.Forward) string {
|
||||
if len(forwards) == 0 {
|
||||
// No forwards assigned yet: restrict everything, permit nothing, so
|
||||
// the key authenticates but cannot open forwarding channels anywhere.
|
||||
return "restrict"
|
||||
}
|
||||
opts := []string{"restrict", "port-forwarding"}
|
||||
for _, h := range hosts {
|
||||
opts = append(opts, fmt.Sprintf(`permitopen="%s:%s"`, h.Address, strconv.Itoa(h.Port)))
|
||||
for _, f := range forwards {
|
||||
opts = append(opts, fmt.Sprintf(`permitopen="%s:%s"`, f.Address, strconv.Itoa(f.Port)))
|
||||
}
|
||||
return strings.Join(opts, ",")
|
||||
}
|
||||
@@ -40,7 +43,7 @@ func BuildKeyOptions(hosts []model.Host) string {
|
||||
// WriteAuthorizedKeys writes the single managed key line (with its
|
||||
// permitopen restrictions) into ~<username>/.ssh/authorized_keys, replacing
|
||||
// any previous ssh-access-tui-managed line for that user.
|
||||
func WriteAuthorizedKeys(username, pubKeyLine string, hosts []model.Host) error {
|
||||
func WriteAuthorizedKeys(username, pubKeyLine string, forwards []model.Forward) error {
|
||||
u, err := user.Lookup(username)
|
||||
if err != nil {
|
||||
return fmt.Errorf("lookup user %s: %w", username, err)
|
||||
@@ -49,7 +52,7 @@ func WriteAuthorizedKeys(username, pubKeyLine string, hosts []model.Host) error
|
||||
if err := os.MkdirAll(sshDir, 0o700); err != nil {
|
||||
return fmt.Errorf("create .ssh dir: %w", err)
|
||||
}
|
||||
line := fmt.Sprintf("%s %s", BuildKeyOptions(hosts), strings.TrimSpace(pubKeyLine))
|
||||
line := fmt.Sprintf("%s %s", BuildKeyOptions(forwards), strings.TrimSpace(pubKeyLine))
|
||||
content := managedMarker + "\n" + line + "\n"
|
||||
|
||||
akPath := filepath.Join(sshDir, "authorized_keys")
|
||||
|
||||
Reference in new issue
Block a user