Script-Based Certificate-Authentication Setup

Keywords: deployment script, deploy.py

PrivX provides a host-deployment script. It is a Python script that can be executed on target hosts to automatically set up certificate authentication.

The host-deployment script has the following system requirements:

  • ​​Supported operating systems​​: Amazon Linux, Arch Linux, CentOS, Fedora, FreeBSD, Debian, Gentoo Linux, OpenSUSE, MacOS, Red Hat, Rocky Linux, Ubuntu.
  • ​​Required Python version​​: 2.7.9+ or 3.6.5+
  • ​​Required OpenSSH version​​: 6.9 or later.
  • ​​Network​​: Connectivity to a PrivX server.

📘

Note

On target hosts that do not support the host-deployment script, and on hosts that cannot connect to PrivX, you can set up certificate-authentication manually as described in Manual Certificate-Authentication Setup.

For hosts that cannot be accessed directly by PrivX, you need to first set up a PrivX Extender for proxying host connections. For more information about PrivX Extender setup, see Setting up Hosts.

On-prem machines must have unique machine IDs. For more information about setting up unique machine IDs, see Host External ID and Deployment Script

Quick Setup

To use the host-deployment script to set up certificate authentication on a target host, for connections between certain target accounts and PrivX users from certain roles:

  1. To create a host-deployment script, navigate to the ​Administration→Deployment→Deploy and configure SSH target hosts​ page, select ​Configure using a deployment script​​.

    If you need to granularly delegate host and connection-management permissions, also select the ​Access group​ the host is to be deployed to. For more information about access groups, see Host-Specific Management Permissions​​.

    Click ​Add Script​​. Download the ​deploy.py​​ script to the target host.

  2. Run the deployments script as root.

    In this example, we use --standalone to add an on-premises host, and --delegated-principals-all that allows providing certificate authentication via the PrivX GUI, in host settings:

    sudo python3 deploy.py \
    --standalone \
    --delegated-principals-all
    

    You may verify that the host was added by running the deployment script with --show-config. After successful deployment, you should see output similar to the following:

    sudo python3 deploy.py --show-config
    
    sudo python3 deploy.py --show-config
    ** GET ssh user CA public key from PrivX
    ** GET principals_command.sh from PrivX
    ** Resolve role IDs
    ** Read ssh public host keys
    PrivX deploy script version 99-7566
    Access group ID 6678583d-56dd-4300-6c9e-a5f1f2088555
    
    usepam yes
    permitrootlogin yes
    trustedusercakeys /etc/ssh/privx_ca.pub
    authorizedprincipalscommand /etc/ssh/principals_command.sh %u
    authorizedprincipalscommanduser nobody
    
    Accepted CA certificates:
    ssh-rsa
    <...>
    
    Certificate login allowed with any role for all principals.
    

    For the full list of supported options, run:

    $ /path/to/deploy.py --help
    
  3. Allow PrivX roles (and their users) to access target accounts. To do this, go to Administration→Hosts and Edit the host we just added, then Add Accounts specifying who can access what.

    Save your changes to the host. The specified accounts are automatically set up with passwordless certificate authentication. PrivX users belonging to one of the allowed roles should now see the target host on the ​Connections→Available Hosts​​ page.

    You may also verify that certificate-based authentication is used by checking the OpenSSH-server logs on the target server. Upon successful certificate-based authentication there should be a log message like the following:

    Accepted publickey for alice from 192.0.2.26 port 50930 ssh2: RSA-CERT \
    ID [email protected]:53188 serial 4920619392583124720 \
    (serial 4920619392583124720) \
    CA RSA 98:16:36:bf:6e:c6:3f:e5:a1:5e:31:61:c1:37:ef:d8
    

📘

Note

Certificates issued by PrivX are very time-sensitive. Even a clock skew of just few minutes may prevent certificates from working correctly. Verify that the target-host time is correct. Adjust as necessary.

By default certificates for SSH connections are valid for 5 minutes, starting from 2 minutes prior to the current time in PrivX.

Advanced Setup Options

This section describes advanced host-deployment-script options.

Selecting Host Platform

To specify the host type, use one of the following options:

​​--aws​​: The host runs on AWS.
​​--azure​​: The host runs on Microsoft Azure.
​​--google-cloud​​: The host runs on Google Cloud.
​​--openstack​​: The host runs on OpenStack.
​​--standalone​​: For on-premises, non-cloud hosts.

Defining Target-Account Access

Host-deployment script allows you to specify access using one or more of the following methods:

  • Later via PrivX. Recommended for hosts with changing access requirements.
  • Directly on the command line. Recommended for hosts where required access is already known.

Set any of the following options if you want to add access later via the PrivX GUI or API, which can be useful for hosts with changing access requirements:

--delegated-principals: Any account added via the PrivX GUI that targets the specified principals (target accounts) will automatically be set up with certificate authentication.

--delegated-personal-account-roles: Any role added via the PrivX GUI that targets a Directory account will automatically be set up with certificate authentication.

--delegated-principals-all: Any account added via the PrivX GUI will automatically be set up with certificate authentication.

📘

Note

--delegated-principals-all does not work with agent connections.

You may add access directly using the following options:

--personal-account-roles​​: Allow members of certain roles to log in with their personal accounts (to target accounts whose names match their Windows/Unix username). Corresponds to a ​Directory​​ account.

​​--principals​​: Manually define target accounts and the roles that may access them. Corresponds to an ​Explicit​​ account.

📘

Note

If you run deploy script again with different principals, the new run does not remove the principal file in /etc/ssh/auth_principals/ created by the previous execution.

--user-defined-account-roles​​: Allow members of certain roles to input the target account when connecting (similarly to manual connections). Corresponds to a ​User-Defined​​ account. Note that this option does not enable certificate-based authentication for the specified roles.

For more information about account types, see Account Types.

Deploying Hosts Behind Extenders

If connections to the target host are relayed via a PrivX Extender, use the ​--api-hostname​​ option to specify the Extender's address and port, similarly to the following:

# /path/to/deploy.py --standalone \
--personal-account-roles "Example Role 01" \
​--api-hostname "extender.example.com:8443"​​

You may verify the addresses (subject-alternative names) of your PrivX Extender from its TLS certificate:

# openssl x509 -text -noout -in /opt/privx/extender/extender.crt grep -A 1 "Subject Alternative Name"

The PrivX Extender port is 8443 by default. You may verify the port from the Extender's configuration file, where it is specified by the ​host_deployment_listen_address​​ variable.

Configuration Options

--configure-only: Configures the target host, but does not register the host to PrivX. Can be used to modify existing configuration, if you don't want to override the settings in PrivX.
NOTE: even if target host has been configured to allow access, PrivX needs to still know about it either via host tags or via manual/scripted config.
When deploy script is being run, it will overwrite the PrivX host configuration with the actual config on the target host. This flag is useful, If you have done manual changes to host on PrivX side and do not wish to overwrite those settings.

--show-config: Show which PrivX roles and principals SSHD allows to connect to the host. Verifies the role configs on the target host. This shows only the host SSHD configuration and does not verify PrivX configuration for the host.

Deployment-Script Examples

# /path/to/deploy.py --standalone \
--delegated-principals-all
--personal-account-roles "Example Role 01, Example Role 02" \
--principals alice="Example Role",privx-admin:bob=privx-admin \
--user-defined-account-roles "Example Role 01,Example Role 02"

The previous example specifies:

  • The host type (--standalone means on-premises)
  • Any account added to the host via the PrivX GUI will be automatically set up with certificate authentication.
  • Certificate authentication to personal accounts for all users of Example Role 01 and Example Role 02.
  • Users of Example Role can access alice on the target host. privx-admin users can also access bob.

📘

Note

If connections to the target host are relayed via a PrivX Extender, use the ​--api-hostname​​ option to specify the Extender's address and port, similarly to the following:

# /path/to/deploy.py --standalone \
--personal-account-roles "Example Role 01" \
​​--api-hostname "extender.example.com:8443"​​

You may verify the addresses (subject-alternative names) of your PrivX Extender from its TLS certificate:

# openssl x509 -text -noout -in /opt/privx/extender/extender.crt grep -A 1 "Subject Alternative Name"

The PrivX Extender port is 8443 by default. You may verify the port from the Extender's configuration file, where it is specified by the ​host_deployment_listen_address​​ variable.

--delegated-principals-all does not work with agent connections.

📘

Note

You may disable password login after certificate-based authentication is set up on the target host.

Configuring Access Using Host Tags

For cloud-based hosts, PrivX can be configured to import allowed principals from host tags. This method simplifies host deployment as principals do not need to be provided for the host-deployment script.

📘

Note

Configuring access with host tags can be used for setting up hosts that mostly lack connection to PrivX: An initial instance must be able to connect to PrivX, but subsequent clones of this instance do not need PrivX connectivity.

To configure allowed principals for a cloud-based host using host tags:

  1. Add host tags to the host via your cloud-host-management interface (such as EC2 for AWS instances). Host tags must specify the access rules and SSH/RDP services related to the host.

    The list of supported host tags is provided later in this section.

📘

Note

When specifying tags for cloud hosts, do not include double-quotation marks in the value.

  1. Configure PrivX to import host tags. To do this, navigate to ​Administration→Directories​ in the PrivX GUI and ​Edit​ the directory to which the target host belongs to. Enable the ​Import host instance tags from the directory​ setting. Click ​Save​​ to apply your changes.

  2. Deploy the host using the host-deployment script, or manually.

    Users from PrivX roles are now able to access the host according to the principals defined in the host tags, with certificate-based authentication.

PrivX supports the following host tags:

​​privx-ssh-principals=<target>=<roles1>:<target2>=<roles2>:...​​

  • Allow target accounts to be accessed by specified PrivX roles using SSH connections. Corresponds to an ​Explicit​​ account.

    Access to each target account is specified with ​target=roles syntax, where target is the account name and roles​ is the comma-separated names of PrivX roles allowed to access the account. Each such mapping must be separated with a colon (​:​​).

    For example, to allow target user ​alice​ to be accessed by PrivX roles ​privx-admin​ and ​Role 01​​, and to allow target user ​bob​ to be accessed by ​Role 02​​:

    privx-ssh-principals=alice=Role 01,privx-admin:bob=Role 02
    

​​privx-rdp-principals=<target1>=<roles1>:<target2>=<roles2>:...​​

  • Allow target accounts to be accessed by specified PrivX roles using RDP connections. Corresponds to an ​Explicit​​ account.

    Syntax is the same as with the ​privx-ssh-principals tag.

​​privx-vnc-principals=<target1>=<roles1>:<target2>=<roles2>:...​​

  • Allow target accounts to be accessed by specified PrivX roles using VNC connections. Corresponds to an ​Explicit​​ account.

    Syntax is the same as with the ​privx-ssh-principals tag.

privx-ssh-personal-account-roles=<roles>​​

  • Allow members of certain role(s) to log in with their personal accounts (to target accounts whose names match their Windows/Unix username) using SSH connections. Corresponds to a ​Directory​​ account.

    Any comma-separated PrivX-role names in ​<roles>​ are allowed login to personal accounts. For example, to allow members of ​Role 01​ and ​Role 02​​ to login to personal accounts:

    privx-ssh-personal-account-roles=Role 01,Role 02
    

privx-rdp-personal-account-roles=<roles>​​

  • Allow members of certain role(s) to log in with their personal accounts (to target accounts whose names match their Windows/Unix username) using RDP connections. Corresponds to a ​Directory​​ account.

    Syntax is similar to the ​privx-ssh-personal-account-roles tag.

​​privx-ssh-user-defined-account-roles=<roles>​​

  • Allow members of certain role(s) to freely specify the target account when connecting with SSH. Corresponds to a ​User-Defined​​ account. Note that access defined with this option does not grant certificate-based authentication to the specified roles.

    Syntax is similar to the ​privx-ssh-personal-account-roles​​ tag.

privx-rdp-user-defined-account-roles=<roles>​​

  • Allow members of certain role(s) to freely specify the target account when connecting with RDP. Corresponds to a ​User-Defined​​ account. Note that access defined with this option does not grant certificate-based authentication to the specified roles.

    Syntax is similar to the ​privx-ssh-personal-account-roles​​ tag.

privx-ssh-service-port=<port>​​

  • Specify the SSH-server port of the target host. By default SSH servers run on port 22.

    Example:

    privx-ssh-service-port=22
    

privx-rdp-service-port=<port>​​

  • Specify the RDP-server port of the target host. By default RDP servers run on port 3389.

    Example:

    privx-rdp-service-port=3389
    

privx-vnc-service-port=<port>​​

  • Specify the vnc-server port of the target host. Defaults to 5900.

    Example:

    privx-vnc-service-port=5900
    

privx-vnc-tunnel-port=<port>

  • Specify the port of the SSH server that is used for tunneling VNC connections. Defaults to 22.

    Example:

    privx-vnc-tunnel-port=22
    

privx-extender=<extendername>​​

  • If connections to the host are relayed through a PrivX Extender, use this tag to specify the name of the Extender.

    Example:

    privx-extender=exampleExtender
    

    For more information about PrivX Extender, see ​[ XXX →Proxying Connections to Hosts]​

​​privx-carrier=<carriername>​​

  • Specify the name of the carrier that should be used as the default carrier for this host's web connections.

    Example:

    privx-carrier=exampleCarrier
    

​​privx-enable-auditing=<yes|no>​​

  • Toggle auditing for the host. Defaults to ​no.​​

    Example:

    privx-enable-auditing=yes
    

privx-use-private-ips-only=<yes|no>​​

  • Enabling this prevents using scanned public IP addresses as connection addresses for cloud hosts. This can be used to enforce connecting to hosts via private IP addresses only.

    Example:

    privx-use-private-ips-only=no
    

​​privx-trust-on-first-use=<yes|no>​​

  • Enable/disable ​Trust on First Use​​, allowing regular users to connect to targets without known host keys. If disabled, superuser needs to accept host keys for unknown hosts on the first connection.

    Example:

    privx-trust-on-first-use=yes
    

    For more information about ​Trust on First Use​​, see ​[ XXX →Trusting Target-Host Identities]​​.

privx-access-group=<access_group_name>

  • Deploy the host to the named access group. If unspecified, the host is deployed to the ​Default​​ access group.

    Example:

    privx-access-group=examplegroup01
    

    For more information about access groups, see ​[ XXX →Host-Specific Management Permissions]​​.

`privx-access-group-id=<access_group_id>

  • Deploy the host to the access group with the specified ID. If unspecified, the host is deployed to the ​Default​​ access group.

    Example:

    privx-access-group-id=0bbbc3ef-4771-4292-78af-684151b64428
    

📘

Note

To obtain the tag in key-value format, split the syntax at the first ​=​​ sign. For example, some of the previously-provided examples converted to key-value format:

Key

Value

privx-ssh-principals

alice=Role 01,privx-admin:bob=Role 02

privx-ssh-personal-account-roles

Role 01,Role 02

privx-ssh-service-port

22

privx-rdp-service-port

3389

privx-extender

example-extender

privx-enable-auditing

yes

privx-use-private-ips-only

no

privx-trust-on-first-use

yes

privx-access-group

examplegroup01

privx-access-group-id

0bbbc3ef-4771-4292-78af-684151b64428

Host External ID and Deployment Script

When configuring a new host and registering it to PrivX using deploy script, the host is assigned a unique external ID. For cloud hosts, this external ID is based on instance ID on cloud instance metadata. Instance IDs are automatically used, if you use --aws, --google-cloud, --azure or --openstack deployment flags.

For on-prem hosts and hosts configured with deploy script but without cloud provider flag, the host's machine-id is used instead.

If you're deploying cloned virtual machines or on-prem hosts using machine-id, make sure your machine id's are unique before running the deploy script. The same thing applies, if running PrivX instances on on-prem hosts. Running HA instances on hosts with duplicate IDs might cause issues with license activations.

If host's machine-id cannot be resolved, the deployment script will fail.

📘

Note

You can check your host's machine ID from /etc/machine-id, or by running:

# dmidecode --string system-uuid

For more information about machine IDs, see https://www.man7.org/linux/man-pages/man5/machine-id.5.html

You can regenerate the machine-id on most cloned VM OSes with one of the following commands:

systemd-machine-id-setup
setup-machine-id
uuidgen > /etc/machine-id

For cloned MacOS instances, the machine ID is part of platform registry and can be changed by modifying or resetting NVRAM.

Re-running a deploy script on a host will update the existing host in PrivX host store. Re-running the deployment script requires host's 'deployable' flag to be enabled first for security reasons. If the host does not exist, it will be created. If the host was added using PrivX host directory host scanning feature, the host will have the same external_id as when deploying it with a deployment script and will be updated accordingly.

You should not configure multiple identical host directories which see the same instances. If this is necessary for some reason, use host tagging and "FETCH HOSTS WITH TAG" -feature in PrivX host directory to filter out unwanted hosts.

Hosts added manually via PrivX UI are considered 'local hosts' and have no external ID. Those instances cannot be redeployed via deployment script and need to be configured manually or via automation tools instead.


Did this page help you?