mindsellers


Channel's geo and language: not specified, not specified
Category: not specified


Практики из жизни Linux-админа. Asterisk, Bash, Python и черная магия.
Сайт http://mindsellers.ru
Группа VK https://vk.com/mindsellers
ТыТруба https://www.youtube.com/channel/UC7LUJgzIUL4VGiOWctoa0fw
По всяким вопросам обращаться @alex_dmit

Related channels

Channel's geo and language
not specified, not specified
Category
not specified
Statistics
Posts filter


Разбор письма на Python pop3

Столкнулся с вполне каноничной задачей - получить и проанализировать тело письма через протокол POP3. К сожалению, нормального примера не нашел, так что пришлось разобраться самому. В первую очередь, советую использовать для разбора письма не стандартную либу email, а mail-parser:

pip install mail-parser

Сам по себе дальнейший код, думаю, особых комментариев не требует.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import poplib, mailparser

server = "mx.domain.ru"
port = "110"
login = "bot"
password = "passworf"
result=''
box = poplib.POP3(server, port)
box.user(login)
box.pass_(password)
response, lst, octets = box.list()
for msgnum, msgsize in [i.split() for i in lst]:
(resp, lines, octets) = box.retr(msgnum)
msgtext = "\n".join(lines) + "\n"
#В msgtext будет письмо в "сыром" виде, со всеми хедерами и прочей ерундой.
mail = mailparser.parse_from_string(msgtext)
print mail.subject
print mail.body
result=mail.subject+'\n'+mail.body
#А тут мы получим тему и тело сообщения
box.dele(msgnum) # если надо - удаляем с сервера письмо
box.quit()

Прелесть использования указанной библиотеки в том, что она сама разберется не только с заголовками, но и с кодировками. Подробное описание всех возможностей дешифровки смотрите на сайте проекта https://pypi.org/project/mail-parser/3.3.1/

#python


Отправка сообщения из Python в комнату в Jabber

В связи с тотальной блокировкой телеграма, возникло желание всей корпоративной группой перейти на использование своего кошерного Jabber-сервера, тем более что он уже есть. Быстренько разобрались с настройкой комнаты, но возник вопрос: как всех массово уведомлять о каком-либо проишествии. Конечно, можно просто отправить сообщение по списку пользователей, но мне показалось удобнее слать сообщение один раз - в приватную комнату. Из этой задачи и родился следующий скрипт:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import xmpp,sys

xmpp_jid = 'bot@domain.ru'
xmpp_pwd = 'password'
room = 'it@conference.domain.ru'
msg = sys.argv[1]

#Получаем в качестве аргумента сообщение

jid = xmpp.protocol.JID(xmpp_jid)
client = xmpp.Client(jid.getDomain(),debug=[])
client.connect()
client.auth(jid.getNode(),str(xmpp_pwd),resource='xmpppy')
#Авторизуемся
client.sendInitPresence(requestRoster=0)
client.send(xmpp.Presence(to='{0}/{1}'.format(room, jid)))
#Заходим в комнату
message=xmpp.Message(room, '\n'+msg)
#Формируем сообщение
message.setAttr('type', 'groupchat')
#Устанавливаем тип сообщения - групповой чат
client.send(message)
#Отправляем сообщение и отключаемся
client.disconnect()

Вот, собственно, и все. Теперь можно скормить этот скрипт любой системе мониторинга или использовать в иных целях.

#python #jabber #telegram #дуроввернистену


В связи с тотальной блокировкой телеги в этой стране, все новости канала читаем vk.com/mindsellers и на mindsellers.ru


Забавный баг Asterisk&chan_sip

Перенес я тут систему с астером с тестовой машины на боевую. Сменил Hostname, сменил IP, и стал замечать, что даже внутренний звонок выполняется с задержкой до 15 секунд! Расследование, а именно sip set debug on, показало, что астер принимает инвайт от клиента, а потом просто ничего не отвечает некоторое время. Помятуя о некой взаимосвязи корректности работы DNS-серверов и Asterisk, я просто запустил tcpdump -i eth1 -nn port 53 и с удивлением для себя обнаружил, что мой сервер пытается у гугла уточнить свой же айпишник!!!
15:08:34.016892 IP 10.100.1.1.41021 > 8.8.8.8.53: 7753+ A? asterisk. (26)
Вопрос моментально решился добавлением записи в /etc/hosts вида
10.100.1.1 asterisk

Отсюда вывод: не забывайте про /etc/hosts, даже если вам кажется, что все прекрасно работает без его изменения!
#asterisk #fuckup


Пространные измышления о подходах


На заре моей карьеры не существовало никаких админов, девопсов, DBA, тимлидов, сетевиков, фронт-энд разработчиков и прочих умных слов. Но уже тогда(лет 15 назад) были пограмисты и системотехники. А ещё раньше были просто инженеры ЭВМ.
Ясное дело - чем дальше в лес, тем толще партизаны, но в случае с ИТ 'партизаны' только худеют.
И фронт не знает, что делает бэк. И 'инженер' не умеет пользоваться мультиметром. Да что там говорить, лично знаю админов, которые не умеют обжать коннектор. Зато докер. Зато ансибл.
С другой стороны, 'важные сеньор-админы' не хотят использовать тот же docker. А 'важные разрабы' - поднимать свою жопу с delphi.
Вот захотел я в python - и полез. И форумы есть, и чаты.
Senior Python developer я не стану, факт. И если буду жать rj45 за 10 секунд - не стану проектировщиком ЛВС.
Но если я перестану стремиться, перестану горизонтально прогрессировать, банально читать хабру - быть мне говном.
Что ни делай, но если ты не учишься каждый день - увы тебе.


Offtop
Они еще и шутить умеют....




А вы меня вообще читаете?

Читаю – 9
👍👍👍👍👍👍👍 60%

Просматриваю по диагонали – 4
👍👍👍 27%

Не отписываюсь из вежливости – 2
👍👍 13%

👥 15 people voted so far.


Telegram-бот "Попингуй"

У многих админов, в том числе и у нас, используется система мониторинга Zabbix с прикрученным к ней телеграм-ботом, который всякие ворнинги постоянно кидает в группу. Но бывает так, что падает агент заббикса, или происходит ложное срабатывание, ну и так далее. В итоге приходится ночью вскакивать с кровати, бежать к компу, ломиться на рабочий комп по удаленке - и все это ради того, чтобы просто пропинговать ресурс и убедиться в том, что он жив. Вот и решил я написать свой бот на Python, который будет болтаться на сервере в локальной сети и по заявкам пользователей пинговать что надо.
Сначала добавляем себе супер-бота @BotFather, создаем через него своего бота и получаем токен, который надо будет указать в скрипте, затем переходим к разработке.

Сам скрипт выкладывать в канал смысла не вижу, его можно посмотреть по ссылкам ниже. Кроме стандартной работы с библиотекой telebot, интерес в скрипте представляет механизм авторизации. Используя библиотеку shelve, мы будем хранить в файле эдакую базу данных "ключ: значение". В качестве ключа у нас будет слово users, а в качестве значения - множество ID наших клиентов. При запуске скрипта мы читаем из базы идентификаторы в множество(если, конечно, там уже есть нужный ключ. Если его нет, то множество останется пустым):
db=shelve.open('/admin/teleusers.db')
allowed=set()
try:
allowed=db["users"]
except:
pass
Если пользователь отправит нам пароль, то мы внесем его в множество allowed и положим обновленное множество в базу:
if message.text == password:
print message.from_user.id
allowed.add(message.from_user.id)
db["users"]=allowed
bot.send_message(message.chat.id, 'Вы добавлены в список пользователей бота. Теперь можете писать адрес, который надо пропинговать')
При каждом запросе проверяем, "наш человек или посторонний". Если наш, то запускаем пинг и возвращаем результат. Если пинг завершится неуспешно, то выводим сообщение о недоступности ресурса.
if user in allowed:
bot.send_message(message.chat.id, 'Пингую, подождите')
else:
bot.send_message(message.chat.id, 'Пока не скажешь пароль, ничего не получишь!')

Для того, чтобы не заморачиваться с демонизацией скрипта, но при этом быть уверенным в его работе, воспользуемся systemctl - создадим файл сервиса /etc/systemd/system/telegrambot.service
[Unit]
Description=MyTelegramBot
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python /admin/telegrambot.py
Restart=always

[Install]
WantedBy=multi-user.target

Перечитаем список демонов и запустим нашего

sudo systemctl daemon-reload
sudo systemctl enable telegrambot.service
sudo systemctl start telegrambot.service

Все, можно пробовать подключаться.
Код можно посмотреть в wiki и в vk

http://pubwiki.mindsellers.ru/index.php/Telegram-%D0%91%D0%BE%D1%82_%22%D0%BF%D0%BE%D0%BF%D0%B8%D0%BD%D0%B3%D1%83%D0%B9%22

https://vk.com/@mindsellers-telegram-bot-popingui

#python #linux #bash #telegram


Мультипоточный сокет-сервер на Python

Всем наверняка известно, что в Python есть модуль socket, который реализует, собственно, сокеты и двусторонний обмен данными. Но вот незадача: при классическом использовании, как в официальном примере
# Echo server program
import socket

HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(data)

сервер обслуживает только одно подключение в единицу времени! Пока не свершится подключение conn, addr = s.accept(), не начнется чтение. Пока не будут прочитаны данные data = conn.recv(1024), сервер не будет ждать новых подключений, даже если задать s.listen(10000).

Получается, для того, чтобы иметь, скажем так, ожидаемый функционал сокет-сервера нужно постоянно слушать подключения - метод accept, а для каждого нового подключения формировать отдельный поток, в котором будет производиться общение непосредственно с ним. И уже в потоках нужно работать с каждым клиентом по отдельности.

Поискав готовое решение, я наткнулся на фреймворк SocketServer, но и от него ожидаемого поведения в одну строку получить не удалось, а также на библиотеку Twisted, но она довольно обширна и сложна для понимания. Но, как говорится, не нравится готовое - пиши свое. Результатом трехдневных поисков и страданий стал класс, который обеспечивает прием сообщений от каждого из клиентов и рассылку оного всем остальным.

Исходник доступен на гитхабе, комментарии по коду - в wiki
http://pubwiki.mindsellers.ru/index.php/%D0%9C%D1%83%D0%BB%D1%8C%D1%82%D0%B8%D0%BF%D0%BE%D1%82%D0%BE%D1%87%D0%BD%D1%8B%D0%B9_%D1%81%D0%BE%D0%BA%D0%B5%D1%82-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80

https://github.com/mindsellers/SockServer-py

#python #linux


Получение уникальных строк на Bash

Еще одна простая строка, которая может помочь в разных ситуациях. Допустим, у нас есть почтовик, и тут мы замечаем, что в очереди postqueue -p довольно много писем со статусом Over quota, что говорит нам о переполнении ящиков. Надо бы предупредить пользователей, почистить ящики и так далее. Естественно, мы легко выделим список всех переполненных ящиков примерно так:
postqueue -p | grep 'Over quota' -A1 | grep '@'
Но на выходе мы получим кучу дублированных строк, так как на переполенный ящик в списке на доставку может стоять далеко не одно сообщение. На помощь нам придут две команды - sort, которая по умолчанию отсортирует строки по алфавиту, и uniq, которая удалит из выдачи повторы. Итого, получим
postqueue -p | grep 'Over quota' -A1 | grep '@' |sort | uniq
что на выходе даст нам несколько строк с переполненными ящиками.

#onestringscript #linux #bash


Forward from: Сюда иди!




Video is unavailable for watching
Show in Telegram


Как спасти сервер от коллеги и про тайну личной переписки

За долгие годы админства я уже разучился удивляться тому, что иногда выясняешь, что не знаешь базовых, примитивных вещей. Сегодня, на одиннадцатом году работы с Linux, я с удивлением для себя узнал о крайне полезной, как минимум в двух ситуациях, команде.

Представьте: ваш коллега потопал ножками в серверную, чтобы внести некие изменения на Linux-сервере с консоли. Ну допустим, айпишник сменить, чтобы в случае падения быстренько все на месте исправить. Или ядро обновить. Или просто он не доверяет ssh. Телефон этот раздолбай, как обычно, оставил в кабинете. И тут до вас внезапно доходит осознание того, что если он осуществит задуманное, сервер ляжет и не встанет. Как его остановить? Бежать за ним уже поздно, кричать бесполезно...

Или вот другая ситуация: вы, используя команду who видите, что на сервере есть подключенные по ssh клиенты, а сервер надобно перезагрузить. Как узнать - реально ли кто-то там что-то там делает, или просто забыл закрыть консольку? Как предупредить всех о своем намерении перезагрузить сервер?

Оказывается, в любом современном дистрибутиве есть волшебная команда wall, которая будучи вызванной с некой строкой в качестве аргумента принудительно выплюнет оную во все активные терминалы!!!

wall Hello World!

На всех консолях, даже если там что-то запущено, появится что-то вроде

Broadcast message from root@mindserllers (pts/2) (Fri Mar 23 15:28:21 2018):

Hello World!

Вот такая полезная софтина, на которую я почему-то никогда не натыкался.

Но тут я вспомнил еще об одной давней мечте - иметь возможность обмена информацией по максимально защищенному каналу, но с людьми, для которых настройка VPN - уже целое дело. Догадываетесь, да? Просто ставим putty, даем друзьям дико кастрированный shell до какой-нибудь своей виртуалки в Цюрихе(ну, у всех ж есть виртуалка в Цюрихе, да?), - и готово, переписочка внутри ssh и не надо ничего писать самому. Да, пусть не самая удобная, но зато мы ТОЧНО знаем, что никакой Паша Дуров никакую нашу переписку никуда не сливает.

Но давайте пофантазируем дальше и решим, как все-таки кастрировать shell тем друзьям, которым удастся "продать" нашу безопасность. Да все просто: мы напишем свой shell!

Создадим файл /usr/bin/chat_shell.py с правами 755 и запишем в него

#!/usr/bin/python

import os
from getpass import getuser
user=getuser()
print 'Hello, '+user +'\n'
print 'To quit type "/exit"' + '\n\n'
try:
while True:
string=raw_input(user+'>')
if string == '/exit':
exit()
elif string == '':
pass
else:
os.system('wall'+' ' +string)
except:
pass
Это и будет наш шелл. Теперь добавим его в список командных оболочек:

echo '/usr/bin/chat_shell.py' >> /etc/shells

и еще добавим возможность вызывать его от "нормального" пользователя попроще:

echo alias chat='/usr/bin/chat_shell.py' >> /etc/bash.bashrc

Ну и создаем ограниченного юзера:

adduser username --shell /usr/bin/chat_shell.py

Вот, собственно, и все на сегодня.

P.S. Как вы понимаете, аналогичным образом можно написать свой "ограниченный" shell практически под любые задачи.

Всем хороших выходных!

#onestringscript #python #linux


Про китайские стандарты

Купил я некоторое время назад себе китайскую поделку OrangePi Win Plus, одноплатный комп такой, вроде Raspberry, но мощнее. Потом оказалось, что мощь железа слихвой компенсируется отсутствием софта и дров, но не об этом речь. В целях донастройки линуха на ней, притащил я апельсинку на работу, врубил в лежавший на столе свитч и начал священнодействовать.
Прервал меня минут через 10 резкий запах горящего пластика и характерный белый дымок, исходивший от ethernet-порта платы. БП из розетки - продолжает дымить!
Все порты освободил от кабелей и приступил к вдумчивому органолептическому анализу: пощупал и понюхал. Запах и эпицентр нагрева точно прям в сетевом порту. Рядом вообще никаких микрух! Запускаю заново - все работает! Только ethernet греется... И тут до меня, не без помощи многоопытного коллеги, доходит, что сучий китайский свитч решил накормить мою игрушку PoE! Протокол, согласование - не, не слышали. Даёшь 24 вольта во все порты!
При внимательном осмотре был обнаружен истиный источник дыма - оплавлялся коннектор!!!
Что любопытно, никто из двух китайцев не пострадал! А патч-корд - да хрен с ним.

А теперь самое интересное: что ж это за волшебный свитч-пироман. https://www.gowifi.co.nz/switches/es-8-150w.html Вот эта уеба собственной персоной.

Мораль: не все то нормальное PoE, на чем написано PoE; китайцы таки умеют делать надёжные одноплатники; не надо совать свой конец куда попало.

#fuckup


Про продуманный монтаж и советских инженеров
Есть у нас 2 помещения на одном этаже: условно-серверная и условно-кроссировочная. В первой стойки с серверами, хранилки и прочее, во второй - access-свитчи и патч-панели. Соединить их можно только под Армстронгом, где сейчас валяется n-дцать наших витух 'магистральных', всякие витухи до пользовательских ПК, пары безопасников, пожарников, силовые жгуты... В общем, кто видел подпотолочное пространство в офисном здании - поймет. Лотки есть, но все как бы общие и забитые, новые некуда вешать (да, там ещё и вент.короба). А соединить помещения, естественно, надо оптикой. Класть и варить бронированную или хоть бы просто внешнюю - долго и дорого, а патч-кордовую надо как-то защитить...
Решение, предложенное мной: затянуть в пвх-трубы для внутристенной электрики. Мне указали на невозможность при надобности добавить туда ещё десяток-другой волокон, и наш специалист по организации ЦОД(правда хороший специалист) сработал в лучших традициях советской инженерной школы: 3 дня он обмерял и размечал трассу, был задумчив и благостен. А вчера приволок 20 метров 50мм канализационных труб, стыки, повороты и разветвители для них, охапку наклеек в стиле 'не тронь - убьет администрация', и уже сегодня мы получили отличный канал для проброса целого пучка чего хочешь от А до Б с заложенной в них витухой в качестве протяжки! Трубы надёжно закреплены к капитальным конструкциям, сегменты легко разделяются при необходимости...
В общем, пользуйтесь!
#lifehack #монтаж


Про непродуманный монтаж и управляемые свитчи

Так исторически сложилось, что ЛВС в организации, где я сейчас работаю, развивалась довольно стихийно от пары десятков до пары тысяч "хвостов" в одном большом помещении. Со временем, парк активного оборудования был более-менее приведен в божеский вид, а именно были закуплены, установлены и настроены нормальные управляемые свитчи HP. К сожалению, до "причесывания" кабельной инфраструктуры руки так и не дошли. В итоге имеем over 1000 ПК, кучу всяких сетевых камер, IP-телефонов и иже с ними, подключенные, откровенно говоря, неизвестно куда. Как результат, банальное "сетевой кабель не подключен" приводит в уныние не только пользователей, но и дежурных системотехников. Полагаясь только на обрывочные воспоминания старожилов отдела, осуществляется поиск поврежденной трассы(заржавевшей розетки, вывалившегося из патч-панели проводка), а если действия не увенчаются успехом - прокладка нового кабеля. Опять-таки, без маркировки.

Естественно, такое положение вещей не устраивает всех, но вызванивать пару тысяч хвостов, поключенных в десятки свитчей, расположенные в различных шкафах и стойках - то еще удовольствие. Ну и в рамках освоения Python я написал скрипт. На входе он получает список всех свитчей(благо, их айпишники известны), а также список подсетей, которые используются в организации. Проверяет, используя SNMP, какие маки "светятся" за портами свитчей, а потом nmap-ом сканирует все подсетки уже по ip, выявляя соответствие между портом, айпишником и маком. Результаты помещаются в 2 MySQL таблицы и потом выдаются оттуда с использованием тупой web-формы и cgi-скрипта на том же python.

Размещать листинг скриптов тут не имеет смысла, так что если кому интересно, или реально нужен этот скрипт - милости прошу в wiki - http://pubwiki.mindsellers.ru/index.php/%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D0%BE%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D1%81%D1%82%D0%B2%D0%B8%D1%8F_%D0%B8%D0%BC%D0%B5%D0%BD%D0%B8_%D0%9F%D0%9A_%D0%B8_%D0%BF%D0%BE%D1%80%D1%82%D0%BE%D0%B2_%D1%81%D0%B2%D0%B8%D1%82%D1%87%D0%B5%D0%B9 или VK - https://vk.com/wall-163141805_14

#python #ЛВС #nmap


Создание случайной текстовой строки на Python

Вполне типовая задача, которую часто приходится решать админу, который хоть как-то автоматизирует свою работу. На питоне реализация очень элегантная, а учитывая что в любой современный Linux-based дистрибутив Python включен, а часто еще и в двух версиях..... В общем, ловите

pwd = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(length)])

Итак, что значит сия волшебная строка.... Переменной мы присваиваем странное значение. На самом деле, все довольно просто: конструкция
somevar=[some_operand for n in someradge]
присвоит переменной результат выполнения some_operand по количеству проходов цикла.
В нашей волшебной строке мы присваиваем pwd нечто странное: ''.join(something)
Что это такое? - да все просто: у разных переменных(которые на самом деле объекты, но это не слишком важно), в том числе у строк, есть метод join, который просто дописывает нечто к значению переменной. Cоответственно, мы получаем некую строку сформированную в результате length случайных выборок из символов латинского алфавита и цифр. Но нам требуются два модуля, которые мы использовали:
random
string

Давайте посмотрим на пример программы:
def randpass(length=32):
import random, string
pwd = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(length)])
return pwd
print randpass(16)

Мы объявили функцию и приняли параметр length. Если параметр не задан, используем значение 32.
Далее, мы подгрузили 2 необходимых модуля, присвоили значение переменной pwd и вернули ее с помощью return. Никто не обязывает нас использовать переменную(ну, то есть объект) pwd - можно было запихнуть нашу волшебную строку в return, но читаемость предлагаемого варианта, согласитесь, выше))

Ну а дальше мы просто "дергаем" функцию с параметром 16 и получаем на stdout пароль нужной длины

#onestringscript #python #mindsellers


Hello, World
Ну-с, приступим к наполению канала...
Попросили тут меня слить с одного компьютера все, что можно считать рабочими документами: ворды там всякие, эксели, да еще и сохранить структуру каталогов. Сказано-сделано: монтируем диск и используем черную магию find с регуляркой

find /mnt/source/ -type f -regex ".*\(doc\|docx\|xls\|xlsx\|pdf\|zip\|7z\)$" -print0 |xargs --null cp --parents -t /dest/

#onestringscript #bash

20 last posts shown.

24

subscribers
Channel statistics