Comments (8)
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.
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.
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.
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.
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 itbrokenglass
for now ;)
from breakglass.
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.
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.
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)
- Document the requirements for the ssh keys HOT 6
- Support -tls=self-signed HOT 10
- /etc/breakglass.authorized_keys: is a directory HOT 4
- make parsing authorized_keys more robust
- "sh": executable file not found in $PATH HOT 2
- Enhancement: add port forwarding
- OpenSSH 8.8 cannot log in: Unable to negotiate with 100.77.11.58 port 22: no matching host key type found. Their offer: ssh-rsa HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from breakglass.