Feat: added --install-known-hosts & Fix: Permissons for ssh-cert

This allows users to copy the Host CA Pub key hosts directly into their ~/.ssh/known_hosts

Implemented chmod 600 for /tmp/ssh-cert (CERT_FILE_PATH)
This commit is contained in:
2026-04-09 14:49:44 +05:45
parent 04e3293b30
commit 05cf3b3840
+58 -2
View File
@@ -279,6 +279,12 @@ def request_certificate():
json_result = response.json().get('data', response.json()) json_result = response.json().get('data', response.json())
with open(CERT_FILE_PATH, 'w') as f: with open(CERT_FILE_PATH, 'w') as f:
f.write(json_result['certificate']) f.write(json_result['certificate'])
try:
os.chmod(CERT_FILE_PATH, 0o600)
except OSError:
pass
logger.info(f"Certificate signed successfully, located at {CERT_FILE_PATH}") logger.info(f"Certificate signed successfully, located at {CERT_FILE_PATH}")
logger.info(f"Valid for principals: {', '.join(json_result.get('principals', principals))}") logger.info(f"Valid for principals: {', '.join(json_result.get('principals', principals))}")
logger.info("You can login to your destination server with the following command") logger.info("You can login to your destination server with the following command")
@@ -455,6 +461,51 @@ def checkCert():
logger.warning("Certificate is not valid, renewal required") logger.warning("Certificate is not valid, renewal required")
return 1 return 1
def install_known_hosts():
"""Fetch Host CA from the upstream server and install it into ~/.ssh/known_hosts."""
try:
response = requests.get(f"{SIGN_URL}/api/v1/ssh/ca/public-key?ca_type=host", headers=auth_headers())
if response.status_code != 200:
logger.error(f"Failed to fetch host CA public key: {response.status_code} - {response.text}")
exit(1)
ca_data = response.json().get('data', {})
public_key = ca_data.get('public_key', '').strip()
if not public_key:
logger.error("No public key found in the response.")
exit(1)
known_hosts_path = os.path.expanduser("~/.ssh/known_hosts")
ssh_dir = os.path.dirname(known_hosts_path)
if not os.path.exists(ssh_dir):
os.makedirs(ssh_dir, mode=0o700)
# Standard format for OpenSSH cert-authority
entry = f"@cert-authority * {public_key}\n"
# Check if already present
if os.path.exists(known_hosts_path):
with open(known_hosts_path, 'r') as f:
content = f.read()
if public_key in content:
logger.info("Host CA public key is already in ~/.ssh/known_hosts. No changes made.")
return
with open(known_hosts_path, 'a') as f:
f.write(entry)
try:
os.chmod(known_hosts_path, 0o600)
except OSError:
pass # May not have permission to chmod if owned by root, but let's try
logger.info(f"Successfully installed Host CA public key to {known_hosts_path} for all hosts (*)")
except Exception as e:
logger.error(f"Error during Host CA installation: {e}")
exit(1)
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Sign an SSH key via a web service') parser = argparse.ArgumentParser(description='Sign an SSH key via a web service')
parser.add_argument("-k", "--ssh-key", type=argparse.FileType('rb'), dest="sshkeyfile", help="Add an SSH Public Key to your user profile in gatehouse") parser.add_argument("-k", "--ssh-key", type=argparse.FileType('rb'), dest="sshkeyfile", help="Add an SSH Public Key to your user profile in gatehouse")
@@ -465,11 +516,12 @@ if __name__ == "__main__":
parser.add_argument("--clear-cache", action='store_true', default=False, help="Remove the cached authentication token") parser.add_argument("--clear-cache", action='store_true', default=False, help="Remove the cached authentication token")
parser.add_argument("--remove-key", nargs='?', const='', metavar='KEY_ID', help="Remove an SSH key from your profile. Omit KEY_ID to pick interactively.") parser.add_argument("--remove-key", nargs='?', const='', metavar='KEY_ID', help="Remove an SSH key from your profile. Omit KEY_ID to pick interactively.")
parser.add_argument("--list-keys", action='store_true', default=False, help="List SSH keys in your profile") parser.add_argument("--list-keys", action='store_true', default=False, help="List SSH keys in your profile")
parser.add_argument("--install-known-hosts", action='store_true', default=False, help="Fetch Host CA public key and install into ~/.ssh/known_hosts")
args = parser.parse_args() args = parser.parse_args()
if not (args.check_cert or args.request_cert or args.add_key or args.clear_cache if not (args.check_cert or args.request_cert or args.add_key or args.clear_cache
or args.remove_key is not None or args.list_keys): or args.remove_key is not None or args.list_keys or args.install_known_hosts):
parser.error("At least one of --check-cert, --request-cert, --add-key, --list-keys, --remove-key, or --clear-cache must be provided.") parser.error("At least one of --check-cert, --request-cert, --add-key, --list-keys, --remove-key, --clear-cache, or --install-known-hosts must be provided.")
# Retrieve SSH key from environment variables if not provided via CLI # Retrieve SSH key from environment variables if not provided via CLI
@@ -518,6 +570,10 @@ if __name__ == "__main__":
add_ssh_key(ssh_key_file) add_ssh_key(ssh_key_file)
exit(0) exit(0)
if args.install_known_hosts:
request_token()
install_known_hosts()
exit(0)
if args.request_cert: if args.request_cert:
request_token() request_token()