Skip to content

Commit

Permalink
Merge master to stable
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphux committed Nov 11, 2019
2 parents 1cd4d5d + e878704 commit cff5a8f
Show file tree
Hide file tree
Showing 26 changed files with 505 additions and 339 deletions.
25 changes: 6 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,18 @@ https://docs.passhport.org

Requirements:
-------------
* All users have to provide their public ssh key.
* ssh-agent on client
* Standard OpenSSH server
* Standard OpenSSH client

Goals:
------
* Manage users on a centralized server technology independant (no ldap)
* Manage users as "roles" (or groups): adminsys, devops, supervision team...
* Manage servers and groups of servers
* Limit servers interractions (limitation to some commands)
* Provide a connexions history
* Provide command and actions history (by users)

Done so far:
-------------
* Server API Caneva (REST urls ready to answer with Flask)
* User and target management via the API
* Server database initialization (no data)
* Client interface with interactive console

Used technologies:
------------------
* OpenSSH
* Python
* Docopt
* Flask
* Alchemy
* Flask-Alchemy
* Alchemy-migration
Test the 5 minutes Debian installation :
```
bash <(curl -s https://raw.githubusercontent.com/librit/passhport/master/tools/passhport-install-script-debian.sh)
```
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Now that we have our virtual-env, we install the python’s modules we’ll need

.. code-block:: none
passhport@centos7:~$ /home/passhport/passhport-run-env/bin/pip install sqlalchemy-migrate flask-migrate requests docopt configparser tabulate flask-login ldap3 psutil
passhport@centos7:~$ /home/passhport/passhport-run-env/bin/pip install sqlalchemy-migrate flask-migrate requests docopt configparser tabulate flask-login ldap3 psutil cryptography
Now, let’s start the real thing…

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ If you did not use the packaged version of passhport (deb/rpm), proceed as follo

Before installing python libs, be sure to have *pg_config* in your $PATH and some postgres libraries.

For Debian, install *postgresql-common* and *postgresql-server-dev-9.6*
For Debian, install *postgresql-common* and *postgresql-server*

.. code-block:: none
# apt install postgresql-common postgresql-server-dev-9.6
# apt install postgresql-common postgresql-server
For CentOS, install postgresql :

Expand Down
2 changes: 2 additions & 0 deletions docs/passhport-admin/target.rst
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ If no argument is given, user enters in interactive mode.
OK: "firewall1.compagny.com" -> created
admin@bastion:~#

Once the target is created, you should add a passhport ssh public key to the target and use "checkaccess" to verify everything is ok.

edit
-----------

Expand Down
7 changes: 7 additions & 0 deletions docs/po/fr/LC_MESSAGES/passhport-admin/target.po
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ msgstr "Port SSH à utiliser pour se connecter à la target (optionnel)"
msgid "If no argument is given, user enters in interactive mode."
msgstr "Si aucun argument n'est donné, l'utilisateur entre en mode interactif."

#: ../../passhport-admin/target.rst:382 ../../passhport-admin/target.rst:189
msgid "Once the target is created, you should add a passhport ssh public key to "
"the target and use \"checkaccess\" to verify everything is ok."
msgstr "Pensez à copier une clé public de passhport sur la target et à tester "
"avec \"checkaccess\" les accès à votre nouvelle target."


#: ../../passhport-admin/target.rst:190
msgid "edit"
msgstr "edit"
Expand Down
71 changes: 11 additions & 60 deletions docs/user-side-usage/connect_to_passhport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,72 +4,23 @@ Connect to PaSSHport
On Windows
------------

Well take the
You can use Putty to connect to the passhport bastion indicating your private key.


You can call passhport-admin's CLI, by calling ``passhport-admin`` with the ``-i``.

You can then configure passhportd through this command line. Refer to the good section in the submodule doc to know how to use them.

















Usages :
On Linux / *nix
---------------
Use your standard SSH client and connect to the bastion as passhport user:
.. code-block:: none
passhport-admin target list
passhport-admin target search [<pattern>]
passhport-admin target checkaccess [<pattern>]
passhport-admin target show [<name>]
passhport-admin target create [((<name> <hostname>) [--login=<login>] [--type=<ssh>] [--comment=<comment>] [--sshoptions=<sshoptions>] [--port=<port>])]
passhport-admin target edit [(<name> [--newname=<name>] [--newhostname=<hostname>] [--newlogin=<login>] [--newcomment=<comment>] [--newsshoptions=<sshoptions>] [--newport=<port>])]
passhport-admin target (adduser | rmuser) [(<username> <targetname>)]
passhport-admin target (addusergroup | rmusergroup) [(<usergroupname> <targetname>)]
passhport-admin target delete [([-f | --force] <name>)]
list
-----

`passhport-admin target list` show all the configured targets.

**Example :**

ssh passhport@bastion.tld
If you want to be directly connected, you have to specify the target name in the command AND to activate the -t option:
.. code-block:: none
admin@bastion:~$ passhport-admin target list
srv1.compagny.com
srv2.compagny.com
srv3.compagny.com
websrv.ext.client.com
webbackend.ext.client.com
admin@bastion:~$
search
---------

`passhport-admin target search [<PATTERN>]` searches in the target list for all targets that correspond to the given pattern.

**Example :**

ssh -t passhport@bastion.tld targetname
If you want to launch a command directly, you can use the same syntax adding the command at the end
.. code-block:: none
admin@bastion:~$ passhport-admin target search web
websrv.ext.client.com
webbackend.ext.client.com
admin@bastion:~$
If no pattern is given, user enters in interactive mode.
ssh -t passhport@bastion.tld targetname cat /proc/cpuinfo
49 changes: 42 additions & 7 deletions passhport-admin/manager/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,34 @@ def prompt_checkaccess():

def prompt_create():
"""Prompt user to obtain data to create a target"""
port = ""
sshoptions = ""
changepwd = ""
sessiondur = ""

name = input("Name: ")
hostname = input("Hostname: ")
targettype = input("Type (default is ssh): ")
if targettype == "":
targettype = "ssh"
login = input("Login (default is root): ")
port = ask_port("Port: ")
sshoptions = input("SSH Options: ")
changepwd = input("Change the password after each connection (type 'yes' if you really want it): ")
if targettype == "ssh":
port = ask_port("Port (default is 22):")
sshoptions = input("SSH Options: ")
changepwd = input("Change the password after each connection (type 'yes' if you really want it): ")
elif targettype in ["mysql", "postgresql", "oracle", "kubernetes"]:
port = ask_port("Port:")
sessiondur = input("Session duration in minutes (default is 12hours):")
comment = input("Comment: ")


return {"<name>": name,
"<hostname>": hostname,
"--type": targettype,
"--login": login,
"--sshoptions": sshoptions,
"--port": port,
"--sessiondur": sessiondur,
"--changepwd": changepwd,
"--comment": comment}

Expand All @@ -71,6 +84,7 @@ def create(param):
sshoptions = ""
changepwd = ""
comment = ""
sessiondur = ""

if "--type" in param:
targettype = param["--type"]
Expand Down Expand Up @@ -102,30 +116,50 @@ def create(param):
else:
changepwd = "False"

if "--sessiondur" in param:
sessiondur = param["--sessiondur"]

print(sessiondur)

return {"name": param["<name>"],
"hostname": param["<hostname>"],
"targettype": targettype,
"login": login,
"port": port,
"sshoptions": sshoptions,
"changepwd": changepwd,
"comment": comment}
"comment": comment,
"sessiondur": sessiondur}


def prompt_edit(req):
"""Prompt user to obtain data to edit a target"""
name = input("Name of the target you want to modify: ")
if not name:
return False

new_port = ""
new_sshoptions = ""
new_changepwd = ""
new_sessiondur = ""

if req.show("target", {"<name>": name}) == 0:
new_name = input("New name: ")
new_hostname = input("New hostname: ")
new_targettype = input("New type (ssh, mysql, oracle, postgresql): ")
new_login = input("New Login: ")
new_port = ask_port("New port: ")
new_sshoptions = input("New SSH options: ")
new_changepwd = input("Change the password after each connection (type 'yes' if you really want it): ")
if new_targettype == "ssh":
new_login = input("New Login: ")
new_changepwd = input("Change the password after each connection (type 'yes' if you really want it): ")
new_sshoptions = input("New SSH options: ")
elif new_targettype in ["mysql", "oracle", "postgresql"]:
new_sessiondur = input("New session duration in minutes:")
else: # we can't determine which kind of type is, we ask for all
new_login = input("New Login: ")
new_changepwd = input("Change the password after each connection (type 'yes' if you really want it, ssh root access only): ")
new_sshoptions = input("New SSH options: ")
new_sessiondur = input("New session duration in minutes (mysql, oracle and postgresql only:")
new_comment = input("New comment: ")
if len(new_comment.strip()) == 0:
answer = input("Remove original comment? [y/N]")
Expand All @@ -140,7 +174,8 @@ def prompt_edit(req):
"--newport": new_port,
"--newsshoptions": new_sshoptions,
"--newchangepwd": new_changepwd,
"--newcomment": new_comment}
"--newcomment": new_comment,
"--newsessiondur": new_sessiondur}


def edit(param):
Expand Down
10 changes: 8 additions & 2 deletions passhport-admin/passhport-admin
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ Usage:
passhport-admin target show [<name>]
passhport-admin target create [((<name> <hostname>) [--login=<login>] \
[--type=<ssh>] [--comment=<comment>] [--changepwd=<yes|no>] [--sshoptions=<sshoptions>] \
[--port=<port>])]
[--port=<port>] [--sessiondur=<sessiondur>])]
passhport-admin target edit [(<name> [--newname=<name>] \
[--newhostname=<hostname>] [--newtype=<ssh>] [--newlogin=<login>] [--newchangepwd=<yes|no>] \
[--newcomment=<comment>] [--newsshoptions=<sshoptions>] [--newport=<port>])]
[--newcomment=<comment>] [--newsshoptions=<sshoptions>] [--newport=<port>] \
[--sessiondur=<sessiondur>]) ]
passhport-admin target (adduser | rmuser) \
[(<username> <targetname>)]
passhport-admin target (addusergroup | rmusergroup) \
Expand Down Expand Up @@ -83,6 +84,8 @@ confirmation.
--sshoptions=<sshoptions> Set SSH options to the target.
--port=<port> Set port used to connect with \
the target.
--sessiondur=<sessiondur> Set the session duration in minutes for \
when supported.
--newname=<name> Set the new name of the object.
--newcomment=<comment> Set the new comment of the object.
--newsshkey=<sshkey> Set the new SSH key of the user.
Expand All @@ -91,6 +94,9 @@ the target.
--newsshoptions=<sshoptions> Set the new SSH options \
of the target.
--newport=<port> Set the new port used \
--newsessiondur=<sessiondur> Set the new session duration in minutes for \
when supported.
with the target.
"""

Expand Down
22 changes: 12 additions & 10 deletions passhport/passhport
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ SCRIPT_LOGS_PATH = conf.get("Environment", "SCRIPT_LOGS_PATH")
SCP_THROUGH_TARGET = conf.getboolean("MISC", "SCP_THROUGH_TARGET")
UNIQ_TARGETS_ID = conf.getboolean("MISC", "UNIQ_TARGETS_ID")
NODE_NAME = conf.get("MISC", "NODE_NAME")
SSH_SCRIPT = conf.get("Environment", "SSH_SCRIPT")

def signal_handler(signal, frame):
"""Handle 'ctrl-c' from the users"""
Expand Down Expand Up @@ -83,10 +84,6 @@ def checkandconnect(indexed_target_list, choice, username, originalcmd,
"""Check if the user have entered an accessible target
then check target type and launch the action"""

#In order to allow an automatic login name for each user:
login = re.split("@", username)[0] #We take the first part of the email


# Check the target access and access type
potential_target = False
target_found = False
Expand Down Expand Up @@ -171,7 +168,7 @@ def checkandconnect(indexed_target_list, choice, username, originalcmd,
cert = "/dev/null"
else:
cert = SSL_CERTIFICAT
SSH_SCRIPT = conf.get("Environment", "SSH_SCRIPT")
# Standard SSH connection
ssh.connect(target, filelog, login, port, sshoptions, pid,
url_passhport, cert, SSH_SCRIPT, username, originalcmd)

Expand Down Expand Up @@ -362,7 +359,7 @@ if __name__ == '__main__':
target_list = get(url_passhport + "user" + accessible_targets + \
username).split("\n")
except AttributeError as e:
sys.exit("No user exists in database or can't reach passhportd.\n" +
sys.exit("No such user in PaSSHport database.\n" +
"tip: it can be a SSL certificate misconfiguration.")
originalcmd = os.environ.get('SSH_ORIGINAL_COMMAND')
choice = 0
Expand Down Expand Up @@ -406,15 +403,20 @@ if __name__ == '__main__':
# Let the use chose his server
try:
choice = input("Type the number, name or hostname of the " + \
"server you want to connect to: ").rstrip().casefold()
"server you want to connect to: ").rstrip().casefold()
except EOFError:
print("\nExiting at your own sweet will.")
sys.exit(0)

valid_input = False

# Try to connect the user to the server he choosed or ask to re-type
while not checkandconnect(indexed_target_list, choice, username, originalcmd):
while not checkandconnect(indexed_target_list, choice,
username, originalcmd):
print("You didn't type correctly, please try again.\n")
choice = input("Type the number, name or hostname of the " + \
"server you want to connect to: ").rstrip().casefold()
try:
choice = input("Type the number, name or hostname of the " + \
"server you want to connect to: ").rstrip().casefold()
except EOFError:
print("\nExiting at your own sweet will.")
sys.exit(0)
7 changes: 4 additions & 3 deletions passhport/passhport-connect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ PASSHPORTBIN="${PASSHHOMEDIR}/passhport/passhport/passhport"


###### We trap a manual window close to let the script to end ######
trap "echo 'You are not allowed to stop disconnection'" SIGHUP SIGINT SIGKILL SIGTERM SIGSTOP
trap "echo 'You are not allowed to stop disconnection. Consider Ctrl-D.'" SIGHUP SIGINT SIGKILL SIGTERM SIGSTOP

#Remove 7 first arguments and put the others in the OPTIONS variable
i=0
Expand All @@ -45,7 +45,8 @@ else
fi

# Launch PaSSHport with the same user after the connection
if [ "${KEEPCONNECT}" -eq "1" ]
# If it's a direct connection, we don't connect again
if [ "${KEEPCONNECT}" -eq "1" ] && [ -z "${SSH_ORIGINAL_COMMAND}" ]
then
${PYTHONBIN} ${PASSHPORTBIN} ${USERNAME}
exec ${PYTHONBIN} ${PASSHPORTBIN} ${USERNAME}
fi

0 comments on commit cff5a8f

Please sign in to comment.