SELinux + FreePBX

After watching this awesome talk on SELinux, I realized that I should give SELinux another try.

Disclaimer: This is a learning exercise to me, not a guide on how to secure FreePBX

Most Linux How-To guides just say you should disable SELinux, for whatever particular reason they have. But you shouldn’t be disabling it just because you don’t understand what it’s doing and why it’s blocking your commands. So I’ll try to install FreePBX, a software for managing an Asterisk server, following the instructions from here, skipping the step of disabling SELinux. Doing that will show you that SELinux is blocking most of the actions from the web interface, and things are not working as it was supposed to.

So let’s change the enforcing policy to ‘Permissive‘, using the command setenforce. This allows everything to work, but it also logs everything that would be blocked by SELinux on /var/log/audit/audit.log. If you play around FreePBX for a while, you will see lots of entries on that log file, such as:

...
type=AVC msg=audit(1397677629.300:287): avc:  denied  { execute_no_trans } for  pid=13449 comm="sh" path="/var/lib/asterisk/bin/retrieve_conf" dev=dm-0 ino=12191 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:asterisk_var_lib_t:s0 tclass=file
...
type=AVC msg=audit(1397677629.615:294): avc:  denied  { write } for  pid=13449 comm="retrieve_conf" name="queue_devstate.agi" dev=dm-0 ino=13546 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:asterisk_var_lib_t:s0 tclass=file
...
type=AVC msg=audit(1397677629.778:303): avc:  denied  { open } for  pid=13452 comm="crontab" name="asterisk" dev=dm-0 ino=13629 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_cron_spool_t:s0 tclass=file
...
type=AVC msg=audit(1397677985.862:334): avc:  denied  { write } for  pid=11503 comm="httpd" name="amportal.conf" dev=dm-0 ino=271259 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:etc_t:s0 tclass=file
...
type=AVC msg=audit(1397678526.281:406): avc:  denied  { write } for  pid=14718 comm="retrieve_conf" name="indications.conf" dev=dm-0 ino=276961 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:asterisk_etc_t:s0 tclass=file
...

Every action that would be denied is listed here, how can we use this to allow SELinux to enforce its policies and FreePBX actually works? Another tool can help us: audit2allow. It scans the audit log and figures out what is the best policy to allow those actions to pass SELinux.

First try, I’ll filter only asterisk related logs and pipe it to audit2allow.

grep asterisk /var/log/audit/audit.log | audit2allow -m asterisklocal
module asterisklocal 1.0;

require {
	type asterisk_etc_t;
	type user_cron_spool_t;
	type httpd_t;
	type asterisk_var_lib_t;
	class lnk_file { read getattr };
	class dir { read search open getattr };
	class file { execute setattr read getattr execute_no_trans write ioctl unlink open };
}

#============= httpd_t ==============
allow httpd_t asterisk_etc_t:file write;
allow httpd_t asterisk_var_lib_t:dir { read search open getattr };
allow httpd_t asterisk_var_lib_t:file { execute setattr read ioctl execute_no_trans write getattr open };
allow httpd_t asterisk_var_lib_t:lnk_file { read getattr };
allow httpd_t user_cron_spool_t:file { unlink open };

All those actions comes from httpd_t, so maybe there are more rules that should allowed, let’s try again:

grep httpd /var/log/audit/audit.log | audit2allow -m asterisklocal

The output got a lot bigger, it might cover everything that should be allowed now.

module asterisklocal 1.0;

require {
	type ssh_port_t;
	type asterisk_var_lib_t;
	type httpd_t;
	type port_t;
	type etc_runtime_t;
	type user_cron_spool_t;
	type shadow_t;
	type sysctl_fs_t;
	type asterisk_etc_t;
	type etc_t;
	class capability audit_write;
	class tcp_socket name_connect;
	class file { rename execute setattr read create getattr execute_no_trans write ioctl unlink open };
	class netlink_audit_socket { nlmsg_relay create };
	class lnk_file { read getattr };
	class dir { search read write getattr remove_name open add_name };
}

#============= httpd_t ==============
allow httpd_t asterisk_etc_t:file write;
allow httpd_t asterisk_var_lib_t:dir { read search open getattr };
allow httpd_t asterisk_var_lib_t:file { execute setattr read ioctl execute_no_trans write getattr open };
allow httpd_t asterisk_var_lib_t:lnk_file { read getattr };
allow httpd_t etc_runtime_t:file setattr;
allow httpd_t etc_t:file write;

#!!!! This avc can be allowed using one of the these booleans:
#     allow_ypbind, httpd_can_network_connect
allow httpd_t port_t:tcp_socket name_connect;

#!!!! This avc can be allowed using the boolean 'allow_httpd_mod_auth_pam'
allow httpd_t self:capability audit_write;

#!!!! This avc can be allowed using the boolean 'allow_httpd_mod_auth_pam'
allow httpd_t self:netlink_audit_socket { nlmsg_relay create };
allow httpd_t shadow_t:file { read getattr open };

#!!!! This avc can be allowed using one of the these booleans:
#     allow_ypbind, httpd_can_network_connect
allow httpd_t ssh_port_t:tcp_socket name_connect;
allow httpd_t sysctl_fs_t:dir search;
#!!!! The source type 'httpd_t' can write to a 'dir' of the following types:
# squirrelmail_spool_t, dirsrvadmin_config_t, var_lock_t, tmp_t, var_t, tmpfs_t, dirsrv_config_t, httpd_tmp_t, dirsrvadmin_tmp_t, httpd_cache_t, httpd_tmpfs_t, httpd_squirrelmail_t, var_lib_t, var_run_t, var_log_t, dirsrv_var_log_t, zarafa_var_lib_t, dirsrv_var_run_t, httpd_var_lib_t, httpd_var_run_t, httpd_nagios_rw_content_t, passenger_tmp_t, httpd_nutups_cgi_rw_content_t, httpd_apcupsd_cgi_rw_content_t, httpd_sys_content_t, httpd_dspam_rw_content_t, httpd_mediawiki_rw_content_t, httpd_squid_rw_content_t, httpd_prewikka_rw_content_t, httpd_smokeping_cgi_rw_content_t, passenger_var_run_t, httpd_openshift_rw_content_t, httpd_dirsrvadmin_rw_content_t, httpd_w3c_validator_rw_content_t, cluster_var_lib_t, cluster_var_run_t, httpd_user_rw_content_t, httpd_awstats_rw_content_t, root_t, httpdcontent, httpd_cobbler_rw_content_t, httpd_munin_rw_content_t, cluster_conf_t, httpd_bugzilla_rw_content_t, httpd_cvs_rw_content_t, httpd_git_rw_content_t, httpd_sys_rw_content_t, httpd_sys_rw_content_t

allow httpd_t user_cron_spool_t:dir { write remove_name getattr search add_name };
allow httpd_t user_cron_spool_t:file { rename create unlink open setattr };

But this command only shows what the modules ‘asterisklocal‘ will do, we must run the command with ‘-M‘ to generate the loadable policy file. This post, from Dan Walsh, explains how this work. After generating we need to load it, using semanage -i asterisklocal. Now we can set the SELinux back to enforcing mode and FreePBX should still be working.

That should cover the basics for running FreePBX using SELinux, but this is not supposed to be a complete guide on how to secure FreePBX

Reviewing the policies needed to run FreePBX makes me thing of all the possible exploits and problems that FreePBX hides inside itself. From a security point of view, FreePBX does not use the safest architecture around, it could definitely be improved – maybe splinting in a frontend / backend design. I think it’s safe to say that one should not run other sensitive services on the same server as FreePBX, specially if you disabled SELinux.

Monet

O que fazer em Paris senão ver Monet? Então dedicamos o dia a ele. Começamos visitando o Museu Marmottan-Monet, que possui uma coleção e tanto das obras dele, mas também possui só isso. Sempre me impressiono vendo Monet. Sem fotos desse museu, eles não deixavam tirar fotos, pena por quê tinha vários trabalhos que eu gostaria de guardar uma foto. Como o museu era pequeno a visita foi curta e logos partimos para o Palais de Tokyo.

No Palais de Tokyo há dois museus, um de arte contemporânea e outro de arte moderna e contemporânea com um acervo permanente. A exposição de arte contemporânea que tinha era fraca, só gostamos de uns 3 trabalhos. Mas o espaço expositivo é bastante interessante, ver uma exposição boa aí deve ser bem legal.

11570
11573
11576
11579
11582
11585
11588
11591
11594

O acervo do museu em frente (o de arte moderna e contemporâne) é GENIAL. No mínimo uma aula de como organizar um acervo histórico. Há um passeio pré-definido pelo acervo, com várias informações sobre os periodos dos trabalhos expostos sempre fazendo uma paralelo com outros movimentos de arte da época. Talvez de uma forma resumida possa se dizer que é uma mini aula de história da arte do último século (1900-2000).

Como se isso não bastasse de artes pelo dia e como todas as minhas tentativas de ir na l’Orangerie tinham falhado, rumei para lá. A Lu não foi pois já tinha visitado esse museu, combinei e encontra-la mais tarde no Pompidou – para abusarmos mais um pouco da internet deles. Então tive minha segunda dose massiva de Monet do dia. Se eu já tinha me emocionado na manhã dentro do Marmottan, à tarde foi muito mais intenso. As Ninféias do Monet são simplesmente o máximo. Tirei várias fotos. Muitas fotos. O Museu também acabou de passar por uma reforma, e como bom filho de arquiteto, tirei várias fotos do museu – um pequena seleção abaixo.

11606
11612
11615
11618
11621
11624
11627
11633

Quando eu cansei de ver Monet (jura que isso é possível) fui encontrar a Lu no Pompidou. Devia pegar a linha 1 do metro até Hôtel de Ville, e caminhar até lá. Mas o metro não estava afim de me levar para lá, e fui obrigado a descer do trem junto com as 600 pessoas que estavam dentro dele. Refiz a minha rota por outra linha, afinal era só tomar dois metros e descer na Châtelet: barbada! Chegar em Châtelet foi simples, agora aonde fica a saída desse shopping (Les Halles) que tem em cima do metro? Resumo, quando eu vi estava quase no Palais Royal (que fica do lado oposto ao Pompidou), mas olhando no mapa logo me achei e tomei o rumo correto.

Encontrei a Lu e fomos pegar o metro no Hôtel de Ville, pra nossa surpresa tinha uma pista de patinação no gelo montada com muitas pessoas patinando. Foi o momento descontraido do dia, tirei muitas fotos de todo mundo que estava patinando – alguns literalmente. Selecionei algumas boas para colocar online.

Rio de Janeiro – Lisboa

Com uma hora e meia de atraso decolamos! O Vôo estava vazio, mudei de lugar e dormir com 2 cadeiras só para mim. O A330 da TAP era bastante bom, com tvs de lcd individuais, escovas de dente no banheiro, etc. Revi Simpsons – The Movie no avião, as legendas em português de portugal são engraçadas as vezes, e muito mais corretas em outras – por exemplo, eles conjugam a segunda pessoa do singular direito!
Como meu vôo até Lisboa atrasou, acabei chegando aqui às 8h da manhã, minha conexão ERA as 8h15. Assim como metade das pessoas no meu vôo, tive que esperar numa fila enorme para pegar outro cartão de embarque. Depois mais uma fila enorme para passar pela Aduana e estar finalmente na europa! Próximo vôo para Paris da TAP saí as 12h50, horário local.
Em vista do atraso, ganhei um vale Snack na Harrods, que consiste de uma bebida quente (café, café com leite, chá, etc), uma bebida fria (refrigerante ou água) e um sanduiche de fiambre ou de queijo. Não posso me queixar da comida aqui, presunto bom, chá servido em bule, e a coca-cola deles é menos doce que a nossa, bem melhor! Ah! O alumínio da lata também é umas 20x mais espesso que no brasil, o que é estranho!
Ah, e esses portugas fumam por todos os lugares, inclusive dentro do aeroporto com ar condicionado!!!
Tenho mais umas duas horas para matar por aqui.

Florianopolis – Rio de Janeiro

O tempo, como dizia a previsão, não ajudou e não consegui mais contemplar a paisagem, mas não me importei muito. Consegui continuar sozinho na minha fileira, great! Espero que no trecho Rio – Lisboa aconteça o mesmo. Logo serviram um Snack++: sanduiche de queijos (sim, no plural, tinham uns 4 tipos de queijo) e Coca-Cola.
7 minutos de nuvem separavam o sol semi-escaldante da chuva do Rio de Janeiro (alguém se candidata a calcular a altura das nuvems?). Às 13h30 estava no sagão do GIG (Aeroporto Internacional Tom Jobim aka Galeão), liguei para casa pra contar do meu status atual, e fui almoçar. Agora estou sentando olhando aquela famosa igreja que fica em cima de uma morro, que as favelas ainda não ousaram tomar conta. WiFi aqui é pago, maldita VEX!

Primeira perna da viagem completada, agora só esperar o próximo vôo. Ah! Chove muito aqui.

Fatos curiosos do dia:

  • Ex reitora da ufrgs acaba de passar na minha frente.
  • A TAM não sabe alemão, no seu mini guia de Frankfurt está escrito na seção de frases utéis: “Quanto custa? = wievel kost?”
  • A TAM não sabe alemão, take 2:
    • Lê-se num paragrafo sobre as Frankfurters: “Até hoje fazem sucesso, com batatas fritas cortadas bem finas (as bratkartoffel, chucrute, mostarda, mais forte que a consumida no Brasil, e Sauerkraut, um tipo de repolho fermentado.” Enfases minhas. Será que eles não sabem que chucrute é Sauerkraut? ou será que eles não sabem que chucrute é feito de repolho fermentado? Who knows!
  • Must I write in English to have spelling? Yes! Damn!

Vôo Porto Alegre – Florianopolis

Atraso de 1 hora, not bad! Especialmente por quê o jornal anunciava temporais em vários estados brasileiros. Ricardo, Crocca, meus avós e meus pais estavam no aeroporto para me desejar boa viagem, espero que mande as fotos que tiramos por lá (em resolução decente! ;)).

Sentei na janela, e por sorte (ou azar) ninguem sentou do meu lado. Não tinha metade do A320 ocupado. O vôo foi bastante curto, e o ceú estava completamente limpo! Pena que não tinha uma camera fotográfica. Consegui acompanhar quase todas as cidades que passaram à largo, por exemplo Caxias do Sul no fundo; Nova Petropólis, Gramado e Canela a meia distância; e mais próximo ao avião São Francisco de Paula. Logo a seguir avistei Cambará, e minuto depois São José dos Ausentes.

Snacks do vôo: Amendoim e Coca-Cola.

Consegui acompanhar a geografia até Sombrio, dalí pra frente perdi o rumo e o tempo deixou de cooperar, mas logo aterrisamos no aeroporto de florianopolis, que, diga-se de passagem, tem a menor pista que já pousei (ou será que o piloto foi maneta ?). Ficamos uns 20min no aeroporto, pessoas desceram, pessoas subiram, here we go, next stop Rio de Janeiro!