вторник, 16 мая 2017 г.

редиректы nginx много SSL бесплатных сертификатов


Сделать отчет по redirect откуда и куда
#!/usr/bin/python
file = open("redirects","r")
pairs={}
for row in file:
    if 'server_name' in row:
        name=row.strip().split(" ")
    if 'return' in row:
        redir = row.strip().split(" ")
        pairs[name[1]]=redir[3]
file2 = open("report","w")
for key, value in pairs.items():
    file2.write( key+" => "+value+"\n")
file2.close




Генерация конфига nginx  для бесплатных SSL сертификатов let's encrypt для большого количества редиректов

#!/usr/bin/python
file = open("source","r")
pairs={}
for row in file:
    if 'server_name' in row:
        name=row.strip().split(" ")
    if 'return' in row:
        redir = row.strip().split(" ")
        pairs[name[1]]=redir[2]

for pair in pairs.keys():
#    print "certbot certonly -d "+pair+" -d "+pair[4:] (раскоментируем если нужно сгенерировать для бота)
# второй вариант вывода, если файл не нужен
    print "server {"
    print "    listen <Реальный IP>:80;"
    print "    listen <Реальный IP>:443 ssl;"
    print "    server_name",pair, pair[4:]+";"
    print "    location /.well-known {"
    print "        root /var/www/html;"
    print "    }"
    print "    location / {"
    print "    return 301 ",pairs[pair]
    print "    }"
    print "    ssl_certificate /etc/letsencrypt/live/"+pair+"/fullchain.pem;"
    print "    ssl_certificate_key /etc/letsencrypt/live/"+pair+"/privkey.pem;"
    print "    ssl_trusted_certificate /etc/letsencrypt/live/"+pair+"/chain.pem;"
    print "}"



понедельник, 23 января 2017 г.

Ansible собрать активные default gateway на unix системах

Иногда по историческим причинам на сервере может быть настроено несколько default gateway, но реально работает,  конечно, один.

Ansible определяет интерфейс по умолчанию с помощью команды
ip -4 route get 8.8.8.8


Если нужно проверить (провести аудит) настроек шлюзов то можно использовать такой коротенький yml

---
- hosts: all
  become: yes
  tasks:
    - local_action: file path=report state=touch
    - local_action: lineinfile line="System {{ inventory_hostname }} \ 
has gateway {{ ansible_default_ipv4.gateway }}" dest=report
 
Можно вставить проверку и выводить нужные условия
---
- hosts: all
  become: yes
  tasks:
    - local_action: file path=report state=touch
    - local_action: lineinfile line="System {{ inventory_hostname }} has {{ansible_hostname}} \
gateway {{ ansible_default_ipv4.gateway }}" dest=report
      when: inventory_hostname !=ansible_hostname
 

пятница, 28 октября 2016 г.

Аудит логинов на unix системах

Очень быстрое решение как собрать все учетные записи с unix серверов для аудита
1. Вспомнили, где стоит ansible
2. Навели порядок в файле /etc/ansible/hosts на контрольной (управляющей) машине. Если не все красиво с точки зрения dns, то пользуйтесь ansible_ssh_host, если нестандартные порты - ansible_ssh_port для тех узлов, где без них не получается
3. ansible all -a "cat /etc/passwd" > в файл.
4. Берем cat файл | egrep -v "nologin|false|еще чтонибудь" и удивляемся, а эти учетки почему не удалены :)

воскресенье, 14 августа 2016 г.

куда же ходит сервер собрать IP Linux tcpdump

Часто команда, которая поддерживает програмное обеспечение на серверах "не до конца уверена" куда же ходит сервер ( к каким другим серверам).

Варианты поиска ответов, которые я нашел:


  1. Netflow и коллектор. В качесте netflow источника может быть как сетевое оборудование, так и модуль ядра.
  2. Tcpdump конечно(если сервер не очень, очень нагружен). В крайнем случае может быть конечно зеркалирование порта на сетевом оборудовании (span, rspan, espan в Cisco, port-mirroring в Juniper)
  3. Iptables с включенным логированием (очень желательно в отдельный файл)


В данном случае мне подходил tcpdump прямо на сервере

Процесс сбора:


  1.  Уменьшаем объем захвата на известные адреса (либо запустив сбор на 5 минут, либо опросить команду поддержки приложения)
  2.  Записали tcpdump с ключиками
    •  -w имя файла
    •  -i имя интерфейса 
    •  -С 1000 (размер файла не более 1000 млн байта - чуть меньше 1 Гб). В этом случае при достижении того самого 1000 млн будет начинать создаваться новый файл. Хорошо создавать на отдельный раздел с ощутимым свободным местом, и если на нем закончится место, то чтобы это не вызвало остановки сервисов.
  3. Так как готового способа, который меня устраивал я не нашел, я скопировал к себе все файлы с размером каждого почти 1 Гб  на ПК, меньше шансов было повлиять на активный сервис.

Обработка:

Приемлемых результатов достиг разделив обработку tcp и udp отдельно.
 Для TCP можно выделить соединения (tcp flow), чтобы не бороться с фильтрацией динамических портов, и отфильтровать сканы несуществующих портов

Обработка TCP

1) Для выделения потоков воспользовался утилитой tcpick (ставится на ubuntu
apt-get install tcpick
).


2) Отобрал только established. Быстро просмотрел результат с помощью вывода в more.
3) Дальше немного почистил с помощью egrep -v 'известное1| известное 2' (кому-то больше нравится писать grep -vE  )
Команда выглядела так

tcpick -a -r 123.pcap | grep 'ESTABLISHED' | egrep -v 'известное1|известное2' > temp


2) склеиваем вывод файла в один файл
temp &gt;&gt; temp_result_tcp
, потом
temp2 >> temp_result_tcp 
и так далее

3) Отбираем только destination. Смотрим файл, например less имя файла

В полученном промежуточном сводный файле:
  • выбираем 5 столбец (destination)
  • сортируем, 
  • считаем дубли - ключ c в uniq
  • оставляем uniq только имеющиеся дубли (за счет ключа -d) не нужны мне случайные соединения за неделю (в моем случае так надо, в вашем может быть иначе) 
  • результат сортируем по числам за счет ключа n
  • Самых активных выводим первыми за счет ключа r в программе sort

awk '{print $5}' |  sort | uniq -cd | sort -nr 

Просматриваем глазами результат ( в моем случае были настойчивые сканеры), убираем явных сканеров.
Кстати, смотреть tcpick с ключом - С (цвет) pcap, созданный  тем же tcpdump, мне понравилось.


Обработка UDP



1) Читаем еще раз исходный файл pcap, но уже читаем только udp
tcpdump udp -r имя файла дампа | more . Бегло просматриваем что можно выбросить сразу
2)   чистим tcpdump udp -r 123.cap| egrep -v '.domain|ntp|sip|mdns|dhcpv6|netbios| и прочее'
в моем случае это был multicast и почему-то порт 53413 (оказалась популярная цель для сканеров)
3) Оставил и source и destination и значок направления. Обьем в моем случае очевидно меньше. Команда awk '{print $3,$4,$5} > в файл.
4)  Склеиваем аналогично результат всех в один файл, проходим
awk '{print $3,$4, $5}' |  sort | uniq -cd | sort -nr 
 
5) Просматриваем глазами, убираем явных сканеров и оставшийся мусор

Сводим два файла в один, сравниваем с полученными ранее результатами опроса. Помогаем коллегам найти все компоненты приложения.

воскресенье, 17 января 2016 г.

Державний реєстр лікарських засобів України просмотр на мобильном телефоне

В связи с продолжительным невыкладыванием справочника по лекарственным препаратам хотелось перейти на онлайн вариант.
И вроде бы поиск по сайту Державний реєстр лікарських засобів України
www.drlz.kiev.ua работает и с мобильного. Только вот посмотреть инструкцию по препарату нельзя, она скачивается в формате .mht.  Чтобы посмотреть это нужно поставить firefox на телефон и поставить add-on unmht (в самом firefox есть возможность добавлять различные add-on -три точки в правом углу-> tools->add-on->browse all firefox add-ons). Шрифт конечно караул, но лучше чем ничего.

пятница, 15 января 2016 г.

сбор информации с маршрутизаторов cisco python paramiko

На основе предыдущего скрипта сделал сбор информации и подсчет подходящих под условие
отличие здесь довольно простое
из функции есть возрат значения, а уже значение (по сути ответ устройства) анализируется на наличие строк.
поиск строки сделан очень просто просто проверяется строка целиком с помощью in.

#!/usr/bin/python
#for work with SSH we need paramiko pip install paramiko
import paramiko
#hide password input 
import getpass
#build in library socket for with exception
import socket
list_bad_ip=[]
receive_buffer=""
client = paramiko.SSHClient()
#for connection via ssh you need to accept SSH keys
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#create function for send command and check answer
def send_string_and_wait_for_string(command, wait_string):
#send command
    shell.send(command)
#clear buffer
    receive_buffer = ""
#until receive WAIT_STRING - remote device ready
    while not wait_string in receive_buffer:
        receive_buffer += shell.recv(1024)
#return buffer with output of command 
 return receive_buffer
#read list of IPs from text file one by line
ips = [i.strip() for i in open("./1")]
username1 = raw_input("enter login :")
#hide password input 
password1 = getpass.getpass("enter password :")
#create loop for each IPs
for ip in ips:
#if we use try easy to work with expection
    try:
#connect to device
        client.connect(ip,port=22,username=username1,password=password1)
#check state
#        print "connect to ",ip
        shell = client.invoke_shell()
#wait for enable
        send_string_and_wait_for_string("", "#")
#enter command and wait for return to #
        receive_buffer = send_string_and_wait_for_string("sh int Vlan12 | i line protocol\n","#")
#first option not interesting 
        if "line protocol is up" in receive_buffer:
            print ip+" protocol is up"
#second possible answer interesting save in separate list 
        else:
            print ip+" line protocol is down"
            list_bad_ip.append(ip)
#close with this device
        shell.close()
        client.close()
#work with timeout error
    except socket.error:
        print ip + '=== Device unreachable'
#add ip with errors to list
        list_bad_ip.append(ip)
#save this list to file
with open('bad_ip', 'w') as f:
    for s in list_bad_ip:
        f.write(s + '\n')
#show list at the screen for lazy admin
print list_bad_ip
(END)

массовая настройка маршрутизаторов Cisco по ssh (mass configuring cisco router via ssh)

Написал небольшой скрипт как пример массовой настройки маршрутизаторов Cisco по ssh на python.
Использовал paramiko, а не модуль clogin из rancid, потому что было интересно уменьшить зависимости.

От других подобных скриптов мне кажется отличает такое
1) за счет ожидания wait for string работает и на каналах с большой латентностью (спутниках и наземных в перемешку)
2) в тоже время за счет выноса цикла отправки и ожидания ответа в функцию код получается более-менее компактным и добавлять команды довольно просто
3) за счет getpass получается скрытый ввод пароля
4) да и вообще в скрипте не храняться учетные данные
5) так как в моем списке ip могут попадаться и неактивные устройства, то используется try и  expect  для вывода адресов, до которых не удалось достучаться.
 
#!/usr/bin/python
#for work with SSH we need paramiko pip install paramiko
import paramiko
import getpass
#build in library socket for with exception
import socket
list_bad_ip=[]
client = paramiko.SSHClient()
#for connection via ssh you need to accept SSH keys
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#create function for send command and check answer
def send_string_and_wait_for_string(command, wait_string):
#send command
    shell.send(command)
#clear buffer
    receive_buffer = ""
#until receive WAIT_STRING - remote device ready
    while not wait_string in receive_buffer:
        receive_buffer += shell.recv(1024)
#read list of IPs from text file one by line
ips = [i.strip() for i in open("./1")]
username1 = raw_input("enter login :")
password1 = getpass.getpass("enter password :")
#create loop for each IPs
for ip in ips:
#if we use try easy to work with expection
    try:
#connect to device
        client.connect(ip,port=22,username=username1,password=password1)
#check state
        print "connect to ",ip
        shell = client.invoke_shell()
#wait for enable
        send_string_and_wait_for_string("", "#")
#enter conf t and wait for #
        send_string_and_wait_for_string("conf t\n", "(config)#")
#enter command and wait for return to #
        send_string_and_wait_for_string("login on-failure log\n","(config)#")
        send_string_and_wait_for_string("login on-success log\n","(config)#")
#end is important, exit worse in this case
        send_string_and_wait_for_string("end\n","#")
#don't forget store in flash
        send_string_and_wait_for_string("wr mem\n","#")
#we are near end with device
        print ip+" ok"
#close with this device
        shell.close()
        client.close()
#work with timeout error
    except socket.error:
        print ip + '=== Device unreachable'
#add ip with errors to list
        list_bad_ip.append(ip)
#save this list to file
with open('bad_ip', 'w') as f:
    for s in list_bad_ip:
        f.write(s + '\n')
#show list at the screen for lazy admin
print list_bad_ip