# -*- coding: utf-8 -*-
from setuphelpers import *
import re
import datetime
import jinja2
###################
#
# This package is inspireted by "(Open)SSH secure use recommendations" documentation
# from National Cybersecurity Agency of France / ANSSI.
# English link : https://www.ssi.gouv.fr/en/guide/openssh-secure-use-recommendations/
# Franch link : https://www.ssi.gouv.fr/guide/recommandations-pour-un-usage-securise-dopenssh/
#
###################
# If you want to recording all command, set True
trap_command = False
options_list_check = ['Protocol 2','Port 22','#HostKey /etc/ssh/ssh_host_rsa_key','#HostKey /etc/ssh/ssh_host_ecdsa_key','HostKey /etc/ssh/ssh_host_ed25519_key',
'LoginGraceTime 2m','PermitRootLogin no','StrictModes yes','PasswordAuthentication no','PermitEmptyPasswords no','ChallengeResponseAuthentication no',
'UsePAM yes','AllowTcpForwarding no','X11Forwarding no','TCPKeepAlive yes','ClientAliveInterval 600','ClientAliveCountMax 0','PermitUserEnvironment no',
'AllowAgentForwarding no','MaxAuthTries 5','PermitTunnel no','LogLevel VERBOSE']
# If some servers need other AllowUsers than define in get_allow_users().
add_allow_users = {'server':{'user':'user@server','comment':'servername'}
}
sshd_config_file = makepath('/etc','ssh','sshd_config')
sshd_config_dir = makepath('/etc','ssh','sshd_config.d')
def get_allow_users():
add_user = ''
add_comment = ''
for server in add_allow_users:
if get_computername().lower() == server:
add_user = add_allow_users[server]['user']
add_comment = add_allow_users[server]['comment']
default_allow_users = f"""AllowUsers admin {add_user}
# {add_comment}
"""
return default_allow_users
def install():
print("Installing: %s" % control.package)
error('This package is protect against accidental launch. To disable the protection, edit the package and remove this line')
options_add = []
options_in = []
for option in options_list_check:
pattern = re.compile("^(%s)$" % option)
for line in open(sshd_config_file):
for match in re.finditer(pattern, line):
options_in.append(line.replace('\n',''))
pattern_allow_users = re.compile("^%s$" % get_allow_users().split('\n')[0])
for line in open(sshd_config_file):
for match in re.finditer(pattern_allow_users,line):
options_in.append(line.split('\n')[0])
options_list_check.append(get_allow_users().split('\n')[0])
print('Parameters already set : %s' % options_in)
for option in options_list_check:
if option in options_in:
pass
else:
options_add.append(option)
print('This parameters are to set : %s' % options_add)
if len(options_add)>0:
print('Backup old file config')
backup_file = makepath('/etc','ssh','sshd_config.old')
if isfile(backup_file):
backup_file = makepath('/etc','ssh','sshd_config.old%s' % datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
filecopyto(sshd_config_file,backup_file)
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'))
template = jinja_env.get_template('sshd_config.j2')
template_variables = {
'allow_users': get_allow_users(),
}
config_string = template.render(template_variables)
print(f'Create sshd_config configuration file with allow_users {get_allow_users()}')
with open(makepath('/etc','ssh','sshd_config'), 'wt') as dst_file:
dst_file.write(config_string)
print('Set 600 permission on sshd_config file')
run('chmod 600 /etc/ssh/sshd_config')
print('Set root ownership on sshd_config file')
run('chown root:root /etc/ssh/sshd_config')
print('Set permissions on /etc/ssh/sshd_config')
run('chown root:root /etc/ssh/sshd_config')
run('chmod og-rwx /etc/ssh/sshd_config')
if not isdir(sshd_config_dir):
mkdirs(sshd_config_dir)
filecopyto('files/ciphers.conf',sshd_config_dir)
run('chown -R root:root /etc/ssh/sshd_config.d/')
run('chmod -R 600 /etc/ssh/sshd_config.d/')
print('Restart sshd')
run('systemctl restart sshd')
if trap_command:
print('Set trap login')
trap_syslog = """function trap_to_syslog {
printf "%s %s from %s %s" "$HOSTNAME" "$SSHCLIENTUSER" "$SSH_CLIENT" "$USER[$$]@$PWD> $BASH_COMMAND" |logger -p local3.notice
}
trap trap_to_syslog DEBUG
"""
print('Check')
enable_trap = False
if is_debian_based():
bashrc_path = makepath('/etc','bash.bashrc')
else:
bashrc_path = makepath('/etc','bashrc')
for line in open(bashrc_path):
for match in re.finditer('^(function trap_to_syslog {)$',line):
enable_trap = True
if not enable_trap:
print('Set trap syslog')
with open(bashrc_path, 'a') as bashrc:
bashrc.write(trap_syslog)
def audit():
options_add = []
options_in = []
for option in options_list_check:
pattern = re.compile("^(%s)$" % option)
for line in open(sshd_config_file):
for match in re.finditer(pattern, line):
options_in.append(line.replace('\n',''))
pattern_allow_users = re.compile("^%s$" % get_allow_users().split('\n')[0])
for line in open(sshd_config_file):
for match in re.finditer(pattern_allow_users,line):
options_in.append(line.split('\n')[0])
options_list_check.append(get_allow_users().split('\n')[0])
for option in options_list_check:
if option in options_in:
pass
else:
options_add.append(option)
if len(options_add) > 0:
print('Some parameters are wrongs ! %s' % options_add)
WAPT.write_audit_data_if_changed("Securized SSH", 'Parameters in fault', options_add, keep_days=365)
return "ERROR"
else:
print('All parameters are OK')
WAPT.write_audit_data_if_changed("Securized SSH", 'Parameters in fault', "OK", keep_days=365)
return "OK"