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 encerrar o TLS na interface pública. Nosso IDP estará monitorando o loopback para que possa ver o tráfego não criptografado.
Nosso IDP estava vendo datas malformadas/incorretas, então começamos a cavar mais fundo.
[Atualização 2] Como o @kasperd mencionou, o tcpdump está obtendo os carimbos de data e hora do sistema operacional. Dito isso, acontece que esse bug está realmente atrapalhando o IDP, além do tcpdump. Ele vê o connection_established, mas não conseguiu ver uma sessão http válida, pois o syn-ack não é válido.
Um bug foi registrado em redhat.com e centos.org.
Observação
O primeiro syn-ack no loopback sempre tem uma data próxima ao início da época, ou dentro de 2 anos em VMs. Isso varia muito de dezembro de 1970 a fevereiro de 1973 em VMs e no futuro em servidores bare metal Xeon. O NTP está correto em todas as nossas VMs e servidores bare metal, com menos de 50ms de desvio.
Isso só acontece no loopback. Nunca vemos isso no bond0 nos servidores ou eth0 nas VMs.
Servidores de teste e laptops
SO: CentOS 7
Plataformas:
Servidores Dell 20 Core Xeon (sistema operacional de host bare metal)
Servidores HP 20 Core Xeon (sistema operacional de host bare metal)
VirtualBox no MacOS
Hyper-V no Windows 10 Enterprise no Lenovo P50 com 6 núcleos virtuais.
Um roteador baseado em Celeron 4 Core 1,6 GHz (não pode reproduzir no Celeron)
Passos para reproduzir
Em cada plataforma, iniciamos um web listener na porta 80 no loopback.
./simple_python 127.0.0.1 &
O código acima está aqui
Então iniciamos o tcpdump
tcpdump -p -NNnn -XXxx -tttt -vv -s0 -c2 -i lo &
Então nós enrolamos para localhost
curl -s -o /dev/null http://127.0.0.1/
Resultado
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 alguma data entre 1970 e 1973 nas VMs e no futuro nos Xeons.
- Consigo reproduzir isso 100% do tempo em cada uma das plataformas, exceto no Celeron. 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 configurar diferentes variáveis 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 deveriam fazer nada.
- Eu tentei algumas configurações diferentes de sysctl.
- Eu tentei usar snaplen diferente no tcpdump. (Estou ciente de alguns problemas históricos em torno do snaplength)
- Verifiquei que o relógio do hardware está correto.
O que eu não tentei
- Não tentei configurar o direcionamento do fluxo de recebimento, pois não faríamos isso em nossos data centers sem uma boa razão.
- Provavelmente há uma infinidade de outras coisas que eu poderia tentar, mas isso realmente parece um bug de condição de libc / buffer / race de algum tipo.
Algum pensamento sobre onde no código do Linux isso pode estar ocorrendo? Estou hesitante em mergulhar na glibc, pois não sou um desenvolvedor C.
[Atualização] Parece que @jackthecoiner encontrou onde outra pessoa está tendo esse problema e ainda não recebeu nenhum feedback no site da Redhat.