Prefácio
Estamos testando alguns IPS baseados em host. Neste caso de teste, nosso aplicativo está escutando no loopback e o aplicativo está recebendo tráfego em texto não criptografado. Estamos usando nginx ou haproxy para finalizar o TLS na interface pública. Nosso IDP estará monitorando o loopback para que ele possa ver o tráfego não criptografado.
Nosso PDI estava vendo datas incorretas / incorretas, então começamos a investigar mais profundamente.
[Update 2] Como @kasperd mencionou, o tcpdump está recebendo os timestamps do sistema operacional.
Dito isto, este bug está realmente desarmando o IDP além do tcpdump. Ele vê a conexão_estabelecida, mas não conseguiu ver uma sessão http válida, pois a sincronização não é válida.
Um bug foi arquivado em redhat.com e centos.org.
Observação
O primeiro syn-ack no loopback sempre tem uma data próxima ao início do epoch, ou dentro de 2 anos dele no VM. Isso varia muito de dezembro de 1970 para fevereiro de 1973 nos servidores VM e Xreon. O NTP está correto em todos os nossos servidores VMs e bare-metal, com menos de 50ms de desvio.
Isso só acontece no loopback. Nós nunca vemos isso em bond0 nos servidores ou eth0 em VMs.
Servidores de teste e laptops
SO: CentOS 7
Plataformas:
Servidores Dell 20 Core Xeon (sistema operacional host bare metal)
Servidores HP 20 Core Xeon (sistema operacional hospedeiro bare-metal)
VirtualBox no MacOS
Hyper-V no Windows 10 Enterprise no Lenovo P50 com 6 núcleos virtuais.
Um roteador baseado no Celeron 4 Core de 1,6 GHz (não pode ser reproduzido no Celeron)
Etapas para reproduzir
Em cada plataforma, iniciamos um ouvinte da Web na porta 80 no loopback.
./simple_python 127.0.0.1 &
O código acima é aqui
Em seguida, iniciamos o tcpdump
tcpdump -p -NNnn -XXxx -tttt -vv -s0 -c2 -i lo &
Então, nos curvamos para localhost
curl -s -o /dev/null http://127.0.0.1/
Saída
2018-04-10 21:05:30.087769 IP (tos 0x0, ttl 127, id 49233, offset 0, flags [DF], proto TCP (6), length 60)
127.0.0.1.25134 > 127.0.0.1.80: Flags [S], cksum 0xfe30 (incorrect -> 0xce27), seq 4053136920, win 65495, options [mss 65495,sackOK,TS val 22951497 ecr 0,nop,wscale 13], length 0
0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E.
0x0010: 003c c051 4000 7f06 3d68 7f00 0001 7f00 .<.Q@...=h......
0x0020: 0001 622e 0050 f195 f618 0000 0000 a002 ..b..P..........
0x0030: ffd7 fe30 0000 0204 ffd7 0402 080a 015e ...0...........^
0x0040: 3649 0000 0000 0103 030d 6I........
1973-02-14 22:12:10.785902 IP (tos 0x0, ttl 127, id 0, offset 0, flags [DF], proto TCP (6), length 60)
127.0.0.1.80 > 127.0.0.1.25134: Flags [S.], cksum 0xfe30 (incorrect -> 0x2f28), seq 3928063281, ack 4053136921, win 65483, options [mss 65495,sackOK,TS val 22951497 ecr 22951497,nop,wscale 13], length 0
0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E.
0x0010: 003c 0000 4000 7f06 fdb9 7f00 0001 7f00 .<..@...........
0x0020: 0001 0050 622e ea21 7d31 f195 f619 a012 ...Pb..!}1......
0x0030: ffcb fe30 0000 0204 ffd7 0402 080a 015e ...0...........^
0x0040: 3649 015e 3649 0103 030d 6I.^6I....
Em todos os casos, o syn-ack é sempre uma data entre 1970 e 1973 nas VMs e no futuro nos Xeons.
- Eu posso reproduzir esse 100% do tempo em cada uma das plataformas, com exceção do Celeron. Nós não usamos Celerons no data center. Eu estava apenas tentando encontrar algo não afetado.
O que mais eu tentei fazer isso ir embora?
- Eu tentei fixar aplicativos em um núcleo usando
taskset
.
- Tentei definir variáveis diferentes que afetam a libc, como TZ, LANG, LC_ALL, etc ...
- Eu tentei desabilitar todos os recursos de descarregamento da interface, apesar de ser um loopback e eles não devem realmente fazer nada.
- Eu tentei algumas configurações de sysctl diferentes.
- Eu tentei usar diferentes snaplen no tcpdump. (Eu estou ciente de algumas questões históricas em torno da snaplength)
- verifiquei que o relógio do hardware está correto.
O que eu não tentei
- Eu não tentei configurar o fluxo de recebimento, já que não faríamos isso em nossos datacenters sem uma boa razão.
- Provavelmente existe uma infinidade de outras coisas que eu poderia tentar, mas isso realmente parece um bug de algum tipo de condição libc / buffer / race.
Alguma idéia sobre onde no código Linux isso pode estar ocorrendo? Eu estou hesitante em cavar na glibc como eu não sou um desenvolvedor C.
[Update] Aparece @jackthecoiner encontrado onde outra pessoa está tendo esse problema também e ainda não recebeu nenhum feedback sobre o site da Redhat.