Skip to content

Commit 20cc762

Browse files
committed
Move SSH key generation script from pam.d to /etc/profile
When FSx Lustre is configured with the new root_squash feature, and ParallelCluster is configured with Active Directory with home folders within the FSx mount, pam_exec.so is unable to properly run the SSH key generation script. This is because pam_exec.so runs the script as root, but root does not have access to any home folders to manipulate the files due to the fact that root is regarded as nobody/nogroup within the root_squash'd FSx mount point. Using su in the generation script to impersonate the user does not work around the problem, as su itself would trigger pam_exec.so, and trigger a loop, which doesn't look trivial to avoid to me. Instead, I suggest moving the key generation to /etc/profile, which is executed by default for every interactive shells, by the connecting user, and serves the purpose.
1 parent cb63b87 commit 20cc762

File tree

3 files changed

+30
-27
lines changed

3 files changed

+30
-27
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ This file is used to list changes made in each version of the AWS ParallelCluste
3030
- Change the logic to number the routing tables when an instance have multiple NICs.
3131
- Upgrade Python from 3.7.13 to 3.9.13.
3232
- Upgrade Slurm to version 22.05.3.
33+
- Move SSH key generation from pam.d to /etc/profile to enable root_squash'd FSx
3334

3435
3.2.0
3536
------

cookbooks/aws-parallelcluster-config/recipes/directory_service.rb

+26-19
Original file line numberDiff line numberDiff line change
@@ -155,38 +155,45 @@
155155
sensitive true
156156
end
157157

158-
pam_services = %w(sudo su sshd)
159-
pam_config_dir = "/etc/pam.d"
160158
generate_ssh_key_path = "#{node['cluster']['scripts_dir']}/generate_ssh_key.sh"
161-
ssh_key_generator_pam_config_line = "session optional pam_exec.so log=/var/log/parallelcluster/pam_ssh_key_generator.log #{generate_ssh_key_path}"
162-
if node['cluster']["directory_service"]["generate_ssh_keys_for_users"] == 'true'
159+
ssh_key_generator_profile_config_line = "bash #{generate_ssh_key_path} >> /var/log/parallelcluster/pam_ssh_key_generator.log 2>&1"
160+
if node['cluster']["directory_service"]["generate_ssh_keys_for_users"] == 'true'
163161
template generate_ssh_key_path do
164162
source 'directory_service/generate_ssh_key.sh.erb'
165163
owner 'root'
166164
group 'root'
167165
mode '0755'
168166
end
169-
pam_services.each do |pam_service|
170-
pam_config_file = "#{pam_config_dir}/#{pam_service}"
171-
append_if_no_line "Ensure PAM service #{pam_service} is configured to call SSH key generation script" do
172-
path pam_config_file
173-
line ssh_key_generator_pam_config_line
174-
end
167+
file "/var/log/parallelcluster/pam_ssh_key_generator.log" do
168+
action :touch
169+
mode '0777'
170+
end
171+
append_if_no_line "Ensure /etc/profile is configured to call SSH key generation script" do
172+
path "/etc/profile"
173+
line ssh_key_generator_profile_config_line
175174
end
176175
else
177-
# Remove script used to generate key if it exists and ensure PAM is not configured to try to call it
176+
# Remove script used to generate key if it exists and ensure /etc/profile is not configured to try to call it
178177
file generate_ssh_key_path do
179178
action :delete
180179
only_if { ::File.exist? generate_ssh_key_path }
181180
end
182-
183-
pam_services.each do |pam_service|
184-
pam_config_file = "#{pam_config_dir}/#{pam_service}"
185-
delete_lines "Ensure PAM service #{pam_service} is not configured to call SSH key generation script" do
186-
path pam_config_file
187-
pattern %r{session\s+optional\s+pam_exec\.so\s+log=/var/log/parallelcluster/pam_ssh_key_generator\.log}
188-
ignore_missing true
189-
end
181+
delete_lines "Ensure /etc/profile is not configured to call SSH key generation script" do
182+
path "/etc/profile"
183+
line ssh_key_generator_profile_config_line
184+
end
185+
end
186+
187+
# Ensure pam.d based SSH generation is removed
188+
ssh_key_generator_pam_config_line = "session optional pam_exec.so log=/var/log/parallelcluster/pam_ssh_key_generator.log #{generate_ssh_key_path}"
189+
pam_services = %w(sudo su sshd)
190+
pam_config_dir = "/etc/pam.d"
191+
pam_services.each do |pam_service|
192+
pam_config_file = "#{pam_config_dir}/#{pam_service}"
193+
delete_lines "Ensure PAM service #{pam_service} is not configured to call SSH key generation script" do
194+
path pam_config_file
195+
pattern %r{session\s+optional\s+pam_exec\.so\s+log=/var/log/parallelcluster/pam_ssh_key_generator\.log}
196+
ignore_missing true
190197
end
191198
end
192199
else

cookbooks/aws-parallelcluster-config/templates/default/directory_service/generate_ssh_key.sh.erb

+3-8
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,11 @@ set -ex
33
env
44

55
# Root does not need SSH key generation
6-
[ ${PAM_USER} == "root" ] && exit 0
7-
8-
# The home directory for every user must be determined in the most generic way because
9-
# we should not assume that every user has its home directory in /home/$USER.
10-
user_home_dir="$(getent passwd ${PAM_USER} | cut -d ':' -f 6)"
11-
[ ! -d "${user_home_dir}" ] && echo "ERROR Cannot create SSH key for user ${PAM_USER} if its home directory is not found" && exit 1
6+
[ ${USER} == "root" ] && exit 0
127

138
# Skip SSH key creation if the SSH has been already configured for the user.
149
# We assume that SSH has been already configured if the directory .ssh already exists in the user home.
15-
user_ssh_dir="${user_home_dir}/.ssh"
10+
user_ssh_dir="${HOME}/.ssh"
1611
[ -d "${user_ssh_dir}" ] && exit 0
1712

1813
mkdir -m 0700 "${user_ssh_dir}"
@@ -22,4 +17,4 @@ cat "${user_ssh_dir}/id_rsa.pub" >> "${user_ssh_dir}/authorized_keys"
2217
chmod 0600 "${user_ssh_dir}/authorized_keys"
2318
ssh-keyscan <%= node['hostname'] %> > "${user_ssh_dir}/known_hosts"
2419
chmod 0600 "${user_ssh_dir}/known_hosts"
25-
chown ${PAM_USER}:$(id -g ${PAM_USER}) -R "${user_ssh_dir}"
20+
chown ${USER}:$(id -g ${USER}) -R "${user_ssh_dir}"

0 commit comments

Comments
 (0)