Перейти к основному содержимому

Злополучный перенос строки

·240 слов·2 минут
Оригинал опубликован в Telegram

Яндекс — это живой организм: появляются новые сервисы, закрываются старые, переписываются имеющиеся.

Инфраструктура — не исключение, и практически каждый год мы куда-то переезжаем ради светлого будущего.

Один раз я стал источником такого переезда для многих команд в Яндексе. Мне необходимо было закопать ряд старых API и перевести всех клиентов на новые версии.

Масштаб был следующий:

  • 7 HTTP API
  • 15к rps входящего трафика
  • 150+ задач в трекере
  • 1 год работы

Тогда я познакомился, наверное, с половиной Яндекса :)

В результате кропотливой работы у одного из API осталось всего два клиента. Клиенты передавали специальный параметр key для своей идентификации.

Я решил явно ограничить доступ на уровне nginx, чтобы случайно не появился третий клиент:

if ($args !~ "key=(AF7SR0kBOFwIA6...rgAYKvhTSvW6lg==|AAhenE0BAAAA...BoBzqNuwHcQ==)(&|$)") {
...
}

Проверил на сервере. Работает. Прошел кодревью. Со спокойной совестью начал раскатывать в продакшен.

Через несколько минут приходит wwax@ и вежливо спрашивает:

Привет) Вы уже ручку закапываете? У нас очень плавно перестает отвечать ваш сервис.

Клиент стал получать примерно 1.3к rps ошибок со статусом 403. В спешке откатили. Начали разбираться.

Оказалось, когда я копировал код с сервера, то случайно скопировал перенос строки.

Клиент отсылал нормальный ключ: AAhenE0BAAAA…BoBzqNuwHcQ==

Мы ожидали на выход ключ с переносом строки: AAhenE0BAAAA…\nBzqNuwHcQ==.

Даже на ревью две пары глаз не заметили лишнего переноса строки. Один лишний символ = инцидент. Такая вот факапочная арифметика.

Мораль: никогда не доверяйте себе на 100% и лучше лишний раз перестрахуйтесь при выкладке. Самоуверенность в любой момент может привести к печальным последствиям.