Создайте подобный сайт на WordPress.com
Начало работы

SaltStack. Основы

SaltStack — система управления конфигурациями и удаленного выполнения операций. Для коммуникации Salt может использовать SSH или собственный протокол, работающий на базе ZeroMQ.

Для работы используются 2 TCP порта 4505 и 4506.

Для работы Salt не нужен SSH

Отличия и сходства с Ansible:

  • Ansible и Salt написаны на Python
  • Ansible работает только через SSH, Salt может работать через SSH или собственный протокол
  • В классической модели работы Salt использует на каждом хосте агенты
  • Асинхронная связь сервера с клиентами (из-за этого параметра Salt работает быстрее чем Ansible)

Ключевые понятия и элементы:

  • Salt master — процесс, который управляет агентами (миньонами)
  • Salt minion — процесс, работающий на управляемых машинах.
  • Salt state (SLS) — конфигурационные файлы, написанные на YAML (аналог Playbook в Ansible)
  • Formulas — множества вызовов к модулям состояний (state modules), организованных таким образом, чтобы достичь определённого результата; они описывают как должна выглядеть система в том случае, когда формула применена. Формулы это заранее приготовленные состояния (salt states).
  • Templates ( шаблоны)
  • Pillars — защищённые хранилища важной информации, собственно salt state’ов.
  • Grains — факты о системах (ОС, ip-адреса, модель процессора и т.д.)
  • Mine – хранилище результатов исполнения команд на миньонах на мастер-сервере. С помощью Mine нельзя откатиться обратно.

Источник — http://xgu.ru/wiki/SaltStack

Установка и настройка

В документации можно посмотреть, как правильно установить Salt Master и Salt Minion.

Для удобства на моём GitHub можно забрать готовый стенд с одним мастером и двумя миньонами. Настроены базово.

Примеры работы команд:

  • Проверка работы Salt на хостах:
salt '*' cmd.run "uname -a"
  • Запуск команды «uname -a» на хосте:
salt minion1 cmd.run "uname -a"
  • Просмотр информации о хосте minion1:
salt minion1 grains.items
  • Пробный запуск (без внесения изменений) файла (/srv/salt/nginx/init.sls) состояния:
sudo salt minion1 state.apply nginx test=True
  • Если проблем не обнаружено, то можно запустить state:
sudo salt minion1 state.apply nginx 

Пример установки nginx на хосте с помощью Salt:

Далее все действия выполняются от root

Создадим каталог nginx /srv/salt/nginx

mkdir -p /srv/salt/nginx

Далее создадим файл /srv/salt/nginx/init.sls со следующим содержимым:

vim /srv/salt/nginx/init.sls

#Установка nginx
nginx:              
  pkg:           
    - installed    

#Запуск службы
  service:            
    - running     

#Отслеживание изменений, при которых будет перезапуск службы
    - watch:      
      - pkg: nginx    
      - file: /etc/nginx/nginx.conf    

#Отправка файла /etc/nginx/nginx.conf на удаленный хост
/etc/nginx/nginx.conf:
  file:
    - managed
    - source: salt://nginx/nginx.conf #путь к файлу на мастер-хосте
    - user: root
    - group: root
    - mode: 644

Создадим файл конфигурации nginx.conf который будет отправлен на удаленный хост:

vim /srv/salt/nginx/nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 512;
}

http {

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        gzip on;

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

Далее создадим файл top.sls который будет запускать файл init.sls из каталога nginx:

vim /srv/salt/top.sls

base:
  'minion1':      #'*' - установка на всех хостах
    - nginx

Проверим как отработает тестовый запуск:

root@master:/srv/salt# salt '*' state.highstate test=True

minion2:
----------
          ID: states
    Function: no.None
      Result: False
     Comment: No Top file or master_tops data matches found. Please see master log for details.
     Changes:   

Summary for minion2
------------
Succeeded: 0
Failed:    1
------------
Total states run:     1
Total run time:   0.000 ms
minion1:
----------
          ID: nginx
    Function: pkg.installed
      Result: None
     Comment: The following packages would be installed/updated: nginx
     Started: 15:18:32.250134
    Duration: 164.761 ms
     Changes:   
              ----------
              installed:
                  ----------
                  nginx:
                      ----------
                      new:
                          installed
                      old:
----------
          ID: /etc/nginx/nginx.conf
    Function: file.managed
      Result: None
     Comment: The file /etc/nginx/nginx.conf is set to be changed
              Note: No changes made, actual changes may
              be different due to other states.
     Started: 15:18:32.428594
    Duration: 36.336 ms
     Changes:   
              ----------
              newfile:
                  /etc/nginx/nginx.conf
----------
          ID: nginx
    Function: service.running
      Result: None
     Comment: Service is set to be started
     Started: 15:18:32.491839
    Duration: 15.134 ms
     Changes:   

Summary for minion1
------------
Succeeded: 3 (unchanged=3, changed=2)
Failed:    0
------------
Total states run:     3
Total run time: 216.231 ms
ERROR: Minions returned with non-zero exit code
root@master:/srv/salt# 

Сначала мы увидим ошибку, в ошибке будет написано, что по хосту minion2 не найдено изменений. Так и должно быть, по хосту minion1 проблем не найдено, можем запустить state:

salt '*' state.highstate

После установки, можно проверить, был ли установлен nginx, указав в адресной строке адрес сервер minion1:

Если у нас получается зайти на веб-интерфейс, значит установка прошла успешно.

Настройка SSH по ключу

Когда у нас настроен классический доступ по SSH, то от нас требуется знать логин, пароль, и номер SSH-порта (если он вдруг изменён. SSH порт по умолчанию TCP 22)

Если у Вас в распоряжении, есть 2-3 сервера, то проблем возникнуть не должно, но если у Вас много linux-машин, постоянно вводить пароль будет очень неудобно. Для того, чтобы упростить доступ, был придуман доступ по SSH-ключу.

Как работает авторизация пользователя по ключу?

На linux-машине генерируется 2 ключа: открытый и закрытый. Открытый ключ отправляется на другой сервер, к которому планируется настроить доступ без пароля. С помощью открытого ключа шифруются сообщения. Закрытый ключ нужен для того, чтобы расшифровать сообщения, зашифрованные открытым ключом. Если доступ к закрытому ключу будет получен злоумышленниками, то доступ будет скомпрометирован.

Настройка доступа по SSH-ключу между двумя linux-машинами

У нас есть два linux-сервера: Debian 10 (10.166.0.3) и CentOS 7 (10.166.0.4). Начнём настраивать доступ по ключу с сервера CentOS 7.

  1. По умолчанию ключи хранятся в скрытой папке пользователя. (/home/user/.ssh). Проверяем что на серверах данная папка есть:
#На CentOS 7 (10.166.0.4)
[tv1n94@c7-ssh ~]$ ls -la
total 12
drwx------. 3 tv1n94 tv1n94  74 Jan 10 14:29 .
drwxr-xr-x. 4 root   root    35 Jan 10 14:29 ..
-rw-r--r--. 1 tv1n94 tv1n94  18 Apr  1  2020 .bash_logout
-rw-r--r--. 1 tv1n94 tv1n94 193 Apr  1  2020 .bash_profile
-rw-r--r--. 1 tv1n94 tv1n94 231 Apr  1  2020 .bashrc
drwx------. 2 tv1n94 tv1n94   6 Jan 10 14:32 .ssh
[tv1n94@c7-ssh ~]$ 

#На Debian 10 (10.166.0.3)
tv1n94@d10-ssh:~$ ls -la
total 28
drwxr-xr-x 4 tv1n94 tv1n94 4096 Jan 10 14:50 .
drwxr-xr-x 4 root   root   4096 Jan 10 14:29 ..
-rw-r--r-- 1 tv1n94 tv1n94  220 Apr 18  2019 .bash_logout
-rw-r--r-- 1 tv1n94 tv1n94 3526 Apr 18  2019 .bashrc
drwx------ 3 tv1n94 tv1n94 4096 Jan 10 14:50 .gnupg
-rw-r--r-- 1 tv1n94 tv1n94  807 Apr 18  2019 .profile
drwx------ 2 tv1n94 tv1n94 4096 Jan 10 14:50 .ssh
tv1n94@d10-ssh:~$ 

2. На CentOS 7 выполняем генерацию открытого и закрытого ключа. Предварительно нужно проверить, что нет сгенерированных ключей. Если уже есть сгенерированные ключи, то заново генерировать не нужно.

[tv1n94@c7-ssh ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/tv1n94/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/tv1n94/.ssh/id_rsa.
Your public key has been saved in /home/tv1n94/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:+LjfzdcTs8vGeGqliDfn1WZK/zQC0JNwwJr1SttRsCk tv1n94@c7-ssh
The key's randomart image is:
+---[RSA 2048]----+
|        .o.o.    |
|         o+ +.   |
|        +E.*.    |
|       + .oo.    |
|      . S +..    |
|       o o ..  +.|
|      . . . ..*+O|
|       . o * *=%o|
|      ... o B+=o*|
+----[SHA256]-----+
[tv1n94@c7-ssh ~]$ 

При генерации ключей будет запрошен путь к их расположению и пароль на использование ключа. Если вы всё планируете оставить без изменений (стандартный путь и ключ без пароля), то можно просто 3 раза нажать на Enter. Если вы введете пароль на использование ключа, то его нужно будет вводить при каждом подключении к другим серверам.

3. В папке .ssh у нас должно появится 2 ключа (id_rsa — закрытый и id_rsa.pub — открытый). Открытый ключ нужно отправить на сервер Debian 10 (10.166.0.3).

#Проверяем, что ключи были созданы
[tv1n94@c7-ssh ~]$ ls -la .ssh/
total 8
drwx------. 2 tv1n94 tv1n94   38 Jan 10 14:53 .
drwx------. 3 tv1n94 tv1n94   74 Jan 10 14:29 ..
-rw-------. 1 tv1n94 tv1n94 1679 Jan 10 14:53 id_rsa
-rw-r--r--. 1 tv1n94 tv1n94  395 Jan 10 14:53 id_rsa.pub
[tv1n94@c7-ssh ~]$ 

#Копируем открытый ключ на другой сервер
[tv1n94@c7-ssh ~]$ ssh-copy-id -i .ssh/id_rsa.pub tv1n94@10.166.0.3
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
tv1n94@10.166.0.3's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'tv1n94@10.166.0.3'"
and check to make sure that only the key(s) you wanted were added.

#Пытаемся подключиться
[tv1n94@c7-ssh ~]$ ssh 10.166.0.3
Linux d10-ssh 4.19.0-13-cloud-amd64 #1 SMP Debian 4.19.160-2 (2020-11-28) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Jan 10 14:50:57 2021 from 35.235.240.176
tv1n94@d10-ssh:~$ 
tv1n94@d10-ssh:~$ 

Если вдруг на linux-машине нет утилиты ssh-copy-id, то нам нужно просто перенести ключ id_rsa.pub на другой сервер в папку .ssh. Например, можно использовать утилиту scp.

На данном этапе мы настроили доступ по ключу с сервера CentOS 7 на сервер Debian 10. Давайте теперь настроим доступ по ключу с сервера Debian 10 на сервер CentOS 7:

#Генерируем ключи
tv1n94@d10-ssh:~$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/home/tv1n94/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/tv1n94/.ssh/id_rsa.
Your public key has been saved in /home/tv1n94/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:JQM6VM85NpcmV2yLPOeXwpiHmo7ltNl2cEbF0QdQ9qg tv1n94@d10-ssh
The key's randomart image is:
+---[RSA 2048]----+
|    ..o    .o+=+ |
|   . . + . oo.ooo|
|    o   @.*o o. o|
|     . . @+ +.   |
|        S  XE  . |
|          = B o  |
|        oo = o   |
|       =o+. .    |
|      ..=...     |
+----[SHA256]-----+

#Отправляем открытый ключ на сервер CentOS 7 
tv1n94@d10-ssh:~$ ssh-copy-id -i .ssh/id_rsa.pub tv1n94@10.166.0.4
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
tv1n94@10.166.0.4's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'tv1n94@10.166.0.4'"
and check to make sure that only the key(s) you wanted were added.

#Пробуем залогиниться
tv1n94@d10-ssh:~$ ssh 10.166.0.4
Last failed login: Sun Jan 10 15:17:19 UTC 2021 from d10-ssh.europe-north1-a.c.psychic-root-276212.internal on ssh:notty
There were 2 failed login attempts since the last successful login.
Last login: Sun Jan 10 14:29:22 2021 from 35.235.240.176
[tv1n94@c7-ssh ~]$ exit
logout
Connection to 10.166.0.4 closed.
tv1n94@d10-ssh:~$ 

На данном этапе настройка доступа по ssh-ключу завершена, теперь мы можем логиниться между серверами без ввода пароля.

Когда используется много серверов, сложно удержать в голове все ip-адреса, для того, чтобы можно было логиниться на сервер с помощью его доменного имени, нужно внести данный сервер в файл /etc/hosts

[root@c7-ssh tv1n94]# vi /etc/hosts
#Пример файла /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.166.0.4 c7-ssh
10.166.0.3 d10-ssh

#Попробуем залогиниться по доменному имени
[tv1n94@c7-ssh ~]$ ssh d10-ssh
The authenticity of host 'd10-ssh (10.166.0.3)' can't be established.
ECDSA key fingerprint is SHA256:FOJ8Uot3DriaFAfXdFZwFL5CEXSNOEqEXh52O4F2OMY.
ECDSA key fingerprint is MD5:d2:5d:89:22:c7:5b:6d:fe:a7:c6:50:0f:a1:de:86:3f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'd10-ssh' (ECDSA) to the list of known hosts.
Linux d10-ssh 4.19.0-13-cloud-amd64 #1 SMP Debian 4.19.160-2 (2020-11-28) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Jan 10 15:08:04 2021 from 10.166.0.4
tv1n94@d10-ssh:~$ 

mdraid: компоненты и управление

mdraid — linux-утилита для создания и управления программными RAID-массивами.

Преимущества программного RAID-массива:

  • Бесплатно (не надо тратиться на покупку аппаратного RAID-контроллера)
  • Одинаковый интерфейс управления на всех популярных linux
  • Гибкая настройка (можно перенести RAID в другой сервер, нет привязки к железу, производителю дисков и т д.)

Недостатки программного RAID-массива:

  • Отсутствие BBU (батарейки RAID-контроллера. Батарейка RAID-контроллера позволит перенести информацию с кэша на диски, если сервер выключится)
  • Отсутствие выделенного кэша (В аппаратных RAID-контроллерах есть специальный кэш, информация сначала пишется в него, и только потом переносится на диски, это может сильно ускорить работу)
  • Отсутствие службы поддержки
  • Производители некоторого ПО (например vmWare) не поддерживают работу на программном RAID

mdraid может работать не только с дисками, но и с разделами, томами LVM и т.д. Информация о RAID-массиве записывается в суперблок диска.

Рассмотрим на примере ОС CentOS как управлять RAID-массивами

Как создать RAID-массив?

Если вы только устанавливаете ОС на сервер, то RAID-массив можно создать прямо из установщика. Давайте на примере сделаем RAID1:

Переходим в раздел INSTALLATION DESTINATION
Перед нами откроется список дисков, с помощью клавиши ctrl выделяем оба диска и в разделе partitioning выбираем пункт I will configure partitioning и нажимаем Done

Если бы у нас был создан аппаратный RAID на уровне BIOS, то мы бы увидели просто один диск, на который сразу могли бы устанавливать ОС.

Перед нами откроется окно ручной разметки дисков, в левом нижнем углу можно посмотреть количество выделенных дисков (в нашем случае их должно быть 2). Нажимаем на раздел Click here to create them automatically
Тут проходим по каждому созданному разделу (/, /boot, /swap) и в Device Type указываем тип RAID, RAID Level — RAID1 и нажимаем Done
Применяем список настроек — Accept Changes

После успешной установки ОС мы увидим следующее состояние дисков и разделов:

[root@c7-raid ~]# lsblk
NAME      MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda         8:0    0    8G  0 disk
├─sda1      8:1    0  6.2G  0 part
│ └─md125   9:125  0  6.2G  0 raid1 /
├─sda2      8:2    0  823M  0 part
│ └─md126   9:126  0  822M  0 raid1 [SWAP]
└─sda3      8:3    0    1G  0 part
  └─md127   9:127  0 1022M  0 raid1 /boot
sdb         8:16   0    8G  0 disk
├─sdb1      8:17   0  6.2G  0 part
│ └─md125   9:125  0  6.2G  0 raid1 /
├─sdb2      8:18   0  823M  0 part
│ └─md126   9:126  0  822M  0 raid1 [SWAP]
└─sdb3      8:19   0    1G  0 part
  └─md127   9:127  0 1022M  0 raid1 /boot
sr0        11:0    1 1024M  0 rom
[root@c7-raid ~]# cat /proc/mdstat
Personalities : [raid1]
md125 : active raid1 sda1[0] sdb1[1]
      6491136 blocks super 1.2 [2/2] [UU]
      bitmap: 0/1 pages [0KB], 65536KB chunk

md126 : active raid1 sdb2[1] sda2[0]
      841728 blocks super 1.2 [2/2] [UU]

md127 : active raid1 sda3[0] sdb3[1]
      1046528 blocks super 1.2 [2/2] [UU]
      bitmap: 0/1 pages [0KB], 65536KB chunk

unused devices: <none>
[root@c7-raid ~]#

#Исправный диск будет отображаться буквой U, неисправный прочерком (_). Сейчас мы #видим что под каждый раздел создалась отдельная RAID-группа.

Собирать все разделы в RAID необязательно, можно собрать лишь тот, который требуется, например /

Дальнейшее управление RAID-массивом будет происходить через утилиту mdadm:

Установка утилиты mdadm: yum install -y mdadm

В Debian\Ubuntu можно установить командой: sudo apt install -y mdadm

Просмотр всех созданных RAID-массивов: mdadm —examine —scan

[root@c7-raid ~]# mdadm --examine --scan
ARRAY /dev/md/root  metadata=1.2 UUID=f8eaae19:53973f7b:a79fe7da:e0493fea name=c7-raid:root
ARRAY /dev/md/swap  metadata=1.2 UUID=bd51902c:d3a004a1:dd7a3ec2:9b0fc8ae name=c7-raid:swap
ARRAY /dev/md/boot  metadata=1.2 UUID=30b96e90:1b5f1775:232bd954:b28f671f name=c7-raid:boot

#/dev/md/root - адрес символьной ссылки на массив
#metadata=1.2 - используемая версия суперблока
#UUID=f8eaae19:53973f7b:a79fe7da:e0493fea - UUID массива
#name=c7-raid:root - имя массива

Вывод подробной информации о RAID-массиве: mdadm -D /dev/md127

[root@c7-raid md]# mdadm -D /dev/md127
/dev/md127:
           Version : 1.2
     Creation Time : Sun Nov  8 16:10:55 2020
        Raid Level : raid1
        Array Size : 1046528 (1022.00 MiB 1071.64 MB)
     Used Dev Size : 1046528 (1022.00 MiB 1071.64 MB)
      Raid Devices : 2
     Total Devices : 2
       Persistence : Superblock is persistent

     Intent Bitmap : Internal

       Update Time : Sun Nov  8 16:52:55 2020
             State : clean
    Active Devices : 2
   Working Devices : 2
    Failed Devices : 0
     Spare Devices : 0

Consistency Policy : bitmap

              Name : c7-raid:boot  (local to host c7-raid)
              UUID : 30b96e90:1b5f1775:232bd954:b28f671f
            Events : 22

    Number   Major   Minor   RaidDevice State
       0       8        3        0      active sync   /dev/sda3
       1       8       19        1      active sync   /dev/sdb3

Что делать, если RAID-массив деградировал?

Допустим, мы заметили, что один диск у нас вышел из строя. Мы извлекли сбойный диск и установили вместо него новый (с таким же размером)

  1. Сначала проверяем состояние RAID-массива и виден ли новый диск:
[root@c7-raid ~]# lsblk
NAME      MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda         8:0    0    8G  0 disk
├─sda1      8:1    0  6.2G  0 part
│ └─md126   9:126  0  6.2G  0 raid1 /
├─sda2      8:2    0  823M  0 part
│ └─md125   9:125  0  822M  0 raid1 [SWAP]
└─sda3      8:3    0    1G  0 part
  └─md127   9:127  0 1022M  0 raid1 /boot
sdb         8:16   0    8G  0 disk
sr0        11:0    1  906M  0 rom
[root@c7-raid ~]# cat /proc/mdstat
Personalities : [raid1]
md125 : active (auto-read-only) raid1 sda2[0]
      841728 blocks super 1.2 [2/1] [U_]

md126 : active raid1 sda1[0]
      6491136 blocks super 1.2 [2/1] [U_]
      bitmap: 1/1 pages [4KB], 65536KB chunk

md127 : active raid1 sda3[0]
      1046528 blocks super 1.2 [2/1] [U_]
      bitmap: 1/1 pages [4KB], 65536KB chunk

unused devices: <none>

#Видим что появился диск sdb, но на нём нет RAID-масива

Если сбойный диск ещё не извлечен и он числится в RAID-массиве, то необходимо сделать следующие действия:

  • Пометить диск как сбойный (для каждого raid-массива): mdadm /dev/md125 —set-faulty /dev/sdb
  • Удалить диск из каждого RAID-массива: mdadm /dev/md125 —remove /dev/sdb

2. Копируем на новый диск все разделы с рабочего диска (очень важно не перепутать диски местами, сначала идёт диск с которого копируем): sfdisk -d /dev/sda | sfdisk —force /dev/sdb

3. Проверяем, что были созданы идентичные разделы: lsblk

[root@c7-raid ~]# lsblk
NAME      MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda         8:0    0    8G  0 disk
├─sda1      8:1    0  6.2G  0 part
│ └─md126   9:126  0  6.2G  0 raid1 /
├─sda2      8:2    0  823M  0 part
│ └─md125   9:125  0  822M  0 raid1 [SWAP]
└─sda3      8:3    0    1G  0 part
  └─md127   9:127  0 1022M  0 raid1 /boot
sdb         8:16   0    8G  0 disk
├─sdb1      8:17   0  6.2G  0 part
├─sdb2      8:18   0  823M  0 part
└─sdb3      8:19   0    1G  0 part
sr0        11:0    1  906M  0 rom

4. Добавляем диски в RAID-массив:

  • mdadm —manage /dev/md125 —add /dev/sdb2
  • mdadm —manage /dev/md126 —add /dev/sdb1
  • mdadm —manage /dev/md127 —add /dev/sdb3

5. После добавления диска сразу начнётся ребилд массива: cat /proc/mdstat

[root@c7-raid ~]# cat /proc/mdstat
Personalities : [raid1]
md125 : active raid1 sdb2[2] sda2[0]
      841728 blocks super 1.2 [2/2] [UU]

md126 : active raid1 sdb1[2] sda1[0]
      6491136 blocks super 1.2 [2/1] [U_]
      [==========>..........]  recovery = 54.2% (3524608/6491136) finish=0.4min speed=104103K/sec
      bitmap: 1/1 pages [4KB], 65536KB chunk

md127 : active raid1 sdb3[2] sda3[0]
      1046528 blocks super 1.2 [2/1] [U_]
        resync=DELAYED
      bitmap: 0/1 pages [0KB], 65536KB chunk

unused devices: <none>

После успешного ребилда RAID-массивы вернутся в обычное состояние:

[root@c7-raid ~]# cat /proc/mdstat
Personalities : [raid1]
md125 : active raid1 sdb2[2] sda2[0]
      841728 blocks super 1.2 [2/2] [UU]

md126 : active raid1 sdb1[2] sda1[0]
      6491136 blocks super 1.2 [2/2] [UU]
      bitmap: 1/1 pages [4KB], 65536KB chunk

md127 : active raid1 sdb3[2] sda3[0]
      1046528 blocks super 1.2 [2/2] [UU]
      bitmap: 0/1 pages [0KB], 65536KB chunk

unused devices: <none>

Если вдруг загрузчик находится у вас только на одном диске, то необходимо установить загрузчик на этот диск:

# grub-install /dev/sda
# update-grub

Создание RAID-массива без использования системных дисков из ОС

Допустим, в данный сервер мы установили ещё 3 диска одинаковых размеров и хотим собрать из них RAID5 и смонтировать его в ОС:

  1. Находим буквы дисков с одинаковым размером: lsblk | grep 20
[root@c7-raid ~]# lsblk | grep 20
sdb         8:16   0   20G  0 disk
sdd         8:48   0   20G  0 disk
sde         8:64   0   20G  0 disk

2. Добавляем в диски суперблок: mdadm —zero-superblock /dev/sd{b,d,e}

3. Создаём RAID5 из 3 дисков: mdadm —create /dev/md0 —level 5 -n3 /dev/sd{b,d,e}

4. Проверяем, что RAID создан успешно:

[root@c7-raid ~]# cat /proc/mdstat
Personalities : [raid1] [raid6] [raid5] [raid4]
md0 : active raid5 sde[3] sdd[1] sdb[0]
      41908224 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/3] [UUU]

5. Создаём том для LVM (Необязательно, делается для того, чтобы потом было проще увеличить размер): pvcreate /dev/md0

Удаление RAID-массива:

  1. Останавливаем RAID-массив: mdadm -S /dev/md0
  2. Очищаем суперблоки дисков: mdadm —zero-superblock /dev/sd{b,d,e}
  3. Удаляем метаданные и остальную информацию с дисков: wipefs —all —force /dev/sd{b,d,e}

NFS: теория и практика

NFS (Network File System) — протокол, который позволяет пользователям совместно работать с файлами, расположенными на разных компьютерах.

У протокола NFS есть несколько версий:

  • NFSv2 — старая версия, работает только через UDP
  • NFSv3 — работает через TCP и UDP
  • NFSv4 — работает только через TCP

Рекомендуется использовать протокол NFS версии 3 и 4. Разные версии протокола не совместимы друг с другом, но серверы, поддерживающие протокол NFS обычно предоставляют сразу несколько версий протокола.

В NFS версии 2 и 3 нет контроля состояния файлов, после удачного монтирования клиенту выдаётся специальный ключ, который позволяет получить доступ содержимому каталога. Ключ сохраняется после перезагрузки

В NFSv4 нет ключей. Протокол сохраняет состояния файлов; и клиент и сервер сохраняют информацию об открытых файлах и блокировках.

Режимы аутентификации в NFS:

  • AUTH_NONE — без аутентификации
  • AUTH_SYS — работает в NFSv2 и v3, права на каталог ставятся на конкретный UID. При запросе доступа, сервер проверяет свой файл /etc/passwd на наличие UID и смотрит можно ли предоставить доступ.
  • RPCSEC_GSS — работает в NFSv4

Базовая настройка NFS сервера на CentOS 7

  1. Устанавливаем пакеты для работы NFS:
sudo yum install nfs-utils nfs-utils-lib

2. Запускаем службы и добавляем их в автозагрузку

systemctl start rpcbind
systemctl start nfs-server
systemctl start nfs-lock
systemctl start nfs-idmap
systemctl enable rpcbind
systemctl enable nfs-server
systemctl enable nfs-lock
systemctl enable nfs-idmap

3. Открываем порты в firewalld

sudo firewall-cmd --permanent --add-port=111/tcp
sudo firewall-cmd --permanent --add-port=54302/tcp
sudo firewall-cmd --permanent --add-port=20048/tcp
sudo firewall-cmd --permanent --add-port=2049/tcp
sudo firewall-cmd --permanent --add-port=46666/tcp
sudo firewall-cmd --permanent --add-port=42955/tcp
sudo firewall-cmd --permanent --add-port=875/tcp
sudo firewall-cmd reload

4. Создаём папку /nfs-share к которой будем предоставлять доступ

mkdir /nfs-share

5. Настройки доступа к NFS-серверу лежат в файле /etc/exports. Давайте настроим его: vi /etc/exports

Добавим в файл следующую строку:

/nfs-share 192.168.223.0/24(rw,sync,no_root_squash,no_all_squash)

Разберем параметры, указанные в этой строке:

  • /nfs-share — адрес папки, к которой будет предоставляться доступ
  • 192.168.223.0/24 — сеть. из которой будут приниматься запросы. Вместо адреса сети можно указать FQDN-клиента, @имя группы, имя пользователя.
  • rw — разрешение на чтение и запись (также можно указать ro — только чтение)
  • sync — синхронизация указанной директории (файлы не зависают в оперативной памяти, а сразу записываются на сервер)
  • no_root_squash — включение root-привилегий (По умолчанию, сервер NFS перехватывает входящие запросы, посланные от имени пользователя root (UID=0) и подменяет пользователя на nobody (UID=65534). Этот приём называется поражением в правах — squashing root. Если нужно, чтобы у root-пользователя были все права, то необходимо указать параметр no_root_squash)
  • no_all_squash — включение пользовательской авторизации

Дополнительные параметры можно найти на официальной MAN-страницы NFS — https://linux.die.net/man/5/nfs

6. После добавления информации в файл /etc/exports, необходимо назначить права на папку /nfs-share. Например: создадим пользователя bill и разрешим чтение и запись только для root и bill, остальным разрешим только чтение.

[root@centos ~]# useradd bill
[root@centos ~]# passwd bill
[root@centos ~]# passwd bill
Changing password for user bill.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@centos ~]# cat /etc/passwd | grep bill
bill:x:1001:1001::/home/bill:/bin/bash
[root@centos ~]# cat /etc/group | grep bill
bill:x:1001:
[root@centos ~]# chmod 775 /nfs-share
[root@centos ~]# ls -l / | grep nfs-share
drwxrwxr-x    2 root   root      6 Aug 30 18:52 nfs-share
[root@centos ~]# chown root:bill /nfs-share
[root@centos ~]# ls -l / | grep nfs-share
drwxrwxr-x    2 root   bill      6 Aug 30 18:52 nfs-share
[root@centos ~]#

7. Перезапускаем службу NFS: service nfs-server restart

На этом настройка NFS-сервера закончена.

Настройка NFS-клиента:

  1. Устанавливаем пакеты NFS-клиента:
yum install nfs-utils nfs-utils-lib

2. Создаём папку /mnt/nfs в которую будем монтировать папку /nfs-share

[root@vtl ~]# mkdir /mnt/nfs
[root@vtl ~]# mount -t nfs 192.168.223.204:/nfs-share /mnt/nfs
[root@vtl ~]# ls -l /mnt/nfs
total 8
-rw-r--r--. 1 root root  7 Aug 30 19:29 test
-rw-r--r--. 1 root root 10 Aug 30 19:30 test2
[root@vtl ~]# cd /mnt/nfs
[root@vtl nfs]# rm test2
rm: remove regular file ‘test2’? y
[root@vtl nfs]#

Монтирование прошло успешно. Мы даже смогли удалить файл, так как разрешили пользователям root и bill читать и изменять файлы. Давайте создадим пользователя ivan и попробуем подключиться от его имени.

[ivan@vtl root]$ cd /mnt/nfs
[ivan@vtl nfs]$ ls
test
[ivan@vtl nfs]$ rm test
rm: remove write-protected regular file ‘test’? y
[ivan@vtl nfs]$ ls
[ivan@vtl nfs]$ cd ..
[ivan@vtl mnt]$ ls -l
total 0
drwxr-xr-x. 2 root root 6 Aug 10 09:51 arctape
drwxr-xr-x. 2 root root 6 Sep 26  2019 hgfs
drwxrwxr--. 2 root ivan 6 Aug 30 19:37 nfs
[ivan@vtl mnt]$ cat /etc/passwd | grep ivan
ivan:x:1001:1001::/home/ivan:/bin/bash
[ivan@vtl mnt]$

Как мы видим, от пользователя ivan также получилось удалить файл. Проблема заключается в том, что во время проверки доступа проверяется не имя пользователя а его UID. Давайте поменяем UID пользователя ivan и попробуем ещё раз что-нибудь удалить:

[root@vtl ~]# vi /etc/passwd
[root@vtl ~]# vi /etc/group
[root@vtl ~]# cat /etc/passwd | grep ivan
ivan:x:1011:1011::/home/ivan:/bin/bash
[root@vtl ~]# cat /etc/group | grep ivan
ivan:x:1011:
[root@vtl ~]#
[root@vtl nfs]# su ivan
bash: /home/ivan/.bashrc: Permission denied
bash-4.2$ ls
test3
bash-4.2$ rm test3
rm: remove write-protected regular file ‘test3’? y
rm: cannot remove ‘test3’: Permission denied
bash-4.2$

Монтирование с помощью команды mount будет работать до перезагрузки системы. Если требуется, чтобы папка монтировалась автоматически во время старта системы, то необходимо добавить строку в файл /etc/fstab: vi /etc/fstab

192.168.223.204:/nfs-share /mnt/nfs nfs rw,sync,hard,intr 0 0

После перезагрузки системы папка должна автоматически примонтироваться. Если не получается перезагрузить сервер, а проверить изменения нужно, то можно ввести команду: sudo mount -fav

Важно помнить при монтировании каталога используются только клиент и сервер, нельзя монтировать каталоги по очереди между тремя серверами.

Команда для размонтирования папки: umount /mnt/nfs

Как решить проблемы с размонтированием папки?

Самая частая ошибка при размонтировании — это device is busy. Я часто забываю выйти из каталога, который хочу отмонтировать и мне достаточно перейти в другой каталог командой cd.

Если проблемы более серьёзные, то можно попробовать следующие варианты:

1) Размонтировать с параметром force: umount -f /mnt/nfs

2) Если предыдущая команда не помогла, то находим процесс, которым занята папка, а потом убиваем его:

[root@vtl ~]# ps aux | grep /mnt/data
root      11251  0.0  0.0 112712   968 pts/0    S+   20:00   0:00 /mnt/data
[root@vtl ~]# kill 11251 #или вводим kill -9 11251
[root@vtl ~]# umount -f /mnt/nfs

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

Offline обновление CentOS

Обычно с обновлением linux, проблем не возникает: написал в командной строке yum update, подождал, перезагрузил и готово. Но бывают случаи, когда надо обновить до конкретной версии ядра или просто на серверах нет интернета. В такой момент очень помогает офлайн обновление.

Давайте попробуем на примере обновить CentOS версии 1611 до версии 1708:

  1. Проверяем текущую версию ОС
[root@test ~]# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

2. Подключаем образ ОС с версией 1708 и монтируем его в папку /mnt/iso

[root@test ~]# mkdir /mnt/iso
[root@test ~]# lsscsi
[0:0:0:0]    disk    ATA      VBOX HARDDISK    1.0   /dev/sda
[0:0:1:0]    cd/dvd  VBOX     CD-ROM           1.0   /dev/sr0
[root@test ~]# mount -t iso9660 -o ro /dev/sr0 /mnt/iso
[root@test ~]# ls -l /mnt/iso

#В данном примере мы монтируем физический диск, вставленный в сервер. 
#Если на сервере просто лежит ISO-образ, то команда монтирования будет следующей
[root@test ~]# mount -o loop <iso_name> /mnt/iso

3. Проверка числового значения, находящегося в первой строке файла .discinfo

[root@test iso]# head -n1 /mnt/iso/.discinfo
1504618416.850667

4. Переходим в каталог /etc/yum.repos.d/ и временно переносим от туда все каталоги с текущими репозиториями в каталог /root/old_repo:

[root@test iso]# cd /etc/yum.repos.d/
[root@test yum.repos.d]# ls -la
total 40
drwxr-xr-x.  2 root root  187 Nov 15  2016 .
drwxr-xr-x. 78 root root 8192 Jul 30 10:59 ..
-rw-r--r--.  1 root root 1664 Nov 29  2016 CentOS-Base.repo
-rw-r--r--.  1 root root 1309 Nov 29  2016 CentOS-CR.repo
-rw-r--r--.  1 root root  649 Nov 29  2016 CentOS-Debuginfo.repo
-rw-r--r--.  1 root root  314 Nov 29  2016 CentOS-fasttrack.repo
-rw-r--r--.  1 root root  630 Nov 29  2016 CentOS-Media.repo
-rw-r--r--.  1 root root 1331 Nov 29  2016 CentOS-Sources.repo
-rw-r--r--.  1 root root 2893 Nov 29  2016 CentOS-Vault.repo
[root@test yum.repos.d]# 
[root@test yum.repos.d]# 
[root@test yum.repos.d]# mkdir /root/old_repo
[root@test yum.repos.d]# mv *.repo /root/old_repo/
[root@test yum.repos.d]# ls -la
total 12
drwxr-xr-x.  2 root root    6 Jul 30 11:19 .
drwxr-xr-x. 78 root root 8192 Jul 30 10:59 ..
[root@test yum.repos.d]#

5. Создаём файл с расширением .repo (iso.repo) vi iso.repo и указываем его параметры:

[offline_repo] 
#В media_id указываем значение, которое получили в 3 пункте
mediaid=1504618416.850667
#name должно совпадать с именем репозитория в квадратных скобках
name=offline_repo
#Указываем адрес до смонтированного каталога
baseurl=file:///mnt/iso/
#Указываем наш ключ
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#Параметр показывает что к этому репозиторию можно обращаться
enabled=1 
#Включить проверку ключа
gpgcheck=1

6. Запускаем процесс обновления: yum update

7. После успешного обновления проверяем текущую версию ОС:

[root@test yum.repos.d]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

8. Отключаем диск с образом, перезагружаем ОС, возвращаем на место старые репозитории, удаляем файл с оффлайн репозиторием:

[root@test ~]# umount /mnt/iso
[root@test ~]# reboot

[vagrant@test ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@test ~]# rm /etc/yum.repos.d/iso.repo
rm: remove regular file ‘/etc/yum.repos.d/iso.repo’? y
[root@test ~]#

#После удаления файла с нашим репозиторием в каталоге должны остаться файлы с другими репозиториями. У меня они подтянулись с перезагрузкой
[root@test ~]# ls -l /etc/yum.repos.d/
total 28
-rw-r--r--. 1 root root 1664 Aug 30  2017 CentOS-Base.repo
-rw-r--r--. 1 root root 1309 Aug 30  2017 CentOS-CR.repo
-rw-r--r--. 1 root root  649 Aug 30  2017 CentOS-Debuginfo.repo
-rw-r--r--. 1 root root  314 Aug 30  2017 CentOS-fasttrack.repo
-rw-r--r--. 1 root root  630 Aug 30  2017 CentOS-Media.repo
-rw-r--r--. 1 root root 1331 Aug 30  2017 CentOS-Sources.repo
-rw-r--r--. 1 root root 3830 Aug 30  2017 CentOS-Vault.repo
[root@test ~]#

Если после перезагрузки файлы не вернулись обратно в каталог — просто перенестите их из каталога /root/old_repo следующей командой:

mv /root/old_repo/*.repo /etc/yum.repos.d/

Если просто ввести команду yum update, то ОС обновится просто до последней версии репозитория.

Изучаем keepalive

Keepalived — сервис, для настройки плавающего ip-адреса. В случае выхода из строя одного сервера, плавающий ip-адрес будет сразу переброшен на другой сервер.

Keepalive использует следующие протоколы:

  • VRRP разделяет устройства на Master и Backup, плавающий адрес хранится на всегда на Мастере.
  • BFD — протокол быстрого обнаружения неисправных линков. Сервера постоянно обмениваются между собой Hello-пакетами. Если пакет не приходит, то протокол отправляет информацию в VRRP и плавающий адрес перелетает на другой сервер. На практике, протокол BFD может определить неисправный линк менее чем за одну секунду.
  • IP Multicast

Настройка Keepalived на CentOS 7 (SELinux отключен):

Требования для настройки keepalived: сервера должны находиться в одном VLAN.

Есть 2 сервера: Node1 (192.168.223.222, Master) и Node2 (192.168.223.221, Slave). Настроим плавающий ip 192.158.223.223. В keepalived можно добавить и больше серверов, но все остальные должны иметь роли Backup.

  1. На node1 и node2 установим keepalived и добавим в автозагрузку, разрешим трафик keepalived в firewalld:
yum install keepalived
systemctl enable keepalived
firewall-cmd --add-rich-rule='rule protocol value="vrrp" accept' --permanent
firewall-cmd --reload

2. На node1 внесём изменения в файл /etc/keepalived/keepalived.conf

vi /etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {
   router_id uMASTER
}
#Указываем название задания (VI_1)
vrrp_instance VI_1 {
    #Указываем роль сервера
    state MASTER
    #Указываем имя интерфейса, к которому будет привязан VRRP инстанс
    interface ens33
    #Указываем id (1-255) роутера, на остальных серверах значение должно остаться таким же
    virtual_router_id 230
    #Ставим приоритет. У Master приоритет должен быть выше чем у Backup. 
    #Значение по умолчанию=100
    priority 102                       
    #Период проверки доступности сервера. Значение по умолчанию=1
    advert_int 1
    authentication {
        #Указываем тип аутентификации
        auth_type PASS
        #Указываем пароль для аутентификации
        auth_pass YOURPASSWORD          
    }


   virtual_ipaddress {
       #Указываем ip-адрес, имя устройства и метку устройства
       192.168.223.223/24 dev ens33 label ens33:0
    }
}

3.На node2 внесем изменения в файл /etc/keepalived/keepalived.conf

vi /etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {
   router_id uBACKUP
}

vrrp_instance VI_1 { #Имя задания должно совпадать
    state BACKUP 
    interface ens33
    virtual_router_id 230
    priority 101                       
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass YOURPASSWORD
    }


   virtual_ipaddress {
       192.168.223.223/24 dev ens33 label ens33:0
    }
}

4. На node1 и node2 перезапускаем службу командой service keepalived restart

5. Проверяем, что на Master сервере появился новый сетевой интерфейс ens33:0

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

6. Теперь можно проверить работу самого keepalive. Поставим постоянный пинг до адреса 192.168.223.223 и немного подождав выключим node1. Мы увидим небольшой разрыв и далее удачный пинг:

При сбое node1 плавающий ip перелетит на node2. Если работа node1 восстановится, то keepalived переведет плавающий ip обратно на node1.

NTP-севера и клиенты

NTP-сервер — это сервер точного времени. К нему подключаются NTP-клиенты, чтобы синхронизировать своё время.

Перед тем, как изучать NTP, давайте немного рассмотрим теорию, как вообще работает время в Linux:

В ОС Linux есть два типа часов:

  • Системные часы — время операционной системы. Предоставляется ядром linux и реализуется простым подсчётом количества секунд от 0 часов 01.01.1970. NTP работает с системными часами! Посмотреть время системных часов можно командой: date
  • Аппаратные часы — часть материнской платы. Время, которое отображается в BIOS. Посмотреть время аппаратных часов: hwclock

При включении сервера, обычно ядро linux запрашивает время у аппаратных часов и отправляет его в системные часы.

Внутри самой ОС аппаратное время можно назначить системному и наоборот:

  • Назначить системное время аппаратному: hwclock —systohc
  • Назначить аппаратное время системному: hwclock —hctosys

Протокол NTP имеет иерархическую структуру, которая состоит из уровней:

  • Эталонные часы от которых начинается цепочка, обычно имеют уровень 0. К часам нельзя подключиться по ip, поэтому уровня 0 в NTP не существует.
  • К данным часам подключается сервер, у которого есть внешний адрес, и, иногда доменное имя. У сервера будет уровень 1.
  • Сервер который мы настраиваем у себя в локальной сети будет являться клиентом сервера с уровнем 1 и иметь уровень 2.
  • И т.д.

Если сервер уровня 1 перестаёт работать, то время нам будет отдавать сервер уровня 2. Максимальное количество уровней — 256.

Настройка NTP-сервера на CentOS 7

Предварительные условия: установлены обновления, отключен SElinux, работает firewalld.

  1. Установим ntpd демон: yum install -y ntp
  2. Очень важно чтобы на сервере работал только один NTP-демон. Остановим и уберём из автозагрузки демон chronyd:
systemctl stop chrony
systemctl disable chrony

3. Разрешим трафик NTP в firewalld:

firewall-cmd --zone=public --add-service=ntp --permanent
firewall-cmd --zone=public --add-port=123/udp --permanent
firewall-cmd --reload

#Проверим что порт 123 открыт
netstat -tulpn | grep 123
udp        0      0 192.168.200.200:123      0.0.0.0:*                           14943/ntpd
udp        0      0 127.0.0.1:123           0.0.0.0:*                           14943/ntpd
udp        0      0 0.0.0.0:123             0.0.0.0:*                           14943/ntpd
udp6       0      0 ::1:123                 :::*                                14943/ntpd
udp6       0      0 :::123                  :::*                                14943/ntpd

4. Устанавливаем часовой пояс (Москва, +3):timedatectl set-timezone Europe/Moscow

5. Вносим изменения в файл /etc/ntp.conf

vi /etc/ntp.conf

#Указываем файл, в котором будет храниться частота смещения времени
driftfile /var/lib/ntp/drift

#Устанавливаем запрет на подключение к серверу из вне
restrict default nomodify notrap nopeer noquery

#Разрешаем доступ с localhost
restrict 127.0.0.1
restrict ::1

#Разрешаем запрашивать время клиентов из сети 192.168.200.0/24
restrict 10.29.7.0 mask 255.255.255.0 nomodify notrap

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server ntp1.stratum2.ru iburst
server ntp2.stratum2.ru iburst
server ntp3.stratum2.ru iburst
server ntp4.stratum2.ru iburst
#Параметры серверов: 
# iburst - отправка сразу нескольких пакетов к серверу
# true - отмечаем сервер как правильный

#Защита NTP-сервера от уязвимости CVE-2013-5211
disable monitor

#Указываем файл в который будут отправляться логи.
logfile /var/log/ntp.log

#Остальные параметры можно оставить как есть или удалить. 

6. Запускаем службу ntpd и добавляем её в автозагрузку:

systemctl start ntpd
systemctl enable ntpd

7. Проверяем, как сервер синхронизировался с внешним сервером:

ntpq -p 
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*unknown230-n1.h 88.147.254.229   2 u  242 1024  377   21.715   -0.402   0.202
+n1.sigma.d6.hsd 88.147.254.229   2 u 1020 1024  377   21.398    0.173   0.473
+ns1.hsdn.org    88.147.254.227   2 u  892 1024  377   21.658   -0.463   0.571

Столбцы означают следующую информацию:

  • remote — имя хоста или адрес NTP-сервера
  • refid — адрес вышестоящего сервера
  • st — уровень (stratum) сервера
  • t — тип клиента (u-unicast, m-multicast)
  • when — прошло секунд от последней синхронизации
  • poll — период синхронизации в секундах
  • reach — состояние доступности сервера; после восьми успешных попыток синхронизации значение этого параметра становится равным 377
  • delay — задержка ответа сервера
  • ofset — разница во времени между серверами (- часы отстают, + часы спешат)
  • jitter — джиттер

Слева от перечисленных серверов располагаются символы, означающие состояние NTP-сервера:

  • * пригоден для обновления
  • + рекомендован для обновления
  • не рекомендуется синхронизироваться
  • x сервер недоступен

Настройка NTP-клиента:

  1. Устанавливаем ntp: yum install -y ntp
  2. Остановим и уберём из автозагрузки демон chronyd:
systemctl stop chrony
systemctl disable chrony

3. Разрешим трафик NTP в firewalld:

firewall-cmd --zone=public --add-service=ntp --permanent
firewall-cmd --zone=public --add-port=123/udp --permanent
firewall-cmd --reload

#Проверим что порт 123 открыт
netstat -tulpn | grep 123
udp        0      0 192.168.200.1:123       0.0.0.0:*                           14943/ntpd
udp        0      0 127.0.0.1:123           0.0.0.0:*                           14943/ntpd
udp        0      0 0.0.0.0:123             0.0.0.0:*                           14943/ntpd
udp6       0      0 ::1:123                 :::*                                14943/ntpd
udp6       0      0 :::123                  :::*                                14943/ntpd

4. Устанавливаем часовой пояс (Москва, +3):timedatectl set-timezone Europe/Moscow

5. Вносим изменения в файл /etc/ntp.conf

vi /etc/ntp.conf

#Указываем файл, в котором будет храниться частота смещения времени
driftfile /var/lib/ntp/drift

#Устанавливаем запрет на подключение к серверу из вне
restrict default nomodify notrap nopeer noquery

#Разрешаем доступ с localhost
restrict 127.0.0.1
restrict ::1

#Разрешаем запрашивать время клиентов из сети 192.168.200.0/24
restrict 10.29.7.0 mask 255.255.255.0 nomodify notrap

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 192.168.200.200 iburst true
server 192.168.200.201 iburst

#Параметры серверов: 
# iburst - отправка сразу нескольких пакетов к серверу
# true - отмечаем сервер как правильный
# true используют когда указано 2 сервера, чтобы не было конфликта при синхронизации

#Защита NTP-сервера от уязвимости CVE-2013-5211
disable monitor

#Указываем файл в который будут отправляться логи.
logfile /var/log/ntp.log

6. Запускаем службу ntpd и добавляем её в автозагрузку:

systemctl start ntpd
systemctl enable ntpd

7. Проверяем, как сервер синхронизировался с внешним сервером:

ntpq -p 
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+192.168.200.200 88.147.254.235   3 u  248  512  377    0.495   -0.156   0.050
*192.168.200.201 88.147.254.237   3 u  247  512  377    0.297    0.119   0.067

На этом настройка NTP-сервера и клиента завершена.

Если вы планируете разворачивать NTP-сервера на виртуальной машине (например я использую vmWare ESXi), то стоит учитывать что гипервизор иногда синхронизирует время на гостевой машине со своими часами. Если при синхронизации будет большой разрыв, то демон перестанет работать, и в логах можно будет увидеть следующие ошибки:

  • При запросе состояния (service ntpd status):
    • ntp systemd[1]: ntpd.service: main process exited, code=exited, status=255/n/a
    • ntp systemd[1]: Unit ntpd.service entered failed state.
    • ntp systemd[1]: ntpd.service failed.
  • При просмотре логов (less /var/log/ntp.log):
    • 0.0.0.0 0617 07 panic_stop -2106 s; set clock manually within 1000 s

Одним из вариантов решения данной проблемы будет полное отключение синхронизации времени. Более подробно это рассказывается тут.

Если кратко, то помимо отключения снятия галочки time synchronization в настройках ВМ, необходимо выключить машину и дописать следующие параметры: VM Options — Advanced options — Configuration Parameters — Edit Configuration

NameValue
tools.syncTime0
time.synchronize.continue0
time.synchronize.restore0
time.synchronize.resume.disk0
time.synchronize.shrink0
time.synchronize.tools.startup0
time.synchronize.tools.enable0
time.synchronize.resume.host0

Изучаем Git и GitHub

Git — это система контроля версий. Позволяет отслеживать изменения в файле от откатить файл к предыдущим значениям.

Git сохраняет только изменения, для хранения изменений используются хэш-суммы, которые записываются в БД Git.

Установка и первоначальная настройка Git

sudo apt install git   
git config --global user.name "Alex"  
git config --global user.email "aliesha1994@rambler.ru"   

Далее необходимо создать собственный git-репозиторий и выполнить инициализацию

mkdir project
cd project
git init

Команда git init инициализирует репозиторий и создаёт папку .git в которой будет храниться структура репозитория. Далее, можно создать файл, добавить его в git внести изменения и сделать commit.

vim document
git status

После добавления файла, можно проверить статус командой git status

В данный момент, команда сообщает что найден один файл (document), который не будет отслеживаться. Далее, добавляем этот файл в git и проверяем статус.

git add document
git status

Добавить одновременно все изменённые файлы: git add -u

Теперь статус файла отслеживаемый, можно сделать commit (сохранение версии)

git commit -m "Add document file"

Commit файла завершен, если далее понадобится опять внести в него изменения, то необходимо снова добавить его в git и сделать commit

vim document
git add document
git commit -m "Edit document file"

Посмотреть историю изменений файла: git log

Если потребуется восстановить файл к одной из предыдущих версий, необходимо воспользоваться командой git revert <хэш-функция изменения>. Если в версии будет несколько файлов, то они вернутся в исходное состояние одновременно!

Проверка несохраненных изменений: git diff

В Git есть понятие веток, их используют если git-проект большой и с ним работает несколько человек. Если проект простой, то работа идёт только в главной ветке master.

Создание новой ветки (line) и переход в неё:

git branch line
git checkout line

Созданные файлы, к которым был применён commit будут отображаться только в данной ветке:

Работа с GitHub

Для начала работы с GitHub, необходимо создать учётную запись и сделать первый репозиторий, далее к нему можно будет подключаться из терминала.

GitHub поддерживает те же самые команды что и Git, но добавляются команды работы с удалённым репозиторием.

Скачиваем репозиторий себе в ОС, переходим в скаченную папку, заходим в требуемую ветку (если есть несколько веток) и проверяем содержимое:

git clone https://github.com/tv1n94/infrastructure.git
cd infrastructure
git checkout scripts
ls -l

Далее можно создать файл или изменить существующий, после чего необходимо добавить файл в git, сделать commit и отправить файлы обратно на сервер(потребуется логин и пароль от GitHub), после чего выйдет сообщение об успешной загрузки:

nano README.md
git add README.md
git commit -m "Edit README.md"
git push

Повторно забрать изменения с сервера можно с помощью команды git pull