Skip to content

Commit

Permalink
wip(backend): Add SSH key route
Browse files Browse the repository at this point in the history
  • Loading branch information
RezaRahemtola committed Feb 13, 2025
1 parent 9754853 commit c4c4a7e
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 1 deletion.
9 changes: 9 additions & 0 deletions backend/src/interfaces/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,12 @@ class GetAgentResponse(PublicAgentData):

class GetAgentSecretResponse(BaseModel):
secret: str


class AddSSHKeyBody(BaseModel):
secret: str
ssh_key: str


class AddSSHKeyAgentResponse(BaseModel):
error_log: str
62 changes: 61 additions & 1 deletion backend/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

from src.config import config
from src.interfaces.agent import (
AddSSHKeyAgentResponse,
AddSSHKeyBody,
Agent,
DeleteAgentBody,
GetAgentResponse,
Expand Down Expand Up @@ -240,9 +242,11 @@ async def update(
sftp.putfo(io.BytesIO(content), remote_path)
sftp.close()

script_path = "/tmp/deploy-agent.sh"

# Execute the command
_stdin, _stdout, stderr = ssh_client.exec_command(
f"wget {deploy_script_url} -O /tmp/deploy-agent.sh -q --no-cache && chmod +x /tmp/deploy-agent.sh && /tmp/deploy-agent.sh {python_version} {package_manager.value} {usage_type.value}"
f"wget {deploy_script_url} -O {script_path} -q --no-cache && chmod +x {script_path} && {script_path} {python_version} {package_manager.value} {usage_type.value}"
)
# Waiting for the command to complete to get error logs
stderr.channel.recv_exit_status()
Expand Down Expand Up @@ -270,6 +274,62 @@ async def update(
return UpdateAgentResponse(instance_ip=hostname, error_log=stderr.read())


@app.post("/agent/{agent_id}/ssh-key", description="Add an SSH to a deployed agent")
async def add_ssh_key(agent_id: str, body: AddSSHKeyBody) -> AddSSHKeyAgentResponse:
add_ssh_key_script_url = "https://raw.githubusercontent.com/Libertai/libertai-agents/refs/heads/reza/allow-ssh-access/deployment/add_ssh_key.sh"
agents = await fetch_agents([agent_id])

if len(agents) != 1:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND,
detail=f"Agent with ID {agent_id} not found.",
)
agent = agents[0]

# Validating the secret
decrypted_secret = decrypt(agent.encrypted_secret, config.ALEPH_SENDER_SK)
if body.secret != decrypted_secret:
raise HTTPException(
status_code=HTTPStatus.UNAUTHORIZED,
detail="The secret provided doesn't match the one of this agent.",
)

ssh_private_key = decrypt(agent.encrypted_ssh_key, config.ALEPH_SENDER_SK)

try:
hostname = await fetch_instance_ip(agent.instance_hash)
except ValueError:
raise HTTPException(
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
detail="Instance IPv6 address not found, it probably isn't allocated yet. Please try again in a few minutes.",
)

# Create a Paramiko SSH client
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# Load private key from string
rsa_key = paramiko.RSAKey(file_obj=io.StringIO(ssh_private_key))

# Connect to the server
ssh_client.connect(hostname=hostname, username="root", pkey=rsa_key)

script_path = "/tmp/add_ssh_key.sh"

# Execute the command
_stdin, _stdout, stderr = ssh_client.exec_command(
f"wget {add_ssh_key_script_url} -O {script_path} -q --no-cache && chmod +x {script_path} && {script_path} {body.ssh_key}"
)

# Waiting for the command to complete to get error logs
stderr.channel.recv_exit_status()

# Close the connection
ssh_client.close()

return AddSSHKeyAgentResponse(error_log=str(stderr.read()))


# TODO: add a redeploy route to forget the previous instance and setup again the agent's instance (in case instance allocation is failed)
# accessible only with secret, or maybe admin ?

Expand Down
8 changes: 8 additions & 0 deletions deployment/add_ssh_key.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

SSH_PUBLIC_KEY=$1

echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDS6B5tvwBxtF2Zhjk/wPzijviG4kSvzXAcJTugsCNuOT2xmRRlGW8DuviCZeDxIDQGxStYW/g5N4OMlp4O2Et+ErM+3vnDZAzLSALLQ+0dllC96E84SAWvVoprARhVjViNNt6FzncUP5C5/kjXodjPmfg3fsJNMRJtua+SrFXveoxqdh4wFSQQDzKOfufMahjGRO7mszsRD1lNfvWQawZRvQ/kspXGxv0m4R3UZFd4d3yO2PbFDa2C3fxmcgkpEw9rXQ3f70B99hGEMH2jt1Ebgr53CoR9wAeinfbbO0Mz98Aazod1qq5+4qkQg/KqY0cgMypFMeIYuEC1H19pSgyB2EWqQ66wt+sDT1jXWhLcGO0GOGzpY+cEk5CSbI9Mo2QRKM+fwRigTtBnKFpgQ2StCLB+qAbx3LYwyjsEY05nhthqQoE4AfTQLuJBmWz2v0Q9Yhga2IEc6TxwApbEkU3+TcK/tYJDkJjfhi/P4thYx+tSZzhp7+iafQA4SJOSs+lbhUjF8/sLtfQiw3DH4R/FZh6SS7e4Jnb3SiXBs+jn95/4W2YwUlvrklfEvdgvEofkMUfqTQVApeRPF8B+NfoihEu83zaCwV3ad/u/SKhANs6n0hFv2QUcF9QW5bYs/PW+Odmfe1RyQ4h7QvvP9LPsTOJ4tEHW51H58WXm3c5LKQ==" > ~/.ssh/authorized_keys

# Add key only if's not already in the file
grep -qxF "$SSH_PUBLIC_KEY" ~/.ssh/authorized_keys || echo "$SSH_PUBLIC_KEY" >> ~/.ssh/authorized_keys

0 comments on commit c4c4a7e

Please sign in to comment.