Coder Social home page Coder Social logo

ssh-ldap-pubkey's Introduction

OpenSSH / LDAP public keys

Build Status Code Climate version

This project provides an utility to manage SSH public keys stored in LDAP and also a script for OpenSSH server to load authorized keys from LDAP.

Why?

When you have dozen of servers it becomes difficult to manage your authorized keys. You have to copy all your public keys to ~/.ssh/authorized_keys on every server you want to login to. And what if you someday change your keys?

It’s a good practice to use some kind of a centralized user management, usually an LDAP server. There you have user’s login, uid, e-mail, … and password. What if we could also store public SSH keys on LDAP server? With this utility it’s easy as pie.

Alternatives

If you need just a lightweight utility for OpenSSH server to load authorized keys from LDAP, then you can use ssh-getkey-ldap written in Lua or this one written in POSIX shell (but it requires ldapsearch utility and may not work well on some systems).

Requirements

You can install both Python modules from PyPI. python-ldap requires additional system dependencies – OpenLDAP. Refer to Stack Overflow for distribution-specific information.

Installation

PyPI:

pip install ssh-ldap-pubkey

Alpine Linux

apk add ssh-ldap-pubkey

Note: The package is currently in the (official) community repository; make sure that you have community in /etc/apk/repositories.

Usage

List SSH public keys stored in LDAP for the current user:

ssh-ldap-pubkey list

List SSH public keys stored in LDAP for the specified user:

ssh-ldap-pubkey list -u flynn

Add the specified SSH public key for the current user to LDAP:

ssh-ldap-pubkey add ~/.ssh/id_rsa.pub

Remove SSH public key(s) of the current user that matches the specified pattern:

ssh-ldap-pubkey del flynn@grid

Specify LDAP URI and base DN on command line instead of configuration file:

ssh-ldap-pubkey list -b ou=People,dc=encom,dc=com -H ldaps://encom.com -u flynn

As the LDAP manager, add SSH public key to LDAP for the specified user:

ssh-ldap-pubkey add -D cn=Manager,dc=encom,dc=com -u flynn ~/.ssh/id_rsa.pub

Show help for other options:

ssh-ldap-pubkey --help

Configuration

Configuration is read from /etc/ldap.conf — file used by LDAP nameservice switch library and the LDAP PAM module. An example file is included in etc/ldap.conf. The following subset of parameters are used:

  • uri ... URI(s) of the LDAP server(s) to connect to, separated by a space. The URI scheme may be ldap, or ldaps. Default is ldap://localhost.
  • nss_base_passwd ... distinguished name (DN) of the search base.
  • base ... distinguished name (DN) of the search base. Used when nss_base_passwd is not set.
  • scope ... search scope; sub, one, or base (default is sub).
  • referrals ... should client automatically follow referrals returned by LDAP servers (default is on)?
  • pam_filter ... filter to use when searching for the user’s entry, additional to the login attribute value assertion (pam_login_attribute=<login>). Default is objectclass=posixAccount.
  • pam_login_attribute ... the user ID attribute (default is uid).
  • ldap_version ... LDAP version to use (default is 3).
  • sasl ... enable SASL and specify mechanism to use (currently only GSSAPI is supported).
  • binddn ... distinguished name (DN) to bind when reading the user’s entry (default is to bind anonymously).
  • bindpw ... credentials to bind with when reading the user’s entry (default is none).
  • ssl ... LDAP SSL/TLS method; off, on, or start_tls. If you use LDAP over SSL (i.e. URI ldaps://), leave this empty.
  • timelimit ... search time limit in seconds (default is 10).
  • bind_timelimit ... bind/connect time limit in seconds (default is 10). If multiple URIs are specified in uri, then the next one is tried after this timeout.
  • tls_cacertdir ... path of the directory with CA certificates for LDAP server certificate verification.
  • pubkey_class ... objectClass that should be added/removed to/from the user’s entry when adding/removing first/last public key and the pubkey_attr is mandatory for this class. This is needed for the original openssh-lpk.schema (not for the one in this repository). Default is ldapPublicKey.
  • pubkey_attr ... name of LDAP attribute used for SSH public keys (default is sshPublicKey).

The only required parameter is nss_base_passwd or base, others have sensitive defaults. You might want to define uri parameter as well. These parameters can be also defined/overriden with --bind and --uri options on command line.

For more information about these parameters refer to ldap.conf man page.

Set up OpenSSH server

To configure OpenSSH server to fetch users’ authorized keys from LDAP server:

  1. Make sure that you have installed ssh-ldap-pubkey and ssh-ldap-pubkey-wrapper in /usr/bin with owner root and mode 0755.

  2. Add these two lines to /etc/ssh/sshd_config:

    AuthorizedKeysCommand /usr/bin/ssh-ldap-pubkey-wrapper
    AuthorizedKeysCommandUser nobody
    
  3. Restart sshd and check log file if there’s no problem.

Note: This method is supported by OpenSSH since version 6.2-p1 (or 5.3 onRedHat). If you have an older version and can’t upgrade, for whatever weird reason, use openssh-lpk patch instead.

Set up LDAP server

Just add the openssh-lpk.schema to your LDAP server, or add an attribute named sshPublicKey to any existing schema which is already defined in people entries. That’s all.

Note: Presumably, you’ve already set up your LDAP server for centralized unix users management, i.e. you have the NIS schema and users in LDAP.

License

This project is licensed under MIT license.

ssh-ldap-pubkey's People

Contributors

arno avatar basvandervlies avatar bish0polis avatar epoelke avatar frennkie avatar frillip avatar jirutka avatar jnv avatar k1rk avatar robbat2 avatar yysushi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ssh-ldap-pubkey's Issues

New commands (including sync with file, validity management…)

Hello,

my team has been using ssh-ldap-pubkey for a while, and made lots of changes to it, based on the 0.4.1 version. I'm currently porting these changes to the 1.3.2 version, and I wonder if some of them are worth being merged upstream. I'm aware this tool needs to keep its simplicity, but I'm sure some of these changes can benefit to many people, that's why I'd like to share them. Here is the usage text:

Usage:
  ssh-ldap-pubkey list [options]
  ssh-ldap-pubkey listall [options]
  ssh-ldap-pubkey add [options] FILE
  ssh-ldap-pubkey rm [options] FILE
  ssh-ldap-pubkey sync [options] FILE
  ssh-ldap-pubkey del [options] PATTERN
  ssh-ldap-pubkey purge [options]
  ssh-ldap-pubkey --help

  -                      Read public key from stdin.
  FILE                   Path to the public key file to add.
  PATTERN                Pattern that specifies public key(s) to delete, i.e.
                         a complete key or just a part of it.

Options:
  -a ATTRS --attrs=ATTRS
                         Comma separated list of returned attributes when
                         listing public key(s) for all users. [default: uid]
  -b DN --base=DN        Base DN where to search for the users' entry. If not
                         provided, then it's read from the config file.
  -c FILE --conf=FILE    Path of the ldap.conf (default is /etc/ldap.conf).
                         The ldap.conf is not required when at least --base is
                         provided.
  -D DN --binddn=DN      DN to bind with instead of the user's DN.
  -e DAYS --expire=DAYS  When adding a public key: add an expiration date, when
                         listing public key(s): check if the key will be
                         expired in DAYS days from today (instead of today).
  -H URI --uri=URI       URI of the LDAP server to connect; loaded from the
                         config file by default. If not defined even there,
                         then it defaults to ldap://localhost.
  -j --json              Output in json format (only for listall)
  -m MAX --max=MAX       Max count of keys included in FILE that is allowed to
                         be processed. If greater than MAX, no operation is
                         performed (checked in add/sync).
  -p --purge             In sync mode, purge stored entries instead of expiring
                         them when necessary.
  -q --quiet             Be quiet.
  -u LOGIN --user=LOGIN  Login of the user to bind as and change public key(s)
                         (default is the current user).
  -U --uid               Only display uid (only for listall)
  -V VALIDITY --validity=VALIDITY
                         VALIDITY can be: 'all' to list all public keys,
                         'valid' to list only valid (i.e. unexpired) public
                         key(s), 'invalid' to list public keys not having an
                         expiration date, 'expired' to list expired public
                         key(s) or 'expire' to list key(s) still valid but
                         that will be expired in DAYS days from today having
                         DAYS provided using -e DAYS, [default: all].
  -v --version           Show version information.
  -h --help              Show this message.

New commands

listall

Without options, lists public keys of all users.
With the --uid option, lists all logins which have a public key.
With the --json option, outputs logins and keys in JSON format. You can use --attrs if you want to list other attributes. Yes it adds a dependence to json, but it's really useful for admins / bots to have a global view of users and public keys.

rm

Same as del, but instead of using a pattern, it uses a file containing the keys to delete. Maybe should we add an option to del in order to use a file?

sync

Synchronize public keys of a user with a file. If a key is in the file, make sure it is in ldap. If a key is not in the file, delete it from ldap.
The --purge option affects the behavior related to key expiration (see below).

purge

Delete all key of a user.

New options

--expire=DAYS and --validity=VALIDITY

These options add the support of key expiration. It's an important security feature, and allows to keep track of old expired keys (so they're not used again).

--max=MAX

Limits the number of authorized keys in a file during imports (with add / sync).

Your opinion?

What's your opinion about this? If you think some of this is worth being merged upstream, please tell me how you'd want me to proceed. I can make small patches and PRs in your preferred order if you don't want to include everything in one big patch (it's not that big in fact). If you think some functionality is interesting but should be made differently, please let me know, I'll be happy to rework it.

ssh-ldap-pubkey always timeouts

I'm struggling to configure another instance using ssh-ldap-pubkey – I'm getting forever search (set by /etc/ldap.conf:timelimit) ldap.TIMEOUT.

I have this config:

binddn cn=provider,dc=example,dc=com
bindpw secretpass
base dc=example,dc=com
nss_base_passwd ou=users,dc=example,dc=com

The connection is estabilished to LDAP server (can see it via lsof -iTCP).

Users in my LDAP are having DN like:
uid=my.user,ou=users,dc=example,dc=com

Any ideas where timeout comes?

Attribute name

Hello,

I want to store SSH public keys in LDAP server. I found several solutions and I think that your variant is better. But we use Univention Corporate Server 4.1 and it has ability to create custom extended attribute. But it provides already predefined names of these attributes (from univentionFreeAttribute1 to univentionFreeAttribute20). Also we can create custom attribute only inside univentionFreeAttributes object class.
Since your software uses predefined attribute named sshPublicKey, then it doesn't find key in LDAP server. So question is can we specify somehow what LDAP attribute contains SSH key?
Or maybe you will add such functionality?

Thanks in advance.

ssh-ldap-pubkey-wrapper would fail with "logger: unrecognized option: i" in alpine

In the context of alpine environment,
I suppose that logger command in /usr/bin/ssh-ldap-pubkey-wrapper is wrong.

It expects to log its PID by passing i option. But, logger command in alpine (strinctly speeking, busybox?) not support it.
The below code block shows the issue which I faced.

/ # sh -x /usr/bin/ssh-ldap-pubkey-wrapper johndoe
+ set -eu
+ SSH_USER=johndoe
+ ssh-ldap-pubkey list -q -u johndoe
+ KEYS='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIETyLURmpRVOS6sLEy1wC9p4RO0BzgGZoZu5QDKMEKri'
+ printf '%s\n' 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIETyLURmpRVOS6sLEy1wC9p4RO0BzgGZoZu5QDKMEKri'
+ grep ^ssh
+ wc -l
+ KEYS_COUNT=1
+ logger -i -t sshd -p info 'Loaded 1 SSH public key(s) from LDAP for user: johndoe'
logger: unrecognized option: i
BusyBox v1.31.1 () multi-call binary.

Usage: logger [OPTIONS] [MESSAGE]

Write MESSAGE (or stdin) to syslog

        -s      Log to stderr as well as the system log
        -t TAG  Log using the specified tag (defaults to user name)
        -p PRIO Priority (numeric or facility.level pair)

My alpine and busybox version are 3.11.6 and v1.31.1 respectively.

/ # alpine -version
ash: alpine: not found
/ # cat /etc/alpine-release
3.11.6
/ # busybox
BusyBox v1.31.1 () multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
...

And ssh-ldap-pubkey version is 1.3.2.

/ # apk info ssh-ldap-pubkey
WARNING: Ignoring APKINDEX.70f61090.tar.gz: No such file or directory
WARNING: Ignoring APKINDEX.ca2fea5b.tar.gz: No such file or directory
ssh-ldap-pubkey-1.3.2-r1 description:
Utility to manage SSH public keys stored in LDAP

ssh-ldap-pubkey-1.3.2-r1 webpage:
https://github.com/jirutka/ssh-ldap-pubkey

ssh-ldap-pubkey-1.3.2-r1 installed size:
135168

I confirmed authentication started to succeed after overwriting the command option.
Thank you for very useful software.

1.3.1 breaks listing keys

# ssh-ldap-pubkey list -u cmclaughlin
dc=XXXmyorgXXX,dc=com 2 (&((objectclass=posixAccount))(uid=cmclaughlin))
Traceback (most recent call last):
  File "/usr/local/bin/ssh-ldap-pubkey", line 144, in <module>
    main(**kwargs)
  File "/usr/local/bin/ssh-ldap-pubkey", line 126, in main
    keys = ldapssh.find_pubkeys(login)
  File "/usr/local/lib/python2.7/site-packages/ssh_ldap_pubkey/__init__.py", line 209, in find_pubkeys
    return self._find_pubkeys(self.find_dn_by_login(login))
  File "/usr/local/lib/python2.7/site-packages/ssh_ldap_pubkey/__init__.py", line 241, in find_dn_by_login
    result = self._conn.search_s(conf.base, conf.scope, filter_s, ['dn'])
  File "/usr/local/lib64/python2.7/site-packages/ldap/ldapobject.py", line 854, in search_s
    return self.search_ext_s(base,scope,filterstr,attrlist,attrsonly,None,None,timeout=self.timeout)
  File "/usr/local/lib64/python2.7/site-packages/ldap/ldapobject.py", line 847, in search_ext_s
    msgid = self.search_ext(base,scope,filterstr,attrlist,attrsonly,serverctrls,clientctrls,timeout,sizelimit)
  File "/usr/local/lib64/python2.7/site-packages/ldap/ldapobject.py", line 843, in search_ext
    timeout,sizelimit,
  File "/usr/local/lib64/python2.7/site-packages/ldap/ldapobject.py", line 331, in _ldap_call
    reraise(exc_type, exc_value, exc_traceback)
  File "/usr/local/lib64/python2.7/site-packages/ldap/ldapobject.py", line 315, in _ldap_call
    result = func(*args,**kwargs)
ldap.FILTER_ERROR: {u'info': 'Resource temporarily unavailable', 'errno': 11, 'desc': u'Bad search filter'}

Downgrading to 1.3.0 made the problem go away.

Thanks

Ldap password bindpw cannot contain #

Hi,

I have a ldap password that contains "#". In this case, I have a

Error: Invalid credentials for XXX

Analysis:
The code https://github.com/jirutka/ssh-ldap-pubkey/blob/master/ssh_ldap_pubkey/config.py transforms the config /etc/ldap.conf into a dict. This convenient method:
re.match(r'^(\w+)\s+([^#]+)', line)
reject all comments after "#". Eg:
binddn cn=XXX # exemple of comment to ignore

However this also make impossible to use a password with "#" inside. Eg:
bindpw abcd#efg
will set a bindpw to abcd.

If we want both the ability to add comment at the end of a configuration line, and the ability to add "#" in password, we should make the bindpw a special parsing. I do not see another way.

SSSD/Winbind support?

Currently, my Linux systems are Active Directory joined using SSSD and realmd (but I would be willing to migrate to using winbind directly if that's easier). My AD controller is Server 2016 with LDAPS enabled.

I'm not super familiar with how the architecture works internally (other than how to install and turn it on), but I believe SSSD is doing its own LDAP lookups against the DC without consulting OpenLDAP.

Is it possible for this project to integrate with something like that? Or do I have to set up OpenLDAP in addition to SSSD to make this work?

requires ldif + sasl headers on system

If those are not installed, you end up in compile errors during pip install, like

Modules/LDAPObject.c:16:10: fatal error: sasl/sasl.h: No such file or directory

support for multiple nss_base_passwd in config

I've users under multiple DN eg: ou=People,dc=org,dc=net and ou=Account,dc=org,dc=net

I've added multiple nss_base_passwd in /etc/ldap.conf. This is not working with ssh-ldap-pubkey. The config is only picking one entry which ever is last. Is it possible to support for multiple DN for base?

ssh-ldap-pubkey-wrapper can't find ssh-ldap-pubkey if not in PATH

I installed ssh-ldap-pubkey using pip, pip is using /usr/local as the base path because I am using a python3.8 from pkgsrc.

Everything works fine when running as myself, root or nobody (via sudo) as the PATH variable gets set correctly by /etc/profile, but no such lock when ssh-ldap-pubkey-wrapper is run by sshd as /usr/local does not get added to PATH for it.

For now I have added an export of PATH to ssh-ldap-pubkey-wrapper, but there are probably better solutions.

1.1.0 seems to break existing single-URI setups

This looks to be due to the new config parsing a single uri from the default config file (/etc/ldap.conf) as a list of chars, instead of a string.

So the argument passed to ldap.initialize https://github.com/jirutka/ssh-ldap-pubkey/blob/master/ssh_ldap_pubkey/init.py#L104 becomes l d a p : / / m y . l d a p . u r i/. . .

It looks like some backwards-compatibility considerations were included but are not helping for reasons I can't yet see. The quick fix for my situation is to just join on '' instead of ' ', effectively rolling the update back.

Please let me know if you have any trouble reproducing and I can put together a specific test case to help.

Login process without creating first the users

Hey guys,

This process works just fine if:

  • the useradd random_user command was run on the server (prior to user's attempt to log in)
  • the random_user has an entry in LDAP with a correct sshPublicKey value set up

Hooray!

However...
Is there a process for this to work without first creating the users locally?

You guys would probably save my life if there is such a thing :)

Thanks,
Marius

Can't connect to ldap when anonymous binding is disabled

I disable anonymous binding on openldap and I can't connect using specified bind dn

# The distinguished name to bind to the server with.
# Default is to bind anonymously.
uid=binduser,ou=People,dc=example,dc=com
# The credentials to bind with. Default is no credential.
bindpw hhhhhhh

ldif to disable anon binding ldap_disable_bind_anon.ldif

dn: cn=config
changetype: modify
add: olcDisallows
olcDisallows: bind_anon

dn: cn=config
changetype: modify
add: olcRequires
olcRequires: authc

dn: olcDatabase={-1}frontend,cn=config
changetype: modify
add: olcRequires
olcRequires: authc

Binding works correctly when anon binding is enabled on openldap.

ssh-ldap-pubkey 1.3.2
OpenLDAP: slapd 2.4.44
Stack from python

/usr/local/bin/ssh-ldap-pubkey-wrapper tester
Traceback (most recent call last):
  File "/usr/local/bin/ssh-ldap-pubkey", line 144, in <module>
    main(**kwargs)
  File "/usr/local/bin/ssh-ldap-pubkey", line 126, in main
    keys = ldapssh.find_pubkeys(login)
  File "/usr/local/lib/python3.6/site-packages/ssh_ldap_pubkey/__init__.py", line 209, in find_pubkeys
    return self._find_pubkeys(self.find_dn_by_login(login))
  File "/usr/local/lib/python3.6/site-packages/ssh_ldap_pubkey/__init__.py", line 240, in find_dn_by_login
    result = self._conn.search_s(conf.base, conf.scope, filter_s, ['dn'])
  File "/usr/lib64/python3.6/site-packages/ldap/ldapobject.py", line 852, in search_s
    return self.search_ext_s(base,scope,filterstr,attrlist,attrsonly,None,None,timeout=self.timeout)
  File "/usr/lib64/python3.6/site-packages/ldap/ldapobject.py", line 846, in search_ext_s
    return self.result(msgid,all=1,timeout=timeout)[1]
  File "/usr/lib64/python3.6/site-packages/ldap/ldapobject.py", line 738, in result
    resp_type, resp_data, resp_msgid = self.result2(msgid,all,timeout)
  File "/usr/lib64/python3.6/site-packages/ldap/ldapobject.py", line 742, in result2
    resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all,timeout)
  File "/usr/lib64/python3.6/site-packages/ldap/ldapobject.py", line 749, in result3
    resp_ctrl_classes=resp_ctrl_classes
  File "/usr/lib64/python3.6/site-packages/ldap/ldapobject.py", line 756, in result4
    ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
  File "/usr/lib64/python3.6/site-packages/ldap/ldapobject.py", line 329, in _ldap_call
    reraise(exc_type, exc_value, exc_traceback)
  File "/usr/lib64/python3.6/site-packages/ldap/compat.py", line 44, in reraise
    raise exc_value
  File "/usr/lib64/python3.6/site-packages/ldap/ldapobject.py", line 313, in _ldap_call
    result = func(*args,**kwargs)
ldap.UNWILLING_TO_PERFORM: {'desc': 'Server is unwilling to perform', 'info': 'authentication required'}

connection with starttls

I have a problem with a connection over tls.

cat /etc/ldap.conf

uri ldap://192.168.1.2

base ou=Users,dc=domain,dc=name
ldap_version 3
ssl start_tls
tls_cacertfile /etc/ssl/certs/cacert.pem
sudo ssh-ldap-pubkey list -u myusername
Traceback (most recent call last):
  File "/usr/local/bin/ssh-ldap-pubkey", line 144, in <module>
    main(**kwargs)
  File "/usr/local/bin/ssh-ldap-pubkey", line 108, in main
    ldapssh.connect()
  File "/usr/local/lib/python2.7/dist-packages/ssh_ldap_pubkey/__init__.py", line 108, in connect
    conn.start_tls_s()
  File "/usr/local/lib/python2.7/dist-packages/python_ldap-2.4.40-py2.7-linux-x86_64.egg/ldap/ldapobject.py", line 614, in start_tls_s
    return self._ldap_call(self._l.start_tls_s)
  File "/usr/local/lib/python2.7/dist-packages/python_ldap-2.4.40-py2.7-linux-x86_64.egg/ldap/ldapobject.py", line 108, in _ldap_call
    result = func(*args,**kwargs)
ldap.CONNECT_ERROR: {'info': '(unknown error code)', 'desc': 'Connect error'}

if I set the ssl config on my openldap server to:
ssl off
then I am able to connect to my openldap server but unable to connect from other servers via the openldap server.

it works but only for my openldap server (I can login with my user without password prompt).

is there a configuration issue from my side, or is it running for someone over tls?

thanks for your help.

Installation path assumptions

When installing this from pip, the default on Debian/Ubuntu is to put the files under /usr/local/bin - but the wrapper script assumes a path prefix of /usr/bin.

Python 3.9 "AttributeError: module 'base64' has no attribute 'decodestring'"

Hey, I recently tried this project on debian testing, which is using python 3.9. Unfortunately i get the following error.

Traceback (most recent call last):
  File "/usr/local/bin/ssh-ldap-pubkey", line 144, in <module>
    main(**kwargs)
  File "/usr/local/bin/ssh-ldap-pubkey", line 114, in main
    ldapssh.add_pubkey(login, passw, pubkey)
  File "/usr/local/lib/python3.9/dist-packages/ssh_ldap_pubkey/__init__.py", line 146, in add_pubkey
    if not is_valid_openssh_pubkey(pubkey):
  File "/usr/local/lib/python3.9/dist-packages/ssh_ldap_pubkey/__init__.py", line 43, in is_valid_openssh_pubkey
    data = base64.decodestring(data64)

According to the release notes for 3.9 (https://docs.python.org/3/whatsnew/3.9.html) it should be now base64.decodestring()

base64.encodestring() and base64.decodestring(), aliases deprecated since Python 3.1, have been removed: use base64.encodebytes() and base64.decodebytes() instead. (Contributed by Victor Stinner in bpo-39351.)

base64.decodestring() is in python since 3.1. Do you think it is as simple as change the method name or what would be the minimum python version to support?

Specify LDAP URI and base DN on command line instead of configuration file

Hi,
when I issue the following command I get the following error message:
root@ldap:~# ssh-ldap-pubkey list -b ou=users,dc=intern,dc=example,dc=com -H ldaps://ldap.intern.example.com -u stefan.harbich Traceback (most recent call last): File "/usr/local/bin/ssh-ldap-pubkey", line 144, in <module> main(**kwargs) File "/usr/local/bin/ssh-ldap-pubkey", line 126, in main keys = ldapssh.find_pubkeys(login) File "/usr/local/lib/python2.7/dist-packages/ssh_ldap_pubkey/__init__.py", line 209, in find_pubkeys return self._find_pubkeys(self.find_dn_by_login(login)) File "/usr/local/lib/python2.7/dist-packages/ssh_ldap_pubkey/__init__.py", line 240, in find_dn_by_login result = self._conn.search_s(conf.base, conf.scope, filter_s, ['dn']) File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 852, in search_s return self.search_ext_s(base,scope,filterstr,attrlist,attrsonly,None,None,timeout=self.timeout) File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 845, in search_ext_s msgid = self.search_ext(base,scope,filterstr,attrlist,attrsonly,serverctrls,clientctrls,timeout,sizelimit) File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 841, in search_ext timeout,sizelimit, File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 329, in _ldap_call reraise(exc_type, exc_value, exc_traceback) File "/usr/lib/python2.7/dist-packages/ldap/ldapobject.py", line 313, in _ldap_call result = func(*args,**kwargs) ldap.SERVER_DOWN: {'info': u'(unknown error code)', 'errno': 115, 'desc': u"Can't contact LDAP server"}
The LDAP server is online:
`root@ldap:# netstat -tulpen | grep 636
tcp 0 0 192.168.20.20:636 0.0.0.0:* LISTEN 0 53490689 32604/slapd
root@ldap:
# nslookup

192.168.20.20
20.20.168.192.in-addr.arpa name = dsme01.intern.example.com.
20.20.168.192.in-addr.arpa name = ldap.intern.example.com.
20.20.168.192.in-addr.arpa name = mysql.intern.example.com.
`
Could it be a rights issue?

Greetings from Stefan Harbich

Support Kerberos for LDAP Authentication

I started using this to manage SSH Keys that are stored in an Active Directory. When I log into a linux machine I then already have a valid Kerberos ticket from the AD. It would be great if ssh-ldap-pubkey could simply use the existing user ticket for the LDAP connection.

AuthorizedKeysCommand /usr/bin/ssh-ldap-pubkey-wrapper failed, status 1

I installed ssh-ldap-pubkey as instructed, and tested it with:

ssh-ldap-pubkey list -u  abc
ssh-rsa AAA....

however when I tried to login as abc, I got this error in auth.log (after setting LogLevel DEBUG in /etc/ssh/sshd_config):

AuthorizedKeysCommand /usr/bin/ssh-ldap-pubkey-wrapper abc failed, status 1

What can I try to troubleshoot this problem?

SSH is not asking for the Private/Public Key

Hello there,

I have configured everything as explained in your guide.
I have changed my sshd configs as said too, but even though all of this was done, any SSH connection that I attempt to do still do not ask for any private key.

Running "ssh-ldap-pubkey list" returns me my Public key for the user, but even if that works, my SSH never asks me for a private key, and in fact I am able to login without any key for any user, which goes through the LDAP server.

I am using CentOs 6.6, my ssh version is 5.3 RHEL.

I am starting to wonder if something is missing in PAM ?
Any help would be greatly appreciated !

Provide option to turn off LDAP referrals

I ran into an issue trying to pull sshkeys out of my active directory and kept getting an Operations Error. After some digging I found this little nugget:

ldap.set_option(ldap.OPT_REFERRALS, 0)

http://peeved.org/blog/2007/11/20/

It appears that pyldap will try to chase down referrals causing the operations error. After setting this option I was successfully able to pull LDAP results from my active directory without issue.

Could we add this as a configurable option to address this kind of issue? It seems to be a fairly common one.

Installing python-ldap first causes mismatch between wrapper script and lib

If you install the python-ldap library globally with pip before installing ssh-ldap-pubkey, the ssh-ldap-pubkey-wrapper script will import the python-ldap module at the top level, but it will attempt to use the version installed by pyldap. This leads to errors when the two libraries drift.

We experienced an issue the other day due to the mismatch in an __init__ function between python-ldap (2.5.2) and pyldap (2.4.45):

$ /usr/local/bin/ssh-ldap-pubkey-wrapper test.user
Traceback (most recent call last):
  File "/usr/local/bin/ssh-ldap-pubkey", line 144, in <module>
    main(**kwargs)
  File "/usr/local/bin/ssh-ldap-pubkey", line 108, in main
    ldapssh.connect()
  File "/usr/local/lib/python2.7/dist-packages/ssh_ldap_pubkey/__init__.py", line 101, in connect
    self._conn = conn = ldap.initialize(' '.join(conf.uris))
  File "/usr/local/lib/python2.7/dist-packages/ldap/functions.py", line 94, in initialize
    return LDAPObject(uri,trace_level,trace_file,trace_stack_limit,bytes_mode)
TypeError: __init__() takes at most 5 arguments (6 given)

I'm not sure what the correct fix is here, just passing it along.

Supress python traceback in normal operation

When e.g. calling ssh-ldap-pubkey add for an user that is still missing the sshPublicKey attribute there naturally is an error message. But the ldap errors are covered by all the lines of the python traceback:

# ssh-ldap-pubkey add -H ldaps://<ldap-server>/ .ssh/id_ed25519.pub
Enter login (LDAP) password for user '<username>': 
Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/ssh_ldap_pubkey/__init__.py", line 159, in add_pubkey
    self._conn.modify_s(dn, modlist)
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 631, in modify_s
    return self.modify_ext_s(dn,modlist,None,None)
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 604, in modify_ext_s
    resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout)
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 751, in result3
    resp_ctrl_classes=resp_ctrl_classes
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 758, in result4
    ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 331, in _ldap_call
    reraise(exc_type, exc_value, exc_traceback)
  File "/usr/lib/python3.7/site-packages/ldap/compat.py", line 44, in reraise
    raise exc_value
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 315, in _ldap_call
    result = func(*args,**kwargs)
ldap.OBJECT_CLASS_VIOLATION: {'desc': 'Object class violation', 'info': "attribute 'sshPublicKey' not allowed"}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python-exec/python3.7/ssh-ldap-pubkey", line 147, in <module>
    main(**kwargs)
  File "/usr/lib/python-exec/python3.7/ssh-ldap-pubkey", line 117, in main
    ldapssh.add_pubkey(login, passw, pubkey)
  File "/usr/lib/python3.7/site-packages/ssh_ldap_pubkey/__init__.py", line 163, in add_pubkey
    self._conn.modify_s(dn, modlist)
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 631, in modify_s
    return self.modify_ext_s(dn,modlist,None,None)
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 604, in modify_ext_s
    resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all=1,timeout=self.timeout)
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 751, in result3
    resp_ctrl_classes=resp_ctrl_classes
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 758, in result4
    ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 331, in _ldap_call
    reraise(exc_type, exc_value, exc_traceback)
  File "/usr/lib/python3.7/site-packages/ldap/compat.py", line 44, in reraise
    raise exc_value
  File "/usr/lib/python3.7/site-packages/ldap/ldapobject.py", line 315, in _ldap_call
    result = func(*args,**kwargs)
ldap.INSUFFICIENT_ACCESS: {'desc': 'Insufficient access'}

I'd like to have only the lines:

# ssh-ldap-pubkey add -H ldaps://<ldap-server>/ --quiet .ssh/id_ed25519.pub
Enter login (LDAP) password for user '<username>': 
ldap.OBJECT_CLASS_VIOLATION: {'desc': 'Object class violation', 'info': "attribute 'sshPublicKey' not allowed"}

During handling of the above exception, another exception occurred:

ldap.INSUFFICIENT_ACCESS: {'desc': 'Insufficient access'}

here.

I'd suggest adding a new option -d --debug and printing the python traceback only when this option is supplied.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.