
Лига Сисадминов
Ответ на пост «Regex должен быть уничтожен»1
Если решили проверять email regexp'ом, то вот корректный вариант для реализации RFC822:
(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?: \r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:( ?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0 31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\ ](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+ (?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?: (?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n) ?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\ r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n) ?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t] )*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])* )(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*) *:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+ |\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r \n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?: \r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t ]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031 ]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\]( ?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(? :(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(? :\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(? :(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)? [ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]| \\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<> @,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|" (?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(? :[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[ \]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000- \031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|( ?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,; :\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([ ^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\" .\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\ ]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\ [\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\ r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\] |\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0 00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\ .|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@, ;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(? :[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])* (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[ ^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\] ]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*( ?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:( ?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[ \["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t ])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t ])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(? :\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+| \Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?: [^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\ ]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n) ?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[" ()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n) ?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<> @,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@, ;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)? (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?: \r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[ "()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t]) *))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]) +|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\ .(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:( ?:\r\n)?[ \t])*))*)?;\s*)
Ну ладно, чертов перл давно устарел, вот чуть попроще:
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
Ещё не передумали? Просто поверьте на наличие "собаки", и попробуйте туда отправить письмо. Если пользователь подтвердил регистрацию пройдя по ссылке из письма - всё хорошо. А Парсить email'ы откуда попало - это путь спамера. Они должны страдать.
365 дней спустя, или жизнь еще одного мониторинга
Помню в детстве, перед началом летних каникул, казалось, что лето никогда не кончится - 3 месяца где-то рядом с бесконечностью. А сейчас... Оказывается мы уже больше года разрабатываем RMON, первый коммит в Github был 15 марта 2024 года. Вжух и один год жизни пролетел. Ладно, хватит разговаривать на скуфском - это было маленькое вступление для подведения небольшого итога года работы. Вперед!
Terraform
Изначально мы его не планировали, но впереди была большая инсталляция и показалось, что настраивать кучу агентов руками и серверов, такое себе. Создавать проверки через Terraform оказалось очень удобно.
Одна проверка с нескольких агентов
Изначально мы планировали эту возможность, но реализовали, только, спустя полгода. У фичи достаточно сложная логика, по этому прокрастинировали, как можно дольше :). Получилось, вроде неплохо:
Переписали HTTP проверки на libcurl
Изначально использовали Python requests, так как было проще всего начать с нее, но мы сразу понимали, что requests не подходит из-за скорости работы и не возможности снимать HTTP метрики. В поисках решения нашли libcurl. Оказывается, curl - это не просто консольная утилита, с помощью, которой можно скачать файл и дернуть ifconfig.io, но и мощная библиотека для выполнения разных запросов. Кто ж знал.
С помощью Pycurl с libcurl достаточно легко и удобно работать из Python:
class CurlHttp:
def __init__(self, **kwargs) -> None:
...
def curl(self):
try:
buf = io.BytesIO() # We need to measure download time.
c = pycurl.Curl()
self.set_http_method(c)
self.set_curl_options(c, buf)
except pycurl.error as e:
raise Exception(f'Cannot set curl http_{self.check_id} {e.args[1]}')
try:
c.perform()
except pycurl.error as e:
self.reset_http_results(e.args[1])
except Exception as e:
self.reset_http_results(e)
return c, buf
def set_http_method(self, c):
http_methods = {
'get': c.HTTPGET,
'post': c.POST,
'put': c.PUT,
'head': c.NOBODY
}
custom_http_methods = {
'patch': "PATCH",
'delete': "DELETE",
'options': "OPTIONS"
}
if self.http_method in http_methods:
c.setopt(http_methods[self.http_method], 1)
else:
c.setopt(c.CUSTOMREQUEST, custom_http_methods[self.http_method])
def set_curl_options(self, c, buf):
c.setopt(c.URL, self.url)
c.setopt(c.DNS_CACHE_TIMEOUT, 0) # disable dns cache.
c.setopt(c.FORBID_REUSE, 1) # disable dns cache.
c.setopt(c.FRESH_CONNECT, 1) # disable dns cache.
c.setopt(c.HEADERFUNCTION, self.headers.write)
c.setopt(c.WRITEFUNCTION, buf.write)
c.setopt(c.TIMEOUT, self.timeout)
c.setopt(c.USERAGENT, 'RMON-bot')
# c.setopt(pycurl.VERBOSE, 1)
# c.setopt(pycurl.DEBUGFUNCTION, self.debug_curl)
...
if self.is_https == 'https':
c.setopt(c.OPT_CERTINFO, 1)
if self.ignore_ssl_error:
c.setopt(c.SSL_VERIFYPEER, 0)
c.setopt(c.SSL_VERIFYHOST, 0)
При переходе на libcurl удалось запустить несколько тысяч HTTP проверок на довольно слабенькой ВМ, вместо сотен на requests. Кстати, так же с помощью libcurl удалось реализовать SMTP проверки!
Больше параметров богу параметров!
Разве необходимо много параметров, чтобы проверить работает ли сайт? Как оказалось - да, надо много! Сейчас их много, что аж на экран не помещается (классная метрика, достаточности "что аж на экран не помещается", да?):
Но надо еще больше. Как минимум сейчас не хватает:
Важности алертов (warning, critical)
Инверсивная проверка
Возможность принимать несколько статус кодов ответа
Авторизация.
Нет предела совершенству и есть куда развиваться.
Что-то вроде итога
Это конечно же не все изменения что были проделаны, но лишь то что может быть интересно пользователям. Что еще хотелось бы отметить:
Добавление поддержки PostgreSQL
Возможность писать логи в JSON
Пуш метрик в VictoriaMetrics
Свои CSS стили для Status pages
Стабилизация проекта и более читаемый вывод ошибок
Переписали всю документацию на сайте
Кто захочет попробовать и потестить, не смотрите на прайс, просто напишите мне ;).
Ответ BiGGGGGX в «Что я узнал, работая системным администратором»7
Технический долг: То, что система работает "на соплях", не означает, что она не требует внимания. Системы, которые изначально настроены ненадежно, могут привести к большому количеству проблем в будущем, например, к сбоям, утечкам данных или ухудшению производительности. Рано или поздно эти проблемы проявятся.
Обновления и безопасность: Важно следить за обновлениями программного обеспечения и применять их в срок. Даже если система работает, это не значит, что уязвимости не могут быть использованы. Оставив систему "на костылях", вы рискуете не только потерей производительности, но и безопасностью.
Оптимизация и масштабирование: Со временем нагрузка на сервер может возрасти, и "костыльные" решения могут не выдержать этой нагрузки. Лучше заранее предугадать возможные проблемы и сделать систему более масштабируемой и устойчивой.
Прогнозируемость и документация: Когда используется временное или неидеальное решение, оно становится трудным для понимания и поддержки в будущем. Лучше сделать правильную настройку сразу, чем потом разбираться, почему система работает не так, как нужно.
Профилактика: Важно не только устранять проблемы, но и предотвращать их. Не стоит ждать, пока система начнет ломаться — лучше потратить время на улучшения, чтобы минимизировать риски.
В конечном счете, "не трогай, если работает" — это подход, который может сработать в краткосрочной перспективе, но в долгосрочной — он только накапливает проблемы. Системный администратор должен стремиться к улучшению и оптимизации системы, а не только к сохранению того, что работает.
Ответ xxVIRUSxxThe1 в «Что я узнал, работая системным администратором»7
То что я 150% даже не так...150 000% прохавал работая сисадмином так это то, что если что то работает, похрен как (костыль, сопли, жвачка) не трогай это! Пока работает не лезь туда!!
Столько раз я обжигался, когда думал блин...На какие это сопли сделано, сейчас я сделаю лучше.. И потом пару дней минимум возился с этим. Спустя пару лет золотое правило - работает не лезь!..
Ну из такого опыта, что мне запомнился. Обслуживали серверную (по ГПХ) то есть это не мои сервера ничего..Мы лишь переносили все подключения, переключили на новые розетки и патч панели, а я параллельно решил бонусом почистить сервер от пыли...И что потом произошло? Правильно сервер больше не поднимался нормально..Потом уже выяснилось, что там виртуализация была и надо было в определенном порядке запускать VM...Да и до этого сколько такого было, всего не припомнить. Кароче если что то работает нехуй туда лазить, пока оно не сломается.
Ответ на пост «Что я узнал, работая системным администратором»7
Ремонтировал магазины как айти, кассы, сервера, сканера, и компы ну там все такое в общем, собственна, в каких бы я не был сетевых магазинах, а я не одну тысячу их объездил разные, пятаки, переки, Дикси, магнит, мираторг, Ашан, глобус, и так далее, и не поверите, начиная от педали под кассой которая толкает ленту, а такие еще остались, до расшитых патч панелей и серверов, ни где, ни когда не видел изоленту. Мем про изоленту особенно с пингвинчиком, меня всегда самого радовал, и я его поддерживал, но ни где в моей работе не было изоленты, я один рулончик возил года 4, и использовал только в машине и то своей же... Везде стяжки, хомуты, кому как комфортнее и привычнее, а что бы не лопались ну не надо дешевить и держать их в холоде, и тогда все будет тип топ. Я бы за столько лет так заебался бы изоленту мотать, шо пиздец, да и по стандартам планово профилактических работ и при пуско наладочных работах, изоленту использовать запрещено, только хомуты. Прикиньте в кабель канале на высоте 4-5 метров, скручивать изолентой охапку проводов витой пары? Даже две штуки, молчу уже про кабелей 10+ когда касается камер видео наблюдения, так что хомуты наше все. Реально тупо удобнее.





