Показаны сообщения с ярлыком безопасность. Показать все сообщения
Показаны сообщения с ярлыком безопасность. Показать все сообщения

понедельник, 23 сентября 2024 г.

ip листы по автономной сети (AS) и их применение (возможно блокировка по ним) скажем в nginx/angie и т.д.

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

Также чуть переделав данный сценарий - можно генерировать подобные листы для фаерволов и других систем, где это может понадобиться.

Итак, допустим нам прилетела задача по блокировке входящих соединений скажем нууу... С microsoft'а... Мы знаем AS мелгомякгой компании - это AS8075.

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

#!/bin/bash
echo 'geo $remote_addr $ipblocked {'
echo '         default 0;'
whois -h whois.radb.net -- "-i origin $1" | grep 'route:\|route6:' | awk '{print $2 " 1;"}'
echo '}' 

Вызовем его так:

./t.sh AS8075 > msblocklist.conf  

Получим файл с примерно таким содержимым:

geo $remote_addr $microsoft {
        default 0;
1.186.0.0/16 1;
2.58.103.0/24 1;
...

}

Не забудем подключить данный файл в nginx добавив строку вида:

include /etc/nginx/blacklists/microsoft.conf;

Ну и теперь, где оно необходимо будем использовать данный список согласно нашим хотелкам примерно так:

  if ($microsoft) {
       return 403;
 }

Данный лист генерируется с учётом как ipv4, так и с учётом ipv6 адресов. Если необходимо оставить только ipv4, то достаточно

grep 'route:\|route6:' 

  исправить на

grep 'route:'

понедельник, 21 марта 2022 г.

Мониторинг за обновлениями серверов на базе Ubuntu

По просьбам трудящихся так и быть - выкладываю на всеобщее пользование своего скрипта за мониторингом обновлений на серверах, кои бегут под убунтой... Все красивости решать на своё усмотрение так сказать, у меня лично influxdb+grafana+telegram...

Собственно вся писанина лежит в общем доступе тут:

https://github.com/constantinekg/ubuntu-checksoftwareupdates

Если будут у кого какие комменты - писать мне в личку али кидать в репе пожелания так сказать...

четверг, 22 июля 2021 г.

PCPO - Pc park observer


 PC park observer - система учёта комплектующих компьютеров парка, базирующегося на MS Windows

 Для чего эта система

Данная система предназначена для учёта комплектующих в компьютерном парке, базирующемся на Windows. Я выложил систему под GNU/GPL v. 3 лицензией, так что денег не прошу, можете использовать как угодно... Все пожелания и т.п. обсуждаются отдельно...

Особенности и возможности

Система работает под управлением ОС GNU Linux (на данный момент успешно обкатана на ubuntu 20.04).  Система собирает информацию и создаёт оповещения в случае изменений в необходимых хостах (в частности информацию об:

- мак адрес сетевого адаптера
- ip адрес
- имя хоста
- информацию о мат. плате (по возможности и её серийный номер)
- информацию о процессоре (по возможности и её серийный номер)
- информацию об оперативной памяти (по возможности серийный номер, тип памяти - ECC или не ECC, объём)
- видеоадаптер (с указанием PNP Device id)
- жёсткие диски (можно опционально включить проверку тех, что подключены по USB или iSCSI) - серийный номер, модель, объём

).

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

Доступ к системе регулируется на основе двух ролей - администраторов (могут менять системные настройки и менять перечень проверяемых сетей/хостов); менеджеров - могут просматривать статистику и аналитику по проверяемым хостам.

пятница, 19 марта 2021 г.

Блокировка "плохих" ip адресов через список blocklist.de

 Собственно на машинке помимо iptables нужно поставить ipset, а далее скрипт, который запихать в крон: 

#!/bin/bash
cd /opt/blackips/
rm tempips.txt -rf
if wget https://www.blocklist.de/downloads/export-ips_all.txt -O tempips.txt
then
iptables -D FORWARD -m set --match-set blacklist src -j DROP
iptables -D INPUT -m set --match-set blacklist src -j DROP
iptables -D FORWARD -m set --match-set blacklist src -j DROP
ipset destroy blacklist
#ipset create blacklist hash:ip hashsize 1227600
ipset create blacklist hash:net family inet hashsize 32768 maxelem 300000
iptables -I FORWARD -m set --match-set blacklist src -j DROP
iptables -I INPUT -m set --match-set blacklist src -j DROP
iptables -I FORWARD -m set --match-set blacklist src -j DROP
while read -r line; do
if [[ $line =~ .*:.* ]];
then
  echo "IPv6"
else
  ipset add blacklist "$line";
fi
done < tempips.txt
rm tempips.txt -rf
else
echo 'Error! Can not download black list of ip addresses!'
fi
 

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

Nginx - включение basic авторизации для определённых ip адресов

 Первым делом заготовим файл, в котором будем хранить перечень ip адресов, для которых будем производить авторизацию. Положим его в /etc/nginx/ipsets/authips.conf. Собственно его содержимое будет примерно таким:

...
deny 1.1.0.0/19;
deny 2.2.3.0/24;
deny 3.3.3.0/22;
deny 4.4.4.4/32;
...

Для того, чтобы авторизация заработала, нам также надо создать файл, содержащий учётные записи с паролями. Для этого с помощью утилиты htpasswd
 
(если таковой не нашлось в системе, то доставим её, находится она в пакете apache2-utils: sudo apt install apache2-utils) создаём его:

пятница, 29 ноября 2019 г.

Блокирование гадов в iptables по подписке



Пока копался в интернетах на тему блок листов всяких, я нашёл один хороший чёрный список всяких гадов, кои сканируют ресурсы и напичканы всякими плохими ботами. Список этот обновляется регулярно и поставляется любезно в виде списка правил для операционки routerOS. Но тут мне понадобилось получить ровно такой же функционал и на машинках под управлением обычных дистрибутивов GNU Linux. Оговорюсь сразу, что это можно/лучше проделывать на машинках, у которых есть хороший запас по cpu и памяти. Итак, я ставлю для начала на машинку пакет ipset:

sudo apt install ipset

Я написал короткий bash-скрипт, который положил в /opt/blackips/block-black-ips.sh (Будем блочить ТОЛЬКО IPv4):

#!/bin/bash
cd /opt/blackips/
rm drop.malicious.rsc -rf
if wget https://www.squidblacklist.org/downloads/drop.malicious.rsc -O drop.malicious.rsc
then
iptables -D FORWARD -m set --match-set blacklist src -j DROP
iptables -D INPUT -m set --match-set blacklist src -j DROP
iptables -D FORWARD -m set --match-set blacklist src -j DROP
ipset destroy blacklist
#ipset create blacklist hash:ip hashsize 1227600
ipset create blacklist hash:net family inet hashsize 32768 maxelem 300000
iptables -I FORWARD -m set --match-set blacklist src -j DROP
iptables -I INPUT -m set --match-set blacklist src -j DROP
iptables -I FORWARD -m set --match-set blacklist src -j DROP
cat drop.malicious.rsc | grep address= | awk '{print $8}' | sed 's/address=//' > tempips.txt
while read -r line; do
if [[ $line =~ .*:.* ]];
then
  echo "IPv6"
else
  ipset add blacklist "$line";
fi
done < tempips.txt
rm tempips.txt -rf
else
echo 'Error! Can not download black list of ip addresses!'
fi


Теперь добавим его в cron (sudo crontab -e):

# download black list of bad ip's and put them into iptables rules for DROP action
*/12 * * * * /opt/blackips/block-black-ips.sh

вторник, 18 июня 2019 г.

Безопасность для блогера и прочих авторов крутяцкого контента

Недавно меня попросили рассказать на тему безопасности авторов различных youtube-каналов 
и прочих блогов. Я подумал что в целом давно я ничего такого не писал и вот как бы небольшое 
эссе на эту тему... Комментарии и всё в таком духе приветствуются...

Основными правилами, за нарушение которых вводятся какие то санкции по отношению 
к автору со стороны различных социальных сетей или всеобщих мультимедийных 
платформ для ведения блогов являются:
  • Сцены сексуального или порнографического характера.
  • Проявление всех разновидностей ненависти и возмущение откровенной вражды.
  • Угрозы кому либо.
  • Дискриминация, ложь, подлог.
  • Воровство чужого контента и последующее использование оного в своих коммерческих 
    целях или в целях повышения рейтингов.
  • Недолжное отношение к модерации своего контента, вызывающее впоследствии 
    наличие спама, различного другого контента, вводящего в заблуждение пользователей 
    (реклама различных аферистов и т.д.).

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

понедельник, 8 апреля 2019 г.

О чём мне red hat рассказали...

Поговорил я тут на медни с представителем компании red hat (в частности с Максимом Праховым - он продаёт решения от red hat по СНГ и Грузии)...

Тут я его спрашиваю на тему мол а чего ожидать после покупки red hat компанией ibm? А он мне говорит мол всё будет пучком, нас мол не тронут и у ibm вообще свои цели, притянутые больше к облакам... 

А ещё мне рассказал, что вероятней всего таким всем известным сборкам как centos и fedora в скором времени ждать (а точнее всего после выпуска 8й версии их энтерпрайзного линукса) от red hat плюшек и всяких патчей вовремя получать будет скорее всего затруднительно... Так что любители секьюрности и в то же время халявы могут в скором времени отдохнуть... А зачем им вообще centos поддерживать? Ну они на нём тестируют, обкатывают фичи и прочее...

Так чем же так примечателен всё таки red hat? Весь их секрет заложен в их компиляторе - особо построенный и с особыми опциями он позволяет достигать офигенского прироста в производительности (сам не проверял, но так и быть - в энтерпрайзах пара-десяток процентов в производительности может играть роль существенную)...

Сейчас если так подсчитать - их решения в отличии от виртуализации от vmware и прочих для энтерпрайза прям существенно по цене ниже (на текущий момент 1300$ за сервер с 2мя процами и без каких либо доп. лимитаций). Сюда же плюсуем их легендарный тех. под. и прям резкое закрытие багов и дырок - в итоге их любят в российском нац. банке, в Белоруссии в сфере банков тоже, да и по их словам сбербанк после года затрахов с кубернетом таки свалил в сторону их openshift в связке с их cef (и точно молчу про различные телекомы)...

Ещё я спросил про сертификацию и вот что - ближайший к нам офлайн центр с компетенцией в плане обучения сертифицирует только по первому одному курсу с экзаменом всего то за 2 штуки грина! А зачем тебе мол платить 2 штуки, когда ты платишь 3 штуки и получаешь в онлайне доступ до 50 курсов...

А что наши местные линуксоиды говорят? К примеру так: а пох, я debian юзаю... Или так: торчал на ubuntu и дальше буду продолжать торчать на gentoo... :) В общем всё это конечно весело и прекрасно, но правда такова, что всяким банкам и прочим телекомам и большим энтерпрайзам конечно лучше даже не пробовать строить надёжные отказоустойчивые системы на коленках...

Что ещё сказал... А да! Если будут вопросы, то можно с ним контактировать спрашивать и всё такое если кому интересно...


P.S: Спасибо за ништяки!

воскресенье, 12 октября 2014 г.

Антипорно или защита для маленьких

Недавно один из наших местных провайдеров запустил услугу по фильтрации контента "Родительский контроль" и мне тут же задали вопрос - а чего Вы мол не запустите у Вас такую штуку. Отвечаю... Она просто не будет работать против людей, которые хоть один раз включат мозги. Но допустим против недалеких будет работать вполне нормально. Итак, давайте сначала определимся - для чего это всё нужно, как это работает и поговорим о плюсах и минусах...

четверг, 21 ноября 2013 г.

PUBS - Python universal backup script для linux

Данный скрипт был наваян мной в целях автоматизации процессов резервного копирования. Основным назначением является создание резервных копий (архивов с данными) как на локальном хранилище linux серверов, так и их дальнейшее дублирование на удалённом хранилище, которое расположено на windows сервере (зеркало).

В целом такая вот картинка....


Что делает мой скрипт (пошагово):

1. Сначала проверяет доступен ли удалённый windows server, проверяя состояние открытости порта netbios (по умолчанию 135 порт)
2. Затем проверяет запущен ли mysql на локальной машине (по умолчанию 127.0.0.1), проверяя возможность соединиться с портом mysql (по умолчанию 3306).
3. Если проверки прошли удачно, то скрипт начинает монтировать удалённую расшаренную директорию на windows сервере к директории, расположенной на локальном сервере.
3. Если монтирование прошло удачно, то скрипт создаёт новую директорию с именем, отражающим текущую дату в директории на локальном сервере (на примере /backup/20131121/).
4. Далее создаются дампы баз данных, имена которых указаны в переменных скрипта и складируются в ранее созданную директорию (к примеру складируются в  /backup/20131121/, с именами в формате mysql-имя базы-.sql.годмесяцдень.часминутасекунда.gz)
5. Затем пакуются директории в виде tar.gz архивов в ранее созданную директорию (к примеру /backup/20131121/), с именами в формате  dir-путьдодиректориибеззнаков'/'-годмесяцдень.час-минута-секунда.tar.gz.
6. Далее производится очистка от старых файлов и директорий (удаляются те файлы и директории, время модификации которых больше числа указанных дней (к примеру 30).
7. Далее производится синхронизация данных с помощью rsync между локальной директорией, в которой находятся все архивы и удаленной директорией, которая примонтированна к локальной директории.
8. После выполнения синхронизации производится размонтирование удаленной директории и закрытие программы.

Перед тем как приступать к работе:

- Установить rsync
- Установить необходимые пакеты, чтобы корректно срабатывала команда mount -t smbfs //ip/share...

Листинг скрипта:


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# PUBS - Python Universal Backup Script
# Created by Constantine in november 2013
# Mailto: myainetwork@gmail.com
# This script you can find on http://infdots.blogspot.com
# You can use this code under your own risk.

# Variables section
keepdays = '30'                              # How many time (in days) we must keep archives on local storage
addr = '192.168.0.1'                     # IP address of remote windows based server with share
port = '135'                                # Number of port on remote server to try check connection (netbios)
localdir4backups = '/backup/'               # Location of local storage where we will keep all backups
mountdir = '/winshare/'                   # Location of directory where we will mount remote windows share
winshare = 'docs'                   # Name of share on windows based server
winusername = 'administrator'                 # User name who have an access for windows share
winpassword = 'Fan09!%fdkjfd'                    # Password of windows user
workgroup = 'workroup'                           # Workgroup or domain name
backupfolder = ['/var/www/', '/opt/']       # Which directories we will archive to local backup storage
bases = ['joomla','feng','sold']    # Names of databases on local mysql server
mysqlhost = '127.0.0.1'                     # Address of mysql server
mysqlport = '3306'                          # Mysql port number
muser = 'root'                              # Mysql user name
mpass = 'superpuperpassword'                           # Mysql user password

# Importing of some modules
import socket
import sys
import subprocess
import os
import errno
import datetime
import string
import time

# Script vars
now = datetime.datetime.now()
storedir = localdir4backups+str(now.year)+str(now.month)+str(now.day)
ctime = str(now.year)+str(now.month)+str(now.day)+"."+str(now.hour)+"-"+str(now.minute)+"-"+str(now.second)

# Function for delete of old archives on local storage
def oldclear():
    try:
        starttime = time.time()
        oldout = subprocess.PIPE
        ocd = subprocess.Popen(["time find "+localdir4backups+" -type d -mtime +"+keepdays+" -exec rm -rf {} \;", "non existent"], shell=True, stdout=oldout, stderr=oldout)
        time.sleep(2.0)
        ocf = subprocess.Popen(["find "+localdir4backups+" -type f -mtime +"+keepdays+" -exec rm -rf {} \;", "non existent"], shell=True, stdout=oldout, stderr=oldout)
        time.sleep(2.0)
        output = ocd.poll()
        ocd.wait()
        ocf.wait()
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')
    except:
        output = output
    return output


# Function for test port connection on remote backup server (Checking of SMB service is running)
def check_server(address, port):
        # Create a TCP socket
        s = socket.socket()
        print "Attempting to connect to %s on port %s" % (address, port)
        try:
                s.connect((address, port))
                print "Connected to %s on port %s" % (address, port)
                return True
        except socket.error, e:
                print "Connection to %s on port %s failed: %s" % (address, port, e)
                return False

# Function for syncing of local backup and remote
def sync():
    try:
        starttime = time.time()
        sout = subprocess.PIPE
        syncr = subprocess.Popen(["time rsync -avz --delete --stats "+localdir4backups+" "+mountdir, "non existent"], shell=True, stdout=sout, stderr=sout)
        time.sleep(2.0)
        output = syncr.poll()
        syncr.wait()
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')
    except:
        output = output
    return output

# Function for mount remote share to local directory
def mountshare():
    try:
        starttime = time.time()
        loutput = subprocess.PIPE
        mnt = subprocess.Popen(["time mount -t smbfs //"+addr+"/"+winshare+" "+mountdir+" -o username="+winusername+",password="+winpassword+",workgroup="+workgroup, "non existent"], shell=True, stdout=loutput, stderr=loutput)
        time.sleep(2.0)
        output = mnt.poll()
        subprocess.Popen.kill(mnt)
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')
    except:
        output = output
    return output

# Function for unmount remote directory
def unmount():
    try:
        starttime = time.time()
        unout = subprocess.PIPE
        umount = subprocess.Popen(["time umount "+mountdir, "non existent"], shell=True, stdout=unout, stderr=unout)
        time.sleep(2.0)
        output = umount.poll()
        umount.wait()
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')
    except:
        output = output
    return output



# Function for creating folders in date format (Year:month:day) for local backups
def newdir():
    try:
        os.makedirs(storedir)
        result = 0
    except OSError:
        print 'Error can not create directory on local storage. Probably directory exist or you havent any privilegies for writing. Please check your permissions'
        result = 2
        if not os.path.isdir(storedir):
            raise
    except:
        result = 1
    return result


# Function TAR backup directories (such as /var/www etc.)
def tardir(backupfolder):
    clen = len(backupfolder)
    try:
        starttime = time.time()
        result = 0
        for bf in backupfolder:
            p = subprocess.Popen(["time tar -pczf "+storedir+"/"+"dir-"+bf.replace("/",'')+'-'+ctime+".tar.gz"+" "+bf+" > /dev/null 2>&1"], shell=True)
            time.sleep(2.0)
            p.wait()
        endtime = time.time()
        print (u'Estimated time is: ')
        print endtime - starttime
        print (u'')

    except OSError:
        print 'Error can not create archive. Probably file exist or you have not any privilegies for writing. Please check your permissions'
        result = 2
        if not os.path.isdir(storedir):
            raise
    except:
        result = 1
    return result


# Function for mysql backup
def mysql_backup(bases, user, passs, ocaldir4backups):
        try:
                starttime = time.time()
                for b in bases:
                        mb = subprocess.Popen(["time mysqldump -u "+user+" -p"+passs+" "+b+" | gzip > `date +"+storedir+"/"+"mysql-"+b+"-.sql.%Y%m%d.%H%M%S.gz`"], shell=True)
                time.sleep(2.0)
                mb.wait()
                endtime = time.time()
                print (u'Estimated time is: ')
                print endtime - starttime
                print (u'')
        except Exception as e:
                print ("Error with connection to database:")



if __name__ == '__main__':
        from optparse import OptionParser
        parser = OptionParser()

        parser.add_option("-a", "--address", dest="address", default=addr, help="ADDRESS for server", metavar="ADDRESS")

        parser.add_option("-p", "--port", dest="port", type="int", default=port, help="PORT for server", metavar="PORT")

        (options, args) = parser.parse_args()

        print ('')
        print ("Backup process launched at: "+ctime)
        print ('-----------------------------------------------------------------')
        check = check_server(options.address, options.port)

        print ('')

        check2 = check_server(mysqlhost, int(mysqlport))
        print ('')

        resret = check2+check

        print ('')

        if resret == 2:
            starttime = time.time()
            print ('Mysql working and remote backup server is accessible. Trying to mount remote share...')
            m = mountshare()
            if m == 0 or m == 32:
                    print ('Remote share mounted. Trying to create backups on local storage...')
                    ndr = newdir()
                    print ('Dump mysql databases...')
                    mysql_backup(bases, user=muser, passs=mpass, ocaldir4backups=localdir4backups)
                    print ('Backup directories...')
                    tardir(backupfolder)
                    print ("Backups has been made. Delete old archives, which older than "+keepdays+" days on local storage...")
                    odel = oldclear()
                    print ('Trying to sync...')
                    sn = sync()
                    print ('Unmount remote share...')
                    ut = unmount()
                    print ('DONE')
                    endtime = time.time()
                    print (u'Total time is (in minutes): ')
                    print (endtime - starttime)/60
                    print ('-----------------------------------------------------------------')
            else:
                    print ('Oops... I can not create archives on local storage and i can not sync')
                    print ('-----------------------------------------------------------------')


sys.exit()
Как запускать:

Ничего криминального в принципе нет - запихать в cron, если хотим регулярно его вызывать или же если хотим сами, то с команды скажем ./pubs-script.py... Вывод скрипта можно кстати перенаправить (скажем ./pubs-script.py >> /var/log/pubs.log).


P.S:
Перед тем как запустить скрипт, необходимо поправить переменные под Ваше хозяйство, которые расположены в самом начале программы после строчки # Variables section.

Что ещё можно сделать:

Возможно реализовать выгрузку данных на удалённый линуксовый сервер, необходимо поправить функцию и сделать право выбора (мол на какой тип сервера будем выгружать - линуксовый или виндушный).

вторник, 3 апреля 2012 г.

Размышления на тему безопасности web

После прочтения довольно неплохого обзора на тему безопасности веб приложений ( http://goo.gl/ATZzP ), я решил провести для себя одно исследование. В обзоре больше описывались такие темы как наличие на машинах каких то руткитов и способы противостояния им. А я вот подумал о более тривиальных и наиболее распространённых вещах. Я пересканировал отдельно взятую подсеть одного провайдера и пришёл к выводу, что народ не шибко то и печётся в вопросах устойчивости различных web сервисов к различного рода атакам. Из 254 пересканированных мной хостов может процентов 30 оказалось за какими то файрволами и с имеющимися надлежащими заплатками, остальные увы оказались по каким либо критериям возможными к компроментации. В этом зоопарке устройств имелись хосты как windows-based, так и unix-based, а также различного рода маршрутизаторы и voip шлюзы. Особо отметил то, что народ откровенно описывал предназначение той или иной машины прямо в имени хоста. К примеру особо не парясь, я узнал что такая то машина - узел одной платежной системы, а в имени другой было написано Nashalnike. Отмечу сразу, что наиболее податливыми к взлому оказались машинки на windows (а потому что народ видать жмотится платить за лицензию и вовремя подкачивать обновления). Не остались под защитой всеми хвалёные линуксы и прочие юниксы - обнаружились и возможность отказа работы служб и удалённое выполнение произвольного кода и т.д. Что же касается каких либо маршрутизаторов и voip шлюзов, то там также обнаружились возможности выполнения произвольного кода атакой на telnet. Вы спросите причем тут web? Да почти на всех этих машинках крутился какой то веб сервер и почти на всех них можно было посмотреть какой то контент. Отдельные товарищи не стали вообще как то париться и оставили открытыми к доступу базы данных с учётными записями пользователей, которые идут с этими базами данных по умолчанию. Не буду сильно углубляться в дебри аспектов безопасности, но в свете всего этого держателям различных web проектов я бы хотел сказать следующее:

1. Держите впереди вашей инфраструктуры какой никакой файрвол
2. Вовремя обновляйте программное обеспечение, благо на это существуют и автоматическая загрузка обновлений и различные списки рассылок, подписавшись на которые вы будете иметь актуальную информацию об обновлениях вашего любимого программного обеспечения.
3. Переодически (ну или хотя бы как только уже установили всё необходимое ПО (от веб сервера до вашего любимого блог движка) устраивайте пентесты на возможность проникновения.
4. Не используйте простые пароли (да я понимаю что вы где то это уже не раз слышали, но по всей видимости авось у вас в головах иногда берёт верх).
5. Если вы сомневаетесь (ну хотя бы хоть где то), что вы несколько некомпетентны в вопросах поддержки сервисов и обеспечения надлежайшей безопасности - перепоручите вопросы профессиональным компаниям (порой некоторые издержки бывают довольно оправданы).

Как гласит одна поговорка - всё что создано человеком, человеком же может и быть взломанно, т.е. вы всё равно никогда не убережётесь на все 100%, но вы можете свести эту возможность к минимуму.