Disable ssh root login by modifying /etc/ssh/sshd_conf from within a script?
You can do something like that
#!/bin/bashif [[ "${UID}" -ne 0 ]]; then echo " You need to run this script as root" exit 1fi#To directly modify sshd_config.sed -i 's/#\?\(Port\s*\).*$/\1 2231/' /etc/ssh/sshd_configsed -i 's/#\?\(PerminRootLogin\s*\).*$/\1 no/' /etc/ssh/sshd_configsed -i 's/#\?\(PubkeyAuthentication\s*\).*$/\1 yes/' /etc/ssh/sshd_configsed -i 's/#\?\(PermitEmptyPasswords\s*\).*$/\1 no/' /etc/ssh/sshd_configsed -i 's/#\?\(PasswordAuthentication\s*\).*$/\1 no/' /etc/ssh/sshd_config#Check the exit status of the last commandif [[ "${?}" -ne 0 ]]; then echo "The sshd_config file was not modified successfully" exit 1fi/etc/init.d/ssh restartexit 0
Configuring SSH programmatically
I did some investigation on this and I think JNevevill's answer is the most solid. I have some example script that illustrated the two ways, SED
and AWK
.
Preparation
Showing the test data only once for better readability in the examples. It has been initialized for each approach the same way. It will define some rules in a test file and a dictionary of new rules that should replace the rules in the file or be written to the file.
echo 'LoginGraceTime 120' > ./data.txtecho '#PermitRootLogin yes' >> ./data.txtecho 'PermitRootLogin no' >> ./data.txtecho 'PasswordAuthentication yes' >> ./data.txtdeclare -A rules=( ["LoginGraceTime"]="1m" ["PermitRootLogin"]="no" ["PasswordAuthentication"]="no" ["AllowUsers"]="blue")
SED
SED
will replace the rules it finds. If a line is commented, it will remove the #
and replace the value. This approach is less solid as it can lead to duplicate rules. I.E. A rule exists commented and uncommented. Also, if the rule wasn't there, it will not be written at all.
for rule in "${!rules[@]}"; do regex="s/#\?\(${rule}\s*\).*$/\1 ${rules[${rule}]}/" sed "${regex}" ./data.txt > temp.txt; mv -f temp.txt ./data.txtdone
Result:
LoginGraceTime 1mPermitRootLogin noPermitRootLogin noPasswordAuthentication no
AWK
AWK
is more solid in this situation. It yields better control.It will read line by line and replace the value if it exists without changing commented rules. If a rule wasn't found at the end of the file, it will append this rule to the file. This is much more solid than the SED
approach. We can be sure there will be not duplicate rule and all rules are defined.
for rule in "${!rules[@]}"; doawk -v key="${rule}" -v val="${rules[${rule}]}" \ '$1==key {foundLine=1; print key " " val} $1!=key{print $0} END{if(foundLine!=1) print key " " val}' \ ./data.txt > sshd_config.tmp && mv sshd_config.tmp ./data.txtdone
Result:
LoginGraceTime 1m#PermitRootLogin yesPermitRootLogin noPasswordAuthentication noAllowUsers blue
Conclusion
AWK is clearly the better choice. It is more safe and can handle rules that are not in the file.