7

I found some code in a script given to me by another person as a resource for lockdown/hardening of Ubuntu 16.04 for a project I am doing.

I have no idea what it does and do no want to run it if I can't identify the change it would make, is anyone aware of what it does or changes? Only code without a brief explanation comment, and it happens to be the only thing I do not know. Also, second function is identifiable by function but I don't understand the purpose or specifics.

function bacon.config.ubuntu.chage() {
CHAGE_SCRIPT='/etc/cron.daily/userchage'
if [ ! -e $CHAGE_SCRIPT ]; then
printf "#%c/bin/bash \nfor i in \$(awk -F: '{if(($3 >= 1000)&&($3 <65534)) print \$1}' /etc/passwd); do \nchage -m 0 -M 60 -W 10 \$i \ndone \n" ! > $CHAGE_SCRIPT
    chmod +x $CHAGE_SCRIPT
fi
}

function bacon.config.ubuntu.log.rotate() {
  echo "bacon.config.ubuntu.log.rotate: [INFO] Installing logrotate..."

  sudo apt-get install logrotate 1>/dev/null

  echo "bacon.config.ubuntu.log.rotate: [INFO] Configuring logrotate..."
  sed 's/rotate 4/rotate 60/' /etc/logrotate.conf > /etc/logrotate.conf.new
  mv /etc/logrotate.conf.new /etc/logrotate.conf
  sed 's/rotate 1/rotate 60/' /etc/logrotate.conf > /etc/logrotate.conf.new
  mv /etc/logrotate.conf.new /etc/log.rotate.conf
  sed 's/rotate 7/rotate 1825/' /etc/logrotate.d/rsyslog > /etc/logrotate.d/rsyslog.new
  mv /etc/logrotate.d/rsyslog.new /etc/logrotate.d/rsyslog
}

Any help identifying these would be amazing.

  • 4
    I would ask the person who gave me the code what it does. – WinEunuuchs2Unix Apr 25 at 11:49
  • 1
    @WinEunuuchs2Unix Normally I would as well, but they are away from the office for a while due to personal circumstances. Trust me, I know how much easier that would be. :) – Brendan77222 Apr 25 at 11:52
  • 4
    Well done on not running a script as root when you don't know what it does. – Wildcard Apr 25 at 19:34
  • You can always fire up a VM and test! I've always been a try and fail and learn kinda guy – FreeSoftwareServers Apr 26 at 4:01
6

The first function checks whether file $CHAGE_SCRIPT exists, and if not attempts to create it with a printf statement. You can see what this statement does by running it in a terminal:

$ printf "#%c/bin/bash \nfor i in \$(awk -F: '{if(($3 >= 1000)&&($3 <65534)) print \$1}' /etc/passwd); do \nchage -m 0 -M 60 -W 10 \$i \ndone \n" !
#!/bin/bash 
for i in $(awk -F: '{if(( >= 1000)&&( <65534)) print $1}' /etc/passwd); do 
chage -m 0 -M 60 -W 10 $i 
done 

You will notice that instances of $3 evaluate empty because (unlike \$1) they are not protected from expansion by the shell. The use of %c to insert the ! in #!/bin/bash suggests the original author doesn't really understand how bash's history expansion works.

IMHO it would be simpler and clearer to use a here-document:

function bacon.config.ubuntu.chage() {
CHAGE_SCRIPT='/etc/cron.daily/userchage'
if [ ! -e "$CHAGE_SCRIPT" ]; then
    cat << 'EOF' > "$CHAGE_SCRIPT"
#!/bin/bash 
for i in $(awk -F: '{if(($3 >= 1000)&&($3 <65534)) print $1}' /etc/passwd); do 
chage -m 0 -M 60 -W 10 $i 
done
EOF
    chmod +x "$CHAGE_SCRIPT"
fi
}

The operation of the second function should be pretty obvious - it could be simplified by combining all the sed commands so that the file is only written / moved once.

  • If the $3 evaluates empty, is there a reason to include it? If I wanted something to complete the same task, without useless portions included how much would I need to change it? – Brendan77222 Apr 25 at 13:06
  • 1
    @Brendan77222 I'm assuming the empty evaluation of $3 was unintentional - since it would result in a syntax error from awk – steeldriver Apr 25 at 14:29
  • would leaving it in or taking it out be something I need to be concerned with? Should I want it to function as intended at least. – Brendan77222 Apr 25 at 17:27
4

The script contains two function definitions. The first function, bacon.config.ubuntu.chage, creates a script at /etc/cron.daily/userchage (comments added by me):

#!/bin/bash
# loop through users with uid >= 1000 and uid < 65534 theoretically, but $3 isn't escaped -> doesn't work
for i in $(awk -F: '{if(( >= 1000)&&( <65534)) print $1}' /etc/passwd);do
    # set password to expire after 60 days, warning after 50 days
    chage -m 0 -M 60 -W 10 $i
done

The second function installs logrotate and creates a config file for it.

  • Awesome those comments help a lot. is there a reason for inserting a script at /etc/chron.daily/userchage rather than just executing the for loop you put here? I am unfamiliar with userchage file's function – Brendan77222 Apr 25 at 12:49
  • 1
    Yes, any scripts in /etc/cron.daily/ will be executed once per day. – FliegendeWurst Apr 25 at 12:59
  • Awesome, thank you for the confirmation on what I suspected. Awesome help. – Brendan77222 Apr 25 at 13:01
2

The chage program changes the password expiry for all users. That is, it only lets them keep their current password for at most 60 days. It is run daily. The minimum duration of 0 is questionable as of https://security.stackexchange.com/questions/78758/what-is-the-purpose-of-the-password-minimum-age-setting. Maybe ask on https://security.stackexchange.com if this is really recommended.

Why logrotate should improve security is a bit above me.

  • 1
    Oh, we definitely want a minimum password age of 24 hours. I assume that is the -m flag? I can read the man page as well, just was confused on why it used a check for a script. But I now feel from your comment it does that to ensure this is checked daily rather than a one time thing. – Brendan77222 Apr 25 at 12:54
  • 1
    Exactly. And -m seems correct. If you can read the man pages, you can see man cron for the cron.daily folder. – serv-inc Apr 25 at 16:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.