GithubHelp home page GithubHelp logo

Allow users to upload key about breakglass HOT 8 CLOSED

gokrazy avatar gokrazy commented on September 3, 2024
Allow users to upload key

from breakglass.

Comments (8)

stapelberg avatar stapelberg commented on September 3, 2024 1

Of course, but that‘s not suitable for end user consumption.

End users should definitely not get a root shell either, though.

If you need to access specific files or system info for troubleshooting, your application should gather these and make them available.

Is this really an additional line of defense? With user/password attackers can already update the binary and access everything on the device.

They can not do so at runtime, and can only do so in a destructive way, though (replace the whole installation with their own build), which is much more likely to be noticed at least.

If the application has a per-build crypto key with which it encrypts sensitive data, replacing the device with an attacker build doesn’t help much. I’m not saying using encryption like that is easy or expected of application developers like yourself, but it’s certainly possible for security-conscious use-cases.

from breakglass.

stapelberg avatar stapelberg commented on September 3, 2024 1

It's yaml config and will eventually be replaced with proper admin UI. While that's not available I'm looking for an interim, low-effort solution.

A HTML <textarea> that is saved to the YAML file? :)

If you want to consider password-based log in (may be as opt-in on compile time?)

I’d rather not, sorry. Access should be granted based on a properly secured SSH key (password-protected, and/or on a hardware crypto device), and only allowing keys nudges people in that direction.

from breakglass.

stapelberg avatar stapelberg commented on September 3, 2024

You can always just mount the SD card (or image) and add the host/authorized keys.

Requiring physical access to do this is one more hurdle attackers need to cross.

Given that breakglass allows for remote code execution, I’m not sure it should really be made much easier.

Note that if you disagree and really want to do this, you could do it in a separate program.

from breakglass.

andig avatar andig commented on September 3, 2024

You can always just mount the SD card (or image) and add the host/authorized keys.

Of course, but that‘s not suitable for end user consumption.

Requiring physical access to do this is one more hurdle attackers need to cross.

Is this really an additional line of defense? With user/password attackers can already update the binary and access everything on the device.

Would it be a valid compromise to allow SSH access with the same user/password pair by default (which would require some sort of minishell)? Or allow certificate upload using u/p on the supervisor side?

from breakglass.

andig avatar andig commented on September 3, 2024

Having lesser security requirements and the need for users to be able to SCP in for uploading config files I‘ll look into the following:

  • self-generate host key
  • allow password-based login same as web ui
    Calling it brokenglass for now ;)

from breakglass.

stapelberg avatar stapelberg commented on September 3, 2024

the need for users to be able to SCP in for uploading config files

What sort of config files are those? Wouldn’t it be easier to allow drag&drop on a web user interface for getting files into the appliance?

from breakglass.

andig avatar andig commented on September 3, 2024

What sort of config files are those? Wouldn’t it be easier to allow drag&drop on a web user interface for getting files into the appliance?

It's yaml config and will eventually be replaced with proper admin UI. While that's not available I'm looking for an interim, low-effort solution.

If you want to consider password-based log in (may be as opt-in on compile time?), it could look something like this and I'd be happy to provide a PR:

diff --git a/breakglass.go b/breakglass.go
index e7e0151..25eaa67 100644
--- a/breakglass.go
+++ b/breakglass.go
@@ -5,6 +5,8 @@ package main
import (
	"bufio"
	"bytes"
+	"crypto/rand"
+	"crypto/rsa"
	"flag"
	"fmt"
	"io/ioutil"
@@ -27,8 +29,14 @@ var (
	hostKeyPath = flag.String("host_key",
		"/perm/breakglass.host_key",
		"path to a PEM-encoded RSA, DSA or ECDSA private key (create using e.g. ssh-keygen -f /perm/breakglass.host_key -N '' -t rsa)")
+
+	hostPasswordPath = flag.String("host_password",
+		"/etc/gokr-pw.txt",
+		"path to host password")
)

+func createHostKey(path string) (ssh.Signer, error) {
+	key, err := rsa.GenerateKey(rand.Reader, 1024)
+	if err != nil {
+		return nil, err
+	}
+
+	// file, err := os.OpenFile(path, os.O_CREATE, 0400)
+	// if err != nil {
+	// 	return nil, err
+	// }
+	// defer file.Close()
+
+	// err = pem.Encode(file, &pem.Block{
+	// 	Type:  "PRIVATE KEY",
+	// 	Bytes: x509.MarshalPKCS1PrivateKey(key),
+	// })
+
+	var signer ssh.Signer
+	if err == nil {
+		signer, err = ssh.NewSignerFromKey(key)
+	}
+
+	return signer, err
+}
+
+func loadPassword(path string) ([]byte, error) {
+	b, err := ioutil.ReadFile(path)
+	return bytes.TrimSpace(b), err
+}
+
func main() {
	flag.Parse()
	log.SetFlags(log.LstdFlags | log.Lshortfile)

-	gokrazy.DontStartOnBoot()
+	config := &ssh.ServerConfig{}

	authorizedKeys, err := loadAuthorizedKeys(*authorizedKeysPath)
-	if err != nil {
-		if os.IsNotExist(err) {
+	if err == nil {
+		// pubkey auth
+		log.Printf("authorized keys found - using pubkey authorization")
+		config.PublicKeyCallback = func(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
+			if authorizedKeys[string(pubKey.Marshal())] {
+				log.Printf("user %q successfully authorized from remote addr %s", conn.User(), conn.RemoteAddr())
+				return nil, nil
+			}
+			return nil, fmt.Errorf("public key not found in %s", *authorizedKeysPath)
+		}
+	} else {
+		// terminal error
+		if !os.IsNotExist(err) {
			log.Printf("see https://github.com/gokrazy/breakglass#installation")
+			log.Fatalf("could not load authorized keys: %v", err)
		}
-		log.Fatal(err)
-	}

-	config := &ssh.ServerConfig{
-		PublicKeyCallback: func(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
-			if authorizedKeys[string(pubKey.Marshal())] {
+		hostPassword, errPass := loadPassword(*hostPasswordPath)
+		if errPass != nil {
+			log.Fatalf("could not load either authorized keys (%v) or host password (%v)", err, errPass)
+		}
+
+		// password auth
+		log.Println("authorized keys not found - falling back to password authorization")
+		config.PasswordCallback = func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
+			if bytes.Compare(hostPassword, password) == 0 {
				log.Printf("user %q successfully authorized from remote addr %s", conn.User(), conn.RemoteAddr())
				return nil, nil
			}
			return nil, fmt.Errorf("public key not found in %s", *authorizedKeysPath)
-		},
+		}
	}

	signer, err := loadHostKey(*hostKeyPath)
	if err != nil {
-		if os.IsNotExist(err) {
+		if !os.IsNotExist(err) {
			log.Printf("see https://github.com/gokrazy/breakglass#installation")
+			log.Fatalf("could not load host keys: %v", err)
+		}
+
+		// create host key
+		log.Println("host key not found, creating initial host key")
+		signer, err = createHostKey(*hostKeyPath)
+		if err != nil {
+			log.Fatalf("could not create host key: %v", err)
		}
-		log.Fatal(err)
	}
	config.AddHostKey(signer)

Saving the generated host key does not work yet as /perm is apparently readonly (need to find out why).

from breakglass.

andig avatar andig commented on September 3, 2024

For those who want to accept lesser security (NOT RECOMMENDED per above) as discussed above can use https://github.com/andig/brokenglass to get started. It's forked and host key generation as well as password login added.

from breakglass.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.