Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!(ns-api): removed file calls for SSH keys #1078

Merged
merged 2 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/ns-api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=ns-api
PKG_VERSION:=2.2.0
PKG_VERSION:=3.0.0
PKG_RELEASE:=1

PKG_BUILD_DIR:=$(BUILD_DIR)/ns-api-$(PKG_VERSION)
Expand Down
51 changes: 48 additions & 3 deletions packages/ns-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4622,16 +4622,61 @@ Read SSH keys

### list-keys

Return the content of `/etc/dropbear/authorized_keys` file:
```
Returns list of authorized keys:

```bash
api-cli ns.ssh list-keys
```

Output example:

```json
{'keys': '\nssh-rsa AAAAB3N...6m5 [email protected]\n'}
{
"keys": [
{
"type": "ssh-rsa",
"key": "...",
"comment": "very_cool_key"
}
]
}
```

### add-key

Add a new key for SSH access:

```bash
api-cli ns.ssh add-key --data '{"key": "..."}'
```

Example response:

```json
{
"message": "success"
}
```

### delete-key

Delete a key from the list:

```bash
api-cli ns.ssh delete-key --data '{"key": "..."}'
```

NOTE: API call only requires the key, not the full entry. Discard the comment and type of key.

Example response:

```json
{
"message": "success"
}
```


## ns.reverseproxy

Allows to configure a reverse proxy through the nginx web server.
Expand Down
80 changes: 71 additions & 9 deletions packages/ns-api/files/ns.ssh
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,79 @@ import os
import sys
import json

from nethsec.utils import validation_error, ValidationError, generic_error


def __list_keys():
keys = []
if os.path.exists(KEYS_FILE):
with open(KEYS_FILE, 'r') as file:
for line in file:
if line.startswith('#') or len(line.split()) < 2:
continue
line_split = line.strip().split()
keys.append({
'type': line_split[0],
'key': line_split[1],
'comment': ' '.join(line_split[2:])
})
return keys


def __add_key():
data = json.load(sys.stdin)
if 'key' not in data:
raise ValidationError('key', 'required')
# NOTE: we are not validating the key format here, it can be done using `ssh-keygen -lf <keyfile>`, but it's
# overkill and can be implemented later on if needed.
if len(data['key'].split()) < 2:
raise ValidationError('key', 'key_invalid_format', data['key'])
if data['key'].split()[1] in [key['key'] for key in __list_keys()]:
raise ValidationError('key', 'key_already_exists', data['key'])
file_descriptor = os.open(
KEYS_FILE,
os.O_APPEND | os.O_WRONLY | os.O_CREAT,
mode=0o600
)
with open(file_descriptor, 'w') as file:
file.write(data['key'] + '\n')


def __delete_key():
data = json.load(sys.stdin)
if 'key' not in data:
raise ValidationError('key', 'required')
keys = __list_keys()
if data['key'] not in [key['key'] for key in keys]:
raise ValidationError('key', 'key_not_found', data['key'])
with open(KEYS_FILE, 'w') as file:
for key in keys:
if key['key'] != data['key']:
file.write(f"{key['type']} {key['key']} {key['comment']}\n")


KEYS_FILE = '/etc/dropbear/authorized_keys'

cmd = sys.argv[1]

if cmd == 'list':
print(json.dumps({"list-keys": {}}))
print(json.dumps({
"list-keys": {},
"add-key": {"key": "string"},
"delete-key": {"key": "string"}
}))
else:
action = sys.argv[2]
if action == "list-keys":
keys = '/etc/dropbear/authorized_keys'
if os.path.exists(keys):
with open(keys, 'r') as fp:
print(json.dumps({"keys": fp.read()}))
else:
print(json.dumps({"keys": ""}))

try:
if action == "list-keys":
print(json.dumps({"keys": __list_keys()}))
elif action == "add-key":
__add_key()
print(json.dumps({"message": "success"}))
elif action == "delete-key":
__delete_key()
print(json.dumps({"message": "success"}))
except ValidationError as e:
print(json.dumps(validation_error(e.parameter, e.message, e.value)))
except Exception as e:
print(json.dumps(generic_error(str(e))))
Loading