Pull to refresh

Проект юного DevOps Глава 1: Введение и подготовка стенда

Level of difficultyMedium
Reading time16 min
Views16K

В данной серии статей описан процесс создания первого pet-проекта для начинающего инженера в DevOps:

Глава 1: Введение и подготовка стенда

Глава 2: Настройка центра сертификации и репозитория

Глава 3: Настройка OpenVPN

Глава 4: Настройка мониторинга

Друзья, хочу ответить на комментарии об отсутствии в данной серии статей инструментов DevOps - Terraform, Ansible, Kubernetes, GitLab CI/CD и прочих инструментов. Полностью согласен с тем, что DevOps без вышеупомянутых инструментов существовать не может.

Данная серия статей является отправной точкой в изучении DevOps и уверен, что именно начинающим инженерам данный материал точно будет полезен. Здесь большой акцент сделан на написании скриптов. Цель данного pet-проекта - практическое ознакомление с Linux перед тем как двигаться дальше в DevOps - именно поэтому название «Проект юного DevOps». В планах написание следующей серии статей уже с углублением в DevOps и его инструменты.

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

В процессе настройки мы пройдем через следующие этапы:

  • настроим лабораторный стенд на хостинге;

  • настроим удостоверяющий центр (или CA) с помощью Easy-RSA;

  • настроим репозиторий для хранения deb-пакетов с помощью Aptly;

  • настроим OpenVPN-сервер;

  • настроим систему мониторинга Prometheus и систему визуализации данных Grafana;

  • соберем собственные пакеты с программами;

  • напишем bash-скрипты для автоматизации процесса развертывания всех сервисов.

Docker в данном проекте использовать не будем.

Лабораторный стенд будет выглядеть следующем образом:

Логическая топология стенда
Логическая топология стенда

Стенд будет состоять из 4-х виртуальных машин (далее vm):

  • VPN - обеспечивает сервис шифрования данных, скрытие IP-адреса, удаленный доступ и защиту от кибератак, создавая безопасное и конфиденциальное подключение пользователей к интернету или частным сетям

  • CA - выдает и поддерживает цифровые сертификаты для подтверждения личности, управляя их статусом и обеспечивая безопасность обмена цифровой информацией

  • Monitor - обеспечивают комплексное решение для сбора, хранения, визуализации и анализа метрик, что позволяет эффективно отслеживать и управлять производительностью и состоянием системы

  • Repo - это репозиторий, который представляет собой центральное место, где пользователи операционных систем Linux могут находить, загружать и обновлять программы, обеспечивая удобное управление ПО на своих устройствах.

Итак приступим!


Работа в интерфейсе облачного провайдера

Для реализации проекта может быть достаточно использования VirtualBox или VMware, но для хорошей практики лучше развернуть инфраструктуру на хостинге. Исторически сложилось так, что я использую timeweb.cloud, вы, в свою очередь, можете выбрать любого другого провайдера, который придется вам по душе.

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

После регистрации мы получим доступ к личному кабинету и сможем приступить к созданию виртуальных машин (или «облачных серверов» в терминологии timeweb.cloud).

Генерация ssh-ключей

Для подключения к виртуальным машинам мы будем использовать протокол SSH, который имеет несколько возможностей авторизации на сервере:

  • авторизация по логину и паролю

  • авторизация по ssh-ключу

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

Сгенерируем пару ssh-ключей в консоли на своей локальной машине (у меня Windows):

ssh-keygen -t ed25519 -C twcvm -N password -f C:\Users\justn/.ssh/twcvm
Опции команды ssh-keygen

-t: Указывает алгоритм ключа, в данном случае, это Ed25519.

-C: Устанавливает комментарий к ключу. В данном случае, «twcvm» будет использован как комментарий.

-N: Устанавливает пароль для защиты закрытого ключа. Вместо "password" вы должны ввести фактический пароль.

-f: Указывает файл, в который следует сохранить закрытый ключ. Здесь используется полный путь «C:\Users\justn/.ssh/twcvm». Пожалуйста, убедитесь, что указанный каталог существует, или измените путь по вашему усмотрению.

Таким образом, команда ssh-keygen создаст новую пару ключей Ed25519 с комментарием "twcvm", установит пароль для закрытого ключа и сохранит ключи в указанном файле.

В результате мы получим два ключа - открытый и закрытый:

C:\Users\justn\.ssh>dir
twcvm
twcvm.pub

Как описано в статье «Памятка пользователям ssh»:

Структура ssh-ключа:

~/.ssh/id_rsa.pub — открытый ключ. Его копируют на сервера, куда нужно получить доступ.

~/.ssh/id_rsa — закрытый ключ. Его нельзя никому показывать. Если вы в письмо/чат скопипастите его вместо pub, то нужно генерировать новый ключ. (Я не шучу, примерно 10% людей, которых просишь дать ssh-ключ постят id_rsa, причём из этих десяти процентов мужского пола 100%).

Как настроить автоматическую аутентификацию по ssh-ключу?

Настройка SSH Agent на Windows

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

SSH Agent может хранить закрытые ключи и предоставлять их в контексте безопасности пользователя. Запустим службу ssh-agent и настроим автоматический запуск в консоли PowerShell:

Set-service ssh-agent -StartupType 'Automatic'
Start-Service ssh-agent

Добавим закрытый ключ в базу ssh-agent:

ssh-add "C:\Users\justn/.ssh/twcvm"

Для настройки SSH Agent на Linux и Mac интернет в помощь.

Теперь загрузим публичный ключ на хостинг для последующей передачи его на виртуальные машины:

Заметка

Записать публичный ключ можно на vm в ручном режиме в файл (~/.ssh/authorized_keys) в домашней директории пользователя, через которого планируется авторизация.

1) Перейдем во вкладку «SSH-ключи», затем «Добавить»:

2) Добавим открытый ключ:

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

Создание виртуальных машин

timeweb.cloud предоставляет функционал создания «Проектов» - это позволяет группировать свои vm в различные группы. Я воспользовался данным функционалом и создал проект «Хабракадабра» - в нем и буду хранить все vm в рамках данного проекта.

Итак процесс создания vm:

1) Перейдем во вкладку проекта, нажмем «Создать», затем выберем «Облачный сервер»:

2) Выберем параметры для новой vm:

  • Образ операционной системы Ubuntu 22.04

  • Регион Санкт-Петербург

  • Конфигурация:

    • CPU 1 x 3.3 ГГц

    • RAM 1 Гб

    • NVMe 15 Гб

    • Канал 200 Мбит/с

  • Без дополнительных услуг

Данную процедуру необходимо повторить 4 раза.

В результате мы получим готовые к работе виртуальные машины:

По умолчанию на новой vm настроен единственный пользователь root.

Настройка приватной сети

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

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

Процесс настройки приватной сети:

1) Перейдем во вкладку «Сети», затем выберем «Добавить»:

2) Выберем параметры для новой приватной сети:

  • регион Санкт-Петербург

  • Подсеть IPv4 10.0.0.0/24

  • Имя сети private

В результате мы получим новую приватную сеть, в которую необходимо добавить наши новые vm:

1) Перейдем в нашу приватную сеть из списка сетей, затем выберем «Добавить»:

2) Перейдем в раздел «Существующий» и в выпадающем меню поочередно выберем созданных ранее vm:

В результате за каждым публичным ip-адресом будет закреплен адрес из приватной сети:

В хостинге timeweb.cloud приватная сеть реализована через NAT - на интерфейсе самой vm мы будем видеть только приватный адрес.

Регистрация доменного имени

Теперь зарегистрируем свое собственное доменное имя для нашего проекта - это позволит нам немного более удобно работать с нашими vm, а именно подключаться к машинам и сервисам не по ip-адресу, а по «красивому» (или не очень) доменному имени, что позволит легче различать машины между собой.

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

1) Перейдем во вкладку «Домены», затем выберем «Купить домен»:

2) Введем желаемое доменное имя и если оно не занято, то мы сможем его зарегистрировать:

В своем проекте я буду использовать доменное имя «justnikobird.ru»

Настройка поддоменов

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

1) Перейдем во вкладку «Домены», затем в блоке нашего доменного имени выберем кнопку «Поддомены»:

2) Выберем «Добавить», и в открывшемся окне введем имя поддомена и выберем соответствующую ему vm:

В результате мы успешно привязали поддомены к vm:

Как сократить доменное имя при подключении к vm?

Файл hosts

Файл hosts — текстовый документ, который содержит в себе информацию о домене и IP-адресе, который ему соответствует. Файл hosts появился во времена зарождения Интернета (ARPANET) и служил неким маршрутизатором, пока на замену ему не пришла служба DNS. Но до сих пор он не утратил важности и по-прежнему используется как инструмент, который обладает приоритетом перед обращением к DNS-серверам.

Где находится файл hosts

Путь к папке, где лежит файл hosts, зависит от операционной системы, которая установлена на вашем компьютере:

  • Windows XP, 2003, Vista, 7, 8, 10 — c:\windows\system32\drivers\etc\hosts

  • Linux, Ubuntu, Unix, BSD — /etc/hosts

  • MacOS — /private/etc/hosts

Пример настройки моего файла hosts на Windows:

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#	127.0.0.1       localhost
#	::1             localhost
90.156.211.234	ca
90.156.210.97	vpn
87.249.54.20	monitor
85.92.111.123	repo

Мы подготовили vm к работе:

Domain name

Description

Public address

Privat address

ca.justnikobird.ru

Certificate Authority (CA)

90.156.211.234

10.0.0.4

vpn.justnikobird.ru

OpenVPN server

90.156.210.97

10.0.0.5

monitor.justnikobird.ru

Prometheus + Grafana

87.249.54.20

10.0.0.6

repo.justnikobird.ru

Repo server

85.92.111.123

10.0.0.7


Первичная настройка vm

При первичном подключении к vm нам необходимо выполнить следующие настройки:

  • создать нового пользователя с sudo правами;

  • отредактировать prompt statement;

  • отключить ipv6;

  • настроить ssh;

  • настроить iptables.

Приступим!

Подключимся к vm «ca» используя пользователя root:

ssh root@ca

Если ранее все настроили правильно, то авторизация на машине пройдет автоматически, но если по какой-то причине по ssh-ключу подключиться не удастся, то пароль от пользователя root можно найти в личном кабинете на сайте хостинга - необходимо выбрать интересующую vm, перейти во вкладку «Доступ» и скопировать root-пароль.

Создание нового пользователя

Создать пользователя можно одной командой.

Для примера создим пользователя «nikolay» c паролем «password»:

useradd -p $(openssl passwd -1 "password") "nikolay" -s /bin/bash -m -G sudo

Перенесем ssh-ключи в домашнюю директорию нового пользователя и сменим владельца файлов:

cp -r /root/.ssh/ /home/nikolay/ 
chown -R nikolay:nikolay /home/nikolay/.ssh/

Зайдем в систему под новым пользователем не выходя из сессии:

su nikolay

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

Настройка часового пояса

Выполним настройку часового пояса:

sudo timedatectl set-timezone Europe/Moscow

Перезагрузим сервис времени:

sudo systemctl restart systemd-timesyncd.service

Проверим корректность настроек времени:

timedatectl

Время успешно синхронизировано:

               Local time: Fri 2024-01-26 19:15:38 MSK
           Universal time: Fri 2024-01-26 16:15:38 UTC
                 RTC time: Fri 2024-01-26 16:15:38
                Time zone: Europe/Moscow (MSK, +0300)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Корректировка prompt statement

Prompt Statement (дословно переводится как «пригласительное заявление») - если кратко, то это информация, которую мы видим в начале строки в bash.

При подключении к vm вы наверное заметили, что информативность PS оставляет желать лучшего:

nikolay@1930349-justnikobird:~$

Понятно, что мы зашли под пользователем «nikolay», а дальше не самая полезная информация - сейчас мы это исправим.

Предлагаю после знака «@» выводить название vm, чтобы было понятно куда мы зашли.

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

Для изменения prompt statement пользователя «nikolay», необходимо откорректировать файл «/home/nikolay/.bashrc» - а именно в конце файла добавить следующую строку:

PS1='${debian_chroot:+($debian_chroot)}\u@ca:\w\$ '
Расшифровка PS

Prompt

Description

Example

Result

\a

An ASCII bell character (07)

\a$

$ (and beep)

\d

The date in “Weekday Month Date” format

\d$

Wed Mar 08$

\e

An ASCII escape character (033)

\h

The hostname up to the first `.’

\h$

beebo$

\H

The hostname

\H$

beebo.example.com$

\j

The number of jobs currently managed by the shell

\j$

0$

\l

The basename of the shell’s terminal device name

\l$

1$

\n

Newline

\d\n\h$

Wed Mar 08 <newline>beebo$

\r

Carriage return

\d\r\h$

beebo$r 08

\s

The name of the shell, the basename of $0 (the portion following the final slash)

\s$

bash$

\t

The current time in 24-hour HH:MM:SS format

\t$

07:24:57$

\T

The current time in 12-hour HH:MM:SS format

\T$

07:24:57$

\@

The current time in 12-hour am/pm format

\@$

07:25 AM$

\u

The username of the current user

\u$

david$

\v

The version of bash (e.g., 2.00)

\v$

3.1$

\V

The release of bash, version + patchlevel (e.g., 2.00.0)

\V$

3.1.5$

\w

The current working directory

\w$

~/articles/bash-prompts$

\W

The basename of the current working directory

\W$

bash-prompts$

\!

The history number of this command

\!$

537$

\#

The command number of this command

\#$

40$

\$

If the effective UID is 0, a #, otherwise a $

\$

$ or # as root

\nnn

The character corresponding to the octal number nnn

\141$

a$

\\

A backslash

\\$

\$

\[

Begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt

\]

End a sequence of non-printing characters

После корректировки файла «.bashrc» необходимо применить внесенные изменения:

source /home/nikolay/.bashrc

Теперь при администрировании vm, мы точно будем знать ее роль в нашем стенде:

nikolay@ca:~$

Отключение ipv6

Если адреса IPv6 не используется на компьютере или сервере с Linux, то стоит отключить их функционал совсем. Это необходимо для обеспечения безопасности. Например можно забыть настроить правила фаервола для IPv6, сделав это для IPv4.

Для отключения ipv6 необходимо добавить опцию «ipv6.disable=1» в строки файла «/etc/default/grub»:

До
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"
После
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash ipv6.disable=1"
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 ipv6.disable=1"

Перезагрузим grub для применения изменений:

sudo update-grub

IPv6 успешно отключен, двигаемся дальше.

Настройка ssh

Для повышения безопасности, настроим ssh следующим образом:

  • сменим порт подключения на отличный от значения 22;

  • запретим подключение пользователю root;

  • запретим использование пустого пароля (на всякий случай);

  • разрешим аутентификацию только по ssh-ключу.

Внесем изменения в строки файла «/etc/ssh/sshd_config»:

Port 1870
PermitRootLogin no
PubkeyAuthentication yes
PermitEmptyPasswords no
PasswordAuthentication no

Для применения изменений, перезагрузим сервис ssh:

sudo service ssh restart

Перезайдем на vm используя пользователя nikolay:

ssh nikolay@ca -p 1870

Настройка iptables

Теперь настроим firewall - закроем все и откроем только то, что нам нужно.

Если iptables не установлен на vm, то выполним его установку:

sudo apt-get install -y iptables 

Разрешим исходящий трафик для сервиса DNS:

sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT -m comment --comment dns
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT -m comment --comment dns

Разрешим исходящий трафик для протокола NTP:

sudo iptables -A OUTPUT -p udp --dport 123 -j ACCEPT -m comment --comment ntp

Разрешим трафик ICMP для работы команды ping:

sudo iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Разрешим трафик loopback-интерфейса для работы внутренних сервисов:

sudo iptables -A OUTPUT -o lo -j ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT

Разрешим доступ по новому порту протокола ssh:

sudo iptables -A INPUT -p tcp --dport 1870 -j ACCEPT -m comment --comment ssh

Разрешим протокол HTTP и HTTPS для подключения к репозиториям:

sudo iptables -A OUTPUT -p tcp -m multiport --dports 443,80 -j ACCEPT

Разрешим траффик для установленных сессий:

sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Запретим все сессии в статусе Invalid:

sudo iptables -A OUTPUT -m state --state INVALID -j DROP
sudo iptables -A INPUT -m state --state INVALID -j DROP

Запретим весь остальной трафик во всех направлениях:

sudo iptables -P OUTPUT DROP
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP

Проверим корректность настроек iptables:

sudo iptables -L -v -n
Вывод команды
Chain INPUT (policy DROP 19 packets, 888 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW,RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
   66  3864 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:1870 /* ssh */
    1    76 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy DROP 29 packets, 23504 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53 /* dns */
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53 /* dns */
    1    76 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:123 /* ntp */
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW,RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  *      lo      0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 443,80
   35  4196 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID

Сохраним конфигурацию iptables с помощью инструмента iptables-persistent:

sudo apt-get install -y iptables-persistent
sudo service netfilter-persistent save

Bash-cкрипт для vm

Настало время написать bash-скрипт, который сможет выполнить настройку vm автоматически:

vm-start.sh
#!/bin/bash

# активируем опцию, которая прерывает выполнение скрипта, если любая команда завершается с ненулевым статусом
set -e

# проверим, запущен ли скрипт от пользователя root
if [[ "${UID}" -ne 0 ]]; then
  echo -e "You need to run this script as root!\nPlease apply 'sudo su root' and add your host-key to /root/.ssh/authorized_keys before run this script!"
  exit 1
fi

# проверим, загружены ли открытые ssh-ключи у пользователя root
if [ ! -f /root/.ssh/authorized_keys ]; then
  echo -e "\n====================\nFile /root/.ssh/authorized_keys not found!\n====================\n"
  exit 1
else
  if [ ! -s /root/.ssh/authorized_keys ]; then
    echo -e "\n====================\nFile /root/.ssh/authorized_keys is empty!\n====================\n"
    exit 1
  fi
fi

# функция, которая проверяет наличие пакета в системе и в случае его отсутствия выполняет установку
command_check() {
  if ! command -v "$1" &>/dev/null; then
    echo -e "\n====================\n$2 could not be found!\nInstalling...\n====================\n"
    apt-get install -y "$3"
    echo -e "\nDONE\n"
  fi
}

# функция, которая запрашивает имя нового пользователя и проверяет его на наличие в системе
username_request() {
  while true; do
    read -r -p $'\n'"new username: " username
    if id "$username" >/dev/null 2>&1; then
      echo -e "\nUser $username exists!\n"
    else
      break
    fi
  done
}

# функция, которая проверяет наличие правила в iptables и в случае отсутствия применяет его
iptables_add() {
  if ! iptables -C "$@" &>/dev/null; then
    iptables -A "$@"
  fi
}

# настроим часовой пояс
echo -e "\n====================\nSetting timezone\n===================="
timedatectl set-timezone Europe/Moscow
systemctl restart systemd-timesyncd.service
timedatectl
echo -e "\nDONE\n"

# установим все необходимые пакеты используя функцию command_check
apt-get update
command_check wget "Wget" wget
command_check iptables "Iptables" iptables
command_check netfilter-persistent "Netfilter-persistent" iptables-persistent
command_check openssl "Openssl" openssl
command_check update-ca-certificates "Ca-certificates" ca-certificates

# проверим наличие конфигурационного файла ssh
if [ ! -f /etc/ssh/sshd_config ]; then
  echo -e "\n====================\nFile /etc/ssh/sshd_config not found!\n====================\n"
  exit 1
fi

# проверим наличие конфигурационного файла grub
if [ ! -f /etc/default/grub ]; then
  echo -e "\n====================\nFile /etc/default/grub not found!\n====================\n"
  exit 1
fi

# создадим нового пользователя
echo -e "\n====================\nNew user config\n===================="

while true; do
  read -r -n 1 -p "Continue or Skip? (c|s) " cs
  case $cs in
  [Cc]*)
    # запросим имя пользователя используя функцию username_request (функция создаст глобальную переменную "username")
    username_request

    # запросим пароль для нового пользователя
    read -r -p "new password: " -s password

    # создадим нового пользователя и перенесем ssh-ключи
    useradd -p "$(openssl passwd -1 "$password")" "$username" -s /bin/bash -m -G sudo
    cp -r /root/.ssh/ /home/"$username"/ && chown -R "$username":"$username" /home/"$username"/.ssh/
    echo -e "\n\nDONE\n"

    # выполним корректировку prompt statement
    echo -e "\n====================\nEdit prompt statement for this user?\n===================="

    while true; do
      read -r -n 1 -p "Continue or Skip? (c|s) " cs
      case $cs in
      [Cc]*)
        # запросим имя vm
        read -r -p $'\n'"vm name: " vm_name

        # выполним корректировку prompt statement
        echo "PS1='\${debian_chroot:+(\$debian_chroot)}\\u@$vm_name:\\w\\\$ '" >>/home/"$username"/.bashrc

        echo -e "\n\nDONE\n"
        break
        ;;
      [Ss]*)
        echo -e "\n"
        break
        ;;
      *) echo -e "\nPlease answer C or S!\n" ;;
      esac
    done

    break
    ;;
  [Ss]*)
    echo -e "\n"
    break
    ;;
  *) echo -e "\nPlease answer C or S!\n" ;;
  esac
done

# настроим ssh
echo -e "\n====================\nEdit sshd_config file\n===================="

while true; do
  read -r -n 1 -p "Continue or Skip? (c|s) " cs
  case $cs in
  [Cc]*)
    sed -i 's/#\?\(Port\s*\).*$/\1 1870/' /etc/ssh/sshd_config
    sed -i 's/#\?\(PermitRootLogin\s*\).*$/\1 no/' /etc/ssh/sshd_config
    sed -i 's/#\?\(PubkeyAuthentication\s*\).*$/\1 yes/' /etc/ssh/sshd_config
    sed -i 's/#\?\(PermitEmptyPasswords\s*\).*$/\1 no/' /etc/ssh/sshd_config
    sed -i 's/#\?\(PasswordAuthentication\s*\).*$/\1 no/' /etc/ssh/sshd_config
    echo -e "\n\n"
    /etc/init.d/ssh restart
    echo -e "\nDONE\n"
    break
    ;;

  [Ss]*)
    echo -e "\n"
    break
    ;;
  *) echo -e "\nPlease answer C or S!\n" ;;
  esac
done

# выключим ipv6
echo -e "\n====================\nDisabling ipv6\n===================="

while true; do
  read -r -n 1 -p "Continue or Skip? (c|s) " cs
  case $cs in
  [Cc]*)
    echo -e "\n\n"
    sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/&ipv6.disable=1 /' /etc/default/grub
    sed -i 's/^GRUB_CMDLINE_LINUX="/&ipv6.disable=1 /' /etc/default/grub
    update-grub
    echo -e "\nDONE\n"
    break
    ;;

  [Ss]*)
    echo -e "\n"
    break
    ;;
  *) echo -e "\nPlease answer C or S!\n" ;;
  esac
done

# настроим iptables
echo -e "\n====================\nIptables config\n===================="
while true; do
  read -r -n 1 -p "Current ssh session may drop! To continue you have to relogin to this host via 1870 ssh-port and run this script again. Are you ready? (y|n) " yn
  case $yn in
  [Yy]*) #---DNS---
    iptables_add OUTPUT -p tcp --dport 53 -j ACCEPT -m comment --comment dns
    iptables_add OUTPUT -p udp --dport 53 -j ACCEPT -m comment --comment dns
    #---NTP---
    iptables_add OUTPUT -p udp --dport 123 -j ACCEPT -m comment --comment ntp
    #---ICMP---
    iptables_add OUTPUT -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    iptables_add INPUT -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    #---loopback---
    iptables_add OUTPUT -o lo -j ACCEPT
    iptables_add INPUT -i lo -j ACCEPT
    #---Input-SSH---
    iptables_add INPUT -p tcp --dport 1870 -j ACCEPT -m comment --comment ssh
    #---Output-HTTP---
    iptables_add OUTPUT -p tcp -m multiport --dports 443,80 -j ACCEPT
    #---ESTABLISHED---
    iptables_add INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    iptables_add OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    #---INVALID---
    iptables_add OUTPUT -m state --state INVALID -j DROP
    iptables_add INPUT -m state --state INVALID -j DROP
    #---Defaul-Drop---
    iptables -P OUTPUT DROP
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    # save iptables config
    echo -e "\n====================\nSaving iptables config\n====================\n"
    service netfilter-persistent save
    echo -e "DONE\n"
    break
    ;;
  [Nn]*)
    echo -e "\n"
    exit
    ;;
  *) echo -e "\nPlease answer Y or N!\n" ;;
  esac
done

echo -e "\nOK\n"
exit 0

Запуск bash-скрипта

Файлу скрипта необходимо выдать права на исполнение:

sudo chmod 755 ~/start.sh

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

Сделаем пользователя «nikolay» полноправным владельцем файла:

sudo chown nikolay:nikolay ~/start.sh

Запустим скрипт:

sudo ~/start.sh

Настройка Git-репозитория

Git - это консольная утилита, для отслеживания и ведения истории изменения файлов, в проекте. Чаще всего его используют для кода, но можно и для других файлов.

В репозитории Git мы будем хранить все скрипты, написанные для данного стенда.

Создадим git-репозиторий на Github и загрузим туда наш первый bash-скрипит.

Более подробно изучить работу с Git можно в статье «Git для новичков».

Git со всеми bash-скриптами данного проекта

В репозитории young-devops-project хранятся все bash-скрипты данного проекта.

Также если вам интересна работа с генераторами трафика, то предлагаю ознакомиться с моей статьей «Cisco TRex на практике».

Tags:
Hubs:
Total votes 11: ↑7 and ↓4+3
Comments18

Articles