Miroslav Kuric (Siemens): Zabezpečení průmyslových podniků? Lidé z IT výrobě často nerozumí, je nutné řešit ji odděleně

11. 6. 2025
Doba čtení: 14 minut

Sdílet

Miroslav Kuric - Siemens
Autor: Siemens
Ve výrobě se hraje o čas, proto tam nelze použít stejné principy kybernetické bezpečnosti principy jako v IT systémech. Jak se průmyslové podniky chrání před útoky hackerů?

[Partnerský rozhovor] Kyberútoky dosud směřovaly zejména na IT systémy, jak se ale ve firmách stále častěji propojují s průmyslovými zařízeními, stoupá i riziko útoků přímo ve výrobě. Jejich ochrana se ale od řízení rizik v IT výrazně liší, říká odborník na kybernetickou bezpečnost ve výrobě z českého Siemensu Miroslav Kuric.

„Jedním ze specifik je velká roztříštěnost výrobců, standardů a systémů. Neexistuje obecný standard, jakým způsobem se řídí výrobní linka. Každý výrobce má svoje postupy. Samozřejmě existují snahy o standardizaci, které se týkají datové komunikace, sběrnic a podobně. Ale stále jsou několik desetiletí za úrovní standardizace v IT,“ upozorňuje.

Klíčovým opatřením podle něj je, aby se ve firmě o bezpečnost výrobních linek staral dedikovaný tým. „Velmi často setkáváme s tím, že lidé v IT požadavkům výroby nerozumí. Řešíte třeba dilema, jestli máte udělat upgrade, který záplatuje kritickou zranitelnost, i když tím přerušíte výrobu a například zničíte nějaký materiál, nebo systém chvilku nechat nezáplatovaný a počkat do následující odstávky. A to je typická situace, kterou je potřeba vydiskutovat a vyargumentovat. Když se odehrává pod výrobou, zastřešuje ji jeden člověk, který má odpovědnost za výrobu,“ vysvětluje.

Díval jsem se, jaké velké útoky na průmyslové firmy proběhly v uplynulém roce. Jeden mířil na německého výrobce baterií Varta, který kvůli němu musel na nejméně dva týdny odstavit výrobu. Útok cílil i na velkou americkou firmu Halliburton, která dodává zařízení pro těžbu ropy a zemního plynu. I té útok způsobil velké škody, když musela odstavit své IT systémy. Samozřejmě je to jen ukázka útoků, které byly zveřejněny. Viděl jsem i čísla, která říkají, že útoků na průmyslové firmy přibývá. Jaká je vaše zkušenost? Platí to? A jakých firem nebo jakých oborů se riziko nejvíc týká?

Naše zkušenosti to potvrzují a zveřejněné případy jsou jenom špičkou ledovce. Útočit se dnes dá mnohem jednodušeji než dřív a útoky se dají automatizovat, což dává útočníkům výhodu. Může jim být jedno, jestli nabourávají síť nemocnice nebo nějakého výrobního podniku. U výrobních podniků to nebylo ze začátku tolik vidět, protože když byly zasaženy jejich IT systémy, výroba většinou běžela dál. Vyrábělo se třeba na sklad, expedovalo se pomocí papírových faktur a podobně, takže to nevypadalo „tak kriticky“.

S tím, jak se výrobní světy otevírají a jak roste průchodnost mezi IT a OT, začínají útoky zasahovat přímo výrobu. V takovém okamžiku dopady útoku pocítí i zákazníci: jsou přerušené dodávky, začíná se něco dít v dodavatelském řetězci a je mnohem složitější útok utajit. Firma pak musí jít s kůží na trh a zveřejnit, že se něco stalo a že incident řeší.

Kromě zkratky IT, kterou asi všichni známe, jste použil také zkratku OT. Co to je?

Operational technology. Jde o výrobní technologie a související infrastrukturu. Když uvedu příklad, máme výrobní línku, která je propojená datovou sítí, což znamená infrastrukturu. Ve výrobní lince jsou také uložené recepty – vyrábíte například pivo, takže musíte vědět, kolik přidat sladu, chmele a dalších přísad. Tyto informace mohou být uložené na serveru, který je umístěn někde v síti. To všechno dohromady je operational technology.

Týká se to zvýšené množství útoků konkrétního oboru? 

Děje se to rozhodně napříč obory. Je pravda, že u některých oborů je to lépe vidět. Pokud využíváte třeba just-in-time metodologii, tak ve chvíli, kdy nevyrábíte, máte okamžitě problém. Když vyrábíte na sklad, nějakou dobu přežijete i bez bežící výroby – samozřejmě stále musíte být schopen zboží dodávat zákazníkovi.

Hodně se mluví o kritické infrastruktuře, o elektrárnách, vodárnách a podobně. Jsou i tyto průmyslové podniky více ohroženy?

Rozhodně. Firmy v kritické infrastruktuře ale mají jednu podstatnou výhodu: legislativa na ně myslela o něco dříve a podniky jsou připravenější, minimálně z legislativního pohledu. Mají tak určitý náskok. Průmyslová výroba dosud často fungovala v „ostrovním režimu“, to znamená že byla odstřižená od zbytku firmy a nikdo z ní nepotřeboval stahovat data. Nicméně výhody propojení výroby se světem dat teď převažují a jak se všechno začíná propojovat, začínají firmy zjišťovat, že se potřebují chránit.

Jsou útoky vedené pořád častěji na IT vrstvu, to znamená na servery a počítačové systémy? Anebo se setkáváte i s útoky na výrobní část?

Obecné útoky jdou většinou do IT světa. Jednotlivé výrobní ekosystémy se od sebe liší, takže když chcete provést automatizovaný útok například na průmyslové systémy Siemens, je to mnohem složitější, než když spustíte automatizovaný útok třeba na Windows. IT svět není tak roztříštěný a panuje v něm větší standardizace. Ale už se začínají objevovat útoky cílené na konkrétní oběti, a tam už útočníci míří hlavně na OT část, protože ta je většinou méně zabezpečená než IT.

Co vlastně obvykle bývá cílem útočníků? Snaží se narušit provoz firmy, vyžadují výkupné?

Většinou jim jde o peníze, proto je mezi útočníky tak populární ransomware. Samozřejmě je tady skupina útočníků, která se snaží o zničení nebo poškození funkčnosti daného subjektu. Jde například o útoky na energetickou infrastrukturu na Ukrajině. Takovým skupinám je pak jedno, kolik vydělají peněz, protože je obvykle někdo sponzoruje.

Jakým způsobem se útočníci pokoušejí dostat do cílových systémů? Používají klasický phishing a snaží se získat přístupové údaje? Nebo používají více plošné skenování portů a hledání zranitelností?

Vidím dva hlavní trendy. Prvním je využití všeobecně známých zranitelností, které se občas objeví i v řídících systémech ve výrobě. Útočník na tuto zranitelnost připraví nějaký <a>exploit (akce využívající tuto zranitelnost), snaží se rozhodit sítě a čeká, kde se „chytne“. Druhým trendem je cílení na zaměstnance. Když kliknou na něco podezřelého, nastane neplecha.

Pojďme se podrobněji podívat na výrobní systémy. V čem se liší od IT?

Specifik průmyslových systémů je celá řada. Obecně se oproti IT liší ve třech hlavních ohledech. Za prvé musí obvykle být v provozu 24 hodin 7 dní v týdnu. Není to samozřejmě pravidlem, občas se dá výroba odstavit, ale v řadě případů musí linka jet kontinuálně. Buď je to dáno ekonomicky: vyrábím a existuje určitá cena za to, že výroba stojí. Nebo je to dáno technologicky. Třeba u tavení skla putuje tavenina kontinuálně z místa, kde se taví, a já nemám šanci ji zastavit, protože kdybych ji zastavil, dojde k destrukci výrobního zařízení.

Dalším specifikem je velká roztříštěnost výrobců, standardů a systémů. Neexistuje obecný standard, jakým způsobem se řídí výrobní linka. Každý výrobce má svoje postupy. Samozřejmě existují snahy o standardizaci, které se týkají datové komunikace, sběrnic a podobně. Ale stále jsou několik desetiletí za úrovní standardizace v IT.

Třetím specifikem je dlouhý životní cyklus zařízení. Průmyslová zařízení se staví tak, aby měla dlouhou životnost. Když koupíte stroj a dáte za něj desítky milionů, nechcete ho za dva roky měnit kvůli tomu, že nemá nejnovější operační systém. Oproti tomu šéf IT v bance nemá problém vyměnit server, který mu běží tři roky, za nový. V IT jsou obrátky infrastruktury mnohem rychlejší a každé tři roky přijde něco nového. U výrobních strojů nemáte šanci postupovat stejně rychle.

Jak se vlastně vůbec nějaký útočník může do OT systémů dostat? Jsou standardně připojené někam k internetu? Čekal bych, že budou úplně oddělené.

Oddělené by samozřejmě být měly. Ale u komplexnějších systémů začíná být složitější i údržba a pokud na ni máte málo kvalifikovaných lidí, stoupá také tlak na vzdálený přístup a vzdálenou údržbu. Dále jsou tady nové postupy, jako je například prediktivní údržba, kdy se konstantně vyhodnocuje, jestli stroj běží v optimálním režimu. K tomu se dělají různé typy analýz a pohledů na výrobu, které sledují alarmové hlášky, stavy stroje, kvalitu výroby a podobně. A to bez dat nejde. Výrobní firmy jsou tak postupně nuceny své systémy do datového ekosystému podniku  připojovat. Samozřejmě, když člověk aspoň trochu přemýšlí, nepřipojí je přímo do internetu, ale je potřeba vyřešit to nějak jinak. Ani v IT si svoji databázi rovnou nevystavíte na internet.

No, neměl byste (smích).

To tedy (smích).

Miroslav Kuric - SiemensAutor: Siemens

Mluvil jste o dlouhém životním cyklu průmyslových zařízení. Znám případ strojů, které obsahovaly určitá čidla, která fungovala asi dvacet let a neprobíhaly u nich žádné softwarové updaty. V dotyčné firmě už nikdo pořádně nevěděl, jestli společnost, která je vyrobila, vůbec existuje. Je to v průmyslu standardní stav?

Neměl by to být standardní stav, ale často se s tím potkáváme. Výrobci strojů po těch dvaceti letech třeba už neexistují, někdo někoho koupil, někdo zkrachoval. Opakovaně se setkáváme s tím, že průmyslové aplikace postavily specializované firmy, které mají na danou oblast třeba jednoho experta a když ten člověk odejde do důchodu, systém běží, dokud funguje. Ale co potom s ním? Udržovat takový stroj ve funkčním a bezpečném stavu je oříšek. Nechci říct, že to je nemožné, ale je to složité.

Jak je možné takové OT systémy chránit? To se na každou velkou CNC mašinu nainstaluje firewall?

V IT světě je všechno online, všechno je připojené, všechno je možné udělat prakticky hned. Princip kybernetické ochrany tady tkví v tom, že zavádím určité standardizace. IT manažer řekne, že všichni budou mít tuto verzi Windows, upgradovat se bude v těchto momentech, bude se používat tento konkrétní antivir. Hardware je ideálně taky standardní. Strategie je tedy založená na standardech a občas řešíte nějakou výjimku.

Ve světě OT je to přesně naopak. Tam v podstatě nejde vybudovat standard a aplikovat obecné normy. Neustále řešíte specifické situace. Z toho vychází i to, jak chránit výrobu. Uvedu jednoduchý příklad. V IT je naprosto běžnou věcí vícefaktorová autentizace. Je to skvělá věc, kterou má útočník velký problém překonat. Jenže kdybyste ji chtěli aplikovat ve výrobě, dostanete se často do neřešitelné situace.

Máte například operátora, který se má autorizovat vůči nějakému displeji. Jenomže ten operátor běhá všude možně, pracuje v rukavicích, má ulepené prsty… Jak ten dvoufaktor provedete? Jedním faktorem, tím fyzickým, může být to, že si pípne kartou. A co ten druhý? Má v rukavicích zadávat PIN? Autentifikovat se otiskem, který mu střídavě bude a nebude fungovat? Nebo naskenovat sítnici, když třeba výroba vyžaduje, aby měl nasazené ochranné brýle?

A jak se to tedy dáte vyřešit? Autentizuje se jen kartou? 

Prostě třeba použijete jen jeden faktor, ale takto přihlášený operátor bude mít třeba omezené možnosti, co může v systému dělat. Podstatné úpravy pak např. povolíme technologovi, který je ale udělá z počítače, kde už vícefaktor realizujete výrazně jednodušeji.

Jakým způsobem se tedy výroba před kyberútoky chrání?

Na začátku je ideální udělat si koncept kybernetické bezpečnosti, který určí, jakým způsobem chci výrobu chránit. Naprostým základem je oddělit IT a OT. Ideálně i personálně, tedy aby to neřešil stejný tým, protože tyto dvě oblasti fungují úplně jinak. U výroby je nejdůležitější, aby jela. Hraje se o čas. Když to porovnáte s IT, tak když vám e-mail přijde o 10 minut později, svět se nezboří. Jenže když se dopravník pohne o 20 milisekund později, může dojít k velké katastrofě.

Jeden ze základních konceptů ochrany je proto výrobu oddělit od IT světa. To znamená, že mezi ně nasadím firewall nebo i více firewallů. Potom se snažím do výroby omezit přístup lidí, kteří tam nemají co dělat. Je to jednak z bezpečnostních důvodů, ale také proto, že vím, že stroje nebudu schopný stoprocentně zabezpečit. V kancelářích třeba můžu mít Wi-Fi síť, která má dosah po celém prostoru. Ve výrobě udělám pokrytí jen pro konkrétní pracoviště, které připojení potřebuje. Proč by měla síť svítit do celé výroby? A to je jen jeden z příkladů bezpečnostního konceptu.

Z našich zkušeností vyplývá, že ve firmách, kterým se povedlo vyčlenit OT do samostatné jednotky, se daří prosazovat principy a implementace bezpečnostních projektů výrazně lépe. Většinou to je spojené s tím, že bezpečnostní tým je přímo podřízen výrobě, která mu říká, co potřebuje a jaká jsou omezení.

To je důležité, protože se velmi často setkáváme s tím, že lidé v IT požadavkům výroby nerozumí. Proč teď nemůžu udělat upgrade, když záplatuje kritickou zranitelnost? Řešíte dilema, jestli máte upgrade udělat, i když tím přerušíte výrobu a například zničíte nějaký materiál, nebo systém chvilku nechat nezáplatovaný a počkat do následující odstávky. A to je typická situace, kterou je potřeba vydiskutovat a vyargumentovat. Když se odehrává pod výrobou, zastřešuje ji člověk, který má odpovědnost za výrobu.

Pokračujeme dál. Když máte oddělené OT a IT, provedete segmentaci výroby. To znamená, že se snažíte zajistit, aby při zasažení jednoho článku výroby nepadlo všechno. Typicky například z kapacitních důvodů provozujete tři výrobní línky, které dělají to samé. Když je oddělíte a dojde k útoku, jedna může spadnout, ale další dvě jedou.

Rozumím oddělení IT a OT, ale na druhou stranu spolu tyhle dvě části firmy musí nějakým způsobem spolupracovat.

Je možná důležité říct, že charakteristika dat, která běží na infrastruktuře ve výrobě, je jiná než u dat, která běží v IT. Ve výrobě většinou jde o pravidelnost – máte například senzor, který odešle data každé tři vteřiny. Nebo řídící systém, který v definovaný okamžik pošle příkaz „posuň celý dopravník“. Datové toky jsou relativně dobře predikovatelné a mají očekávaný rozsah a velikost. V IT je to jinak. Jednou stahujete soubor, jednou brouzdáte na internetu, jednou posíláte nějakou tabulku. Je to naprosto nahodilé. Monitoring sítě v IT zjednodušeně sleduje, co kam jde, jak je to velké a dívá se víc do obsahu. V OT světě je to jiné. Máte obraz toho, jak probíhá komunikacea jak síť ve standardní výrobě funguje a když se tam objeví něco nového, co najednou začne generovat „traffic v IT stylu“, tak víte, že máte asi problém.

Detekce anomálií je tedy v OT asi o něco jednodušší.

V tomto ohledu určitě ano. Ale zase na druhou stranu je složitější analýza obsahu. Ve výrobě se totiž používá řada specifických průmyslových protokolů.

Mluvil jste o tom, že se u průmyslových zařízení často aktualizuje software, musí tam tedy existovat například nějaké vzdálené přístupy. Dají se dostatečně zabezpečit firewallem nebo správou přístupů?

Funguje to podobně jako v IT: máte určitou oblast, demilitarizovanou zónu (DMZ), přes kterou k jednotlivým zařízením zvenčí přistupujete. Tato oblast je zabezpečená firewally, dochází v ní k autorizaci a teprve pak vás systém pustí do interní sítě. Takže když jdete z internetu, nejdřív se dostanete do DMZ, pak do IT sítě, která je striktně oddělená od OT, opět přes firewall, který vás autorizuje, a teprve poté můžete jít do demilitarizované zóny OT. V OT DMZ by měly být jenom aplikace, které přímo souvisí s výrobou. A když chcete dělat s výrobními daty v IT síti, je rozumné nejdřív je přenést z OT světa do databáze, která je v IT světě, a tam s nimi teprve pracovat.

Co supply-chain útoky? Jsou problémem i ve výrobě?

Nestává se, že by vám přišel nějaký infikovaný materiál. Ani si nemyslím, že by to byla hrozba na úrovni dodávek výrobních technologií, protože jde o systémy, které zákaznici dodávají „jako box“, do kterého nikoho jiného nepouští. Na úrovni OT je to, řekněme, jednodušší situace než v IT.

Co do oblasti zabezpečení výrobních systémů přinese kyberbezpečnostní směrnice NIS2, kterou implementuje právě schvalovaný zákon o kybernetické bezpečnosti?

Kdybych to výrazně zjednodušil, tak směrnice říká, že se výroba považuje za regulovanou službu a firma má tuto regulovanou službu chránit z hlediska kybernetické bezpečnosti. To znamená, že musí zjistit, jak daný výrobek vyrábí, zanalyzovat současný stav a případné hrozby a přijmout odpovídající opatření, včetně opatření, která se stýkají tzv. business continuity, zajištění kontinuity činností podniku. To mimo jiné znamená, že musím vědět, co budu dělat, když se výroba kvůli kybernetickému útoku zastaví.

Je pro firmy lepší řešit bezpečnost v rámci výrobního procesu interně, nebo by bezpečnostní analýzu měla dělat spíš externí společnost?

V oblasti kybernetické bezpečnosti je vždycky lepší, když si ji řešíte sám. Ale je tady jedno velké ale. Potřebujete mít člověka, který má zkušenosti jak z oblastí výroby, tak z oblasti kybernetické bezpečnosti. A najít takového člověka je velmi těžké. Pokud máte skutečně silný tým kybernetické bezpečnosti, který má detailní znalosti výroby a ví, jaké principy tam využít, je možné řešit to svými silami. To je třeba případ Siemensu, protože máme i výrobní závody a tuto oblast velmi podrobně a dlouhodobě řešíme. Ale většina výrobních firem v podobné situaci určitě nebude. Pak je potřeba najít nějakého důvěryhodného, stabilního partnera, který má zkušenosti i z výrobního sektoru.

Alekompletně pokryt kybernetickou bezpečnost externími zdroji v zásadě není možné. I schvalovaný kyberbezpečnostní zákon jasně říká, že firmy musí zapojit vlastní zaměstnance. To zapojení může být malé, velké, až skoro 100%, ale vždycky tam je potřeba dodat svůj pohled z hlediska firmy, svoje know-how ohledně výroby.

Nekomplikují situaci konvergenční trendy, kdy principy IT pronikají i do OT světa? 

Konvergence může určitým způsobem zvyšovat rizika. Ať už se týká virtualizace, <a>což je v OT trochu strašidelný pojem – třeba virtualizace nějakého řídícího systému,– ale i tyto technologie už existují a mají své místo a využití. Může se týkat také aplikačních serverů. V OT DMZ už nemusí figurovat fyzické železo, může to být nějaký virtuální server, který funguje na základě principů z IT. To určitě není problém. A ještě je tady jedno riziko: že když přijde management a vidí, že v OT se používají podobné principy jako v IT, řekne si, ano, pojďme to všechno hodit na IT oddělení, oni to zvládnou. Ale pak to většinou dost skřípe.

CIF25 SE debata

Takže konvergovat, ale opatrně (smích).

Opatrně (smích). Když přijde poradenská firma a řekne, ano, poradíme vám, jak na to, a ani se nejde podívat do výroby, nebo řekne, že se výroba přizpůsobí nějakým standardům, třeba: přestavíme linku tak, aby byla na Windowsech a mohla se updatovat každých 15 minut (smích), mělo by rovnou zvednout červenou vlajku. Kouzlo je skryté v drobných detailech, které se musí vyřešit, aby to celé fungovalo. A to ne každý vidí a umí vyřešit efektivně.

  • Chcete mít Lupu bez bannerů?
  • Chcete dostávat speciální týdenní newsletter o zákulisí českého internetu?
  • Chcete mít k dispozici strojové přepisy podcastů?
  • Chcete získat slevu 1 000 Kč na jednu z našich konferencí?

Staňte se naším podporovatelem

Seriál: Rozhovory
Neutrální ikona do widgetu na odběr článků ze seriálů

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.


Autor článku

Šéfredaktor Lupa.cz a externí spolupracovník Českého rozhlasu Plus. Dříve editor IHNED.cz, předtím Aktuálně.cz a Českého rozhlasu. Zaměřuje se na telekomunikace, umělou inteligenci i na média. Najdete ho na Twitteru nebo na LinkedIn

Upozorníme vás na články, které by vám neměly uniknout (maximálně 2x týdně).
'; document.getElementById('outstream-iframe').onload = function () { setupIframe(); } replayScreen = document.getElementById('iinfoOutstreamReplay'); iinfoOutstreamPosition = document.getElementById('iinfoOutstreamPosition'); outstreamContainer = document.getElementsByClassName('outstream-container')[0]; setupReplayScreen(); } function setupIframe() { outstreamDocument = document.getElementById('outstream-iframe').contentWindow.document; let el = outstreamDocument.createElement('style'); outstreamDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:-5px;right:25px}"; videoContent = outstreamDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; if ( location.href.indexOf('rejstriky.finance.cz') !== -1 || location.href.indexOf('finance-rejstrik') !== -1 || location.href.indexOf('firmy.euro.cz') !== -1 || location.href.indexOf('euro-rejstrik') !== -1 || location.href.indexOf('/rejstrik/') !== -1 || location.href.indexOf('/rejstrik-firem/') !== -1) { outstreamDirectPlayed = true; soundAllowed = true; iinfoVastUrlIndex = 0; } if (!outstreamDirectPlayed) { console.log('OUTSTREAM direct'); setUpIMA(true); } else { if (soundAllowed) { const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('OUTSTREAM sound allowed'); setUpIMA(false); }).catch(function () { console.log('OUTSTREAM sound forbidden'); renderBanner(); }); } } else { renderBanner(); } } } function getWrapper() { let articleWrapper = document.querySelector('.rs-outstream-placeholder'); // Outstream Placeholder from RedSys manipulation if (articleWrapper && articleWrapper.style.display !== 'block') { articleWrapper.innerHTML = ""; articleWrapper.style.display = 'block'; } // Don't render OutStream on homepages if (articleWrapper === null) { if (document.querySelector('body.p-index')) { return null; } } if (articleWrapper === null) { articleWrapper = document.getElementById('iinfo-outstream'); } if (articleWrapper === null) { articleWrapper = document.querySelector('.layout-main__content .detail__article p:nth-of-type(6)'); } if (articleWrapper === null) { // Euro, Autobible, Zdravi articleWrapper = document.querySelector('.o-article .o-article__text p:nth-of-type(6)'); } if (articleWrapper === null) { articleWrapper = document.getElementById('sidebar'); } if (!articleWrapper) { console.error("Outstream wrapper of article was not found."); } return articleWrapper; } function setupDimensions() { outstreamWidth = Math.min(iinfoOutstreamPosition.offsetWidth, 480); outstreamHeight = Math.min(iinfoOutstreamPosition.offsetHeight, 320); } /** * Sets up IMA ad display container, ads loader, and makes an ad request. */ function setUpIMA(direct) { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); if (direct) { adsRequest.adTagUrl = directVast; console.log('Outstream DIRECT CAMPAING advert: ' + directVast); videoContent.muted = true; videoContent.volume = 0; outstreamDirectPlayed = true; } else { adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Outstream advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; } // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = outstreamWidth; // adsRequest.linearAdSlotHeight = outstreamHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function setupReplayScreen() { replayScreen.addEventListener('click', function () { iinfoOutstreamPosition.remove(); iinfoVastUrlIndex = 0; outstreamInit(); }); } /** * Sets the 'adContainer' div as the IMA ad display container. */ function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. outstreamDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( outstreamDocument.getElementById('adContainer'), videoContent); } function unmuteAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } } /** * Loads the video content and initializes IMA ad playback. */ function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(outstreamWidth, outstreamHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } /** * Handles the ad manager loading and sets ad event listeners. * @param { !google.ima.AdsManagerLoadedEvent } adsManagerLoadedEvent */ function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } /** * Handles actions taken in response to ad events. * @param { !google.ima.AdEvent } adEvent */ function onAdEvent(adEvent) { // Retrieve the ad from the event. Some events (for example, // ALL_ADS_COMPLETED) don't have ad object associated. const ad = adEvent.getAd(); console.log('Outstream event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to // determine whether the ad is a video ad or an overlay. if (!ad.isLinear()) { // Position AdDisplayContainer correctly for overlay. // Use ad.width and ad.height. videoContent.play(); } outstreamDocument.getElementById('adContainer').style.width = '100%'; outstreamDocument.getElementById('adContainer').style.maxWidth = '640px'; outstreamDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); // This event indicates the ad has started - the video player // can adjust the UI, for example display a pause button and // remaining time. if (ad.isLinear()) { // For a linear ad, a timer can be started to poll for // the remaining time. intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } outstreamDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (outstreamLastError === 303) { if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } } break; case google.ima.AdEvent.Type.COMPLETE: // This event indicates the ad has finished - the video player // can perform appropriate UI actions, such as removing the timer for // remaining time detection. if (ad.isLinear()) { clearInterval(intervalTimer); } if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } break; } } /** * Handles ad errors. * @param { !google.ima.AdErrorEvent } adErrorEvent */ function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); outstreamLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { renderBanner(); } } function renderBanner() { if (isBanner) { console.log('Outstream: Render Banner'); iinfoOutstreamPosition.innerHTML = ""; iinfoOutstreamPosition.style.height = "330px"; iinfoOutstreamPosition.appendChild(bannerDiv); } else { console.log('Outstream: Banner is not set'); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoOutstreamPosition.remove(); outstreamInit(); } else { return false; } adVolume = 1; return true; } /** * Pauses video content and sets up ad UI. */ function onContentPauseRequested() { videoContent.pause(); // This function is where you should setup UI for showing ads (for example, // display ad timer countdown, disable seeking and more.) // setupUIForAds(); } /** * Resumes video content and removes ad UI. */ function onContentResumeRequested() { videoContent.play(); // This function is where you should ensure that your UI is ready // to play content. It is the responsibility of the Publisher to // implement this function when necessary. // setupUIForContent(); } function onActiveView() { if (outstreamContainer) { const containerOffset = outstreamContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (outstreamPaused) { adsManager.resume(); outstreamPaused = false; } return true; } else { if (!outstreamPaused) { adsManager.pause(); outstreamPaused = true; } } } return false; } let outstreamInitInterval; if (typeof cpexPackage !== "undefined") { outstreamInitInterval = setInterval(tryToInitializeOutstream, 100); } else { const wrapper = getWrapper(); if (wrapper) { let outstreamInitialized = false; window.addEventListener('scroll', () => { if (!outstreamInitialized) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { outstreamInit(); outstreamInitialized = true; } } }); } } function tryToInitializeOutstream() { const wrapper = getWrapper(); if (wrapper) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { if (cpexPackage.adserver.displayed) { clearInterval(outstreamInitInterval); outstreamInit(); } } } else { clearInterval(outstreamInitInterval); } } }
OSZAR »