<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>David Kistauri</title><author><name>David Kistauri</name></author><id>https://teletype.in/atom/dtroode</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/dtroode?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@dtroode?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dtroode"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/dtroode?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-06T10:14:46.325Z</updated><entry><id>dtroode:y-combinator</id><link rel="alternate" type="text/html" href="https://teletype.in/@dtroode/y-combinator?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dtroode"></link><title>Y-комбинатор</title><published>2022-03-11T18:50:02.992Z</published><updated>2022-03-11T18:50:02.992Z</updated><category term="funkcional-noe-programmirovanie" label="функциональное программирование"></category><summary type="html">Y-комбинатор — один из комбинаторов неподвижной точки — ключ к пониманию рекурсии и подсказка к тому, зачем вообще нужно функциональное программирование и в чем его особенность. В книгах объясняется сложно, поэтому я много раз перечитал, записал каждый шаг и прокоментировал его, чтоб самому понять. А потом отредактировал текст и делюсь со всеми.</summary><content type="html">
  &lt;p id=&quot;PvyW&quot;&gt;Y-комбинатор — один из &lt;a href=&quot;https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80_%D0%BD%D0%B5%D0%BF%D0%BE%D0%B4%D0%B2%D0%B8%D0%B6%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%B8&quot; target=&quot;_blank&quot;&gt;комбинаторов неподвижной точки&lt;/a&gt; — ключ к пониманию рекурсии и подсказка к тому, зачем вообще нужно функциональное программирование и в чем его особенность. В книгах объясняется сложно, поэтому я много раз перечитал, записал каждый шаг и прокоментировал его, чтоб самому понять. А потом отредактировал текст и делюсь со всеми.&lt;/p&gt;
  &lt;p id=&quot;l2S2&quot;&gt;Рассмотрим Y-комбинатор на примере Scheme — диалекта Lisp. Тестовой функцией будет &lt;code&gt;length&lt;/code&gt;, которая измеряет длину списка. Для начала объясню как рабоатет сама функция.&lt;/p&gt;
  &lt;pre id=&quot;ZxeM&quot;&gt;(define length
    (lambda (l)
        (cond
            ((null? l) 0)
            (else (add1 (length (cdr l)))))))&lt;/pre&gt;
  &lt;p id=&quot;1Ia8&quot;&gt;С каждым блоком кода открываются скобки, а потом они закрываются. Почти как &lt;code&gt;{}&lt;/code&gt; в JavaScript. Разберем по строкам.&lt;/p&gt;
  &lt;ol id=&quot;nIs3&quot;&gt;
    &lt;li id=&quot;Mkv5&quot;&gt;&lt;code&gt;define length&lt;/code&gt; — &lt;code&gt;define&lt;/code&gt; определяет называние функции, как если бы мы написали &lt;code&gt;function length&lt;/code&gt; в JavaScript или &lt;code&gt;def length&lt;/code&gt; в Python.&lt;/li&gt;
    &lt;li id=&quot;zrsC&quot;&gt;&lt;code&gt;lambda (l)&lt;/code&gt; — определяет безымянную функцию и её аргументы. В данном случаи аргумент один — &lt;code&gt;l&lt;/code&gt; — в функцию мы передадим список. Передавая безымянную функцию в первую строку, мы определяем для нее имя. Первые две строки — аналог &lt;code&gt;function length(l)&lt;/code&gt; в JavaScript и &lt;code&gt;def length(l)&lt;/code&gt; в Python.&lt;/li&gt;
    &lt;li id=&quot;aN4K&quot;&gt;&lt;code&gt;cond&lt;/code&gt; — начало условия. Это как &lt;code&gt;if&lt;/code&gt;, только туда передается много строк условий и действий подряд и в конце &lt;code&gt;else&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;voSv&quot;&gt;В каждой следующей строке после &lt;code&gt;cond&lt;/code&gt; идет блок кода с условием и действием. Как &lt;code&gt;((null? l) 0)&lt;/code&gt;. Читается так: &lt;code&gt;((если это) то это)&lt;/code&gt;. А &lt;code&gt;null?&lt;/code&gt; — это функция, которая проверяет список, который мы ей передаём, на пустоту.&lt;/li&gt;
    &lt;li id=&quot;VCHt&quot;&gt;&lt;code&gt;add1&lt;/code&gt; — функция, которая добавляет 1; её надо писать самостоятельно. &lt;code&gt;cdr&lt;/code&gt; — функция, которая возвращает список, который мы передаём, но без первого элемента.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;r9Pw&quot;&gt;В общем виде функция работает так:&lt;/p&gt;
  &lt;ol id=&quot;sthc&quot;&gt;
    &lt;li id=&quot;1Qma&quot;&gt;проверяем список на пустоту,&lt;/li&gt;
    &lt;li id=&quot;uOb2&quot;&gt;если пустой — возвращаем 0, если нет, идем дальше,&lt;/li&gt;
    &lt;li id=&quot;2CPK&quot;&gt;добавляем 1 к рекурсивному запуску фукнции,&lt;/li&gt;
    &lt;li id=&quot;FNH5&quot;&gt;запускаем функцию со списком, который меньше на один элемент,&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;gGMS&quot;&gt;Пока список не будет пуст, мы будем добавлять единицу, когда он останется пуст, вернётся 0 из &lt;code&gt;((null? l) 0)&lt;/code&gt; и шаг за шагом в обратном направлении добавится по единице.&lt;/p&gt;
  &lt;p id=&quot;5Ob3&quot;&gt;Если непонятно, то лучше пропустить какой-нибудь список через фукнцию. Например &lt;code&gt;(lisp is great)&lt;/code&gt;. Функция будет запускаться рекурсивно, удаляя по одному элементу из начала: &lt;code&gt;(lisp is great)&lt;/code&gt;, &lt;code&gt;(is great)&lt;/code&gt;, &lt;code&gt;(great)&lt;/code&gt;, &lt;code&gt;()&lt;/code&gt;. Теперь можно приступать к комбинатору неподвижной точки.&lt;/p&gt;
  &lt;p id=&quot;eeJt&quot;&gt;Сперва попробуем избавиться от &lt;code&gt;define&lt;/code&gt;. Функция будет безымянной. В Lisp есть синтаксис мгновенного объявления и вызова функции, как и в JavaScript. В скобки передается безымянная лямба-функция и следом аргумент:&lt;/p&gt;
  &lt;pre id=&quot;KKeO&quot;&gt;((lambda (length)
     (lambda (l)
         (cond
             ((null? l) 0)
             (else (add1 (length (cdr l))))))) eternity)&lt;/pre&gt;
  &lt;p id=&quot;uIcU&quot;&gt;Две лямбды означают, что мы создаём функцию, которая возвращает функцию, готовую принять другой аргумент. &lt;code&gt;eternity&lt;/code&gt; просто пустышка, которая подставляется вместо аргумента. Такая функция будет очень похожа на length, но рекурсивного вызова не будет, потому что у функции нет имени и мы не знаем, как ее вызвать. Но если передать туда пустой список, то сработает первое условие — &lt;code&gt;(null? l)&lt;/code&gt; и функция вернёт 0. То есть для пустого списка всё ок.&lt;/p&gt;
  &lt;pre id=&quot;6DMn&quot;&gt;((lambda (f)
     (lambda (l)
         (cond
             ((null? l) 0)
             (else (add1 (f (cdr l))))))) ; здесь будет вторая фукнция
 ((lambda (g)
      (lambda (l) ; здесь будет cdr l
          (cond
              ((null? l) 0)
              (else (add1 (g (cdr l))))))) ; здесь будет eternity
 eternity))&lt;/pre&gt;
  &lt;p id=&quot;8CK5&quot;&gt;Теперь передадим вместо &lt;code&gt;eternity&lt;/code&gt; другую функцию. В первую функцию передается вторая, а в неё — &lt;code&gt;eternity&lt;/code&gt;. Теперь мы можем передать список с одним элементом. Выполнится &lt;code&gt;else&lt;/code&gt;, вызовется вторая функция, которая такая же, как и первая, и там мы уже остановимся. А можно так добавлять бесконечно. Но код будет не универсальным, а писать так много неудобно. Перейдем к другому определению функции.&lt;/p&gt;
  &lt;pre id=&quot;fPQ3&quot;&gt;((lambda (mk-length) ; (1)
     (mk-length eternity))
 (lambda (length) ; (2)
     (lambda (l)
         (cond
             ((null? l) 0)
             (else (add1 (length (cdr l))))))))&lt;/pre&gt;
  &lt;p id=&quot;LZnE&quot;&gt;Теперь у нас есть отдельная функция (первая), которая возвращает похожую на &lt;code&gt;length&lt;/code&gt;функцию. Функция (2) попадет в лямбду (1) как аругмент &lt;code&gt;mk-length&lt;/code&gt;. Внутри происходит опять объявление с вызовом. В функцию (2) подставляется &lt;code&gt;eternity&lt;/code&gt; вместо &lt;code&gt;length&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;xTGQ&quot;&gt;Теперь повторим прошлый код с новым синтаксисом подстановки, передадим в функцию (2) вместо &lt;code&gt;eternity&lt;/code&gt; саму функцию.&lt;/p&gt;
  &lt;pre id=&quot;2RSA&quot;&gt;((lambda (mk-length) ; (1)
     (mk-length
         (mk-length eternity)))
 (lambda (length) ; (2)
     (lambda (l)
         (cond
             ((null? l) 0)
             (else (add1 (length (cdr l))))))))&lt;/pre&gt;
  &lt;p id=&quot;gBzR&quot;&gt;Здесь мы передаем &lt;code&gt;eternity&lt;/code&gt; в функцию, как и в прошлый раз, и всю эту конструкцию снова передаем в функцию. Уберем &lt;code&gt;eternity&lt;/code&gt;.&lt;/p&gt;
  &lt;pre id=&quot;q6Sn&quot;&gt;((lambda (mk-length) ; (1)
     (mk-length mk-length))
 (lambda (length) ; (2)
     (lambda (l)
         (cond
             ((null? l) 0)
             (else (add1 (length (cdr l))))))))&lt;/pre&gt;
  &lt;p id=&quot;je9b&quot;&gt;Функция (2) передается в функцию (1) и получает там имя &lt;code&gt;mk-length&lt;/code&gt;, а потом передается в себя в строке &lt;code&gt;(mk-length mk-length)&lt;/code&gt;. Вернем &lt;code&gt;eternity&lt;/code&gt;, но теперь в другое место, положим его прямо внутрь функции.&lt;/p&gt;
  &lt;pre id=&quot;LZEQ&quot;&gt;((lambda (mk-length) ; (1)
     (mk-length mk-length))
 (lambda (length) ; (2)
     (lambda (l)
         (cond
             ((null? l) 0)
             (else (add1 ((length eternity) (cdr l))))))))&lt;/pre&gt;
  &lt;p id=&quot;L2CT&quot;&gt;Теперь опять заменим &lt;code&gt;eternity&lt;/code&gt; на функцию, мы уже делали так.&lt;/p&gt;
  &lt;pre id=&quot;9tKj&quot;&gt;((lambda (mk-length) ; (1)
     (mk-length mk-length))
 (lambda (length) ; (2)
     (lambda (l)
         (cond
             ((null? l) 0)
             (else (add1 ((length length) (cdr l))))))))&lt;/pre&gt;
  &lt;p id=&quot;wFKo&quot;&gt;В функциональном программировании используется прием eta-reduction. Он позволяет заменить &lt;code&gt;(lambda (x) (function x))&lt;/code&gt; на &lt;code&gt;function&lt;/code&gt;, потому что в первом варианте мы передаем аргумент в функцию, которая находится в ожидании, во втором варианте функция также ждет аргумент, который можно ей передать. Если мы передадим любое число в оба варианта, то функция получит число и там, и там.&lt;/p&gt;
  &lt;p id=&quot;bpaO&quot;&gt;Сделаем обратную замену: подставим вместо &lt;code&gt;(length length)&lt;/code&gt; функцию &lt;code&gt;(lambda (x) ((length length) x))&lt;/code&gt;. Здесь &lt;code&gt;(length length)&lt;/code&gt; просто функция.&lt;/p&gt;
  &lt;pre id=&quot;yYG7&quot;&gt;((lambda (mk-length) ; (1)
     (mk-length mk-length))
 (lambda (length) ; (2)
     (lambda (l)
         (cond
             ((null? l) 0)
             (else (add1 ((lambda (x) ((length length) x))                    (cdr l))))))))&lt;/pre&gt;
  &lt;p id=&quot;g82A&quot;&gt;Вытащим новую конструкцию за функцию.&lt;/p&gt;
  &lt;pre id=&quot;fBjZ&quot;&gt;((lambda (mk-length)
     (mk-length mk-length))
 (lambda (mk-length) ; новая функция-обертка
     ((lambda (length) ; подстановка аргумента
          (lambda (l)
              (cond
                  ((null? l) 0)
                  (else (add1 (length (cdr l)))))))
      (lambda (x) ; аргумент
          ((mk-length mk-length) x)))))&lt;/pre&gt;
  &lt;p id=&quot;QZnp&quot;&gt;На 4 строке появились двойные скобки: это значит, что мы в функцию передаем аргумент. Выделенный фрагмент — прошлая функция, куда мы передаем последние две строки. Если подставить &lt;code&gt;(lambda (x) ((length length) x))&lt;/code&gt; вместо &lt;code&gt;length&lt;/code&gt; в четвертой строке, то получим функцию из предыдущего блока. Всю эту конструкцию мы обернули в новую фукнцию.&lt;/p&gt;
  &lt;p id=&quot;7Ms7&quot;&gt;Вытащим выделенный фрагмент в отдельный аргумент.&lt;/p&gt;
  &lt;pre id=&quot;eSlh&quot;&gt;((lambda (le)
     ((lambda (mk-length)
          (mk-length mk-length))
      (lambda (mk-length)
          (le (lambda (x)
              ((mk-length mk-length) x))))))
 (lambda (length)
     (lambda (l)
         (cond
             ((null? l) 0)
             (else (add1 (length (cdr l))))))))&lt;/pre&gt;
  &lt;p id=&quot;O2KT&quot;&gt;Выделенный фрагмент — функция, похожая на изначальный &lt;code&gt;length&lt;/code&gt;. Она передается в первую функцию как &lt;code&gt;le&lt;/code&gt;. Остальное — часть, которая выполняет рекурсию. Её можно определить с помощью &lt;code&gt;define&lt;/code&gt;.&lt;/p&gt;
  &lt;pre id=&quot;38ZT&quot;&gt;(define Y
    (lambda (le)
        ((lambda (f) (f f))
         (lambda (f)
             (le (lambda (x) ((f f) x)))))))&lt;/pre&gt;
  &lt;p id=&quot;JtK6&quot;&gt;Здесь &lt;code&gt;le&lt;/code&gt; — функция, которую мы хотим вызывать рекурсивно, &lt;code&gt;x&lt;/code&gt; — ее аргумент, а &lt;code&gt;f&lt;/code&gt; — внутреннее имя функция для применения функции к себе. Эта часть называется Y-комбинатор. Их существует несколько видов, но этот основной. Более сложное, но не менее интересное, объяснение есть в книге The Little Schemer, а еще один вид комбинатора есть во второй части — The Seasoned Schemer. Это интересные и веселые книги по функциональному программированию, которые стоит прочитать навичкам в этом разделе.&lt;/p&gt;

</content></entry><entry><id>dtroode:choose-right-tools</id><link rel="alternate" type="text/html" href="https://teletype.in/@dtroode/choose-right-tools?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dtroode"></link><title>Выбирайте правильные инструменты</title><published>2022-03-11T18:33:40.562Z</published><updated>2022-03-11T18:33:40.562Z</updated><category term="veb" label="веб"></category><summary type="html">Разработчики, которые имели медленный сайт или не имели его, с популярностью React переводят сайты на Gatsby, а потом радостно пишут в Твиттер о 90-100 в Lighthouse и рекомендуют перенести старый WordPress-блог на новый JS-фреймворк. И даже те, кто имел статический сайт на HTML с 70 в Lighthouse, переписывают его на Gatsby, который оптимизирует сайт за них и выдает хорошие цифры в тестах.</summary><content type="html">
  &lt;p id=&quot;2xll&quot;&gt;Разработчики, которые имели медленный сайт или не имели его, с популярностью React переводят сайты на Gatsby, а потом радостно пишут в Твиттер о 90-100 в Lighthouse и рекомендуют перенести старый WordPress-блог на новый JS-фреймворк. И даже те, кто имел статический сайт на HTML с 70 в Lighthouse, переписывают его на Gatsby, который оптимизирует сайт за них и выдает хорошие цифры в тестах.&lt;/p&gt;
  &lt;p id=&quot;ckR7&quot;&gt;Проблема в том, что вам скорее всего не нужен JavaScript для личного блога. Gatsby крут плагинами, но всё, что нужно от него, — генерация страниц из Markdown. Клиент не хочет видеть JS-бандл. Gatsby нужен для сложных сайтов с анимациями и интерактивом, например, &lt;a href=&quot;https://joshwcomeau.com/&quot; target=&quot;_blank&quot;&gt;для этого блога&lt;/a&gt; — он издает звуки, персонажи двигаются, а примеры кода запускаются на месте. React с его JSX, где интерактив легко встраивается в текст, идеально здесь подходит, а еще у Gatsby хорошая поддержка MDX, чтоб делать такое же с Markdown.&lt;/p&gt;
  &lt;p id=&quot;cwzF&quot;&gt;Ситуация описывается так:&lt;/p&gt;
  &lt;blockquote id=&quot;pxpT&quot;&gt;&lt;a href=&quot;https://twitter.com/twanttobealighi/status/1225769570335698944&quot; target=&quot;_blank&quot;&gt;@twanttobealighi&lt;/a&gt;: реакт делает сложное простым, а простое невозможным&lt;/blockquote&gt;
  &lt;p id=&quot;pD8F&quot;&gt;Разработчикам кажется, что Gatsby помогает, раз повышает результаты в тестах, но это не предел: вам дают конфетку и вы не хотите больше, а можно. Gatsby оптимизирует картинки — генерирует несколько размеров, — сжимает код и делает ту работу, которая некоторым кажется магией. Вы не делали ничего раньше и вас ругал Google, а теперь не ругает.&lt;/p&gt;
  &lt;p id=&quot;s1Vx&quot;&gt;Возьмите полную статику: &lt;a href=&quot;https://11ty.dev/&quot; target=&quot;_blank&quot;&gt;Eleventy&lt;/a&gt;, — используйте плагины для сжатия кода и картинок или напишите свой код в десять строк и дайте клиенту минималистичный набор HTML + CSS. Это тоже даст 100 в Lighthouse, но ниже буду написаны цифры, более глубоко описывающие скорость загрузки: первая отрисовка, время до взаимодействия с сайтом, самый крупный элемент сайта, — которые будут в разы меньше, а в сложных тестах вы наберете лучший результат.&lt;/p&gt;
  &lt;p id=&quot;6Uvm&quot;&gt;А пишу я это потому, что у меня тоже сперва была полная статика с Jekyll, а потом я поддался количеству плагинов в Gatsby и автоматической оптимизации изображений. Но недавно я переписал сайт на Eleventy за три дня. &lt;em&gt;Выбирайте правильные инструменты.&lt;/em&gt;&lt;/p&gt;

</content></entry><entry><id>dtroode:google-cloud-ssh-sftp</id><link rel="alternate" type="text/html" href="https://teletype.in/@dtroode/google-cloud-ssh-sftp?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dtroode"></link><title>SSH и SFTP для виртуальных машин на Google Cloud</title><published>2021-11-25T18:27:27.032Z</published><updated>2021-11-25T18:29:06.963Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/67/19/6719f740-70a0-4b3e-bf1b-027b7a53df54.png"></media:thumbnail><category term="eve-ng" label="eve-ng"></category><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/12/85/12852f9e-20f4-4212-9fc1-532202d08173.png&quot;&gt;На гугл-сервере есть отличная поддержка SSH, который нужен как сам по себе, так и для SFTP-подключения. Но иногда этих возможностей не хватает, поэтому можно настроить сервер под себя.</summary><content type="html">
  &lt;p id=&quot;Znvr&quot;&gt;На гугл-сервере есть отличная поддержка SSH, который нужен как сам по себе, так и для SFTP-подключения. Но иногда этих возможностей не хватает, поэтому можно настроить сервер под себя.&lt;/p&gt;
  &lt;p id=&quot;syVq&quot;&gt;Сперва расскажу, как подключаться по SSH от разных пользователей, потом покажу как на основе этого получить SFTP-доступ.&lt;/p&gt;
  &lt;p id=&quot;cYHr&quot;&gt;Самый простой способ работать с SSH – установить терминальное приложение &lt;a href=&quot;https://cloud.google.com/sdk/docs/install&quot; target=&quot;_blank&quot;&gt;gcloud&lt;/a&gt;. Теперь командой &lt;code&gt;gcloud compute ssh --project=АЙДИ_ПРОЕКТА --zone=ЗОНА ИМЯ_МАШИНКИ&lt;/code&gt; подключаемся к машинке. Если не заходили до этого в свой гугл-аккаунт, в терминале появится просьба и инструкция ко входу. gcloud сам создаст пользователя и SSH-ключи в первый раз. Теперь от этого пользователя можно &lt;a href=&quot;#7ZNn&quot;&gt;заходить и по SFTP&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;Onne&quot;&gt;А теперь дополнительные настройки, без которых и так всё работает.&lt;/p&gt;
  &lt;h2 id=&quot;mofy&quot;&gt;Свой SSH&lt;/h2&gt;
  &lt;p id=&quot;futx&quot;&gt;После первого входа гугл создал вам ключи. Они лежат там, где и любая другая программа их положила, можно нагуглить эту папку. У меня – стандартная для мака &lt;code&gt;~/.ssh&lt;/code&gt;. Перейдёте в свою папку и увидите ключ. Его можно использовать для подключения к стандартному пользователю.&lt;/p&gt;
  &lt;p id=&quot;x7jm&quot;&gt;Для большего контроля можно вручную добавить ключи для других пользователей. Следующие действия проделываем на своём компьютере.&lt;/p&gt;
  &lt;p id=&quot;gnxj&quot;&gt;Генерируем ключи для пользователя student, приватный ключ будет в файле &lt;code&gt;~/.ssh/test&lt;/code&gt;, публичный в таком же файле с расширением &lt;code&gt;.pub&lt;/code&gt;.&lt;/p&gt;
  &lt;pre id=&quot;l8jx&quot;&gt;ssh-keygen -f ~/.ssh/test -C student&lt;/pre&gt;
  &lt;p id=&quot;Wh60&quot;&gt;Passphrase – дополнительный, но необязательный пароль, который у вас попросит генератор. Этот пользователь будет использовать в виртуальной машинке, имя можно дать любое, как и название файла. &lt;/p&gt;
  &lt;figure id=&quot;tGye&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/12/85/12852f9e-20f4-4212-9fc1-532202d08173.png&quot; width=&quot;836&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Zvwd&quot;&gt;Выведем содержимое публичного ключа командой &lt;code&gt;cat ~/.ssh/test.pub&lt;/code&gt;, вручную скопируем, оно нам сейчас понадобится. Ключ начинается словом ssh-rsa и заканчивается именем пользователя, для которого создан ключ, всё это копируем.&lt;/p&gt;
  &lt;figure id=&quot;UDkl&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/43/74/43742997-4a56-4cd2-9afe-f9af7b911cfe.png&quot; width=&quot;836&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;kphZ&quot;&gt;Переходим в раздел Metadata на гугл-сервере. Можно через меню поиска внутри сервера. Открываем вкладку SSH Keys, нажимаем Edit, Add item и вставляем в поле скопированный ключ. Получится так:&lt;/p&gt;
  &lt;figure id=&quot;YTX7&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/af/18/af18d22e-839c-48af-87d4-9e9b69571243.png&quot; width=&quot;1670&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;1o2d&quot;&gt;Сохраняем и ждём, пока появится надпись, что ключи сохранены. Машинку всё это время можно держать включённой.&lt;/p&gt;
  &lt;p id=&quot;hNHP&quot;&gt;После сохранения ключей со своего компьютера логинимся:&lt;/p&gt;
  &lt;pre id=&quot;fep5&quot;&gt;ssh -i ~/.ssh/test student@34.88.135.152&lt;/pre&gt;
  &lt;p id=&quot;Sw7g&quot;&gt;Здесь я указал путь к &lt;em&gt;приватному&lt;/em&gt; ключу, пользователя@айпишник.машинки.&lt;/p&gt;
  &lt;figure id=&quot;ixpb&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/65/1b/651b93df-a309-4b94-bc35-b6610d11ef37.png&quot; width=&quot;836&quot; /&gt;
    &lt;figcaption&gt;Получилось! Для выхода &lt;code&gt;exit&lt;/code&gt; или &lt;code&gt;Ctrl + D&lt;/code&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;blockquote id=&quot;jRxX&quot;&gt;Вообще тут я подключился к своему дебиану, но ссылку на эту инструкцию я буду указывать как инструкцию для EVE-NG. Чтоб никто не смущался, вывод в консоли после подключения будет отличаться, это ок :-)&lt;/blockquote&gt;
  &lt;h2 id=&quot;7ZNn&quot;&gt;SFTP&lt;/h2&gt;
  &lt;p id=&quot;F8O9&quot;&gt;На основе существующих пользователей можно подключаться по SFTP. Для этого в разделе Metadata на сервере должен быть ключ на имя пользователя, его пара должна быть на вашем компьютере.&lt;/p&gt;
  &lt;p id=&quot;YBjf&quot;&gt;В любой программе нам понадобится тип подключения (sftp), айпи (нашей машинки), порт (если не меняли, то 22), имя пользователя, пароль (если есть), приватный ссш-ключ. Практически те же данные, что и при обычном ssh-подключении. Вот пример:&lt;/p&gt;
  &lt;figure id=&quot;Po37&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/56/42/56426a3b-47c7-4854-a022-ce1ad1684969.png&quot; width=&quot;713&quot; /&gt;
    &lt;figcaption&gt;Это Cyberduck – FTP-клиент для мака. Чтоб появилось такое окно, я нажал Open Connection&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tapB&quot;&gt;После этого мы имеем полный доступ к данным, как будто они у нас на компьютере. Можно добавлять файлы и качать их.&lt;/p&gt;

</content></entry><entry><id>dtroode:eve-ng-addons</id><link rel="alternate" type="text/html" href="https://teletype.in/@dtroode/eve-ng-addons?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dtroode"></link><title>Добавляем образы в EVE-NG на Google Cloud</title><published>2021-11-09T11:15:27.458Z</published><updated>2021-11-25T18:31:46.519Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/e0/82/e082b4a1-7286-478a-a486-0e50cfe43d00.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/b7/7f/b77fc3b1-3fd0-41ce-b1fb-01c55a457ce2.png&quot;&gt;Чтоб работать с устройствами в EVE-NG, надо добавить образы этих устройств. Теоретически там ничего сложного, только вот с цисками надо немного повозиться, сейчас покажу как это делается практически.</summary><content type="html">
  &lt;p id=&quot;5UVx&quot;&gt;Чтоб работать с устройствами в EVE-NG, надо добавить образы этих устройств. Теоретически там ничего сложного, только вот с цисками надо немного повозиться, сейчас покажу как это делается практически.&lt;/p&gt;
  &lt;h2 id=&quot;iG86&quot;&gt;Откуда брать образы&lt;/h2&gt;
  &lt;p id=&quot;AJgS&quot;&gt;Образы можно легко нагуглить, либо скачать с официальных сайтов. Вот те, с которыми мы будем работать (zip разархивировать):&lt;/p&gt;
  &lt;ul id=&quot;B0cn&quot;&gt;
    &lt;li id=&quot;19It&quot;&gt;&lt;a href=&quot;https://networkhunt.com/download/download-cisco-iou-iol-images/&quot; target=&quot;_blank&quot;&gt;Циски (последние два образа)&lt;/a&gt;,&lt;/li&gt;
    &lt;li id=&quot;KRVZ&quot;&gt;&lt;a href=&quot;https://mikrotik.com/download&quot; target=&quot;_blank&quot;&gt;Микротик&lt;/a&gt;,&lt;/li&gt;
    &lt;li id=&quot;pZRv&quot;&gt;&lt;a href=&quot;https://www.eve-ng.net/index.php/documentation/howtos/howto-create-own-linux-host-image/&quot; target=&quot;_blank&quot;&gt;Линукс&lt;/a&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;AMR4&quot;&gt;В примере я использую образ микротика, который отмечен на картинке и образ линукс &lt;code&gt;linux-ubuntu-desktop-16.04.4.tar.gz&lt;/code&gt;.&lt;/p&gt;
  &lt;figure id=&quot;uwlt&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b7/7f/b77fc3b1-3fd0-41ce-b1fb-01c55a457ce2.png&quot; width=&quot;700&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;ToUr&quot;&gt;Закидываем файлы&lt;/h2&gt;
  &lt;p id=&quot;9gxr&quot;&gt;Закинуть файлы в Еву можно по FTP, это даже будет удобнее, для этого надо разобраться, как подключиться в виртуальной машинке через FTP-клиент. &lt;a href=&quot;https://teletype.in/@dtroode/google-cloud-ssh-sftp&quot; target=&quot;_blank&quot;&gt;Я так и сделал&lt;/a&gt;, но тут расскажу про способ, не предполагающий дополнительных знаний.&lt;/p&gt;
  &lt;p id=&quot;zeaw&quot;&gt;Заходим по SSH в консоль Евы.&lt;/p&gt;
  &lt;p id=&quot;jTjg&quot;&gt;Образы хранятся в папке &lt;code&gt;/opt/unetlab/addons/&lt;/code&gt;, туда и будем добавлять. Сперва надо загрузить их в саму машинку. Нажимаем на шестерёнку, выбираем пункт Upload file, выбираем образ на компьютере, он загружается в отдельную папку. &lt;/p&gt;
  &lt;figure id=&quot;4fxc&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a0/e1/a0e12311-d4ca-4b9f-b16b-a32d36b2dce2.png&quot; width=&quot;397&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;2KTe&quot;&gt;Папка, в которой появится файл будет указана после загрузки файла.&lt;/p&gt;
  &lt;figure id=&quot;lY7n&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/42/7f/427f2f44-92df-46af-8d3c-2a079722c61e.png&quot; width=&quot;516&quot; /&gt;
    &lt;figcaption&gt;Вот тут папка /home/davidkis113_gmail_com&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;qYBn&quot;&gt;Теперь файл из это папки надо переместить в нашу папку с образами. Переходим туда, где сейчас лежит файл: &lt;code&gt;cd /home/davidkis113_gmail_com&lt;/code&gt;. Теперь надо перенести образ в нужную папку.&lt;/p&gt;
  &lt;p id=&quot;3Qc3&quot;&gt;Для микротика:&lt;/p&gt;
  &lt;p id=&quot;nOyx&quot;&gt;Создаём папку в соответствии с версией образа командой.&lt;/p&gt;
  &lt;pre id=&quot;oHhm&quot;&gt;sudo mkdir /opt/unetlab/addons/qemu/mikrotik-6.49/&lt;/pre&gt;
  &lt;p id=&quot;H5Y4&quot;&gt;Выполняем команду для переноса и изменения имени и расширения файла:&lt;/p&gt;
  &lt;pre id=&quot;HG6M&quot;&gt;sudo mv НАЗВАНИЕ_ФАЙЛА /opt/unetlab/addons/qemu/mikrotik-6.49/hda.qcow2&lt;/pre&gt;
  &lt;p id=&quot;CkGp&quot;&gt;Для линукса:&lt;/p&gt;
  &lt;p id=&quot;Xk5O&quot;&gt;В папке, где находится файл &lt;code&gt;cd /home/davidkis113_gmail_com&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;RBv1&quot;&gt;sudo mv НАЗВАНИЕ_ФАЙЛА /opt/unetlab/addons/qemu/НАЗВАНИЕ_ФАЙЛА
cd /opt/unetlab/addons/qemu
sudo tar xzvf НАЗВАНИЕ_ФАЙЛА
rm -f НАЗВАНИЕ_ФАЙЛА&lt;/pre&gt;
  &lt;p id=&quot;c1IW&quot;&gt;Первая команда для переноса файла, вторая для перехода в ту папку, где теперь лежит файл, третья для разархивирования, четвёртая, чтоб удалить архив.&lt;/p&gt;
  &lt;p id=&quot;2ouu&quot;&gt;У меня в примере название файла &lt;code&gt;linux-ubuntu-desktop-16.04.4.tar.gz&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;pBw5&quot;&gt;Общая часть:&lt;/p&gt;
  &lt;p id=&quot;NSHA&quot;&gt;Выполняем команду &lt;code&gt;/opt/unetlab/wrappers/unl_wrapper -a fixpermissions&lt;/code&gt;, чтоб Ева увидела образ. Теперь образ должен отобразиться в списке в лабораторной работе. Если не отобразился обновляем страницу или перезагружаем машинку.&lt;/p&gt;
  &lt;h2 id=&quot;qLsi&quot;&gt;Но с образами Cisco IOL не так просто&lt;/h2&gt;
  &lt;p id=&quot;N24N&quot;&gt;Образы Cisco IOL находятся в папке &lt;code&gt;/opt/unetlab/addons/iol/bin&lt;/code&gt;. Но просто так они работать не будут, нужна лицензия. Это несложно:&lt;/p&gt;
  &lt;ul id=&quot;WXsI&quot;&gt;
    &lt;li id=&quot;Dmpw&quot;&gt;Переносим образы по одному в папку так же командой mv но в другую папку:  &lt;code&gt;sudo mv НАЗВАНИЕ_ФАЙЛА /opt/unetlab/addons/iol/bin/НАЗВАНИЕ_ФАЙЛА&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;lKxe&quot;&gt;После переноса всех образов выполняем команду &lt;code&gt;/opt/unetlab/wrappers/unl_wrapper -a fixpermissions&lt;/code&gt; – чтоб Ева заметила образы.&lt;/li&gt;
    &lt;li id=&quot;MDJY&quot;&gt;Создаём файл script.py в той же директории, где лежат образы, – название не принципиально – командой &lt;code&gt;sudo nano script.py&lt;/code&gt; и записываем в него код, сохраняем как обычно &lt;code&gt;Ctrl + o&lt;/code&gt;, &lt;code&gt;Enter&lt;/code&gt;, &lt;code&gt;Ctrl + x&lt;/code&gt;:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;SE7t&quot; data-lang=&quot;python&quot;&gt;#! /usr/bin/python
print &amp;quot;\n*********************************************************************&amp;quot;
print &amp;quot;Cisco IOU License Generator - Kal 2011, python port of 2006 C version&amp;quot;
import os
import socket
import hashlib
import struct
# get the host id and host name to calculate the hostkey
hostid=os.popen(&amp;quot;hostid&amp;quot;).read().strip()
hostname = socket.gethostname()
ioukey=int(hostid,16)
for x in hostname:
 ioukey = ioukey + ord(x)
print &amp;quot;hostid=&amp;quot; + hostid +&amp;quot;, hostname=&amp;quot;+ hostname + &amp;quot;, ioukey=&amp;quot; + hex(ioukey)[2:]
# create the license using md5sum
iouPad1=&amp;#x27;\x4B\x58\x21\x81\x56\x7B\x0D\xF3\x21\x43\x9B\x7E\xAC\x1D\xE6\x8A&amp;#x27;
iouPad2=&amp;#x27;\x80&amp;#x27; + 39*&amp;#x27;\0&amp;#x27;
md5input=iouPad1 + iouPad2 + struct.pack(&amp;#x27;!L&amp;#x27;, ioukey) + iouPad1
iouLicense=hashlib.md5(md5input).hexdigest()[:16]
# add license info to $HOME/.iourc
print &amp;quot;\n*********************************************************************&amp;quot;
print &amp;quot;Create the license file $HOME/.iourc with this command:&amp;quot;
print &amp;quot; echo -e &amp;#x27;[license]\\n&amp;quot; + hostname + &amp;quot; = &amp;quot; + iouLicense + &amp;quot;;&amp;#x27;&amp;quot; + &amp;quot; | tee $HOME/.iourc &amp;quot;
print &amp;quot;\nThe command adds the following text to $HOME/.iourc:&amp;quot;
print &amp;quot;[license]\n&amp;quot; + hostname + &amp;quot; = &amp;quot; + iouLicense + &amp;quot;;&amp;quot;
# disable phone home feature
print &amp;quot;\n*********************************************************************&amp;quot;
print &amp;quot;Disable the phone home feature with this command:&amp;quot;
print &amp;quot; grep -q -F &amp;#x27;127.0.0.1 xml.cisco.com&amp;#x27; /etc/hosts || echo &amp;#x27;127.0.0.1 xml.cisco.com&amp;#x27; | sudo tee -a /etc/hosts&amp;quot;
print &amp;quot;\nThe command adds the following text to /etc/hosts:&amp;quot;
print &amp;quot;127.0.0.1 xml.cisco.com&amp;quot;
print &amp;quot;\n*********************************************************************&amp;quot;&lt;/pre&gt;
  &lt;ul id=&quot;da1E&quot;&gt;
    &lt;li id=&quot;a4nO&quot;&gt;Запускаем скрипт командой &lt;code&gt;python script.py&lt;/code&gt;, увидим следующие две строки в выводе:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;e7sg&quot;&gt;[license]
название-машинки = НАБОР_ЦИФР_И_БУКВ;&lt;/pre&gt;
  &lt;ul id=&quot;HhdJ&quot;&gt;
    &lt;li id=&quot;7QeZ&quot;&gt;Копируем эти две строки, создаём файл iourc снова в той же директории с образами командой &lt;code&gt;sudo nano iourc&lt;/code&gt;, записываем в него эти две строчки – они будут разными у каждого – и сохраняем как обычно.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;ILBD&quot;&gt;Теперь образы цисок должны отображаться в Еве и работать. Если что – как всегда перезагрузка.&lt;/p&gt;
  &lt;p id=&quot;Q1y3&quot;&gt;Для остальных образов процедура почти та же, нюансы гуглятся.&lt;/p&gt;

</content></entry><entry><id>dtroode:eve-ng-google-cloud</id><link rel="alternate" type="text/html" href="https://teletype.in/@dtroode/eve-ng-google-cloud?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dtroode"></link><title>Установка EVE-NG на Google Cloud</title><published>2021-10-25T13:38:44.178Z</published><updated>2021-12-12T18:13:41.490Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/44/65/4465cb01-0857-4375-9e7a-3c1258cbd9ff.png"></media:thumbnail><category term="eve-ng" label="eve-ng"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/32/32/3232527a-f8d8-4103-aa66-b1c33bfb6852.jpeg&quot;&gt;Google Cloud подойдёт для студентов, он предоставляет бесплатные 300 долларов на 90 дней. Деньги тратятся на обслуживание сервера, затраты зависят от мощности сервера и частоты использования. Поэтому лучше выключать виртуальную машинку каждый раз, когда не используете её.</summary><content type="html">
  &lt;p id=&quot;z4d3&quot;&gt;Google Cloud подойдёт для студентов, он предоставляет бесплатные 300 долларов на 90 дней. Деньги тратятся на обслуживание сервера, затраты зависят от мощности сервера и частоты использования. Поэтому лучше выключать виртуальную машинку каждый раз, когда не используете её.&lt;/p&gt;
  &lt;p id=&quot;rIqa&quot;&gt;Плюсы Google Cloud в том, что не используются мощности вашего компьютера и получить полноценный доступ к Еве можно из любой точки с любого компьютера по айпи.&lt;/p&gt;
  &lt;p id=&quot;Qo8a&quot;&gt;На главной странице выбираем список проектов и создаём новый проект.&lt;/p&gt;
  &lt;figure id=&quot;Zoai&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/32/32/3232527a-f8d8-4103-aa66-b1c33bfb6852.jpeg&quot; width=&quot;2880&quot; /&gt;
    &lt;figcaption&gt;Нажимаем New Project&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;tjNq&quot;&gt;Готовим изображение&lt;/h2&gt;
  &lt;p id=&quot;Omi7&quot;&gt;Ева обычно настраивается на Убунте, поэтому нужно подготовить подходящее изображение Убунты.&lt;/p&gt;
  &lt;p id=&quot;hfj9&quot;&gt;Есть две версии Евы: Community и Pro. Вторая просит лицензионный ключ, первая бесплатная, обновляеся реже и в целом попроще. Для них нужны разные образы.&lt;/p&gt;
  &lt;p id=&quot;WreE&quot;&gt;Для Community:&lt;/p&gt;
  &lt;p id=&quot;GCfP&quot;&gt;Переходим по ссылке &lt;a href=&quot;https://console.cloud.google.com/marketplace/product/ubuntu-os-pro-cloud/ubuntu-pro-xenial?project=fiery-odyssey-325912&quot; target=&quot;_blank&quot;&gt;Ubuntu Pro&lt;/a&gt;, нажимаем Launch и переходим к следующему разделу про виртуалку.&lt;/p&gt;
  &lt;p id=&quot;N5uK&quot;&gt;Для Pro:&lt;/p&gt;
  &lt;p id=&quot;Bk3M&quot;&gt;Можно тоже установить через Ubuntu Pro, но она более финансово затратная, поэтому переходим в консоль проекта: &lt;/p&gt;
  &lt;figure id=&quot;zcJb&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0f/16/0f16bae6-1b17-4306-9aeb-9b0fd60fce9c.jpeg&quot; width=&quot;2374&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;sNs5&quot;&gt;И вставляем эту команду. Если просит авторизовать, разрешаем.&lt;/p&gt;
  &lt;pre id=&quot;eCXA&quot;&gt;gcloud compute images create nested-ubuntu-bionic --source-image-family=ubuntu-1804-lts --source-image-project=ubuntu-os-cloud --licenses https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx&lt;/pre&gt;
  &lt;h2 id=&quot;BLxp&quot;&gt;Виртуалка&lt;/h2&gt;
  &lt;p id=&quot;wNSH&quot;&gt;Находясь в новом проекте, в поиске – находится наверху на любой странице – вбиваем VM Instances и переходим в раздел с виртуальными машинами. Создаём новую машину.&lt;/p&gt;
  &lt;ol id=&quot;eRVl&quot;&gt;
    &lt;li id=&quot;w0T3&quot;&gt;Выбираем имя.&lt;/li&gt;
    &lt;li id=&quot;4mxV&quot;&gt;Выбираем регион и зону. Нужен тот регион, который ближе к нам. Эта зона будет дальше часто использоваться, но запоминать её не надо, всегда можно посмотреть.&lt;/li&gt;
    &lt;li id=&quot;3LB7&quot;&gt;Настраиваем железо. Нам подойдёт процессор типа N1 или N2, характеристики процессора и оперативной памяти на своё усмотрение в заивисмости от проекта. &lt;em&gt;Справа можно увидеть цену, которая уйдёт на обслуживание, но если не держать сервер включённым всё время, то она будет значительно меньше.&lt;/em&gt;&lt;/li&gt;
    &lt;li id=&quot;VPwn&quot;&gt;Выбирам загрузочный диск. Нажимаем изменить. Для Community Евы меняем размер диска на своё усмотрение, обычно 50-60 хватает. Для Pro Евы переходим в Custom images, выбираем свой проект, выбираем то изображение, которое создали, так же меняем размер диска.&lt;/li&gt;
    &lt;li id=&quot;XxZm&quot;&gt;Ниже разрешаем HTTP траффик, потому что будем использовать Еву без SSL-сертификата. Настройка HTTPS – отдельная тема.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;TSPI&quot;&gt;Машинка создастся и скоро станет доступна.&lt;/p&gt;
  &lt;h2 id=&quot;tTRc&quot;&gt;Установка самой Евы&lt;/h2&gt;
  &lt;p id=&quot;yGBi&quot;&gt;Если машинка не включилась, включаем её.&lt;/p&gt;
  &lt;figure id=&quot;M6I0&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/29/0f/290f7216-a7aa-4056-8704-9a2159cd6b7d.jpeg&quot; width=&quot;2118&quot; /&gt;
    &lt;figcaption&gt;Выбираем Start&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Rofk&quot;&gt;Переходим в консоль Евы по SSH:&lt;/p&gt;
  &lt;figure id=&quot;zXkU&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/18/cd/18cddcf2-20fb-4617-a53d-7c3a156af061.jpeg&quot; width=&quot;2044&quot; /&gt;
    &lt;figcaption&gt;Google Cloud попытается открыть ещё одно окно браузера, браузер может заблокировать это действие и сообщить об этом. В каждом браузере по-разному разрешается доступ, решение легко найти&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;NtQ5&quot;&gt;Заходим от рута &lt;code&gt;sudo -i&lt;/code&gt;, выполняем команды для установки евы и обновления:&lt;/p&gt;
  &lt;pre id=&quot;Zd1w&quot;&gt;wget -O - http://www.eve-ng.net/repo/install-eve.sh | bash -i
apt update
apt upgrade&lt;/pre&gt;
  &lt;p id=&quot;8SfM&quot;&gt;Перезапускаем машинку через меню с тремя точками. Снова заходим по SSH, появится синий экран. &lt;strong&gt;Нажимаем Ctrl + c&lt;/strong&gt;, вводим &lt;code&gt;sudo -i&lt;/code&gt; и настраиваем Еву.&lt;/p&gt;
  &lt;figure id=&quot;DgLV&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/9d/70/9d70b4a0-77b7-4dbb-a7e9-a32978630af7.png&quot; width=&quot;696&quot; /&gt;
    &lt;figcaption&gt;Синий экран, на этом моменте нельзя вводить пароль, сперва Ctrl + c&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;kssN&quot;&gt;На моменте с настройкой айпи адреса выбираем DHCP, дальше direct connection.&lt;/p&gt;
  &lt;figure id=&quot;FgUz&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6c/e4/6ce40e75-7b36-4161-8c55-b6c8b523d118.jpeg&quot; width=&quot;697&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;nVkm&quot;&gt;Перезапускаем машинку.&lt;/p&gt;
  &lt;h2 id=&quot;AKWs&quot;&gt;Вложенная виртуализация&lt;/h2&gt;
  &lt;p id=&quot;CrJ7&quot;&gt;Вложенная виртуализация нужна, чтоб можно было запускать виртуальные машинки внутри Евы (которая тоже является виртуальной машинкой). По умолчанию она не настроена.&lt;/p&gt;
  &lt;p id=&quot;VGDW&quot;&gt;Открываем внутреннюю консоль проекта. Прописываем три команды, где меняем EVE_NAME на имя своей виртуальной машинки, ZONE – на указанную зону этой машинки, её можно увидеть рядом с названием машинки, а PROJECT_ID – айди, которое можно узнать, нажав на имя проекта в левом верхнем углу страницы &lt;/p&gt;
  &lt;p id=&quot;m5Lb&quot;&gt;Эта команда копирует конфиг машинки в файл YAML_FILE_PATH. Название файла можно изменить.&lt;/p&gt;
  &lt;pre id=&quot;Ut3E&quot;&gt;gcloud compute instances export EVE-NAME \
  --project=PROJECT_ID \
  --destination=YAML_FILE_PATH \
  --zone=ZONE&lt;/pre&gt;
  &lt;p id=&quot;O2D1&quot;&gt;Эта команда добавляет в скопированный конфиг две строки, которые включают вложенную виртуализацию.&lt;/p&gt;
  &lt;pre id=&quot;QyQA&quot;&gt;cat &amp;lt;&amp;lt;EOT &amp;gt;&amp;gt; YAML_FILE_PATH
advancedMachineFeatures:
  enableNestedVirtualization: true
EOT&lt;/pre&gt;
  &lt;p id=&quot;QfQc&quot;&gt;Эта команда заменяет конфиг Евы на отредактированный нами, который хранится в файле.&lt;/p&gt;
  &lt;pre id=&quot;VX7u&quot;&gt;gcloud compute instances update-from-file EVE-NAME \
  --project=PROJECT_ID \
  --source=YAML_FILE_PATH \
  --most-disruptive-allowed-action=RESTART \
  --zone=ZONE&lt;/pre&gt;
  &lt;p id=&quot;8FZN&quot;&gt;Файл YAML_FILE_PATH можно удалять.&lt;/p&gt;
  &lt;h2 id=&quot;tNX9&quot;&gt;Фаервол&lt;/h2&gt;
  &lt;p id=&quot;m9D4&quot;&gt;По умолчанию многие порты блокируются виртуальной машинкой для внешнего доступа. Проблема в том, что доступ ко всем устройствам внутри лабораторных работ предоставляется по айпи Евы и порту устройства.&lt;/p&gt;
  &lt;p id=&quot;fdQb&quot;&gt;В поиске вбиваем Firewall, создаём правило для фаервола, придумываем ему имя. Разрешаем доступ по любому айпи к портам с 0 по 65535. Вот так:&lt;/p&gt;
  &lt;figure id=&quot;71dv&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/86/cb/86cb3b63-6975-45fe-80d2-ab59c3ca2b16.jpeg&quot; width=&quot;700.9999999999999&quot; /&gt;
    &lt;figcaption&gt;Остальное не меняем&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;bvNd&quot;&gt;И создаём ещё одно такое же правило, где вместо Ingress ставим Egress. Теперь трафик может ходить в обе стороны. Надо понимать, что теперь любой человек сможет подключиться к устройствам внутри вашей лабораторки, зная внешний айпи Евы и порт устройства.&lt;/p&gt;
  &lt;h2 id=&quot;WmRU&quot;&gt;Настройка интерфейсов&lt;/h2&gt;
  &lt;p id=&quot;f4Ip&quot;&gt;Машинка работает, но выхода в интернет у неё нет. Будем настраивать виртуальные интерфейсы таким образом, чтоб они передавали трафик на реальный интерфейс. Покажу на примере одного интерфейса. Всё делаем внутри Евы, чтоб зайти туда, используем кнопку SSH.&lt;/p&gt;
  &lt;ul id=&quot;HoAo&quot;&gt;
    &lt;li id=&quot;ogH3&quot;&gt;Сразу заходим в рут &lt;code&gt;sudo -i&lt;/code&gt; Переходим к файлу с конфигами интерфейсов редактором nano: &lt;code&gt;nano /etc/network/interfaces&lt;/code&gt;, здесь видим заголовок Cloud devices. Это всё интерфейсы. Настраиваем первый, чтоб он выглядел так:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;TNee&quot;&gt;iface eth1 inet manual
auto pnet1
iface pnet1 inet static
    bridge_ports eth1
    bridge_stp off
    address 10.199.199.1
    netmask 255.255.255.0&lt;/pre&gt;
  &lt;p id=&quot;PlMF&quot;&gt;Можно указать другой адрес, он станет адресом для Cloud 1 внутри лабораторки. Чтоб сохранить файл и выйти Ctrl + o, Enter, Ctrl + x.&lt;/p&gt;
  &lt;ul id=&quot;LZ8C&quot;&gt;
    &lt;li id=&quot;5IuO&quot;&gt;Перезагружаем сетевой сервис &lt;code&gt;systemctl restart networking&lt;/code&gt;. Теперь проверим, после ввода команды &lt;code&gt;ip a&lt;/code&gt; у pnet1 должен появится айпи, который мы указали.&lt;/li&gt;
    &lt;li id=&quot;Imuo&quot;&gt;Переходим к системному файлу: &lt;code&gt;nano /etc/sysctl.conf&lt;/code&gt;, убираем решётку в строке &lt;code&gt;net.ipv4.ip_forward=1&lt;/code&gt;, чтоб пакеты перенаправлялись. Так же сохраняем и выходим. Вводим команду &lt;code&gt;sysctl -p /etc/sysctl.conf&lt;/code&gt;, чтоб применить настройки.&lt;/li&gt;
    &lt;li id=&quot;JsID&quot;&gt;Настриваем правила для исходящего трафика командой &lt;code&gt;iptables -t nat -A POSTROUTING -s 10.199.199.0/24 -o pnet0 -j MASQUERADE&lt;/code&gt;. Здесь айпишник – сеть, которая должна соответствовать айпишнику интерфейса (указывали ранее).&lt;/li&gt;
    &lt;li id=&quot;YtD0&quot;&gt;Командой &lt;code&gt;iptables -L -nv -t nat&lt;/code&gt; можно проверить последнюю настройку, должны увидеть строку со знакомыми из прошлой команды словами. Чтоб сохранить изменения вводим несколько команд:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;fjKg&quot;&gt;iptables-save &amp;gt; /etc/iptables.rules
nano /etc/network/if-pre-up.d/iptables&lt;/pre&gt;
  &lt;ul id=&quot;rF6T&quot;&gt;
    &lt;li id=&quot;9vi4&quot;&gt;Вставляем этот кусок кода, чтоб каждый раз правила сами применялись:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;5J1I&quot;&gt;#!/bin/sh
iptables-restore &amp;lt; /etc/iptables.rules
exit 0&lt;/pre&gt;
  &lt;p id=&quot;3bST&quot;&gt; – и сохраняем Ctrl + o, Enter, Ctrl + x.&lt;/p&gt;
  &lt;ul id=&quot;RVXT&quot;&gt;
    &lt;li id=&quot;NFsQ&quot;&gt;Вводим команду: &lt;code&gt;nano /etc/network/if-post-down.d/iptables&lt;/code&gt;. Вставляем этот код, чтоб каждый раз правила сами сохранялись:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;Fask&quot;&gt;#!/bin/sh
iptables-save -c &amp;gt; /etc/iptables.rules
if [ -f /etc/iptables.rules ]; then
    iptables-restore &amp;lt; /etc/iptables.rules
fi
exit 0&lt;/pre&gt;
  &lt;p id=&quot;I42F&quot;&gt;– так же сохраняем.&lt;/p&gt;
  &lt;ul id=&quot;15m8&quot;&gt;
    &lt;li id=&quot;9gm3&quot;&gt;Вводим две команды, чтоб сделать файлы доступными для запуска:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;28Qi&quot;&gt;sudo chmod +x /etc/network/if-post-down.d/iptables
sudo chmod +x /etc/network/if-pre-up.d/iptables&lt;/pre&gt;
  &lt;p id=&quot;vM3A&quot;&gt;Теперь сеть должна работать.&lt;/p&gt;
  &lt;h2 id=&quot;LydC&quot;&gt;Работа с Евой&lt;/h2&gt;
  &lt;p id=&quot;6H8A&quot;&gt;В списке виртуальных машинок, нажав на имя машинки, можно увидеть и отредактировать её характеристики. Справа кнопка с тремя точками, чтоб запускать и выключать машинку.&lt;/p&gt;
  &lt;p id=&quot;jNE7&quot;&gt;External IP – адрес, по которому можно зайти в лабораторки Евы, Internal IP нужен для внутреннего использования, по нему тоже можно зайти в Еву, если натсроен SSH туннель, или из другой машинки.&lt;/p&gt;
  &lt;h2 id=&quot;4M3h&quot;&gt;&lt;a href=&quot;https://teletype.in/@dtroode/eve-ng-addons&quot; target=&quot;_blank&quot;&gt;Добавление образов в Еву&lt;/a&gt;&lt;/h2&gt;
  &lt;p id=&quot;Pycn&quot;&gt;В машинке пока почти нет образов, например Cisco, Mikrotik и разных операционок. Как их добавить рассказываю по ссылке в заголовке.&lt;/p&gt;

</content></entry></feed>