Compare commits

...

No commits in common. "main" and "docs" have entirely different histories.
main ... docs

25 changed files with 8 additions and 690 deletions

11
.gitignore vendored
View File

@ -1,11 +0,0 @@
# ---> Ansible
*.retry
plugins
library
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

View File

@ -1,15 +0,0 @@
---
ansible:
custom_modules:
- iptables_raw
- openssl_pkcs12
- proxmox_kvm
- ucr
- corenetworks_dns
- corenetworks_token
rules:
exclude_files:
- "LICENSE*"
- "**/*.md"
- "**/*.ini"

View File

@ -1,7 +0,0 @@
---
default: True
MD013: False
MD041: False
MD024: False
MD004:
style: dash

View File

@ -1 +0,0 @@
LICENSE

View File

@ -1,47 +0,0 @@
---
when:
- event: [pull_request]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: generate
image: quay.io/thegeeklab/ansible-doctor
environment:
ANSIBLE_DOCTOR_EXCLUDE_FILES: molecule/
ANSIBLE_DOCTOR_FORCE_OVERWRITE: "true"
ANSIBLE_DOCTOR_LOG_LEVEL: INFO
ANSIBLE_DOCTOR_ROLE_NAME: ${CI_REPO_NAME}
ANSIBLE_DOCTOR_TEMPLATE: readme
- name: format
image: quay.io/thegeeklab/alpine-tools
commands:
- prettier -w README.md
- name: diff
image: quay.io/thegeeklab/alpine-tools
commands:
- git diff --color=always README.md
- name: publish
image: quay.io/thegeeklab/wp-git-action
settings:
action:
- commit
- push
author_email: ci-bot@rknet.org
author_name: ci-bot
branch: main
message: "[skip ci] automated docs update"
netrc_machine: gitea.rknet.org
netrc_password:
from_secret: gitea_token
when:
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
depends_on:
- test

View File

@ -1,30 +0,0 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
steps:
- name: ansible-later
image: quay.io/thegeeklab/ansible-later:4
commands:
- ansible-later
environment:
FORCE_COLOR: "1"
- name: python-format
image: docker.io/python:3.12
commands:
- pip install -qq ruff
- ruff format --check --diff .
environment:
PY_COLORS: "1"
- name: python-lint
image: docker.io/python:3.12
commands:
- pip install -qq ruff
- ruff .
environment:
PY_COLORS: "1"

View File

@ -1,26 +0,0 @@
---
when:
- event: [tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
runs_on: [success, failure]
steps:
- name: matrix
image: quay.io/thegeeklab/wp-matrix
settings:
homeserver:
from_secret: matrix_homeserver
password:
from_secret: matrix_password
roomid:
from_secret: matrix_roomid
username:
from_secret: matrix_username
when:
- status: [success, failure]
depends_on:
- docs

View File

@ -1,25 +0,0 @@
---
when:
- event: [pull_request, tag]
- event: [push, manual]
branch:
- ${CI_REPO_DEFAULT_BRANCH}
variables:
- &molecule_base
image: quay.io/thegeeklab/molecule:6
group: molecule
secrets:
- source: molecule_hcloud_token
target: HCLOUD_TOKEN
environment:
PY_COLORS: "1"
steps:
- name: molecule-default
<<: *molecule_base
commands:
- molecule test -s default
depends_on:
- lint

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 Robert Kaussow <mail@thegeeklab.de>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,61 +0,0 @@
---
sshd_protocol: 2
sshd_permit_root_login: "yes"
sshd_permit_empty_passwords: "no"
sshd_password_authentication: "no"
sshd_gssapi_authentication: "no"
sshd_strict_modes: "yes"
sshd_allow_groups: []
sshd_ignore_rhosts: "yes"
sshd_hostbased_authentication: "no"
sshd_client_alive_interval: 900
sshd_client_alive_count_max: 0
sshd_ciphers:
- chacha20-poly1305@openssh.com
- aes256-gcm@openssh.com
- aes128-gcm@openssh.com
- aes256-ctr
- aes192-ctr
- aes128-ctr
sshd_kex:
- curve25519-sha256@libssh.org
- diffie-hellman-group-exchange-sha256
sshd_moduli_minimum: 2048
sshd_macs:
- hmac-sha2-512-etm@openssh.com
- hmac-sha2-256-etm@openssh.com
- umac-128-etm@openssh.com
- hmac-sha2-512
- hmac-sha2-256
- umac-128@openssh.com
sshd_allow_agent_forwarding: "no"
sshd_x11_forwarding: "yes"
sshd_allow_tcp_forwarding: "yes"
sshd_compression: delayed
sshd_log_level: INFO
sshd_max_auth_tries: 6
sshd_max_sessions: 10
sshd_tcp_keep_alive: "yes"
sshd_use_dns: "no"
sshd_login_grace_time: 60
sshd_max_startups: "10:30:60"
sshd_crypto_policy_enabled: True
# @var sshd_challenge_response_authentication:description: >
# If you disable password auth you should disable ChallengeResponseAuth also.
# @end
sshd_challenge_response_authentication: "no"
# @var sshd_google_auth_enabled:description: >
# Google Authenticator required ChallengeResponseAuth!
# @end
sshd_google_auth_enabled: False
# @var sshd_google_auth_exclude_group:description: Exclude a group from 2FA auth
# @var sshd_google_auth_exclude_group:example: $ "my_group"
# @var sshd_google_auth_exclude_group: $ "_unset_"

View File

@ -1,6 +0,0 @@
---
- name: Restart ssh server
ansible.builtin.service:
name: sshd
state: restarted
listen: __sshd_restart

View File

@ -1,13 +1,14 @@
# xoxys.sshd
---
title: sshd
type: docs
---
[![Build Status](https://ci.rknet.org/api/badges/ansible/xoxys.sshd/status.svg)](https://ci.rknet.org/repos/ansible/xoxys.sshd)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?label=license)](https://gitea.rknet.org/ansible/xoxys.sshd/src/branch/main/LICENSE)
[![Source Code](https://img.shields.io/badge/gitea-source%20code-blue?logo=gitea&logoColor=white)](https://gitea.rknet.org/ansible/xoxys.sshd) [![Build Status](https://img.shields.io/drone/build/ansible/xoxys.sshd?logo=drone&server=https%3A%2F%2Fdrone.rknet.org)](https://drone.rknet.org/ansible/xoxys.sshd) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://gitea.rknet.org/ansible/xoxys.sshd/src/branch/main/LICENSE)
Configure sshd server.
## Table of content
<!--more-->
- [Requirements](#requirements)
- [Default Variables](#default-variables)
- [sshd_allow_agent_forwarding](#sshd_allow_agent_forwarding)
- [sshd_allow_groups](#sshd_allow_groups)
@ -40,15 +41,9 @@ Configure sshd server.
- [sshd_use_dns](#sshd_use_dns)
- [sshd_x11_forwarding](#sshd_x11_forwarding)
- [Dependencies](#dependencies)
- [License](#license)
- [Author](#author)
---
## Requirements
- Minimum Ansible version: `2.10`
## Default Variables
### sshd_allow_agent_forwarding
@ -317,14 +312,8 @@ sshd_use_dns: no
sshd_x11_forwarding: yes
```
## Dependencies
None.
## License
MIT
## Author
[Robert Kaussow](https://gitea.rknet.org/xoxys)

View File

@ -1,26 +0,0 @@
---
galaxy_info:
# @meta author:value: [Robert Kaussow](https://gitea.rknet.org/xoxys)
author: Robert Kaussow <mail@thegeeklab.de>
namespace: xoxys
role_name: sshd
# @meta description: >
# [![Build Status](https://ci.rknet.org/api/badges/ansible/xoxys.sshd/status.svg)](https://ci.rknet.org/repos/ansible/xoxys.sshd)
# [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?label=license)](https://gitea.rknet.org/ansible/xoxys.sshd/src/branch/main/LICENSE)
#
# Configure sshd server.
# @end
description: Configure sshd server
license: MIT
min_ansible_version: "2.10"
platforms:
- name: EL
versions:
- "9"
galaxy_tags:
- sshd
- security
dependencies: []
collections:
- xoxys.general
- community.general

View File

@ -1,5 +0,0 @@
---
- name: Converge
hosts: all
roles:
- role: xoxys.sshd

View File

@ -1,17 +0,0 @@
---
driver:
name: molecule_hetznercloud
dependency:
name: galaxy
options:
role-file: molecule/requirements.yml
requirements-file: molecule/requirements.yml
platforms:
- name: "rocky9-sshd"
server_type: "cx11"
image: "rocky-9"
provisioner:
name: ansible
log: False
verifier:
name: testinfra

View File

@ -1,11 +0,0 @@
---
- name: Prepare
hosts: all
gather_facts: False
tasks:
- name: Bootstrap Python for Ansible
ansible.builtin.raw: |
command -v python3 python ||
((test -e /usr/bin/apt && (apt -y update && apt install -y python-minimal)) ||
echo "Warning: Python not boostrapped due to unknown platform.")
changed_when: False

View File

@ -1,16 +0,0 @@
import os
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ["MOLECULE_INVENTORY_FILE"]
).get_hosts("all")
def test_sshd_config_file(host):
sshd = host.file("/etc/ssh/sshd_config")
assert sshd.exists
assert sshd.user == "root"
assert sshd.group == "root"
assert sshd.mode == 0o600

View File

@ -1,4 +0,0 @@
---
collections: []
roles: []

View File

@ -1,17 +0,0 @@
[tool.ruff]
exclude = [".git", "__pycache__"]
line-length = 99
indent-width = 4
[tool.ruff.lint]
ignore = ["W191", "E111", "E114", "E117", "S101", "S105"]
select = ["F", "E", "I", "W", "S"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
line-ending = "lf"
[tool.pytest.ini_options]
filterwarnings = ["ignore::FutureWarning", "ignore::DeprecationWarning"]

View File

@ -1,12 +0,0 @@
---
- ansible.builtin.include_tasks: "{{ lookup('first_found', params) }}"
vars:
params:
files:
- "ssh_{{ ansible_lsb.id | default('') | lower }}.yml"
- "ssh_{{ ansible_os_family | lower }}.yml"
- "ssh_default.yml"
paths:
- "tasks"
- ansible.builtin.include_tasks: ssh_2fa.yml
when: sshd_google_auth_enabled | bool

View File

@ -1,39 +0,0 @@
---
- name: Install google authenticator PAM module
ansible.builtin.package:
name: google-authenticator
state: present
- name: Add google auth module to PAM
community.general.pamd:
name: sshd
type: account
control: required
module_path: pam_nologin.so
new_type: auth
new_control: required
new_module_path: pam_google_authenticator.so
state: before
- name: Skip google auth for specific group
community.general.pamd:
name: sshd
type: auth
control: required
module_path: pam_google_authenticator.so
new_type: auth
new_control: "[success=done default=ignore]"
new_module_path: pam_succeed_if.so
module_arguments:
- user
- ingroup
- "{{ sshd_google_auth_exclude_group }}"
state: "{{ 'before' if sshd_google_auth_exclude_group is defined else 'absent' }}"
- name: Remove password auth from PAM
community.general.pamd:
name: sshd
type: auth
control: substack
module_path: password-auth
state: absent

View File

@ -1,41 +0,0 @@
---
- name: Gather package facts
ansible.builtin.package_facts:
check_mode: False
- name: Hardening sshd config
ansible.builtin.template:
src: etc/ssh/sshd_config.j2
dest: /etc/ssh/sshd_config
owner: root
group: root
mode: "0600"
notify: __sshd_restart
- name: Check if /etc/ssh/moduli contains weak DH parameters
ansible.builtin.shell: awk '$5 < {{ sshd_moduli_minimum }}' /etc/ssh/moduli
register: __sshd_register_moduli
changed_when: False
check_mode: False
- name: Remove all small primes
ansible.builtin.shell:
awk '$5 >= {{ sshd_moduli_minimum }}' /etc/ssh/moduli > /etc/ssh/moduli.new ;
[ -r /etc/ssh/moduli.new -a -s /etc/ssh/moduli.new ] && mv /etc/ssh/moduli.new /etc/ssh/moduli || true
notify: __sshd_restart
when: __sshd_register_moduli.stdout
- name: Create SSH usergroup
ansible.builtin.group:
name: "{{ item }}"
state: present
loop: "{{ sshd_allow_groups }}"
- name: Configure SSH crypto policy usage
ansible.builtin.template:
src: etc/sysconfig/sshd.j2
dest: /etc/sysconfig/sshd
owner: root
group: root
mode: "0640"
when: ('crypto-policies' in ansible_facts.packages)

View File

@ -1,46 +0,0 @@
---
- name: Hardening sshd config
ucr:
path: "{{ item.path }}"
value: "{{ item.value }}"
loop:
- path: sshd/permitroot
value: "{{ sshd_permit_root_login | default('') }}"
- path: sshd/PermitEmptyPasswords
value: "{{ sshd_permit_empty_passwords | default('') }}"
- path: sshd/permitroot
value: "{{ sshd_permit_root_login | default('') }}"
- path: sshd/passwordauthentication
value: "{{ sshd_password_authentication | default('') }}"
- path: sshd/challengeresponse
value: "{{ sshd_password_authentication | default('') }}"
- path: sshd/IgnoreRhosts
value: "{{ sshd_ignore_rhosts | default('') }}"
- path: sshd/HostbasedAuthentication
value: "{{ sshd_hostbased_authentication | default('') }}"
- path: sshd/ClientAliveInterval
value: "{{ sshd_client_alive_interval | default('') }}"
- path: sshd/ClientAliveCountMax
value: "{{ sshd_client_alive_count_max | default('') }}"
- path: sshd/Ciphers
value: "{{ sshd_ciphers | default('[]') | join(',') }}"
- path: sshd/KexAlgorithms
value: "{{ sshd_kex | default('[]') | join(',') }}"
- path: sshd/MACs
value: "{{ sshd_macs | default('[]') | join(',') }}"
loop_control:
label: "variable: {{ item.path }}={{ item.value }}"
notify: __sshd_restart
- name: Set allowed ssh groups
ucr:
path: "auth/sshd/group/{{ item }}"
value: "yes"
loop: "{{ sshd_allow_groups }}"
- name: Create SSH Usergroup
ansible.builtin.group:
name: "{{ item }}"
system: "yes"
state: present
loop: "{{ sshd_allow_groups }}"

View File

@ -1,166 +0,0 @@
#jinja2: lstrip_blocks: True
{{ ansible_managed | comment }}
# This is the sshd server system-wide configuration file.
# See sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
{% if ansible_os_family | lower == "redhat" and ansible_distribution_major_version is version('8', '<') %}
Protocol {{ sshd_protocol }}
{% endif %}
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
{% if sshd_crypto_policy_enabled | bool %}
# This system is following system-wide crypto policy. The changes to
# crypto properties (Ciphers, MACs, ...) will not have any effect here.
# They will be overridden by command-line options passed to the server
# on command line.
# Please, check manual pages for update-crypto-policies(8) and sshd_config(5).
{% else %}
Ciphers {{ sshd_ciphers | join(',') }}
KexAlgorithms {{ sshd_kex | join(',') }}
MACs {{ sshd_macs | join(',') }}
{% endif %}
# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
LogLevel {{ sshd_log_level }}
# Authentication:
LoginGraceTime {{ sshd_login_grace_time }}
PermitRootLogin {{ sshd_permit_root_login }}
StrictModes {{ sshd_strict_modes }}
{% if sshd_allow_groups %}
AllowGroups {{ sshd_allow_groups|join(',') }}
{% endif %}
MaxAuthTries {{ sshd_max_auth_tries }}
MaxSessions {{ sshd_max_sessions }}
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
HostbasedAuthentication {{ sshd_hostbased_authentication }}
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts {{ sshd_ignore_rhosts }}
{% if sshd_google_auth_enabled %}
# Force public key auth then ask for google auth code
AuthenticationMethods publickey,keyboard-interactive
{% endif %}
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication {{ sshd_password_authentication }}
PermitEmptyPasswords {{ sshd_permit_empty_passwords }}
# Change to no to disable s/key passwords
ChallengeResponseAuthentication {{ sshd_challenge_response_authentication }}
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes
# GSSAPI options
GSSAPIAuthentication {{ sshd_gssapi_authentication }}
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported on RH based systems and may
# cause several problems.
UsePAM yes
AllowAgentForwarding {{ sshd_allow_agent_forwarding }}
AllowTcpForwarding {{ sshd_allow_tcp_forwarding }}
#GatewayPorts no
X11Forwarding {{ sshd_x11_forwarding }}
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
{% if ansible_os_family | lower == "redhat" and ansible_distribution_major_version is version('7', '>') %}
PrintMotd no
{% endif %}
#PrintLastLog no
TCPKeepAlive {{ sshd_tcp_keep_alive }}
#UseLogin no
{% if ansible_os_family | lower == "redhat" and ansible_distribution_major_version is version('8', '<') %}
UsePrivilegeSeparation sandbox
{% endif %}
#PermitUserEnvironment no
Compression {{ sshd_compression }}
ClientAliveInterval {{ sshd_client_alive_interval }}
ClientAliveCountMax {{ sshd_client_alive_count_max }}
UseDNS {{ sshd_use_dns }}
#PidFile /var/run/sshd.pid
MaxStartups {{ sshd_max_startups }}
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
{% if sshd_google_auth_exclude_group is defined %}
Match User {{ sshd_google_auth_exclude_group }}
AuthenticationMethods publickey
{% endif %}

View File

@ -1,21 +0,0 @@
#jinja2: lstrip_blocks: True
{{ ansible_managed | comment }}
# Configuration file for the sshd service.
# The server keys are automatically generated if they are missing.
# To change the automatic creation, adjust sshd.service options for
# example using systemctl enable sshd-keygen@dsa.service to allow creation
# of DSA key or systemctl mask sshd-keygen@rsa.service to disable RSA key
# creation.
# Do not change this option unless you have hardware random
# generator and you REALLY know what you are doing
SSH_USE_STRONG_RNG=0
# SSH_USE_STRONG_RNG=1
{% if not sshd_crypto_policy_enabled | bool %}
# Disable system-wide crypto policy
CRYPTO_POLICY=
{% endif %}