Estou procurando criar uma solução de rede escalonável e de alta disponibilidade usando um sistema distribuído de dados. Um nó aqui descreve uma rede que possui controle sobre uma cópia dos dados. Esses nós podem conter mais de uma máquina, mas possuem uma cópia dos dados.
Os nós conterão registros de dados que podem estar em estado gasto ou não gasto. Um cliente pode solicitar uma transição para que um registro passe de um estado não gasto para um estado gasto (uma solicitação para gastar). Existe um risco de segurança se eles conseguirem fazer isso mais de uma vez.
Um único nó, se tiver uma conexão com todos os outros nós, pode informar aos nós que um gasto foi solicitado e pode garantir que nenhum outro nó deseje acessar os dados e que o gasto ainda não tenha ocorrido. O nó pode alterar o estado dos dados para gasto e outros nós não farão isso, pois sabem que um dos nós está atualizando-o e processando o gasto. Todos os nós alterarão os dados, portanto, o registro estará no estado gasto.
Se um nó não puder alcançar outro nó, ele poderá assumir que o outro nó está inativo e continuará operando com os outros nós até que o outro nó seja ativado novamente. Nesse caso, o nó enviará todas as atualizações para o nó que retornou. Se esse nó com falha estivesse no meio de uma operação de gasto incompleta no momento, ele poderá ser concluído. Isso causaria menor tempo de inatividade para algumas operações. Isso seria no caso em que um nó informa aos outros nós que serão gastos e, em seguida, falha antes de concluir o processo de gasto. Nesse caso, os outros nós são impedidos de atualizá-lo, portanto, o nó com falha precisa ficar on-line antes de poder ser concluído.
O problema é que o processamento para o gasto só pode acontecer uma vez. Se a rede foi particionada, um invasor sabendo disso pode solicitar o gasto em uma partição e também no outro. Cada partição da rede assumiria que a outra estava inativa e, portanto, operaria de forma independente. Isso pode fazer com que os gastos sejam processados mais de uma vez.
Isso não seria um problema se a solicitação para os dois lados da rede não estivesse sendo feita durante o tempo em que eles foram particionados. A rede se tornaria eventualmente consistente quando as conexões fossem restabelecidas. Se um ataque tiver êxito, os nós aprenderão sobre o ataque quando restabelecerem conexões, porque os dois lados da rede anunciariam a mesma alteração.
Portanto, é um ataque detectável, mas é praticamente possível?
Um invasor precisa deliberadamente tentar fazer isso. O software não foi projetado para fazer várias solicitações de gastos de uma só vez. Há um custo de tempo para o ataque. Se o invasor falhar, levará algum tempo até que ele possa recriar um registro não gasto. Criar registros não gastos requer dinheiro. E mais dinheiro precisará ser usado em um único ataque para obter um benefício maior. A razão pela qual há um custo de tempo, é que levaria tempo para receber o dinheiro de volta para tentar novamente. Eles poderiam pagar muitos ataques menores e, em seguida, o benefício para eles seria menor e os danos causados, menos também.
Certamente partições são tão raras naturalmente, que um atacante teria que ser ridiculamente sortudo de ganhar, se tentasse atacar a qualquer momento?
Se uma conexão é naturalmente perdida, um nó pode parar todas as operações e tentar uma reconexão. Usar um tempo limite baixo para a conexão com o nó significa que ele não precisa causar nenhum tempo de inatividade (talvez apenas uma latência maior rara). Se a reconexão falhar, ela continuará tentando, mas, em seguida, reiniciará as operações (supondo que o nó esteja inativo). Alguma coisa desse tipo protegeria contra erros ocasionais de conexão?
Então um atacante seria capaz de detectar / causar uma partição na rede? Qual a probabilidade de ocorrerem partições e por quanto tempo? De que maneiras as questões podem ser resolvidas, se possível?
Obrigado.