Skip to content

Update harden_sshd_ciphers/macs_opensshserver_conf_crypto_policy #13374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,63 @@
# disruption = low
{{{ ansible_instantiate_variables("sshd_approved_ciphers") }}}

- name: "{{{ rule_title }}}: Set facts"
set_fact:
path: /etc/crypto-policies/back-ends/opensshserver.config
correct_value: "-oCiphers={{ sshd_approved_ciphers }}"

- name: "{{{ rule_title }}}: Stat"
stat:
path: "{{ path }}"
follow: yes
register: opensshserver_file

- name: "{{{ rule_title }}}: Create"
lineinfile:
path: "{{ path }}"
line: "CRYPTO_POLICY='{{ correct_value }}'"
create: yes
when: not opensshserver_file.stat.exists or opensshserver_file.stat.size <= correct_value|length

- name: "{{{ rule_title }}}"
block:
- name: "Existing value check"
lineinfile:
path: "{{ path }}"
create: false
regexp: "{{ correct_value }}"
state: absent
check_mode: true
changed_when: false
register: opensshserver

- name: "Update/Correct value"
replace:
path: "{{ path }}"
regexp: (-oCiphers=\S+)
replace: "{{ correct_value }}"
when: opensshserver.found is defined and opensshserver.found != 1

when: opensshserver_file.stat.exists and opensshserver_file.stat.size > correct_value|length
- name: "{{{ rule_title }}}: Set relevant paths and correct value"
ansible.builtin.set_fact:
opensshserver_path: /etc/crypto-policies/back-ends/opensshserver.config
local_path: /etc/crypto-policies/local.d/opensshserver-ssg.config
correct_value: "-oCiphers={{ sshd_approved_ciphers }}"

- name: "{{{ rule_title }}}: Ensure crypto config exists"
ansible.builtin.stat:
path: "{{ opensshserver_path }}"
follow: true
register: opensshserver_file

- name: "{{{ rule_title }}}: Generate default config if missing or empty"
ansible.builtin.command: update-crypto-policies --no-reload
when: not opensshserver_file.stat.exists or opensshserver_file.stat.size == 0

- name: "{{{ rule_title }}}: Read opensshserver.config content"
ansible.builtin.slurp:
src: "{{ opensshserver_path }}"
register: ssh_config_raw

- name: "{{{ rule_title }}}: Extract last CRYPTO_POLICY line"
ansible.builtin.set_fact:
last_crypto_policy: "{{ (ssh_config_raw.content | b64decode).splitlines() | select('match', \"^\\s*CRYPTO_POLICY='[^']+'\") | list | last | default('') }}"

- name: "{{{ rule_title }}}: Check if correct_value is present"
ansible.builtin.set_fact:
cipher_is_correct: "{{ correct_value in last_crypto_policy }}"

- name: "{{{ rule_title }}}: Extract current Ciphers if needed"
ansible.builtin.set_fact:
existing_cipher: "{{ (last_crypto_policy | regex_findall('(-oCiphers=\\S+)', '\\1')) | last | default('') }}"
when: not cipher_is_correct and last_crypto_policy != ''

- name: "{{{ rule_title }}}: Build full updated CRYPTO_POLICY line"
set_fact:
updated_crypto_policy: >-
{% if last_crypto_policy == '' %}
CRYPTO_POLICY='{{ correct_value }}'
{% elif existing_cipher != '' %}
{{ last_crypto_policy | regex_replace(existing_cipher, correct_value) }}
{% else %}
{{ last_crypto_policy[:-1] ~ " " ~ correct_value ~ "'" }}
{% endif %}
when: not cipher_is_correct

- name: "{{{ rule_title }}}: Ensure local.d dir exists"
ansible.builtin.file:
path: "{{ local_path | dirname }}"
state: directory

- name: "{{{ rule_title }}}: Write CRYPTO_POLICY to local config"
ansible.builtin.lineinfile:
path: "{{ local_path }}"
line: "{{ '\n' ~ updated_crypto_policy }}"
create: yes
insertafter: EOF

- name: "{{{ rule_title }}}: Apply updated crypto policies"
ansible.builtin.command: update-crypto-policies --no-reload
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,33 @@
{{{ bash_instantiate_variables("sshd_approved_ciphers") }}}

CONF_FILE=/etc/crypto-policies/back-ends/opensshserver.config
LOCAL_CONF_DIR=/etc/crypto-policies/local.d
LOCAL_CONF_FILE=${LOCAL_CONF_DIR}/opensshserver-ssg.config
correct_value="-oCiphers=${sshd_approved_ciphers}"

# Test if file exists
test -f ${CONF_FILE} || touch ${CONF_FILE}

# Ensure CRYPTO_POLICY is not commented out
sed -i 's/#CRYPTO_POLICY=/CRYPTO_POLICY=/' ${CONF_FILE}
# Test if file exists, create default it if not
if [[ ! -s ${CONF_FILE} ]] || ! grep -q "^\s*CRYPTO_POLICY=" ${CONF_FILE} ; then
update-crypto-policies --no-reload # Generate a default configuration
fi

if ! grep -q "\\$correct_value" "$CONF_FILE"; then
# We need to get the existing value, using PCRE to maintain same regex
existing_value=$(grep -Po '(-oCiphers=\S+)' ${CONF_FILE})
# Get the last occurrence of CRYPTO_POLICY
last_crypto_policy=$(grep -Eo "^\s*CRYPTO_POLICY='[^']+'" ${CONF_FILE} | tail -n 1)

if [[ ! -z ${existing_value} ]]; then
# replace existing_value with correct_value
sed -i "s/${existing_value}/${correct_value}/g" ${CONF_FILE}
else
# ***NOTE*** #
# This probably means this file is not here or it's been modified
# unintentionally.
# ********** #
# echo correct_value to end
echo "CRYPTO_POLICY='${correct_value}'" >> ${CONF_FILE}
# Copy the last CRYPTO_POLICY value to the local configuration file
if [[ -n "$last_crypto_policy" ]]; then
if ! grep -qe "$correct_value" <<< "$last_crypto_policy"; then
# If an existing -oCiphers= is found, replace it
# Else, append correct_value before the closing apostrophe
if [[ "$last_crypto_policy" == *"-oCiphers="* ]]; then
last_crypto_policy=$(echo "$last_crypto_policy" | sed -E "s/-oCiphers=\S+/${correct_value}/")
else
last_crypto_policy=$(echo "$last_crypto_policy" | sed -E "s/'[[:space:]]*$/ ${correct_value}'/")
fi
# Write updated line to LOCAL_CONF_FILE
echo -e "\n$last_crypto_policy" > "$LOCAL_CONF_FILE"
fi
else
echo -e "\nCRYPTO_POLICY='${correct_value}'" > ${LOCAL_CONF_FILE}
fi

update-crypto-policies --no-reload
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
{{%- else -%}}
<ind:pattern operation="pattern match">^(?!#).*Ciphers\s+([^\s']+).*$</ind:pattern>
{{%- endif -%}}
<ind:instance operation="equals" datatype="int">1</ind:instance>
<ind:instance operation="greater than or equal" datatype="int">-1</ind:instance>
</ind:textfilecontent54_object>

<ind:textfilecontent54_state id="ste_{{{ rule_id }}}" version="1">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
# platform = Not Applicable
# variables = sshd_approved_ciphers=aes256-ctr,aes192-ctr,aes128-ctr,aes256-gcm@openssh.com,aes128-gcm@openssh.com

sshd_approved_ciphers=aes256-ctr,aes192-ctr,aes128-ctr,aes256-gcm@openssh.com,aes128-gcm@openssh.com

configfile=/etc/crypto-policies/back-ends/opensshserver.config
correct_value="-oCiphers=${sshd_approved_ciphers}"

# Ensure directory + file is there
test -d /etc/crypto-policies/back-ends || mkdir -p /etc/crypto-policies/back-ends

# Get the last CRYPTO_POLICY line
last_crypto_policy=$(grep -E "^CRYPTO_POLICY='[^']+'" "$configfile" | tail -n 1)

# Generate a corrected version by replacing any -oCiphers= value
if grep -qPo '(-oCiphers=\S+)' <<< "$last_crypto_policy"; then
fixed_crypto_policy=$(sed -E "s/-oCiphers=\S+/${correct_value}/" <<< "$last_crypto_policy")
fi

echo -e "\n$fixed_crypto_policy" >> "$configfile"
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash
# platform = Not Applicable
# variables = sshd_approved_ciphers=aes256-ctr,aes192-ctr,aes128-ctr,aes256-gcm@openssh.com,aes128-gcm@openssh.com

configfile=/etc/crypto-policies/back-ends/opensshserver.config

# Ensure directory + file is there
test -d /etc/crypto-policies/back-ends || mkdir -p /etc/crypto-policies/back-ends

# Get the last CRYPTO_POLICY line
last_crypto_policy=$(grep -E "^CRYPTO_POLICY='[^']+'" "$configfile" | tail -n 1)

# Generate a corrected version by replacing any -oCiphers= value
if grep -qPo '(-oCiphers=\S+)' <<< "$last_crypto_policy"; then
fixed_crypto_policy=$(sed -E "s/-oCiphers=\S+[[:space:]]*//" <<< "$last_crypto_policy")
fi

echo -e "\n$fixed_crypto_policy" >> "$configfile"
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,63 @@
# disruption = low
{{{ ansible_instantiate_variables("sshd_approved_macs") }}}

- name: "{{{ rule_title }}}: Set facts"
set_fact:
path: /etc/crypto-policies/back-ends/opensshserver.config
correct_value: "-oMACs={{ sshd_approved_macs }}"

- name: "{{{ rule_title }}}: Stat"
stat:
path: "{{ path }}"
follow: yes
register: opensshserver_file

- name: "{{{ rule_title }}}: Create"
lineinfile:
path: "{{ path }}"
line: "CRYPTO_POLICY='{{ correct_value }}'"
create: yes
when: not opensshserver_file.stat.exists or opensshserver_file.stat.size <= correct_value|length

- name: "{{{ rule_title }}}"
block:
- name: "Existing value check"
lineinfile:
path: "{{ path }}"
create: false
regexp: "{{ correct_value }}"
state: absent
check_mode: true
changed_when: false
register: opensshserver

- name: "Update/Correct value"
replace:
path: "{{ path }}"
regexp: (-oMACs=\S+)
replace: "{{ correct_value }}"
when: opensshserver.found is defined and opensshserver.found != 1

when: opensshserver_file.stat.exists and opensshserver_file.stat.size > correct_value|length
- name: "{{{ rule_title }}}: Set relevant paths and correct value"
ansible.builtin.set_fact:
opensshserver_path: /etc/crypto-policies/back-ends/opensshserver.config
local_path: /etc/crypto-policies/local.d/opensshserver-ssg.config
correct_value: "-oMACs={{ sshd_approved_macs }}"

- name: "{{{ rule_title }}}: Ensure crypto config exists"
ansible.builtin.stat:
path: "{{ opensshserver_path }}"
follow: true
register: opensshserver_file

- name: "{{{ rule_title }}}: Generate default config if missing or empty"
ansible.builtin.command: update-crypto-policies --no-reload
when: not opensshserver_file.stat.exists or opensshserver_file.stat.size == 0

- name: "{{{ rule_title }}}: Read opensshserver.config content"
ansible.builtin.slurp:
src: "{{ opensshserver_path }}"
register: ssh_config_raw

- name: "{{{ rule_title }}}: Extract last CRYPTO_POLICY line"
ansible.builtin.set_fact:
last_crypto_policy: "{{ (ssh_config_raw.content | b64decode).splitlines() | select('match', \"^\\s*CRYPTO_POLICY='[^']+'\") | list | last | default('') }}"

- name: "{{{ rule_title }}}: Check if correct_value is present"
ansible.builtin.set_fact:
mac_is_correct: "{{ correct_value in last_crypto_policy }}"

- name: "{{{ rule_title }}}: Extract current Ciphers if needed"
ansible.builtin.set_fact:
existing_mac: "{{ (last_crypto_policy | regex_findall('(-oMACs=\\S+)', '\\1')) | last | default('') }}"
when: not mac_is_correct and last_crypto_policy != ''

- name: "{{{ rule_title }}}: Build full updated CRYPTO_POLICY line"
set_fact:
updated_crypto_policy: >-
{% if last_crypto_policy == '' %}
CRYPTO_POLICY='{{ correct_value }}'
{% elif existing_mac != '' %}
{{ last_crypto_policy | regex_replace(existing_mac, correct_value) }}
{% else %}
{{ last_crypto_policy[:-1] ~ " " ~ correct_value ~ "'" }}
{% endif %}
when: not mac_is_correct

- name: "{{{ rule_title }}}: Ensure local.d dir exists"
ansible.builtin.file:
path: "{{ local_path | dirname }}"
state: directory

- name: "{{{ rule_title }}}: Write CRYPTO_POLICY to local config"
ansible.builtin.lineinfile:
path: "{{ local_path }}"
line: "{{ '\n' ~ updated_crypto_policy }}"
create: yes
insertafter: EOF

- name: "{{{ rule_title }}}: Apply updated crypto policies"
ansible.builtin.command: update-crypto-policies --no-reload
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,33 @@
{{{ bash_instantiate_variables("sshd_approved_macs") }}}

CONF_FILE=/etc/crypto-policies/back-ends/opensshserver.config
LOCAL_CONF_DIR=/etc/crypto-policies/local.d
LOCAL_CONF_FILE=${LOCAL_CONF_DIR}/opensshserver-ssg.config
correct_value="-oMACs=${sshd_approved_macs}"

# Test if file exists
test -f ${CONF_FILE} || touch ${CONF_FILE}

# Ensure CRYPTO_POLICY is not commented out
sed -i 's/#CRYPTO_POLICY=/CRYPTO_POLICY=/' ${CONF_FILE}
# Test if file exists, create default it if not
if [[ ! -s ${CONF_FILE} ]] || ! grep -q "^\s*CRYPTO_POLICY=" ${CONF_FILE} ; then
update-crypto-policies --no-reload # Generate a default configuration
fi

if ! grep -q "\\$correct_value" "$CONF_FILE"; then
# We need to get the existing value, using PCRE to maintain same regex
existing_value=$(grep -Po '(-oMACs=\S+)' ${CONF_FILE})
# Get the last occurrence of CRYPTO_POLICY
last_crypto_policy=$(grep -Eo "^\s*CRYPTO_POLICY='[^']+'" ${CONF_FILE} | tail -n 1)

if [[ ! -z ${existing_value} ]]; then
# replace existing_value with correct_value
sed -i "s/${existing_value}/${correct_value}/g" ${CONF_FILE}
else
# ***NOTE*** #
# This probably means this file is not here or it's been modified
# unintentionally.
# ********** #
# echo correct_value to end
echo "CRYPTO_POLICY='${correct_value}'" >> ${CONF_FILE}
# Copy the last CRYPTO_POLICY value to the local configuration file
if [[ -n "$last_crypto_policy" ]]; then
if ! grep -qe "$correct_value" <<< "$last_crypto_policy"; then
# If an existing -oMACs= is found, replace it
# Else, append correct_value before the closing apostrophe
if [[ "$last_crypto_policy" == *"-oMACs="* ]]; then
last_crypto_policy=$(echo "$last_crypto_policy" | sed -E "s/-oMACs=\S+/${correct_value}/")
else
last_crypto_policy=$(echo "$last_crypto_policy" | sed -E "s/'[[:space:]]*$/ ${correct_value}'/")
fi
# Write updated line to LOCAL_CONF_FILE
echo -e "\n$last_crypto_policy" > "$LOCAL_CONF_FILE"
fi
else
echo -e "\nCRYPTO_POLICY='${correct_value}'" > ${LOCAL_CONF_FILE}
fi

update-crypto-policies --no-reload
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<ind:textfilecontent54_object id="obj_{{{ rule_id }}}" version="1">
<ind:filepath>{{{ PATH }}}</ind:filepath>
<ind:pattern operation="pattern match">^(?!#).*(-oMACs=\S+).+$</ind:pattern>
<ind:instance operation="equals" datatype="int">1</ind:instance>
<ind:instance operation="greater than or equal" datatype="int">-1</ind:instance>
</ind:textfilecontent54_object>

<ind:textfilecontent54_state id="ste_{{{ rule_id }}}" version="1">
Expand Down
Loading