Academia.eduAcademia.edu

ChongDong.pdf

A tolerância a faltas desde há muitos anos que trata do problema de projectar sistemas confiáveis usando componentes que podem falhar. Recentemente a aplicação deste paradigma no âmbito da segurança começou a suscitar atenção sob a designação de tolerância a intrusões. Este artigo insere-se no âmbito da investigação nesta área. Descreve o projecto de um núcleo distribuído seguro chamado ChongDong com base num pacote de segurança para Linux, o LIDS. O ChongDong é depois usado para suportar a execução de um protocolo tolerante a intrusões que permite a um conjunto de processos chegarem a acordo sobre um valor. O desempenho desse protocolo é avaliado.

Um Núcleo de Segurança Distribuído para Suporte a Protocolos Tolerantes a Intrusões 1 Pan Jieke1 , Miguel Correia2 , Nuno Ferreira Neves2 , Paulo Veríssimo2 Siemens, SA Rua Irmãos Siemens, 1 2720-093 Amadora, Portugal 1 2 LASIGE, Faculdade de Ciências da Universidade de Lisboa Campo Grande, Edifício C6 1749-016 Lisboa, Portugal [email protected] {mpc,nuno,pjv}@di.fc.ul.pt Resumo A tolerância a faltas desde há muitos anos que trata do problema de projectar sistemas confiáveis usando componentes que podem falhar. Recentemente a aplicação deste paradigma no âmbito da segurança começou a suscitar atenção sob a designação de tolerância a intrusões. Este artigo insere-se no âmbito da investigação nesta área. Descreve o projecto de um núcleo distribuído seguro chamado ChongDong com base num pacote de segurança para Linux, o LIDS. O ChongDong é depois usado para suportar a execução de um protocolo tolerante a intrusões que permite a um conjunto de processos chegarem a acordo sobre um valor. O desempenho desse protocolo é avaliado. 1 Introdução A dependência da nossa sociedade em relação a sistemas informáticos distribuídos tem crescido de forma explosiva nos últimos anos. No entanto, esta evolução tecnológica é acompanhada por novos problemas e desafios, entre os quais os relacionados com a segurança informática. As soluções adoptadas na perspectiva clássica da segurança têm um cariz fundamentalmente de prevenção, sendo o objectivo o de construir sistemas “perfeitos”, sem vulnerabilidades que possam ser exploradas por piratas informáticos, quer directamente, quer através de malware (p.ex., worms). No entanto a realidade mostra que esse objectivo é dificilmente atingível em sistemas complexos, e que os sistemas vivem num ciclo permanente: vulnerabilidade descoberta, sistemas atacado, vulnerabilidade remendada (patched ). A tolerância a faltas é uma disciplina que se foi desenvolvendo paralelamente à da segurança ao longo dos anos. Os objectivos de ambas são muito semelhantes: construir sistemas “de confiança”, que se comportem de acordo com a sua especificação. No entanto, na tolerância a faltas, sem esquecer a prevenção, 1 Este trabalho foi parcialmente suportado pela FCT através do projecto POSI/EIA/ 60334/2004 (RITAS) e do Large-Scale Informatic Systems Laboratory (LASIGE). parte-se do princípio de que mesmo as componentes da melhor qualidade podem falhar e que, caso falhem, o sistema como um todo tem de continuar operacional. Este paradigma da tolerância a faltas tem sido aplicado no âmbito da segurança sob a designação de tolerância a intrusões. Apesar da área ter surgido já há muitos anos [1] só mais recentemente ganhou visibilidade, sobretudo graças ao programa americano OASIS [2] e ao projecto europeu MAFTIA [3, 4]. Um pressuposto fundamental desta abordagem é o de que os ataques e as intrusões podem ser considerados como sendo faltas, englobadas na categoria das faltas arbitrárias ou bizantinas [5]. Na tolerância a intrusões, em vez de se tentar prevenir todas as intrusões, assume-se à partida que algumas delas irão ter sucesso, mas os sistemas são construídos de modo a que elas sejam toleradas. O artigo segue uma aproximação que se baseia em enriquecer o sistema “normal” no qual todos os processos e a comunicação podem ser atacados, com um núcleo de segurança distribuído. Este núcleo é uma componente de um tipo que tem sido denominado wormhole [6]. Este tipo de componentes pretende lidar com algum tipo de incerteza em sistemas distribuídos. Neste contexto, considera-se que existe incerteza em termos de segurança, ou seja, que podem existir ataques e intrusões nas componentes do sistema. O wormhole, pelo contrário, é uma componente distribuída que não manifesta essa incerteza, ou seja, que é segura. Assim, ao contrário das operações normais fornecidas pelo sistema, o wormhole pode oferecer um conjunto de operações seguras que devolvem resultados fiáveis e correctos. O wormhole tem necessariamente de oferecer uma funcionalidade muito limitada, para que a sua segurança possa ser certificada usando algum tipo de metodologia formal. O wormhole cuja concretização é descrita neste artigo é chamado ChongDong2 . O sistema que utiliza o ChongDong é composto por um conjunto de máquinas que usam uma rede para comunicarem e cooperam entre si. As máquinas executam diverso software, incluindo um sistema operativo, bibliotecas, servidores de suporte (p.ex., servidores de autenticação), entre outros. Adicionalmente, as máquinas contêm um ChongDong local. Os ChongDongs locais são interligados por um canal de comunicação concretizado através de uma rede Ethernet privada e separada do canal de comunicação das aplicações. Cada máquina que contém um ChongDong local tem dois adaptadores de rede: um para a comunicação “normal” e outro para a comunicação privada do ChongDong. A arquitectura do sistema encontra-se na representada na figura 1. O ChongDong é tratado como qualquer outro software do sistema e as aplicações utilizam os seus serviços sempre que necessário. A sua segurança é garantida pelos mecanismos de controlo de acesso e protecção fornecidos pelo sistema LIDS (Linux Intrusion Detection System) 3 , um patch de segurança do sistema operativo Linux [7]. O artigo descreve também a concretização de um protocolo de consenso tolerante a intrusões baseado no ChongDong. O problema do consenso consiste em fazer com que um conjunto de processos distribuídos que escolhem um valor 2 ChongDong 3O significa wormhole em chinês. . . nome é enganador. O LIDS não é realmente um IDS. 2 Processo utiliza o canal público de comunicação para enviar e receber as mensagens com os outros processos Processo chama o serviço do ChongDong local Pi ChongDong Pi Pi ChongDongs locais utilizam o canal privado e seguro para comunicarem entre si Pi Chong Dong Chong Dong Chong Dong Figura 1: Arquitectura de um sistema que utiliza o ChongDong. A parte da aplicação é representada em cor escura e o ChongDong é representado em cor branca. inicial, cheguem a acordo sobre um único dos valores escolhidos. O consenso é um problema fundamental em sistemas distribuídos, que tem grande interesse teórico e prático, pois é equivalente a diversos outros problemas, como a difusão de mensagens com ordem total [8]. No entanto, é importante notar que o ChongDong não se destina a suportar protocolos de consenso tolerantes a intrusões. Pelo contrário, o protocolo de consenso apresentado server apenas para ilustrar como o ChongDong pode ser usado para concretizar protocolos tolerantes a intrusões. Diversos serviços distribuídos tolerantes a intrusões poderiam ser construídos com base no ChongDong [9]. O problema do consenso é insolúvel de forma determinista em sistemas sobre os quais não se façam hipóteses temporais [10]. A realização de hipóteses temporais sobre tempos de processamento ou comunicação num sistema sujeito a ataques é muito arriscada, já que um ataque de negação de serviço pode muitas vezes quebrar esse tipo de hipóteses. No artigo todas as hipóteses temporais necessárias ao sistema estão encapsuladas no ChongDong que, como vimos, é projectado de forma a ser seguro. O protocolo de consenso usa apenas um serviço do ChongDong para realizar determinado passo da sua execução, sendo de resto executado no sistema “normal” inseguro. As contribuições do artigo são as seguintes: • é descrito o projecto de uma componente distribuída segura da classe dos wormholes com o suporte do LIDS; • é mostrado como essa componente pode ser usada para concretizar um protocolo de consenso tolerante a intrusões; 3 • o desempenho do protocolo de consenso é avaliado. 2 Trabalho Relacionado Um paradigma fundamental em segurança é o de controlo de acesso. Os mecanismos deste tipo são geralmente divididos em duas classes: DAC e MAC. O controlo de acesso discricionário (DAC, Discretionary Access Control ) é o mais comum: cada utilizador pode especificar quem pode aceder aos recursos que lhe pertencem e como esse acesso pode ser feito (p.ex., só para leitura). No caso do controlo de acesso imperativo (MAC, Mandatory Access Control ), os utilizadores têm permissões de acesso estabelecidas administrativamente. Várias extensões e pacotes apareceram recentemente com o objectivo de suportar controlo de acesso MAC em Linux. Muitos desses pacotes são baseados na proposta IEEE 1003.1e (Posix.1e), entretanto retirada [11]. As capabilities fazem parte do próprio núcleo do Linux e permitem controlar o acesso de qualquer processo aos recursos do sistema, mesmo que este tenha privilégios de superuser [12]. O pacote LSM (Linux Security Modules) é um patch para Linux que suporta a concretização de módulos de controlo de acesso [13]. O SecurityEnhanced Linux, desenvolvido pela US National Security Agency, é um conjunto de patches para o núcleo do Linux que suportam MAC [14]. Neste artigo é usado um pacote denominado LIDS para proteger o ChongDong local [7]. O LIDS concretiza MAC e define um conjunto de capacidades mais extenso e com controlo mais fino do que o do Linux original. Uma solução alternativa para proteger o wormhole seria colocar a sua parte local dentro de um módulo de hardware, como um coprocessador seguro ou um microcomputador PC-104. Essa solução alternativa é no entanto menos interessante sob o ponto de vista da possível distribuição do código por outros investigadores interessados em usá-lo. O trabalho em wormholes para tolerância a intrusões teve início no projecto MAFTIA, tendo sido desenvolvidos, entre outros, protocolos de difusão fiável [15] e de consenso [16]. Estes protocolos eram baseados num wormhole denominado TTCB [17] e não conseguiam evitar inteiramente as hipóteses temporais sobre o sistema. Além disso, a TTCB considerava hipóteses de tempo mais fortes do que o ChongDong, já que era síncrona, ou tempo-real. A TTCB foi usada para obter uma solução genérica para a concretização de serviços distribuídos tolerantes a intrusões eficiente em termos de número de réplicas necessárias [18]. Foi também mostrado que é necessário usar um wormhole para suportar recuperação proactiva em sistemas assíncronos [19]. O conceito de wormhole foi ainda usado para lidar com a incerteza em termos de tempo [20]. Para além do protocolo de consenso tolerante a intrusões baseado na TTCB, vários foram propostos na literatura. O protocolo original de Lamport et al. era baseado em comunicação síncrona, uma hipótese que não fazemos neste artigo [5]. Outras aproximações foram usadas para concretizar este tipo de protocolos, como por exemplo a aleatoridade [21], a sincronia parcial [22] e os detectores de falhas [23]. 4 3 O Sistema LIDS Com a crescente popularidade do Linux na Internet, cada vez são encontradas mais vulnerabilidades nas suas aplicações, serviços e até no próprio núcleo [24]. Muitas dessas vulnerabilidades permitem que os piratas informáticos penetrem nos sistemas e, muitas vezes, obtenham privilégios de superuser (ou “root”). Com o modelo de protecção do actual sistema Linux (e dos restantes Unixes), uma vez obtidos os privilégios de superuser, o pirata passa a ter controlo sobre todos os recursos do sistema, podendo inclusive modificar o funcionamento do núcleo através da inserção de módulos nesse mesmo núcleo (loadable kernel modules), como fazem muitos rootkits 4 . Este poder ilimitado do superuser é o principal problema que o LIDS pretende resolver. 3.1 Objectivos do LIDS O LIDS foi escrito por Xie Huagang e Philippe Biondi. Como já ficou dito, é um patch de segurança para o núcleo do Linux. Fornece ferramentas de administração que permitem aumentar a segurança do próprio núcleo através da concretização de Mandatory Access Control (MAC). Quando o LIDS está activo, o acesso a ficheiros seleccionados, às operações de administração do sistema ou da rede, à memória, aos dispositivos de I/O, entre outros, podem ser proibidos até mesmo ao superuser. As protecções de cada recurso são definidos pelo administrador do sistema, sendo as operações reservadas ao administrador protegidas usando uma palavra de passe. O LIDS utiliza e extende as capacidades do Linux para controlar todo sistema. Concretizando, o LIDS fornece as seguintes protecções: • Ficheiros. O LIDS pode proteger ficheiros e directorias de modo a não permitir que um utilizador, mesmo que superuser, efectue alterações não autorizadas. A protecção é feita através da modificação das chamadas ao sistema no núcleo. Cada vez que haja acesso a um ficheiro são verificados o nome do ficheiro e o modo de protecção. Se estiver protegido contra um determinado modo de acesso, as operações correspondentes não são efectuadas. • Processos. Em Linux, enquanto um processo estiver a correr no sistema, deve existir uma entrada na directoria /proc com o nome igual ao pid do processo. Utilizando o comando ps consegue-se obter informação sobre os processos correntes e, através do comando kill, consegue-se terminar processos. Com os mecanismos do LIDS pode-se tornar um processo invisível, ininterrompível e insensível aos sinais do sistema. • Núcleo. O LIDS fornece uma funcionalidade chamada kernel sealing. Só é permitida a inserção de módulos ou outras configurações antes do kernel sealing. 4 Conjunto de ferramentas usado por um atacante para manter o acesso após intrusão num sistema. 5 O LIDS fornece ainda funcionalidades como a detecção de port scans 5 e a resposta a intrusões através da modificação de regras de uma firewall local. Este tipo de mecanismos não vão ser usados no artigo. 3.2 Utilização do LIDS O LIDS permite proteger os recursos do sistema de duas formas. Primeiro, permite limitar o que todo e qualquer processo pode fazer, mesmo que tenha privilégios de superuser, através das capacidades. Por exemplo, se for desactivada a capacidade CAP_SETUID, qualquer processo fica impossibilitado de fazer setuid, ou seja, de modificar os seus user IDs real e efectivo [25]. Se for desactivada a capacidade CAP_SYS_RAWIO, para dar mais um exemplo, deixa de ser possível fazer acesso raw a dispositivos de I/O. O LIDS permite também proteger ficheiros e processos específicos usando listas de controlo de acesso, ACLs. Mais uma vez, o objectivo é o de permitir ou não o acesso a determinados recursos do sistema de forma administrativa, ou seja, controlo de acesso MAC. No entanto, as ACLs são usadas para fazer essa definição de forma fina, para cada recurso. A definição de ACLs é realizada através da ferramenta lidsconf, que actua sobre um sujeito e um objecto. O sujeito é um programa, geralmente um binário ou um shell script. O objecto é o recurso ao qual o sujeito pode pretender aceder, por exemplo, ficheiros, directorias, capacidades e sockets. Seguem-se alguns exemplos de configuração de ACLs: • lidsconf -A -s programa1 -o ficheiro1 -j READONLY O lidsconf adiciona (-A) um controlo de acesso que dá ao sujeito (-s) programa1 o privilégio de leitura ao objecto (-o) ficheiro1. O programa1 não pode eliminar nem alterar ficheiro1, mesmo que esteja a correr com privilégios de superuser. • lidsconf -A -o directoria -j READONLY Como o sujeito não está definido, a regra é aplicada a todos os utilizadores e processos. É dado apenas o privilégio de leitura ao objecto directoria, ou seja, a todos os ficheiros nela incluídos. • lidsconf -A -s /bin/httpd -o CAP_NET_BIND_SERVICE 80 -j GRANT O sujeito httpd (servidor Apache) recebe a capacidade CAP_NET_BIND _SERVICE para se poder ligar ao porto 80. Assume-se que a capacidade CAP_NET_BIND_SERVICE está desactivada globalmente, logo nenhum programa pode fazer bind a portos arbitrários. 3.3 Segurança do LIDS Como já referimos, têm surgido nos últimos anos diversas vulnerabilidades no núcleo do Linux [24]. Algumas dessas vulnerabilidades permitem contornar os 5 Tentativa de visualizar os portos abertos numa máquina, ou conjunto de máquinas, através da rede. 6 mecanismos de segurança fornecidos por esse núcleo. Sendo assim, é pertinente discutir se o LIDS é mais seguro do que o Linux. Do que foi visto até agora fica claro que o que o LIDS permite é a definição de políticas de segurança mais finas do que o Linux. Para esse efeito oferece um modelo mais complexo e com mais mecanismos do que o Linux original, sobretudo através do controlo de acesso MAC. No entanto isso não nos diz nada sobre a segurança do LIDS em si. Os primeiros trabalhos em controlo de acesso identificaram a necessidade desses mecanismos serem concretizados num monitor de referência, uma componente que deve obedecer a três propriedades: completude (o monitor não pode ser contornado), isolamento (não pode ser corrompido) e verificabilidade (tem de ser formalmente verificável) [26]. A arquitectura do LIDS não inclui um monitor de referência, embora o LIDS concretize mecanismos de controlo de acesso semelhantes ao de um monitor de referência. O LIDS em si é apenas um patch de segurança do núcleo do Linux. Basicamente é código de melhoramento espalhado ao longo do núcleo e não uma componente encapsulada e que verifica as três propriedades indicadas. Esta limitação do LIDS traduz-se numa limitação da concretização corrente do ChongDong, mas não põe em causa o modelo de wormhole seguro. Este é um modelo genérico que pode ser realizado de diversas formas, por exemplo em hardware para aplicações comerciais com requisitos exigentes. 4 O Wormhole ChongDong A arquitectura de um sistema tolerante a intrusões que utilize o ChongDong pode ser dividida em duas partes (v. figura 1). Localmente existe um módulo ChongDong que corre em cada máquina. As aplicações ou processos, que potencialmente executam protocolos tolerantes a intrusões, utilizam um canal público de comunicação para efectuar o envio e a recepção das mensagens entre si. Se necessário comunicam também com o ChongDong existente localmente. O principal serviço fornecido pelo ChongDong é um serviço de acordo distribuído seguro chamado ChongDong_TBA. Quando um conjunto de processos pretende executar esse serviço, cada um deles chama localmente a função ChongDong_TBA passando como argumento um valor inicial, sendo depois retornado a todos um resultado. O ChongDong fornece ainda um serviço que permite a cada processo obter um identificador único perante o wormhole. Esse serviço tem de ser chamado por todos os processos que pretendam invocar o ChongDong_TBA. 4.1 API do ChongDong A programação de aplicações que utilizem o ChongDong é feita mediante o recurso a uma biblioteca que define a API do ChongDong. A interface do serviço de atribuição de identificador consiste na seguinte função (em pseudo-código): result, eid ← getEid() 7 A função retorna uma estrutura que contém dois elementos. O eid é o identificador atribuído pelo ChongDong e result indica se a atribuição correu correctamente ou não. A cada processo é atribuído um identificador único. Esta unicidade é garantida através da concatenação do endereço MAC (Media Access Control ) da máquina onde corre o ChongDong com um valor aleatório (não repetido). A interface do serviço ChongDong_TBA é a seguinte: error, value, prop_ok ← ChongDong_T BA(eid, elist, cid, quorum, value) Os primeiros três argumentos da função são basicamente utilizados para identificação: eid é o identificador do processo que invoca o ChongDong_TBA; elist é uma lista de identificadores dos processos envolvidos no ChongDong_TBA e cid representa o identificador do consenso que vai ser executado. O quorum define o número mínimo de processos que devem chamar o ChongDong_TBA antes de este fazer realmente acordo sobre os valores propostos. Este valor pode ser, por exemplo, 2f + 1, em que f é o número máximo de processos que podem falhar. Finalmente, value é o valor proposto por cada processo. O valor é geralmente um hash criptográfico de dados de maior dimensão, já que value tem apenas 160 bits na concretização actual. Diferentes instâncias do serviço ChongDong_TBA são identificadas por conjuntos de (elist, cid, quorum) diferentes. O resultado retornado pela função é uma estrutura que contém os seguintes campos: error que indica se o ChongDong_TBA foi bem executado ou não; value que contém o valor resultante do acordo; e prop_ok que indica o número total dos processos que propuseram o valor resultante. O valor retornado pelo serviço ChongDong_TBA é o valor proposto mais vezes pelos processos que participaram activamente no serviço, ou seja, os processos que chamaram a função a tempo de o seu valor ser levado em conta. Assim, este serviço faz uma espécie de acordo sobre valores de tamanho limitado, os já referidos 160 bits. 4.2 Concretização do serviço ChongDong_TBA Temos usado o termo processo para denominar aquilo que executa o código da aplicação ou protocolo tolerante a intrusões. Um processo nesse contexto pode ser diversas coisas, como um processo no sentido clássico usado em sistemas operativos, um objecto distribuído (p.ex., no sentido usado no CORBA), ou outro tipo de componente de software. O ChongDong é concretizado através de um processo, não nesse sentido abstracto que temos vindo a usar mas no sentido de um processo Linux. Esse processo recebe pedidos dos outros processos através de um mecanismo de comunicação entre processos (sockets Unix ). A comunicação através desses sockets é encapsulada nas chamadas feitas à API introduzida acima, de forma a que a aplicação apenas veja uma chamada a uma função. A concretização da função ChongDong_TBA dentro de um ChongDong local está apresentada em pseudo-código nos algoritmos 1 e 2, um para cada um 8 dos fluxos de execução (threads) do processo. Ao serem chamadas as funções ChongDong_TBA nos ChongDongs locais, estes trocam entre si todos os valores propostos e executam um protocolo de consenso tolerante a faltas por paragem. Através da execução deste protocolo de consenso obtém-se o valor acordado que é devolvido aos processos que invocaram o serviço. Esta utilização de um protocolo de consenso dentro do ChongDong pode causar alguma confusão, já que atrás foi referido que o artigo apresentaria um protocolo de consenso tolerante a intrusões. Na realidade o problema resolvido é o mesmo mas os tipos de faltas levados em conta são diferentes. O protocolo de consenso executado dentro do ChongDong não precisa de tolerar ataques e intrusões, apenas faltas de paragem (“crashes”), pois o ChongDong é construído para ser seguro. Assim, o protocolo usado é relativamente simples. Já o protocolo de consenso tolerante a intrusões precisa de tolerar todo o tipo de comportamento malicioso por partes dos processos, logo o problema é mais complicado e é esse que tratamos neste artigo. Algoritmo 1 Protocolo ChongDong_TBA (tarefa principal) Initialization: {Variáveis partilhadas pelas duas tarefas} 1: 2: 3: 4: TBABackup ← ∅ {Tabela dos TBAs atrasados} LocalTBA ← ∅ {Tabela dos TBAs Locais} VPropose ← ∅ {Tabela c/uma entrada por cada TBA para o qual haja quorum hashes} VResult ← ∅ {Tabela com os TBAs que foram decididos pelo algoritmo de consenso} When ChongDong_TBA(eid, elist, cid, quorum, value) is called do 5: if (elist, cid, quorum) ∈ TBABackup then 6: return TBABackup.getPropose(elist, cid, quorum) 7: end if 8: if exec-cons(elist, cid, quorum) then 9: loop 10: if (elist, cid, quorum) ∈ VResult then 11: return VResult.getTBA(elist, cid, quorum) 12: end if 13: end loop 14: end if {o consenso já está a correr?} 15: multicast(eid, elist, cid, quorum, value) 16: LocalTBA ← LocalTBA ∪ (eid, elist, cid, quorum, value) 17: loop 18: if deliver(eid, elist, cid, quorum, value) then 19: LocalTBA ← LocalTBA ∪ (eid, elist, cid, quorum, value) 20: end if 21: if (elist, cid, quorum) ∈ VResult then 22: return ← VResult.getTBA(elist, cid, quorum) 23: end if 24: end loop O protocolo do ChongDong_TBA começa por fazer algumas inicializações, como se pode ver no algoritmo 1. No início da execução, é verificado se existe ou 9 não uma entrada na tabela TBABackup com o mesmo (elist, cid, quorum), pois a tabela TBABackup serve para guardar todos os resultados de execuções do serviço que já terminaram (linhas 5-7). Se existir, é retornado imediatamente o valor decidido, já que o processo não participou na execução do serviço na altura em que outros processos o fizeram. Se não existir uma entrada com (elist, cid, quorum) na tabela TBABackup mas consenso relativo a essa execução do serviço já estiver a correr, o ChongDong local fica à espera do resultado da execução (linhas 8-14). Quando o consenso terminar, o valor decidido é retornado e o protocolo termina a sua execução. Se nenhuma das duas situações se verificarem, o ChongDong local difunde a informação sobre a chamada ao serviço para todos os outros ChongDongs e adiciona essa informação à tabela LocalTBA (linhas 15-16). Em seguida fica à espera da entrega das mensagens enviadas pelos outros ChongDongs. Quando receber as mensagens dos outros ChongDongs, guarda a informação na tabela LocalTBA (linhas 17-24). Algoritmo 2 Protocolo ChongDong_TBA (tarefa secundária) 1: loop 2: while not LocalTBA.hasQuorum() do 3: wait() 4: end while 5: 6: 7: VPropose ← LocalTBA.tbasWithQuorum() VResult ← early-consensus(VPropose) LocalTBA.clean(VPropose) 8: for all TBA ∈ VResult do 9: TBABackup ← TBA 10: end for 11: end loop A tarefa secundária está geralmente bloqueada à espera de que haja pelo menos uma entrada na tabela LocalTBA para a qual haja quorum valores propostos por diferentes processos (algoritmo 2, linhas 2-4). Quando tal acontecer, a tarefa arranca o algoritmo de consenso tolerante a faltas por paragem early-consensus [27]. O valor a propor é um vector com uma entrada por cada instância do serviço ChongDong_TBA para o qual já haja um quorum de 2f +1 mensagens (linhas 5-6). Quando o algoritmo de consenso devolve todas as instâncias do serviço ChongDong_TBA que tenham sido decididas pelo consenso, limpa as entradas na tabela LocalTBA para evitar repetição da execução do protocolo de consenso (linha 7). As instâncias do serviço ChongDong_TBA decididas são adicionadas a TBABackup (linhas 8-10). Como já referimos, Fischer, Lynch e Paterson provaram que o problema de consenso não tem solução determinista num sistema assíncrono sujeito a paragem de processos [10]. Mais tarde, Chandra e Toueg mostraram que o problema de consenso era solúvel se o sistema fosse extendido com um detector de falhas não fiável [28]. O algoritmo de early-consensus é inspirado no algoritmo fornecido neste último artigo, mas termina em menor número de ciclos 10 de envio de mensagens [27]. O algoritmo precisa de um detector de falhas que foi concretizado usando um esquema simples de envio de heartbeats, ou seja, de mensagens a dizer “estou vivo”. Cada ChongDong local envia um heartbeat periodicamente para cada um dos outros. Se um ChongDong local fica determinado tempo sem receber um heartbeat de outro, considera-o suspeito de ter falhado. Estes detectores são não fiáveis na exacta medida em que se podem enganar nas suspeitas. No entanto o algoritmo funciona bem apesar desses enganos. Note-se que para concretizar o detector de falhas é necessária alguma sincronia, se bem que muito fraca. No entanto essa sincronia fica encapsulada no ChongDong. 4.3 Tornar o ChongDong seguro A parte do ChongDong existente em cada máquina localmente foi tornada segura usando os mecanismos de controlo de acesso fornecidos pelo LIDS. O LIDS fornece duas ferramentas que permitem efectuar a sua administração e configuração: lidsadm e lidsconf. A lidsadm é uma ferramenta que permite administrar o LIDS. Permite realizar operações tais como activar ou desactivar o LIDS, efectuar o kernel sealing e visualizar o estado do LIDS. A ferramenta lidsconf é utilizada para configurar as ACLs. Estas duas ferramentas são utilizadas pelo administrador do LIDS, ao qual é atribuída uma palavra chave de administração. Os aspectos mais importantes que devem ser levados em conta na protecção do ChongDong local são: • A obtenção do identificador do processo do ChongDong (pid ) deve ser inacessível para os utilizadores do sistema, incluindo o superuser. O processo do ChongDong não deve aparecer na tabela dos processos (correndo ps) nem na directoria /proc. • O processo do ChongDong deve ser protegido de modo a que não seja possível enviar-lhe sinais. • O processo do ChongDong não deve ser interrompível, isto é, mesmo que executando o comando kill -9 pelo superuser o ChongDong não é terminado. • O código do ChongDong deve ser protegido contra modificação. Essas protecções são forçadas através dos seguintes comandos: • Esconder o processo do Chongdong: lidsconf -A -s ./ChongDong -o CAP_HIDDEN -j GRANT • Proteger o processo do ChongDong de modo aos sinais do sistema não serem enviados ao processo: lidsconf -A -s ./ChongDong -o CAP_PROTECTED -j GRANT • Tornar ininterrompível o processo do ChongDong: lidsconf -A -s ./ChongDong -o CAP_KILL_PROTECTED -j GRANT 11 • Proteger todo o código do ChongDong contra modificação: lidsconf -A -o ./ChongDong/ -j READONLY A rede privada do ChongDong tem também de ser protegida através dos seguintes comandos: • Desactivar a interface da rede e torná-la apenas acessível para o ChongDong lidsadm -S – -CAP_NET_ADMIN lidsconf -A -s ./ChongDong -o CAP_NET_ADMIN -j GRANT • Desactivar a possibilidade de efectuar broadcast pela rede e torná-la apenas acessível para o ChongDong lidsadm -S – -CAP_NET_BROADCAST lidsconf -A -s ./ChongDong -o CAP_NET_BROADCAST -j GRANT • Desactivar o serviço de binding para portos menores que o 1024 e torná-la apenas acessível para o ChongDong lidsadm -S – -CAP_NET_BIND_SERVICE lidsconf -A -s ./ChongDong -o CAP_NET_BIND_SERVICE -j GRANT Até ao momento, o LIDS ainda não fornece o mecanismo de controlo de acesso para os dispositivos de rede. Mais especificamente, não é possível esconder a placa de rede ou dar autorização de acesso a apenas alguns processos. Por isso não foi possível efectuar a protecção total ao canal de comunicação do ChongDong. Esta funcionalidade está a ser acrescentada ao LIDS a pedido dos autores do artigo, sendo de prever que esteja disponível a médio prazo. Na realização actual os ChongDongs começam a sua operação autenticando-se mutuamente e estabelecendo chaves de sessão. Estas chaves são depois usadas para proteger a integridade da comunicação através de Message Authentication Codes (MACs) [29]. Para aumentar a confiança na segurança do ChongDong, foi feita uma análise estática do seu código [30]. Como toda a concretização do sistema foi feita em linguagem C++, foi utilizada uma ferramenta de análise estática de código para essa linguagem chamada Flawfinder 6 . Esta ferramenta detecta os problemas de segurança mais conhecidos do C++. Alguns exemplos são: os problemas relacionados com buffer overflows, como o uso das funções strcpy(), strcat(), gets(), sprintf(), e scanf() que não efectuam a verificação do tamanho do buffer ; os problemas relacionados com o formato das strings (p.ex., printf(), snprintf() e syslog()); problemas relacionados com execuções de programas (p.ex., família exec(), system(), popen()); e problemas relacionados com a aquisição de números aleatórios fracos (random()). O Flawfinder produz uma lista de potenciais vulnerabilidades ordenadas por gravidade. Os riscos mais graves são mostrados no topo da lista. O nível de risco não depende só das funções, mas também dos valores dos parâmetros da função. 6 http://www.dwheeler.com/flawfinder/ 12 Por exemplo, em muitos contextos o uso de uma string constante envolve menor risco do que um string variável. A execução do Flawfinder com o código do ChongDong gerou uma lista de 59 possíveis vulnerabilidades, todas elas chamadas a memcpy. Como a função memcpy não efectua a verificação do tamanho do buffer de origem, se o tamanho deste for maior do que o do buffer de destino pode existir uma vulnerabilidade a ataques buffer overflow. Todas as 59 utilizações suspeitas do memcpy foram verificadas manualmente mas como os tamanhos dos buffers são sempre verificados antes de execução da função memcpy() essas vulnerabilidades na realidade não existem. 5 Consenso Tolerante a Intrusões Sendo o objectivo do ChongDong suportar a execução de protocolos tolerantes a intrusões, foi concretizado um protocolo com essa propriedade que é significativo e que tem interesse prático: um protocolo de consenso [31]7 . Como foi referido atrás, os processos que correm o protocolo utilizam uma rede pública de comunicação para efectuar o envio e a recepção das mensagens entre si e comunicam com o ChongDong existente em cada máquina local para obter o valor de acordo distribuído. Este funcionamento encontra-se representado na figura 1. A comunicação através da rede pública é protegida usando canais seguros, por exemplo, conexões SSL [32]. Estes canais garantem apenas a integridade da comunicação, encontrando-se a cifra que suporta confidencialidade desligada. O problema de consenso pode ser definido em termos das seguintes propriedades: • Validade. Se todos os processos correctos propuserem o mesmo valor v, então qualquer processo correcto que decida, decide o valor v. • Acordo. Todos os processos correctos decidem o mesmo valor. • Terminação. Qualquer processo correcto acaba por decidir. O protocolo é executado num ambiente assíncrono no qual os processos com intrusões se podem comportar de forma arbitrária. Por, exemplo, os processos nos quais ocorram intrusões podem tentar fazer conluio para quebrar as propriedades do consenso. Assim, o objectivo é garantir que os processos correctos conseguem decidir num valor com a presença de um subconjunto de processos maliciosos. Parte-se da hipótese de que no máximo f processos podem ser maliciosos e que o número total de processos N verifica N ≥ 3f + 1. Por exemplo, pode-se assumir que não há intrusões em mais do que 2 processos (f = 2) e que o número de processos é N = 7. Este tipo de hipóteses é incontornável neste 7 Convém recordar que o consenso que se discute aqui é diferente do que foi referido no capítulo anterior. O protocolo aqui apresentado pretende resolver consenso tolerante a faltas bizantinas, categoria na qual se incluem as intrusões. O early-consensus de Schiper só tolera paragem de processos. 13 tipo de sistemas, sendo fácil perceber que se a maior parte dos processos forem maliciosos, estes poderiam controlar o protocolo. A proporção N = 3f + 1 foi provada ser a que dá o número mínimo de processos necessários para tolerar f faltas bizantinas (intrusões) num sistema assíncrono [33, 22]. 5.1 Protocolo Cada processo que participa no protocolo executa o algoritmo 3. Os argumentos da função são a lista com os identificadores de processos (elist), um identificador da execução do protocolo (cid ) e o valor proposto (valuei ). O valor proposto pode ter um número de bytes arbitrário, por exemplo, um bit, centenas de bytes ou um ficheiro com vários MBytes. A ideia de concretizar um consenso tolerante a intrusões sobre um serviço (ChongDong_TBA) realizado através de um consenso tolerante a faltas por paragem pode parecer estranha. Por isso, convém recordar que o objectivo aqui é apenas ilustrar como o ChongDong pode ser usado para realizar protocolos tolerantes a intrusões; o consenso é apenas um exemplo. É importante também ter em conta que o ChongDong pode ser concretizado em hardware tendo disponíveis recursos mais limitados. Por isso, o ChongDong_TBA faz acordo sobre valores de 160 bits, enquanto o protocolo de consenso tolerante a intrusões pode usar valores de tamanho arbitrário (por exemplo os referidos MBytes). O protocolo é organizado em duas fases. Na primeira fase, os processos começam por utilizar a rede pública de comunicação para transmitir o valor para outros processos (linha 4). Como a comunicação é feita por um canal seguro, mesmo que um intruso controlasse a rede seria incapaz de corromper o conteúdo das mensagens e o valor seria correctamente recebido. O processo bloqueia-se nesta fase até receber 2f + 1 valores de diferentes processos, o que garante que a maioria dos valores recebidos pertencem a processos correctos (assume-se que no máximo f são maliciosos; linhas 5-8). Na segunda fase, os processos tentam chegar ao valor do consenso recorrendo ao serviço ChongDong_TBA (linhas 10-25). Os processos começam por seleccionar o valor mais comum entre os valores propostos existentes em bag (linha 11). Esta condição simples garante que todos os processos correctos escolhem o mesmo valor se todos tiverem proposto valores idênticos (propriedade de Validade). Por outro lado, se os processos correctos tiverem diferentes valores propostos, então podem escolher valores distintos. A seguir, os processos invocam ChongDong_TBA com o hash criptográfico do valor escolhido, Hash(v), e esperam pela decisão (linha 12). A maioria das chamadas a ChongDong_TBA vêm de processos correctos porque o parâmetro quorum é definido com 2f + 1. Quando ChongDong_TBA retorna, todos os processos obterão o mesmo resultado, utilizando depois um pequeno teste para determinar o valor decidido. Basicamente, há dois resultados possíveis, dependendo dos valores propostos originais (linhas 13-17). Se todos os processos correctos (ou pelo menos 2f + 1) tiverem o mesmo valor original, então esse é o valor decidido. Caso contrário, pode ser escolhido um valor por omissão. 14 Algoritmo 3 Consenso tolerante a intrusões (executado por cada pi ) 1: function consensus(elist, cid, valuei ) 2: hash_v ← ⊥ 3: bag ← ⊥ 4: 5: 6: 7: 8: 9: {hash do valor decidido} {bag para guardar os valores recebidos} multicast(B-value, i, valuei ) repeat receive(B-value, k, valuek ) bag ← bag ∪ valuek until (bag has 2f + 1 values from diferente processes) activate task(T 1, T 2) 10: 11: 12: 13: 14: 15: 16: 17: task T 1: v ← most_Common_Value(bag) out ← ChongDong_TBA(eid, elist, cid, 2f + 1, Hash(v)) if (at least f + 1 proposed the same value) then hash-v = out.value else return(default-value) end if 18: 19: 20: 21: 22: 23: 24: 25: task T 2: when receive(Decide, k, valuek ) do bag ← bag∪ valuek end when when (hash-v 6= ⊥) and (∃valuek ∈ bag: Hash(valuek = hash-v )) do multicast(Decide, i, valuek ) return(valuek ) end when 5.2 Concretização A comunicação entre os processo que executam consenso tolerante a intrusões é feita através de canais SSL. Foi utilizada a biblioteca OpenSSL para a sua concretização8 . O protocolo faz multicast das mensagens e o SSL só suporta comunicação ponto-a-ponto. O mecanismo de multicast foi concretizado através de diversos envios de mensagens ponto-a-ponto. Os processos obtêm o IP e o porto uns dos outros através de um servidor designado por SSLCoordinationServer. O seu endereço IP e porto são bem conhecidos. Quando um processo começa a sua execução, em primeiro lugar comunica com o SSLCoordinationServer através de um canal SSL para obter os endereços IP e portos dos outros processos que já estão em execução. Se for o primeiro a ligar-se fica à espera que os restantes processos se liguem. Caso contrário, obtém os endereços IP dos processos já em execução e tenta estabelecer uma conexão SSL com cada um. Depois, fica também à espera das ligações dos restantes processos e estabelece conexões com cada um. Quando todos os processos estão ligados o servidor SSLCoordinationServer deixa de estar envolvido no protocolo (v. figura 2). A concretização actual parte do pressuposto de que o servidor SSLCoordi8 http://www.openssl.org 15 SSLCoordination Server SSLCoordination Server 1 2 P1 P1 Como é o primeiro processo que se ligar, fica logo à escuta de ligações. P2 P2 obtém o ip do P1, liga-se ao P1 e fica à escuta 1 2 SSLCoordination Server 1 2 3 P1 P2 P3 P3 obtém os ips do P1 e do P2, liga-se ao P1 e P2 e fica à escuta P1 P2 P3 Todos estão ligados a todos 3 4 Figura 2: Estabelecimento de conexões SSL entre processos. nationServer é seguro. Essa hipótese poderia ser relaxada tornando o servidor tolerante a intrusões usando um esquema simples baseado em sistemas de quorums [34]. 5.3 Medição do desempenho Esta secção apresenta medições do desempenho do protocolo de consenso tolerante a intrusões. A experiência envolveu quatro PCs com processadores Intel Pentium III a 500 Mhz, e 256MB SDRam PC133. Cada um continha dois adaptadores de rede 3Com 10/100. A rede pública e privada do ChongDong eram duas redes Fast-Ethernet switched a 100 Mbps. As versões de software usadas foram: Red Hat 9.0 com o núcleo Linux 2.4.25, LIDS 1.2.0, e g++ 3.2.2. A função de hash usada foi a concretização do OpenSSL do SHA-1 [35]. Em cada máquina foi executado um ChongDong e uma aplicação que corre o protocolo de consenso tolerante a intrusões. Assim, o número total de processos foi N = 4 e o número máximo de processos que podiam falhar f = 1. Na experiência foi medida a variação da latência do protocolo com a dimensão do valor proposto por todos os processos (v. figura 3). O protocolo foi executado 100 vezes para cada valor no gráfico. A medição foi feita de seguinte maneira: inicialmente um processo difunde a mensagem de iniciação do protocolo para todos os processos envolvidos; quando todos os processos recebem a mensagem de iniciação, executam o protocolo e, quando terminam, calculam o tempo que demorou a sua execução; por fim é efectuada a média dos tempos obtidos. O gráfico mostra que a latência aumenta com o tamanho do pedido, o que 16 Medição do desempenho 200 Latência (ms) 178 150 156 141 134 125 100 90 50 0 0 20 40 60 80 100 120 140 Tamanho do valor (bytes) Figura 3: Medições do desempenho do protocolo de consenso tolerante a intrusões. seria esperado dado que um maior comprimento do valor implica o consumo de tempo de processamento, por exemplo, o tempo gasto a efectuar o cálculo do hash dos valores. Na concretização do serviço ChongDong_TBA, foram utilizadas duas threads correspondentes às duas tarefas do protocolo apresentado na secção 4.2. O mecanismo de controlo de acesso concorrente às variáveis partilhadas pelas duas threads acabou por prejudicar fortemente o desempenho do protocolo. Por isso, as medidas apresentadas acima são ainda medidas preliminares, uma vez que o serviço está a ser novamente concretizado com apenas uma thread. No entanto, estes valores são da ordem de grandeza ou até inferiores aos obtidos com outros protocolos tolerantes a intrusões [36, 37]. 6 Conclusão O presente artigo aborda o problema da segurança em sistemas distribuídos através de uma perspectiva diferente da da segurança clássica: a tolerância a intrusões. O modelo usado considera que algumas componentes do sistema podem falhar arbitrariamente vítimas de intrusões, mas que existe uma componente da classe dos wormholes com propriedades mais fortes do que o resto do sistema, e que fornece um número reduzido de serviços de uma maneira segura e correcta. Este artigo apresenta a concretização de um wormhole chamado ChongDong que fornece um serviço de acordo destinado a suportar a execução dos protocolos tolerantes a intrusões. A própria componente tem um canal de comunicação concretizado através de uma rede Ethernet privada separada do canal de comunicação “normal” (outra Ethernet). A parte do ChongDong existente localmente em cada máquina foi tornada segura usando os mecanismos de controlo de acesso 17 fornecidos pelo LIDS. Foi ainda apresentada a concretização de um protocolo de consenso tolerante a intrusões que utiliza os serviços do ChongDong. O protocolo comporta-se de acordo com a especificação mesmo que ocorram intrusões em até um terço dos processos menos um. Referências [1] Fraga, J.S., Powell, D.: A fault- and intrusion-tolerant file system. In: Proceedings of the 3rd International Conference on Computer Security. (1985) 203–218 [2] Lala, J.H., ed.: Foundations of Intrusion Tolerant Systems. IEEE Computer Society Press (2003) [3] Veríssimo, P., Neves, N.F., Correia, M.: Intrusion-tolerant architectures: Concepts and design. In Lemos, R., Gacek, C., Romanovsky, A., eds.: Architecting Dependable Systems. Volume 2677 of Lecture Notes in Computer Science. Springer-Verlag (2003) 3–36 [4] Adelsbach, A., Alessandri, D., Cachin, C., Creese, S., Deswarte, Y., Kursawe, K., Laprie, J.C., Powell, D., Randell, B., Riordan, J., Ryan, P., Simmonds, W., Stroud, R., Veríssimo, P., Waidner, M., Wespi, A.: Conceptual Model and Architecture of MAFTIA. Project MAFTIA deliverable D21. (2002) [5] Lamport, L., Shostak, R., Pease, M.: The Byzantine generals problem. ACM Transactions on Programming Languages and Systems 4 (1982) 382–401 [6] Veríssimo, P.: Uncertainty and predictability: Can they be reconciled? In: Future Directions in Distributed Computing. Volume 2584 of Lecture Notes in Computer Science. Springer-Verlag (2003) 108–113 [7] Huagang, X.: Build a secure system with LIDS. http://www.lids.org/document/build_lids-0.2.html (2000) [8] Correia, M., Neves, N.F., Veríssimo, P.: From consensus to atomic broadcast: Time-free byzantine-resistant protocols without signatures. DI/FCUL TR 05–14, Department of Informatics, University of Lisbon (2005) [9] Correia, M.: Serviços distribuídos tolerantes a intrusões: resultados recentes e problemas abertos. In Gaspary, L.P., Siqueira, F., eds.: SBSeg 2005, V Simpósio Brasileiro em Segurança da Informação e de Sistemas Computacionais, Livro Texto dos Minicursos. Sociedade Brasileira de Computação (2005) 113–162 [10] Fischer, M.J., Lynch, N.A., Paterson, M.S.: Impossibility of distributed consensus with one faulty process. Journal of the ACM 32 (1985) 374–382 [11] IEEE: Draft Standard for Information Technology - Portable Operating System Interface (POSIX) - Amendment: Protection, Audit and Control Interfaces. P1003.1e. (1999) (withdrawn). [12] Tobotras, B.: Linux Capabilities FAQ 0.2. http://www.kernel.org/pub/linux/libs /security/linux-privs/kernel-2.2/capfaq-0.2.txt (1999) [13] Jaeger, T., Edwards, A., Zhang, X.: Consistency analysis of authorization hook placement in the Linux security modules framework. ACM Transactions on Information and System Security 7 (2004) 175–205 18 [14] Loscocco, P., Smalley, S.: Integrating flexible support for security policies into the Linux operating system. http://www.nsa.gov/selinux/slinux-abs.html (2001) [15] Correia, M., Lung, L.C., Neves, N.F., Veríssimo, P.: Efficient Byzantine-resilient reliable multicast on a hybrid failure model. In: Proceedings of the 21st IEEE Symposium on Reliable Distributed Systems. (2002) 2–11 [16] Correia, M., Neves, N.F., Lung, L.C., Veríssimo, P.: Low complexity Byzantineresilient consensus. Distributed Computing 17 (2005) 237–249 [17] Correia, M., Veríssimo, P., Neves, N.F.: The design of a COTS real-time distributed security kernel. In: Proceedings of the Fourth European Dependable Computing Conference. (2002) 234–252 [18] Correia, M., Neves, N.F., Veríssimo, P.: How to tolerate half less one Byzantine nodes in practical distributed systems. In: Proceedings of the 23rd IEEE Symposium on Reliable Distributed Systems. (2004) 174–183 [19] Sousa, P., Neves, N.F., Veríssimo, P.: Proactive resilience through architectural hybridization. DI/FCUL TR 05–8, Department of Informatics, University of Lisbon (2005) [20] Veríssimo, P., Casimiro, A.: The Timely Computing Base model and architecture. IEEE Transactions on Computers 51 (2002) 916–930 [21] Ben-Or, M.: Another advantage of free choice: Completely asynchronous agreement protocols. In: Proceedings of the 2nd ACM Symposium on Principles of Distributed Computing. (1983) 27–30 [22] Dwork, C., Lynch, N., Stockmeyer, L.: Consensus in the presence of partial synchrony. Journal of the ACM 35 (1988) 288–323 [23] Malkhi, D., Reiter, M.: Unreliable intrusion detection in distributed computations. In: Proceedings of the 10th Computer Security Foundations Workshop. (1997) 116–124 [24] Koziol, J., Litchfield, D., Aitel, D., Anley, C., Eren, S., Mehta, N., Hassell, R.: The Shellcoder’s Handbook. John Wiley & Sons (2004) [25] Hatch, B.: An overview of LIDS. Infocus (2001) http://www.securityfocus. com/infocus/1496. [26] Gasser, M.: Building a secure computer system. Van Nostrand Reinhold Co., New York, NY, USA (1988) [27] Schiper, A.: Early consensus in an asynchronous system with a weak failure detector. Distributed Computing 10 (1997) 149–157 [28] Chandra, T., Toueg, S.: Unreliable failure detectors for reliable distributed systems. Journal of the ACM 43 (1996) 225–267 [29] Menezes, A.J., Oorschot, P.C.V., Vanstone, S.A.: Handbook of Applied Cryptography. CRC Press (1997) [30] Viega, J., McGraw, G.: Building Secure Software. Addison Wesley (2002) [31] Neves, N.F., Correia, M., Veríssimo, P.: Wormhole-aware Byzantine protocols. In: 2nd Bertinoro Workshop on Future Directions in Distributed Computing: Survivability - Obstacles and Solutions. (2004) [32] Hickman, K.: The SSL protocol. Netscape Communications Corp. (1995) 19 [33] Bracha, G., Toueg, S.: Asynchronous consensus and broadcast protocols. Journal of the ACM 32 (1985) 824–840 [34] Malkhi, D., Reiter, M.: Secure and scalable replication in Phalanx. In: Proceedings of the 17th IEEE Symposium on Reliable Distributed Systems. (1998) [35] NIST: Announcement of weakness in the secure hash standard (1994) [36] Reiter, M.: Secure agreement protocols: Reliable and atomic group multicast in Rampart. In: Proceedings of the 2nd ACM Conference on Computer and Communications Security. (1994) 68–80 [37] Kihlstrom, K.P., Moser, L.E., Melliar-Smith, P.M.: The SecureRing group communication system. ACM Transactions on Information and System Security 4 (2001) 371–406 20