Por que não ler linha por linha usando while:
while read -r line
do
if ! grep -Fxq " $line " /etc/sysctl.conf
then
echo -e "$line" >> ~/testfile
fi
done </etc/sysctl.conf
e substituído > com > >.
Estou fazendo o script de instalação do SO do post que incluirá a seção "Hardening". E nessa seção de hardening ele irá ler os parâmetros do Kernel do arquivo A e comparar com o arquivo /etc/sysctl.conf e se os parâmetros não estiverem disponíveis no sysctl.conf, ele irá adicioná-lo no sysctl.conf.
Parâmetros no arquivo personalizado
################## Hardening ############################
kernel.exec-shield = 1
kernel.randomize_va_space = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.log_martians = 1
net.ipv4.tcp_timestamps = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
##########################################################
Agora eu adicionei estas linhas para o endurecimento.
for i in $(cat /etc/sysctl.conf)
do
if ! grep -Fxq " $i " /etc/sysctl.conf
then
echo -e "$i" > ~/testfile
fi
done
Problema com este script é que ele trata cada espaço nos parâmetros do kernel como uma linha de espaço e o problema começa desde o início em "para i in $ (cat /etc/sysctl.conf)"
E esta é a informação de depuração
./LinuxHardening.sh
++ date
+ LOGDATE='Mon Feb 9 07:58:07 EST 2015'
+ echo Mon Feb 9 07:58:07 EST 2015
+ tee HardeningLog
Mon Feb 9 07:58:07 EST 2015
+ echo -e '\n############ Kernel Hardening ############'
+ tee -a HardeningLog
############ Kernel Hardening ############
++ cat kernelparms
+ for i in '$(cat kernelparms)'
+ grep -Fxq '##################' /etc/sysctl.conf
+ echo -e '##################'
+ for i in '$(cat kernelparms)'
+ grep -Fxq Hardening /etc/sysctl.conf
+ echo -e Hardening
+ for i in '$(cat kernelparms)'
+ grep -Fxq '############################' /etc/sysctl.conf
+ echo -e '############################'
+ for i in '$(cat kernelparms)'
+ grep -Fxq kernel.exec-shield /etc/sysctl.conf
+ echo -e kernel.exec-shield
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq kernel.randomize_va_space /etc/sysctl.conf
+ echo -e kernel.randomize_va_space
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.icmp_echo_ignore_broadcasts /etc/sysctl.conf
+ echo -e net.ipv4.icmp_echo_ignore_broadcasts
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.icmp_ignore_bogus_error_responses /etc/sysctl.conf
+ echo -e net.ipv4.icmp_ignore_bogus_error_responses
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.tcp_syncookies /etc/sysctl.conf
+ echo -e net.ipv4.tcp_syncookies
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.all.log_martians /etc/sysctl.conf
+ echo -e net.ipv4.conf.all.log_martians
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.all.accept_redirects /etc/sysctl.conf
+ echo -e net.ipv4.conf.all.accept_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.all.rp_filter /etc/sysctl.conf
+ echo -e net.ipv4.conf.all.rp_filter
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.all.send_redirects /etc/sysctl.conf
+ echo -e net.ipv4.conf.all.send_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.default.accept_redirects /etc/sysctl.conf
+ echo -e net.ipv4.conf.default.accept_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.conf.default.log_martians /etc/sysctl.conf
+ echo -e net.ipv4.conf.default.log_martians
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 1 /etc/sysctl.conf
+ echo -e 1
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv4.tcp_timestamps /etc/sysctl.conf
+ echo -e net.ipv4.tcp_timestamps
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv6.conf.all.accept_redirects /etc/sysctl.conf
+ echo -e net.ipv6.conf.all.accept_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq net.ipv6.conf.default.accept_redirects /etc/sysctl.conf
+ echo -e net.ipv6.conf.default.accept_redirects
+ for i in '$(cat kernelparms)'
+ grep -Fxq = /etc/sysctl.conf
+ echo -e =
+ for i in '$(cat kernelparms)'
+ grep -Fxq 0 /etc/sysctl.conf
+ echo -e 0
+ for i in '$(cat kernelparms)'
+ grep -Fxq '##########################################################' /etc/sysctl.conf
+ echo -e '##########################################################'
Tente algo como:
while read i
do
if ! grep -Fxq " $i " /etc/sysctl.conf
then
echo -e "$i" >> ~/testfile
fi
done<kernelparms
Com awk
e matrizes
awk '!/^($|#)/{arr[$1]=$0}END{for(param in arr) print arr[param]}' /etc/sysctl.conf custom.conf
se a ordem for importante:
awk '!/^($|#)/{
arr[$1] = $0
}
END {
for(key in arr)
print arr[key]
}' /etc/sysctl.conf custom.conf | sort > hardened.conf
!/^($|#)/
- ignora linhas comentadas ou vazias
{arr[$1]=$0}
- armazena cada linha em arr, associando-a ao parametro do kernel; a linha é atualizada toda vez que ele vê o mesmo parâmetro (ou seja, de custom.conf
, que é o último arquivo a ser lido)
END{for(param in arr) print arr[param]}
- depois que toda a entrada foi lida, imprima a linha associada para cada parâmetro do kernel.
Se eu entendi sua pergunta, corrija seu problema é a expansão da expressão $ (cat) que é dividida em espaços para que o loop repita todos os campos nos dados em vez das linhas. Para corrigir isso, você pode usar essa abordagem ...
while IFS= read -r i
do
...your loop code operating on $i here...
done < /etc/sysctl.conf
Defina IFS=$'\n'
e não trate espaços como novas linhas.
Tags text-processing scripting