0

I have a **bash script to setup UFW with an expected output as follows:

user@host:~$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     LIMIT IN    Anywhere                  
80/tcp                     ALLOW IN    Anywhere                  
443/tcp                    ALLOW IN    Anywhere                  
22/tcp (v6)                LIMIT IN    Anywhere (v6)             
80/tcp (v6)                ALLOW IN    Anywhere (v6)             
443/tcp (v6)               ALLOW IN    Anywhere (v6) 

I created a test function to verify the output is as expected. I copied the ouput manually into a variable and stored the output in another variable so i could compare the 2 as follows :

function test() {
    # Verify that output is as excpeted
    local output="$(sudo ufw status verbose)"
    local expected="Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 22/tcp LIMIT IN Anywhere 80/tcp ALLOW IN Anywhere 443/tcp ALLOW IN Anywhere 22/tcp (v6) LIMIT IN Anywhere (v6) 80/tcp (v6) ALLOW IN Anywhere (v6) 443/tcp (v6) ALLOW IN Anywhere (v6)"

    # echo
    # echo $output
    # echo
    # echo $expected
    # echo

    if [[ "$output" == "$expected" ]]; then
        echo "UFW setup: output was as expected"
    else
        echo "UFW setup: output NOT as expected!"
        echo "Please check UFW status before coninuing:"
        echo
        sudo ufw status verbose
    fi

Output:

luc@E580-debian:~$ test
UFW setup: output NOT as expected!
Please check UFW status before coninuing:

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     LIMIT IN    Anywhere                  
80/tcp                     ALLOW IN    Anywhere                  
443/tcp                    ALLOW IN    Anywhere                  
22/tcp (v6)                LIMIT IN    Anywhere (v6)             
80/tcp (v6)                ALLOW IN    Anywhere (v6)             
443/tcp (v6)               ALLOW IN    Anywhere (v6)             

As far as i know they are exactly the same, but I also dont know if there is a way to check if hidden characters are causing this. Or maybe if there is a way to remove/replace them.

Luc vd Enden
  • 155
  • 1
  • 2
  • 7
  • 2
    There's probably differences in whitespace. – Barmar Aug 19 '20 at 23:16
  • Put `set -x` in the script to see a trace. – Barmar Aug 19 '20 at 23:17
  • 1
    Take the habit of not using `test` as a function name. `test` is used by bash, it could lead to confusion. – Nic3500 Aug 19 '20 at 23:23
  • Likely whitespace as Barmar said. *"$expected"* would be one way to fix that, but it can pass when output contains expected and more, so could pass with errors that otherwise may cause failure. – l3l_aze Aug 19 '20 at 23:27
  • 2
    if the `sudo ufw status verbose` call generates a multi-line response then the `output` variable will contain embedded line feeds (`\n`); not sure how `$output` (which includes embedded `\n`s) could match `$expected` which, at a minimum, does not include any `\n`s ... ??? compare the output from `echo "${output}" | od -c` and `echo "${expected}" | od -c` to see the differences – markp-fuso Aug 20 '20 at 00:10
  • 1
    You used `echo $output` to see what the variable contained, but [since that doesn't actually work](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else), you were misled into thinking the output is all on one line. I would suggest you compare multiline output with `diff` instead of string comparison, since this will make it much easier to spot the differences now and later. – that other guy Aug 20 '20 at 00:22
  • thatotherguy ty man, diff did the trick for me. Didn't think of storing the raw output in a file and comparing that to an file containing the expected output. Nic3500 thanks for pointing that out, it was just a temporary name but ill use something different in the future. Im kinda new to bash scripting (first time im taking it serious) so i was kinda clueless as to how to do this properly. Thanks for all the reply's! – Luc vd Enden Aug 20 '20 at 08:40

1 Answers1

1

You are comparing the hard way. You don't know anything about /tabs /spaces in UFW output. This would be more professional way to do it. Please adjust for your needs:

vim ./check_ufw.sh

#!/usr/bin/env bash
#:: Author: pr0logas
#:: Date: 2020-08-20
#:: Description: This program checks if the UFW firewall rules have not changed.

expected_output_file='/tmp/ufw_original.txt'
current_output_file='/tmp/ufw_current.txt'

echo "Just pushing some text as original UFW input to make FAILURE" > $expected_output_file

function check_diff() {
        ufw status numbered verbose > $current_output_file
        diff -q $expected_output_file $current_output_file 1> /dev/null

        if [[ $?  == "0" ]]; then
                echo "SUCCESS! UFW rules are the same."
        else
                echo "FAIL! UFW rules differ, attention needed!"
                exit 1
        fi
}

check_diff

To be 100% sure for the desired output I suggest you copy current output as original input for the first time like this:

cat /tmp/ufw_current.txt > /tmp/ufw_original.txt

Then comment:

#echo "Just pushing some text as original UFW input to make FAILURE" > $expected_output_file
pr0logas
  • 523
  • 1
  • 5
  • 14