mirror of https://github.com/jumpserver/jumpserver
parent
a750fbb785
commit
e3f93a9410
@ -0,0 +1,123 @@
|
||||
from django.utils import timezone
|
||||
|
||||
__all__ = ['GatherAccountsFilter']
|
||||
|
||||
|
||||
# TODO 后期会挪到 playbook 中
|
||||
class GatherAccountsFilter:
|
||||
def __init__(self, tp):
|
||||
self.tp = tp
|
||||
|
||||
@staticmethod
|
||||
def mysql_filter(info):
|
||||
result = {}
|
||||
for _, user_dict in info.items():
|
||||
for username, _ in user_dict.items():
|
||||
if len(username.split('.')) == 1:
|
||||
result[username] = {}
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def postgresql_filter(info):
|
||||
result = {}
|
||||
for username in info:
|
||||
result[username] = {}
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def posix_filter(info):
|
||||
user_groups = info.pop('user_groups', [])
|
||||
username_groups = {}
|
||||
for line in user_groups:
|
||||
if ':' not in line:
|
||||
continue
|
||||
username, groups = line.split(':', 1)
|
||||
username_groups[username.strip()] = groups.strip()
|
||||
|
||||
user_sudo = info.pop('user_sudo', [])
|
||||
username_sudo = {}
|
||||
for line in user_sudo:
|
||||
if ':' not in line:
|
||||
continue
|
||||
username, sudo = line.split(':', 1)
|
||||
if not sudo.strip():
|
||||
continue
|
||||
username_sudo[username.strip()] = sudo.strip()
|
||||
|
||||
last_login = info.pop('last_login', '')
|
||||
user_last_login = {}
|
||||
for line in last_login:
|
||||
if not line.strip() or ' ' not in line:
|
||||
continue
|
||||
username, login = line.split(' ', 1)
|
||||
user_last_login[username] = login
|
||||
|
||||
user_authorized = info.pop('user_authorized', [])
|
||||
username_authorized = {}
|
||||
for line in user_authorized:
|
||||
if ':' not in line:
|
||||
continue
|
||||
username, authorized = line.split(':', 1)
|
||||
username_authorized[username.strip()] = authorized.strip()
|
||||
|
||||
passwd_date = info.pop('passwd_date', [])
|
||||
username_password_date = {}
|
||||
for line in passwd_date:
|
||||
if ':' not in line:
|
||||
continue
|
||||
username, password_date = line.split(':', 1)
|
||||
username_password_date[username.strip()] = password_date.strip().split()
|
||||
|
||||
result = {}
|
||||
users = info.pop('users', '')
|
||||
|
||||
for username in users:
|
||||
if not username:
|
||||
continue
|
||||
user = dict()
|
||||
|
||||
login = user_last_login.get(username) or ''
|
||||
if login and len(login) == 3:
|
||||
user['address_last_login'] = login[1][:32]
|
||||
try:
|
||||
login_date = timezone.datetime.fromisoformat(login[2])
|
||||
user['date_last_login'] = login_date
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
start_date = timezone.make_aware(timezone.datetime(1970, 1, 1))
|
||||
_password_date = username_password_date.get(username) or ''
|
||||
if _password_date and len(_password_date) == 2:
|
||||
if _password_date[0] and _password_date[0] != '0':
|
||||
user['date_password_change'] = start_date + timezone.timedelta(days=int(_password_date[0]))
|
||||
if _password_date[1] and _password_date[1] != '0':
|
||||
user['date_password_expired'] = start_date + timezone.timedelta(days=int(_password_date[1]))
|
||||
|
||||
user['groups'] = username_groups.get(username) or ''
|
||||
user['sudoers'] = username_sudo.get(username) or ''
|
||||
user['authorized_keys'] = username_authorized.get(username) or ''
|
||||
result[username] = user
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def windows_filter(info):
|
||||
info = info[4:-2]
|
||||
result = {}
|
||||
for i in info:
|
||||
for username in i.split():
|
||||
result[username] = {}
|
||||
return result
|
||||
|
||||
def run(self, method_id_meta_mapper, info):
|
||||
run_method_name = None
|
||||
for k, v in method_id_meta_mapper.items():
|
||||
if self.tp not in v['type']:
|
||||
continue
|
||||
run_method_name = k.replace(f'{v["method"]}_', '')
|
||||
|
||||
if not run_method_name:
|
||||
return info
|
||||
|
||||
if hasattr(self, f'{run_method_name}_filter'):
|
||||
return getattr(self, f'{run_method_name}_filter')(info)
|
||||
return info
|
@ -0,0 +1,61 @@
|
||||
- hosts: demo
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- name: Get users
|
||||
ansible.builtin.shell:
|
||||
cmd: >
|
||||
getent passwd | awk -F: '$7 !~ /(false|nologin|true|sync)$/' | grep -v '^$' | awk -F":" '{ print $1 }'
|
||||
register: users
|
||||
|
||||
- name: Gather posix account last login
|
||||
ansible.builtin.shell: |
|
||||
for user in {{ users.stdout_lines | join(" ") }}; do
|
||||
last -i --time-format iso -n 1 ${user} | awk '{ print $1,$3,$4, $NF }' | head -1 | grep -v ^$
|
||||
done
|
||||
register: last_login
|
||||
|
||||
- name: Get user password change date and expiry
|
||||
ansible.builtin.shell: |
|
||||
for user in {{ users.stdout_lines | join(" ") }}; do
|
||||
k=$(getent shadow $user | awk -F: '{ print $3, $5 }')
|
||||
echo "$user:$k"
|
||||
done
|
||||
register: passwd_date
|
||||
|
||||
- name: Get user groups
|
||||
ansible.builtin.shell: |
|
||||
for user in {{ users.stdout_lines | join(" ") }}; do
|
||||
echo "$(groups $user)" | sed 's@ : @:@g'
|
||||
done
|
||||
register: user_groups
|
||||
|
||||
- name: Get sudoers
|
||||
ansible.builtin.shell: |
|
||||
for user in {{ users.stdout_lines | join(" ") }}; do
|
||||
echo "$user: $(grep "^$user " /etc/sudoers | tr '\n' ';' || echo '')"
|
||||
done
|
||||
register: user_sudo
|
||||
|
||||
- name: Get authorized keys
|
||||
ansible.builtin.shell: |
|
||||
for user in {{ users.stdout_lines | join(" ") }}; do
|
||||
home=$(getent passwd $user | cut -d: -f6)
|
||||
echo -n "$user:"
|
||||
if [[ -f ${home}/.ssh/authorized_keys ]]; then
|
||||
cat ${home}/.ssh/authorized_keys | tr '\n' ';'
|
||||
fi
|
||||
echo
|
||||
done
|
||||
register: user_authorized
|
||||
|
||||
- set_fact:
|
||||
info:
|
||||
users: "{{ users.stdout_lines }}"
|
||||
last_login: "{{ last_login.stdout_lines }}"
|
||||
user_groups: "{{ user_groups.stdout_lines }}"
|
||||
user_sudo: "{{ user_sudo.stdout_lines }}"
|
||||
user_authorized: "{{ user_authorized.stdout_lines }}"
|
||||
passwd_date: "{{ passwd_date.stdout_lines }}"
|
||||
|
||||
- debug:
|
||||
var: info
|
@ -0,0 +1,13 @@
|
||||
id: gather_accounts_posix
|
||||
name: "{{ 'Posix account gather' | trans }}"
|
||||
category: host
|
||||
type:
|
||||
- linux
|
||||
- unix
|
||||
method: gather_accounts
|
||||
|
||||
i18n:
|
||||
Posix account gather:
|
||||
zh: 使用命令 getent passwd 收集 Posix 资产账号
|
||||
ja: コマンド getent を使用してアセットアカウントを収集する
|
||||
en: Using command getent to gather accounts
|
@ -0,0 +1,14 @@
|
||||
- hosts: demo
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- name: Gather windows account
|
||||
ansible.builtin.win_shell: net user
|
||||
register: result
|
||||
ignore_errors: true
|
||||
|
||||
- name: Define info by set_fact
|
||||
ansible.builtin.set_fact:
|
||||
info: "{{ result.stdout_lines }}"
|
||||
|
||||
- debug:
|
||||
var: info
|
@ -0,0 +1,13 @@
|
||||
id: gather_accounts_windows
|
||||
name: "{{ 'Windows account gather' | trans }}"
|
||||
version: 1
|
||||
method: gather_accounts
|
||||
category: host
|
||||
type:
|
||||
- windows
|
||||
|
||||
i18n:
|
||||
Windows account gather:
|
||||
zh: 使用命令 net user 收集 Windows 账号
|
||||
ja: コマンド net user を使用して Windows アカウントを収集する
|
||||
en: Using command net user to gather accounts
|
Loading…
Reference in new issue