<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>python &#8211; RSNET.PL</title>
	<atom:link href="https://kubsoo.github.io/rsnet-website/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>https://kubsoo.github.io/rsnet-website/</link>
	<description>wszystko o sieciach komputerowych</description>
	<lastBuildDate>Sat, 22 Feb 2020 11:40:47 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.8</generator>
	<item>
		<title>Palo Alto API tworzenie reguł &#8211; Python skrypt</title>
		<link>https://kubsoo.github.io/rsnet-website/palo-alto-api-reguly-python-skrypt/</link>
		<comments>https://kubsoo.github.io/rsnet-website/palo-alto-api-reguly-python-skrypt/#respond</comments>
		<pubDate>Mon, 19 Mar 2018 19:33:04 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[palo alto]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[skrypt]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=1030</guid>
		<description><![CDATA[Korzystając z API możemy na firewallach Palo Alto dodawać reguły bezpieczeństwa bez konieczności otwierania interfejsu do zarządzania i tworzenia reguł wybierając odpowiednie opcje z menu.   ŚRODOWISKO Do celów demonstracji&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[		<div class="elementor elementor-1030">
			<div class="elementor-inner">
				<div class="elementor-section-wrap">
							<section data-id="b4f5b76" class="elementor-element elementor-element-b4f5b76 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="e876d39" class="elementor-element elementor-element-e876d39 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="93d42a5" class="elementor-element elementor-element-93d42a5 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Korzystając z API możemy na firewallach Palo Alto dodawać reguły bezpieczeństwa bez konieczności otwierania interfejsu do zarządzania i tworzenia reguł wybierając odpowiednie opcje z menu.</span></p><p style="text-align: justify;"><span style="color: #000000;"> </span></p><h5><span style="color: #000000;">ŚRODOWISKO</span></h5><p style="text-align: justify;"><span style="color: #000000;">Do celów demonstracji możliwości tworzenia reguł bezpieczeństwa przy pomocy API na urządzeniach Palo Alto posłużyłem się topologią zbudowaną w GNS3, tą samą co w tym <a href="https://kubsoo.github.io/rsnet-website/palo-alto-api-backup-konfiguracji-python-skrypt/" title="">wpisie</a>. </span></p><p><strong><span style="color: #000000;">TOPOLOGIA</span></strong></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="c4f19c4" class="elementor-element elementor-element-c4f19c4 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="d5954f2" class="elementor-element elementor-element-d5954f2 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="fbbda61" class="elementor-element elementor-element-fbbda61 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/01/topology_1.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-0" data-rl_title="" data-rl_caption="" title="">
							<img width="605" height="452" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/01/topology_1.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/01/topology_1.png 605w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/01/topology_1-300x224.png 300w" sizes="(max-width: 605px) 100vw, 605px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="5fc70e6" class="elementor-element elementor-element-5fc70e6 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="d958656" class="elementor-element elementor-element-d958656 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="aa607b2" class="elementor-element elementor-element-aa607b2 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"> </p><h5><span style="color: #000000;">SKRYPT</span></h5></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="fed1942" class="elementor-element elementor-element-fed1942 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="296c5ed" class="elementor-element elementor-element-296c5ed elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="6e95d2c" class="elementor-element elementor-element-6e95d2c elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Skrypt tworzący regułę bezpieczeństwa, przenoszący ją w odpowiednie miejsce a na końcu robiący commit zmian wygląda następująco:</span></p><p style="text-align: justify;"><strong style="background-color: initial;">config_palo.py</strong></p><pre>#!/usr/bin/python<br /><br />import requests, getpass, re<br /><br />## list of firewalls<br />firewalls_ip = [<br /> '192.168.0.201',<br /> '192.168.0.202',<br /> '192.168.0.203',<br />]<br /><br />## login and password for firewall<br />username = raw_input("Please enter your username: ") <br />password = getpass.getpass("Please enter your password: ")<br /><br />## generate api key<br />url = "https://192.168.0.201/api/?type=keygen&amp;user={}&amp;password={}"<br />response = requests.get(url.format(username,password), verify=False)<br />response.raise_for_status()<br />regex = re.compile(r'&lt;key&gt;(.*)&lt;\/key&gt;')<br />key = regex.findall(response.text)[0]<br />print ("\nYour API key is: %s\n") % (key)<br /><br />rule_path = "/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/rulebase/security/rules"<br />rule_name = "permit_any"<br /><br />rule = """<br /> &lt;entry name="{}"&gt;<br /> &lt;to&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/to&gt;<br /> &lt;from&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/from&gt;<br /> &lt;source&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/source&gt;<br /> &lt;destination&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/destination&gt;<br /> &lt;source-user&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/source-user&gt;<br /> &lt;category&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/category&gt;<br /> &lt;application&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/application&gt;<br /> &lt;service&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/service&gt;<br /> &lt;hip-profiles&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/hip-profiles&gt;<br /> &lt;action&gt;deny&lt;/action&gt;<br /> &lt;log-start&gt;no&lt;/log-start&gt;<br /> &lt;description&gt;permit any any rule&lt;/description&gt;<br /> &lt;disabled&gt;no&lt;/disabled&gt;<br /> &lt;/entry&gt;<br />"""<br /><br />for ip in firewalls_ip:<br /><br /> print ("Adding security rule to: %s\n") % (ip)<br /> url = "https://"+ip+"/api/?type=config&amp;action=set&amp;key={}&amp;xpath={}&amp;element={}"<br /><br /> response = requests.post(url.format(key,rule_path,rule.format(rule_name)), verify=False)<br /> response.raise_for_status()<br /> print (response.text)<br /><br /> print ("Moving security rule ...\n")<br /> move = raw_input("Do you want to move security rule ? (y/n) ")<br /> if move == "y":<br />  rule_pos = raw_input("Insert rule name after which you want to place new rule: ")<br />  url = "https://"+ip+"/api/?type=config&amp;action=move&amp;key={}&amp;xpath={}/entry[@name='{}']&amp;where=after&amp;dst={}"<br />  response = requests.get(url.format(key,rule_path,rule_name,rule_pos), verify=False)<br />  response.raise_for_status()<br />  print (response.text)<br /><br /> print ("Commiting changes ...\n")<br /> commit = raw_input("Are you sure you want to commit ? (y/n) ")<br /> if commit == "y":<br />  url = "https://"+ip+"/api/?type=commit&amp;key={}&amp;cmd=&lt;commit&gt;&lt;/commit&gt;"<br />  commit_response = requests.post(url.format(key),verify=False)<br />  commit_response.raise_for_status()<br />  print (response.text)<br /> else:<br />  print ("Commit cancelled !\n")</pre><p>Cały skrypt można ściągnąć pod tym <a href="https://gist.github.com/kubsoo/cf5880a46bd69300c746f8daaf27859e" title="">linkiem</a>.</p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="7888aac" class="elementor-element elementor-element-7888aac elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="14d378d" class="elementor-element elementor-element-14d378d elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="8a09ec2" class="elementor-element elementor-element-8a09ec2 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p><strong>Opis skryptu:</strong></p><ol><li>Lista IP z firewallami na których chcemy stworzyć regułę bezpieczeństwa:</li></ol><pre>firewalls_ip = [<br /> '192.168.0.201',<br /> '192.168.0.202',<br /> '192.168.0.203',<br />]</pre><p style="text-align: justify;">2. Stworzenie klucza API KEY przy pomocy logowania użytkownikiem i hasłem do jednego z firewalli z listy (pod warunkiem ze na każdym FW mamy tego samego użytkownika i hasło, w innym przypadku klucz musimy generować dla każdego z FW osobno)</p><pre>## login and password for firewall<br />username = raw_input("Please enter your username: ") <br />password = getpass.getpass("Please enter your password: ")<br /><br />## generate api key<br />url = "https://192.168.0.201/api/?type=keygen&amp;user={}&amp;password={}"<br />response = requests.get(url.format(username,password), verify=False)<br />response.raise_for_status()<br />regex = re.compile(r'(.*)&lt;\/key&gt;')<br />key = regex.findall(response.text)[0]<br />print ("\nYour API key is: %s\n") % (key)</pre><p>3. Stworzenie zmiennej o nazwie &#8222;rule&#8221; zawierającej regułę w postaci xml. Można taką regułę odczytać z pliku xml z konfiguracją. W powyższym skrypcie reguła zezwala na cały ruch z każdej strefy i każdego adresu do każdej strefy i do każdego adresu (allow any any)</p><pre>rule_path = "/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/rulebase/security/rules"<br />rule_name = "permit_any"<br /><br />rule = """<br /> &lt;entry name="{}"&gt;<br /> &lt;to&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/to&gt;<br /> &lt;from&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/from&gt;<br /> &lt;source&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/source&gt;<br /> &lt;destination&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/destination&gt;<br /> &lt;source-user&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/source-user&gt;<br /> &lt;category&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/category&gt;<br /> &lt;application&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/application&gt;<br /> &lt;service&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/service&gt;<br /> &lt;hip-profiles&gt;<br /> &lt;member&gt;any&lt;/member&gt;<br /> &lt;/hip-profiles&gt;<br /> &lt;action&gt;deny&lt;/action&gt;<br /> &lt;log-start&gt;no&lt;/log-start&gt;<br /> &lt;description&gt;permit any any rule&lt;/description&gt;<br /> &lt;disabled&gt;no&lt;/disabled&gt;<br /> &lt;/entry&gt;<br />"""</pre><p>4. Tworzenie reguły dla każdego firewalla z listy firewalls_ip:</p><pre>for ip in firewalls_ip:<br /><br />  print ("Adding security rule to: %s\n") % (ip)<br />  url = "https://"+ip+"/api/?type=config&amp;action=set&amp;key={}&amp;xpath={}&amp;element={}"<br /> <br />  response = requests.post(url.format(key,rule_path,rule.format(rule_name)), verify=False)<br />  response.raise_for_status()<br />  print (response.text)</pre><p style="text-align: justify;">5. Reguła stworzona w poprzednim punkcie jest tworzona i dodawana do konfiguracji na końcu. Zmianę miejsca reguły realizuje poniższy fragment skryptu:</p><pre> print ("Moving security rule ...\n")<br /> move = raw_input("Do you want to move security rule ? (y/n) ")<br /> if move == "y":<br />   rule_pos = raw_input("Insert rule name after which you want to place new rule: ")<br />   url = "https://"+ip+"/api/?type=config&amp;action=move&amp;key={}&amp;xpath={}/entry[@name='{}']&amp;where=after&amp;dst={}"<br />   response = requests.get(url.format(key,rule_path,rule_name,rule_pos), verify=False)<br />   response.raise_for_status()<br />   print (response.text)</pre><p>6. Commit zmian:</p><pre> print ("Commiting changes ...\n")<br /> commit = raw_input("Are you sure you want to commit ? (y/n) ")<br /> <br /> if commit == "y":<br />   url = "https://"+ip+"/api/?type=commit&amp;key={}&amp;cmd=&lt;commit&gt;&lt;/commit&gt;"<br />   commit_response = requests.post(url.format(key),verify=False)<br />   commit_response.raise_for_status()<br />   print (response.text)<br /> else:<br />   print ("Commit cancelled !\n")</pre></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="bd3186f" class="elementor-element elementor-element-bd3186f elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="fce5906" class="elementor-element elementor-element-fce5906 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="48ab48e" class="elementor-element elementor-element-48ab48e elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p><span style="color: #000000;">Sprawdźmy działanie skryptu w praktyce:</span></p><p style="text-align: justify;"><span style="color: #000000;">Na początek sprawdźmy jak wygląda zakładka Policies -&gt; Security na każdym z firewalli:</span></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="e3aba3c" class="elementor-element elementor-element-e3aba3c elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="d98d96f" class="elementor-element elementor-element-d98d96f elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="8edb747" class="elementor-element elementor-element-8edb747 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-1" data-rl_title="" data-rl_caption="" title="">
							<img width="720" height="203" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1.png 1006w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1-300x85.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1-768x217.png 768w" sizes="(max-width: 720px) 100vw, 720px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="05fcb24" class="elementor-element elementor-element-05fcb24 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="f6ae8ac" class="elementor-element elementor-element-f6ae8ac elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="8aa0650" class="elementor-element elementor-element-8aa0650 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-2" data-rl_title="" data-rl_caption="" title="">
							<img width="720" height="184" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2.png 1012w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2-300x77.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2-768x197.png 768w" sizes="(max-width: 720px) 100vw, 720px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="833427e" class="elementor-element elementor-element-833427e elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="e5e9c85" class="elementor-element elementor-element-e5e9c85 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="f2611b5" class="elementor-element elementor-element-f2611b5 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-3" data-rl_title="" data-rl_caption="" title="">
							<img width="720" height="186" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3.png 1016w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3-300x77.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3-768x198.png 768w" sizes="(max-width: 720px) 100vw, 720px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="df5b664" class="elementor-element elementor-element-df5b664 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="48038e8" class="elementor-element elementor-element-48038e8 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="5de83d6" class="elementor-element elementor-element-5de83d6 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"> </p><p style="text-align: justify;">Teraz uruchamiamy skrypt&#8230;</p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="e7c6fc3" class="elementor-element elementor-element-e7c6fc3 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="1beea1b" class="elementor-element elementor-element-1beea1b elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="b0baaf8" class="elementor-element elementor-element-b0baaf8 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><pre id="code" class="brush: text; plain-text"><strong>root@NetworkAutomation-1:~# ./config_palo.py</strong>
Please enter your username: admin
Please enter your password:
/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

Your API key is: LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09

Adding security rule to: 192.168.0.201

/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
&lt;response status="success" code="20"&gt;&lt;msg&gt;command succeeded&lt;/msg&gt;&lt;/response&gt;
Moving security rule ...

Do you want to move security rule ? (y/n) n
Commiting changes ...

Are you sure you want to commit ? (y/n) y
/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
&lt;response status="success" code="20"&gt;&lt;msg&gt;command succeeded&lt;/msg&gt;&lt;/response&gt;
Adding security rule to: 192.168.0.202

/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
&lt;response status="success" code="20"&gt;&lt;msg&gt;command succeeded&lt;/msg&gt;&lt;/response&gt;
Moving security rule ...

Do you want to move security rule ? (y/n) n
Commiting changes ...

Are you sure you want to commit ? (y/n) y
/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
&lt;response status="success" code="20"&gt;&lt;msg&gt;command succeeded&lt;/msg&gt;&lt;/response&gt;
Adding security rule to: 192.168.0.203

/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
&lt;response status="success" code="20"&gt;&lt;msg&gt;command succeeded&lt;/msg&gt;&lt;/response&gt;
Moving security rule ...

Do you want to move security rule ? (y/n) n
Commiting changes ...

Are you sure you want to commit ? (y/n) y
/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
&lt;response status="success" code="20"&gt;&lt;msg&gt;command succeeded&lt;/msg&gt;&lt;/response&gt;</pre></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="e5b9742" class="elementor-element elementor-element-e5b9742 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="d779413" class="elementor-element elementor-element-d779413 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="c630b88" class="elementor-element elementor-element-c630b88 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Skrypt wykonał się z ostrzeżeniami, ale możemy je zignorować. Pojawiły się one, ponieważ wszystkie urządzenia posiadają domyślne certyfikaty, które nie są zaufane.</span></p><p style="text-align: justify;"><span style="font-family: Georgia, sans-serif; font-size: 18px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400;">Zobaczmy teraz jak wyglądają polityki bezpieczeństwa po działaniu skryptu:</span></p><p style="text-align: justify;"> </p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="f4fbd90" class="elementor-element elementor-element-f4fbd90 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="e30f7a1" class="elementor-element elementor-element-e30f7a1 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="586a554" class="elementor-element elementor-element-586a554 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1_1.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-4" data-rl_title="" data-rl_caption="" title="">
							<img width="720" height="203" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1_1.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1_1.png 1010w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1_1-300x85.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_1_1-768x217.png 768w" sizes="(max-width: 720px) 100vw, 720px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="799ee64" class="elementor-element elementor-element-799ee64 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="862f2a7" class="elementor-element elementor-element-862f2a7 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="2aafdf5" class="elementor-element elementor-element-2aafdf5 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2_1.png" data-elementor-open-lightbox="default" data-rel="lightbox-image-5" data-rl_title="" data-rl_caption="" title="">
							<img width="720" height="198" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2_1.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2_1.png 1017w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2_1-300x83.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_2_1-768x211.png 768w" sizes="(max-width: 720px) 100vw, 720px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="e8fd54e" class="elementor-element elementor-element-e8fd54e elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="9a8149a" class="elementor-element elementor-element-9a8149a elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="6351ddf" class="elementor-element elementor-element-6351ddf elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3_1.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-6" data-rl_title="" data-rl_caption="" title="">
							<img width="720" height="205" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3_1.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3_1.png 1012w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3_1-300x85.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/03/rules_3_1-768x219.png 768w" sizes="(max-width: 720px) 100vw, 720px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="de8fae7" class="elementor-element elementor-element-de8fae7 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="963807b" class="elementor-element elementor-element-963807b elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="110b5a6" class="elementor-element elementor-element-110b5a6 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><h5><span style="color: #000000;"> </span></h5><h5><span style="color: #000000;">PODSUMOWANIE</span></h5></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="f6d1c33" class="elementor-element elementor-element-f6d1c33 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="a3ba6ef" class="elementor-element elementor-element-a3ba6ef elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="61cf95e" class="elementor-element elementor-element-61cf95e elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Jak widać API na urządzeniach Palo Alto umożliwia w łatwy sposób tworzyć reguły bezpieczeństwa. Jest to bardzo przydatne w sytuacji, gdy musimy tą samą regułę stworzyć na wielu urządzeniach.</span></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
						</div>
			</div>
		</div>
		]]></content:encoded>
			<wfw:commentRss>https://kubsoo.github.io/rsnet-website/palo-alto-api-reguly-python-skrypt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programowanie CGI Pythona</title>
		<link>https://kubsoo.github.io/rsnet-website/cgi_python/</link>
		<comments>https://kubsoo.github.io/rsnet-website/cgi_python/#respond</comments>
		<pubDate>Sat, 03 Feb 2018 19:05:56 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[cgi]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=965</guid>
		<description><![CDATA[Czym jest CGI ? (ang. Common Gateway Interface) &#8211; jest standardowym sposobem przekazywania przez serwer www żądania użytkownika do aplikacji i odbierania danych od aplikacji i przekazywanie ich użytkownikowi. Gdy&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[		<div class="elementor elementor-965">
			<div class="elementor-inner">
				<div class="elementor-section-wrap">
							<section data-id="1a2a34e" class="elementor-element elementor-element-1a2a34e elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="11fe55e" class="elementor-element elementor-element-11fe55e elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="7fe0ec1" class="elementor-element elementor-element-7fe0ec1 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><h5><span style="color: #000000;">Czym jest CGI ?</span></h5><p style="text-align: justify;"><span style="color: #000000;">(ang. Common Gateway Interface) &#8211; jest standardowym sposobem przekazywania przez serwer www żądania użytkownika do aplikacji i odbierania danych od aplikacji i przekazywanie ich użytkownikowi. Gdy użytkownik odwiedza stronę internetową (np. wprowadzając adres strony internetowej), serwer odsyła żądaną stronę. Takie działanie ma miejsce w przypadku stron statycznych, jednakże obecnie mamy w internecie przewagę stron dynamicznych, w przypadku których prezentowana strona jest generowana dynamicznie przez aplikację. Dzieje się tak na przykład w przypadku formularza na stronie internetowej. Użytkownik wypełnia dane w formularzu, przesyła je do serwera, następnie serwer otrzymane dane przesyła do aplikacji, która następnie przetwarza otrzymanie dane i zwraca wynik działania do użytkownika. Ta metoda, lub konwencja przekazywania danych tam i z powrotem między serwerem a aplikacją nazywa się CGI. </span></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="bf52341" class="elementor-element elementor-element-bf52341 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="7f6ed40" class="elementor-element elementor-element-7f6ed40 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="0f95634" class="elementor-element elementor-element-0f95634 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><h5><span style="color: #000000;">Konfiguracja serwera WWW</span></h5><p style="text-align: justify;"><span style="color: #000000;">W celu poprawnego działania skryptów CGI konieczne jest odpowiednie skonfigurowanie serwera www. W moim przypadku serwerem www jest Apache i pokażę jak go skonfigurować do pracy z CGI. Konfigurację apache możemy wykonać w następujących krokach:</span></p><p><span style="color: #000000;"><strong>Krok 1.</strong></span></p><p style="text-align: justify;"><span style="color: #000000;">Edytujemy zawartość pliku z naszą stroną (/sites-available/000-default.conf) odkomentowując linijkę:  </span><strong><span style="color: #000000;">Include conf-available/serve-cgi-bin.conf</span></strong></p><pre><span style="color: #000000;">root@ubuntu-2:/usr/lib/cgi-bin# nano /etc/apache2/sites-available/000-default.conf</span></pre><pre><span style="color: #000000;">&lt;VirtualHost *:80&gt;</span><br /><span style="color: #000000;">        # The ServerName directive sets the request scheme, hostname and port </span><br /><span style="color: #000000;">        # the server uses to identify itself. This is used when creating</span><br /><span style="color: #000000;">        # redirection URLs. In the context of virtual hosts, the ServerName</span><br /><span style="color: #000000;">        # specifies what hostname must appear in the request's Host: header to</span><br /><span style="color: #000000;">        # match this virtual host. For the default virtual host (this file) this</span><br /><span style="color: #000000;">        # value is not decisive as it is used as a last resort host regardless.</span><br /><span style="color: #000000;">        # However, you must set it for any further virtual host explicitly.</span><br /><span style="color: #000000;">        #ServerName www.example.com</span><br /><br /><span style="color: #000000;">        ServerAdmin webmaster@localhost</span><br /><span style="color: #000000;">        DocumentRoot /var/www/html</span><br /><br /><span style="color: #000000;">        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,</span><br /><span style="color: #000000;">        # error, crit, alert, emerg.</span><br /><span style="color: #000000;">        # It is also possible to configure the loglevel for particular</span><br /><span style="color: #000000;">        # modules, e.g.</span><br /><br /><span style="color: #000000;">        #LogLevel info ssl:warn</span><br /><br /><span style="color: #000000;">        ErrorLog ${APACHE_LOG_DIR}/error.log</span><br /><span style="color: #000000;">        CustomLog ${APACHE_LOG_DIR}/access.log combined</span><br /><br /><span style="color: #000000;">        # For most configuration files from conf-available/, which are</span><br /><span style="color: #000000;">        # enabled or disabled at a global level, it is possible to</span><br /><span style="color: #000000;">        # include a line for only one particular virtual host. For example the</span><br /><span style="color: #000000;">        # following line enables the CGI configuration for this host only</span><br /><span style="color: #000000;">        # after it has been globally disabled with "a2disconf".</span><br /><br /><span style="color: #000000;">      <b>  Include conf-available/serve-cgi-bin.conf</b></span><br /><span style="color: #000000;">&lt;/VirtualHost&gt;</span></pre><div><strong><span style="color: #000000;">Krok 2.</span></strong></div><div> </div><div><span style="color: #000000;">Edytujemy plik<strong> conf-available/serve-cgi-bin.conf</strong></span></div><div><pre>         <span style="color: #000000;">&lt;IfDefine ENABLE_USR_LIB_CGI_BIN&gt;</span><br /><span style="color: #000000;">                ScriptAlias <b>/cgi-bin/ /home/kuba/scripts/</b></span><br /><span style="color: #000000;">                &lt;Directory "<b>/home/kuba/scripts/</b>"&gt;</span><br /><span style="color: #000000;">                        AllowOverride None</span><br /><span style="color: #000000;">                        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch</span><br /><span style="color: #000000;">                        Require all granted</span><br /><span style="color: #000000;">                      <b>  AddHandler cgi-script .py</b></span><br /><span style="color: #000000;">                &lt;/Directory&gt;</span><br /><span style="color: #000000;">        &lt;/IfDefine&gt;</span></pre></div><div style="text-align: justify;"><span style="color: #000000;">ScriptAlias wskazuje gdzie będą przetrzymywane nasze skrypty, domyślnie jest to katalog /var/www/cgi-bin, natomiast możemy tu ustawić dowolny inny katalog. Ja ustawiłem katalog /home/kuba/scripts.</span></div><div> </div><div style="text-align: justify;"><span style="color: #000000;">AddHandler wskazuje jakie rozszerzenia skryptów będziemy obsługiwać (w moim przypadku będą to skrypty python więc dodałem rozszerzenie .py)</span></div><p> </p><p><span style="color: #000000;"><strong>Krok 3.</strong></span></p><p><span style="color: #000000;">Aktywujemy moduł cgi w apache i restartujemy apache&#8217;a.</span></p><pre><span style="color: #000000;">root@ubuntu-2:/usr/lib/cgi-bin# a2enmod cgi</span><br /><span style="color: #000000;">root@ubuntu-2:/usr/lib/cgi-bin# systemctl restart apache2</span></pre></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="cb12231" class="elementor-element elementor-element-cb12231 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="95aa223" class="elementor-element elementor-element-95aa223 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="52e7236" class="elementor-element elementor-element-52e7236 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><h5><span style="color: #000000;">Pierwszy skrypt</span></h5><p style="text-align: justify;"><span style="color: #000000;">Stwórzmy sobie pierwszy skrypt python, który wygeneruje nam stronę www z treścią Hello World !!!.</span></p><p><span style="color: #000000;">Skrypt ten wygląda następująco:</span></p><pre><span style="color: #000000;">#!/usr/bin/python</span><br /><br /><span style="color: #000000;">print("Content-Type: text/html\n\n")</span><br /><span style="color: #000000;">print('''</span><br /><span style="color: #000000;">&lt;html&gt;</span><br /><span style="color: #000000;">&lt;head&gt;</span><br /><span style="color: #000000;">&lt;title&gt;Hello World - script&lt;/title&gt;</span><br /><span style="color: #000000;">&lt;/head&gt;</span><br /><span style="color: #000000;">&lt;body&gt;</span><br /><span style="color: #000000;">&lt;p&gt;Hello Word !!!&lt;/p&gt;</span><br /><span style="color: #000000;">&lt;/body&gt;</span><br /><span style="color: #000000;">&lt;/html&gt;</span><br /><span style="color: #000000;">''')</span></pre><p style="text-align: justify;"><span style="color: #000000;">Następnie skrypt musimy umieścić w naszym katalogu ze skryptami (/home/kuba/scripts) i nadać mu atrybuty wykonywalności (chmod +x). </span></p><p style="text-align: justify;"><span style="color: #000000;">Teraz pozostaje tylko otwarcie odpowiedniego linku w przeglądarce:</span></p><p style="text-align: justify;"><span style="color: #000000;"><strong>http://192.168.48.142/cgi-bin/hello.py   </strong></span></p><p style="text-align: justify;"><span style="color: #000000;">gdzie:</span></p><p style="text-align: justify;"><span style="color: #000000;">192.168.48.142 to adres naszego serwera,</span></p><p style="text-align: justify;"><span style="color: #000000;">hello.py to nazwa naszego skryptu.</span></p><p> </p><p><span style="color: #000000;">Jeśli wszystko przebiegło pomyślnie naszym oczom powinna ukazać strona z zawartościa Hello World !!!.</span></p><p> </p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="b555971" class="elementor-element elementor-element-b555971 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="b7e6911" class="elementor-element elementor-element-b7e6911 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="8b8314c" class="elementor-element elementor-element-8b8314c elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/cgi_1.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-0" data-rl_title="" data-rl_caption="" title="">
							<img width="454" height="139" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/cgi_1.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/cgi_1.png 454w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/cgi_1-300x92.png 300w" sizes="(max-width: 454px) 100vw, 454px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="f44b6ba" class="elementor-element elementor-element-f44b6ba elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="72362a9" class="elementor-element elementor-element-72362a9 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="9b8d37c" class="elementor-element elementor-element-9b8d37c elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><h5> </h5><h5><span style="color: #000000;">KALKULATOR IP W PYTHON</span></h5><p style="text-align: justify;">Teraz spróbujmy napisać coś bardziej zaawansowanego w python, a mianowicie kalkulator IP. Do tego celu posłuży nam wbudowana Pythona biblioteka ipaddress, która umożliwia pracę z adresami IP.</p><p>Cała aplikacja będzie składać się z 3 plików:</p><ol><li>/var/www/html/index.html</li><li>/home/kuba/scripts/script.py</li><li>/home/kuba/scripts/calc.py</li></ol><p>Zawartość plików jest następująca:</p><ol><li>/var/www/html/index.html</li></ol><pre>&lt;html&gt;<br />&lt;head&gt;<br />&lt;title&gt;IP Calculator&lt;/title&gt;<br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;p&gt;Python IP Calculator&lt;/p&gt;<br />&lt;iframe src="./cgi-bin/script.py" width="400" height="350"&gt;&lt;/iframe&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</pre><p>2. /home/kuba/scripts/script.py</p><pre>#!/usr/bin/python<br /><br />print("Content-Type: text/html\n\n")<br />print('''<br />&lt;html&gt;<br />&lt;head&gt;<br />&lt;title&gt;IP Calculator&lt;/title&gt;<br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;p&gt;INSERT IP AND SUBNET&lt;/p&gt;<br />&lt;form action = "calc.py" method = "get"&gt;<br />&lt;input type = "text" value = "192.168.0.0" name = "ip"&gt; IP Address (eg. 192.168.0.0)&lt;br /&gt;<br />&lt;input type = "text" value = "24" name = "subnet" /&gt; Subnet Mask (eg. 24)&lt;br /&gt;<br />&lt;input type = "submit" value = "Calc" /&gt;<br />&lt;/form&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;<br />''')</pre><p>3. /home/kuba/scripts/calc.py</p><pre>#!/usr/bin/python<br /><br />import cgi, cgitb, ipaddress<br /><br />form = cgi.FieldStorage()<br />ip = form.getvalue('ip')<br />subnet = form.getvalue('subnet')<br />ips = unicode(ip+"/"+subnet)<br />intf = ipaddress.ip_interface(ips)<br />netmask = intf.with_netmask.split("/")[1]<br /><br />print("Content-Type: text/html\n\n")<br />print('''<br />&lt;html&gt;<br />&lt;head&gt;<br />&lt;title&gt;IP Calculator&lt;/title&gt;<br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;p&gt;RESULTS&lt;/p&gt;<br />''')<br /><br />print"&lt;p&gt;IP Address &lt;font color='blue'&gt;%s&lt;/font&gt;&lt;/p&gt;" % (ip)<br />print"&lt;p&gt;Subnet Mask &lt;font color='blue'&gt;%s = %s&lt;/font&gt;&lt;/p&gt;" % (netmask,subnet)<br />print"&lt;p&gt;Wildcard Mask &lt;font color='blue'&gt;%s&lt;/font&gt;&lt;/p&gt;" % (intf.network.with_hostmask.split('/')[1])<br />print"&lt;p&gt;Network &lt;font color='blue'&gt;%s&lt;/font&gt;&lt;/p&gt;" % (intf.network.with_prefixlen)<br />print"&lt;p&gt;Broadcast &lt;font color='blue'&gt;%s&lt;/font&gt;&lt;/p&gt;" % (intf.network.broadcast_address)<br />print"&lt;p&gt;Host Min &lt;font color='blue'&gt;%s&lt;/font&gt;&lt;/p&gt;" % (intf.network[1])<br />print"&lt;p&gt;Host Max &lt;font color='blue'&gt;%s&lt;/font&gt;&lt;/p&gt;" % (intf.network[-2])<br />print"&lt;p&gt;Hosts/Net &lt;font color='blue'&gt;%s&lt;/font&gt;&lt;/p&gt;" % (intf.network.num_addresses-2)<br /><br />print('''<br />&lt;/form&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;<br />''')</pre><p>Zasada działania kalkulatora jest następująca:</p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="7f1f4a8" class="elementor-element elementor-element-7f1f4a8 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="c37290f" class="elementor-element elementor-element-c37290f elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="2bf1c84" class="elementor-element elementor-element-2bf1c84 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;">Klient wchodzi na stronę http://192.168.48.142/index.html (plik /var/www/html/index.html). Strona składa się z ramki, w której wyświetlany jest wynik skryptu script.py.  Wynikiem działania skryptu script.py jest formularz, składający się z pól tekstowych ip i subnet, oraz przycisku Calc, który uruchamia skrypt calc.py. Skrypt calc.py wykonuje operacje  na podanych w formularzu polach ip i subnet i prezentuje na ich podstawie następujące wyniki:</p><p>IP Address &#8211; adres IP podany w formularzu,</p><p>Subnet Mask &#8211; maska podsieci podana w formularzu,</p><p>Wildcard Mask &#8211; maska w formacie wildard&#8217;owym,</p><p>Network &#8211; adres sieci,</p><p>Broadcast &#8211; adres rozgłoszeniowy,</p><p>Host Min &#8211; najmniejszy adres dostępny dla hosta,</p><p>Host Max &#8211; największy adres dostępny dla hosta,</p><p>Hosts/Net &#8211; ilość adresów dostępna dla hostów.</p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="43f30d7" class="elementor-element elementor-element-43f30d7 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="cff0454" class="elementor-element elementor-element-cff0454 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="e65fc46" class="elementor-element elementor-element-e65fc46 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-1" data-rl_title="" data-rl_caption="" title="">
							<img width="580" height="240" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc.png 580w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc-300x124.png 300w" sizes="(max-width: 580px) 100vw, 580px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="89f72e4" class="elementor-element elementor-element-89f72e4 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="c70b071" class="elementor-element elementor-element-c70b071 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="0a0b9b5" class="elementor-element elementor-element-0a0b9b5 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><h5><span style="color: #000000;"><strong>WYNIK</strong></span></h5><p>Sprawdźmy teraz jak wygląda aplikacja kalkulatora IP z punku widzenia klienta i jego przeglądarki. Otwórzmy w tym celu stronę index.html:</p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="c5d72ec" class="elementor-element elementor-element-c5d72ec elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="542731b" class="elementor-element elementor-element-542731b elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="fde1d1f" class="elementor-element elementor-element-fde1d1f elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc_3.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-2" data-rl_title="" data-rl_caption="" title="">
							<img width="468" height="499" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc_3.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc_3.png 468w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc_3-281x300.png 281w" sizes="(max-width: 468px) 100vw, 468px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="e7308cc" class="elementor-element elementor-element-e7308cc elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="de5f315" class="elementor-element elementor-element-de5f315 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="1139494" class="elementor-element elementor-element-1139494 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc_4.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-3" data-rl_title="" data-rl_caption="" title="">
							<img width="440" height="498" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc_4.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc_4.png 440w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/ip_calc_4-265x300.png 265w" sizes="(max-width: 440px) 100vw, 440px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="382e653" class="elementor-element elementor-element-382e653 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="4f7d80a" class="elementor-element elementor-element-4f7d80a elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="197ced6" class="elementor-element elementor-element-197ced6 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><h5><span style="color: #000000;"><strong>PODSUMOWANIE</strong></span></h5><p style="text-align: justify;">Na powyższym przykładzie aplikacji www kalkulatora IP, widać, że Python z CGI dają olbrzymie możliwości tworzenia aplikacji internetowych przy wykorzystaniu skryptów. Oczywiście powyższe zastosowanie nie jest najlepszą i najwydajniejsza metodą tworzenia stron internetowych, ale pokazuję, że właściwie bez zaawansowanej znajomości kodowania stron www, możemy tworzyć łatwe formularze czy aplikacje wykorzystując skrypty Pythona. Do bardziej zaawansowanych aplikacji można skorzystać z nowoczesnego frameworka opartego na Pythonie a mianowicie <a href="https://www.djangoproject.com/">Django</a>.</p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
						</div>
			</div>
		</div>
		]]></content:encoded>
			<wfw:commentRss>https://kubsoo.github.io/rsnet-website/cgi_python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Palo Alto API backup konfiguracji &#8211; Python skrypt</title>
		<link>https://kubsoo.github.io/rsnet-website/palo-alto-api-backup-konfiguracji-python-skrypt/</link>
		<comments>https://kubsoo.github.io/rsnet-website/palo-alto-api-backup-konfiguracji-python-skrypt/#respond</comments>
		<pubDate>Thu, 28 Dec 2017 19:45:32 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[palo alto]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[skrypt]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=998</guid>
		<description><![CDATA[Korzystając z API możemy na firewallach Palo Alto wykonywać komendy przez przeglądarkę jednym zapytaniem bez konieczności otwierania interfejsu do zarządzania i klikania po menu.     PRZYKŁAD Do celów demonstracji&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[		<div class="elementor elementor-998">
			<div class="elementor-inner">
				<div class="elementor-section-wrap">
							<section data-id="b4f5b76" class="elementor-element elementor-element-b4f5b76 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="e876d39" class="elementor-element elementor-element-e876d39 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="93d42a5" class="elementor-element elementor-element-93d42a5 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Korzystając z API możemy na firewallach Palo Alto wykonywać komendy przez przeglądarkę jednym zapytaniem bez konieczności otwierania interfejsu do zarządzania i klikania po menu.</span></p><p style="text-align: justify;"><span style="color: #000000;"> </span></p><p> </p><h5><span style="color: #000000;">PRZYKŁAD</span></h5><p style="text-align: justify;"><span style="color: #000000;">Do celów demonstracji możliwości API na Palo Alto posłużyłem się topologią zbudowaną z GNS3 składającą się z 3 firewalli, switcha oraz dwóch maszyn wirtualnych (gns3-webterm &#8211; do dostepu do API przez przeglądarkę, oraz NetworkAutomation &#8211; maszyna z pythonem na której będziemy pisać skrypt).</span></p><p><strong><span style="color: #000000;">TOPOLOGIA</span></strong></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="c4f19c4" class="elementor-element elementor-element-c4f19c4 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="d5954f2" class="elementor-element elementor-element-d5954f2 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="fbbda61" class="elementor-element elementor-element-fbbda61 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/01/topology_1.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-0" data-rl_title="" data-rl_caption="" title="">
							<img width="605" height="452" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/01/topology_1.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/01/topology_1.png 605w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2018/01/topology_1-300x224.png 300w" sizes="(max-width: 605px) 100vw, 605px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="b322071" class="elementor-element elementor-element-b322071 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="e50c5f5" class="elementor-element elementor-element-e50c5f5 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="a0120da" class="elementor-element elementor-element-a0120da elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><h5><span style="color: #000000;">API</span></h5><p style="text-align: justify;"><span style="color: #000000;">W celu dostępu do API musimy wygenerować klucz API, który będzie wykorzystywany do zapytań do API. Klucz jest generowany z użytkownika i hasła, więc jeśli posiadamy kilka firewalli i na każdym z nich mamy tego samego usera i hasło to klucz będzie taki sam dla każdego urządzenia.</span></p><p><span style="color: #000000;">Do generacji klucza służy następujące zapytanie:</span></p><pre><strong><span style="color: #000000;">https://firewall_ip/api/?type=keygen&amp;user=username&amp;password=password</span></strong></pre><p style="text-align: justify;"><span style="color: #000000;">Sprawdźmy jak to wygląda na żywo. W tym celu wchodzimy do gns3-webterm i wpisujemy w przeglądarce podany URL zamieniając firewall_ip na jeden z adresów IP firewalli oraz wpisując poprawny login i hasło:</span></p><pre><strong><span style="color: #000000;">https://192.168.0.201/api/?type=keygen&amp;user=admin&amp;password=admin</span></strong></pre></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="ef99376" class="elementor-element elementor-element-ef99376 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="46d5900" class="elementor-element elementor-element-46d5900 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="0334c79" class="elementor-element elementor-element-0334c79 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/key.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-1" data-rl_title="" data-rl_caption="" title="">
							<img width="720" height="272" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/key.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/key.png 925w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/key-300x113.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/key-768x290.png 768w" sizes="(max-width: 720px) 100vw, 720px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="8423225" class="elementor-element elementor-element-8423225 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="d7567a9" class="elementor-element elementor-element-d7567a9 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="1c80ac7" class="elementor-element elementor-element-1c80ac7 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Jak widać z powyższego screena dostaliśmy w odpowiedzi plik XML, który zawiera klucz postaci:</span></p><pre><strong><em><span style="color: #000000;">LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09</span></em></strong></pre><p style="text-align: justify;"><span style="color: #000000;">To samo możemy uzyskać na maszynie NetworkAutomation korzystając z programu curl i komendy:</span></p><pre><strong><span style="color: #000000;">root@NetworkAutomation-1:~# curl -X GET 'https://192.168.0.201/api/?type=keygen&amp;user=admin&amp;password=admin' --insecure</span></strong><br /><br /><span style="color: #000000;">&lt;response status = 'success'&gt;&lt;result&gt;&lt;key&gt;<strong>LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09</strong>&lt;/key&gt;&lt;/result&gt;&lt;/response&gt;</span></pre><p style="text-align: justify;"><span style="color: #000000;">Po otrzymaniu klucza możemy wykonać jakąś komendę przez API. Listę komend i składnię zapytań możemy znaleźć wpisując w przeglądarce https://firewall_ip/api</span></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="da390d6" class="elementor-element elementor-element-da390d6 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="6b697e5" class="elementor-element elementor-element-6b697e5 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="bd09749" class="elementor-element elementor-element-bd09749 elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/api.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-2" data-rl_title="" data-rl_caption="" title="">
							<img width="420" height="406" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/api.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/api.png 420w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/api-300x290.png 300w" sizes="(max-width: 420px) 100vw, 420px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="477fe4a" class="elementor-element elementor-element-477fe4a elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="26f5cf7" class="elementor-element elementor-element-26f5cf7 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="74d6cd6" class="elementor-element elementor-element-74d6cd6 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p><span style="color: #000000;">Do eksportu konfiguracji służy zapytanie postaci:</span></p><pre><span style="color: #000000;"><strong>https://firewall_ip/api/?type=export&amp;category=configuration&amp;key=&lt;key&gt;</strong></span></pre><p style="text-align: justify;"><span style="color: #000000;">gdzie &lt;key&gt; to klucz otrzymany z wcześniejszej komendy. Całe zapytanie wygląda więc następująco:</span></p><pre><strong><span style="color: #000000;">https://192.168.0.201/api/?type=export&amp;category=configuration&amp;key=LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09</span></strong></pre><div><span style="color: #000000;">W odpowiedzi dostaniemy plik xml z konfiguracją:</span></div></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="bddc825" class="elementor-element elementor-element-bddc825 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="22b08fb" class="elementor-element elementor-element-22b08fb elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="71a647a" class="elementor-element elementor-element-71a647a elementor-widget elementor-widget-image" data-element_type="image.default">
				<div class="elementor-widget-container">
					<div class="elementor-image">
											<a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/api_1.png" data-elementor-open-lightbox="no" data-rel="lightbox-image-3" data-rl_title="" data-rl_caption="" title="">
							<img width="592" height="564" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/api_1.png" class="attachment-large size-large" alt="" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/api_1.png 592w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/12/api_1-300x286.png 300w" sizes="(max-width: 592px) 100vw, 592px" />								</a>
											</div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="1266fa3" class="elementor-element elementor-element-1266fa3 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="99e7162" class="elementor-element elementor-element-99e7162 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="d49c11c" class="elementor-element elementor-element-d49c11c elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Spróbujmy teraz to samo uzyskać korzystając z curl&#8217;a:</span></p><pre><strong><span style="color: #000000;">root@NetworkAutomation-1:~# curl -X GET 'https://192.168.0.201/api/?type=export&amp;category=configuration&amp;key=LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09' --insecure</span></strong></pre><pre><span style="color: #000000;">&lt;config version="7.1.0" urldb="paloaltonetworks"&gt;&lt;mgt-config&gt;&lt;users&gt;&lt;entry name="admin"&gt;&lt;phash&gt;fnRL/G5lXVMug&lt;/phash&gt;&lt;permissions&gt;&lt;role-based&gt;&lt;superuser&gt;yes&lt;/superuser&gt;&lt;/role-based&gt;&lt;/permissions&gt;&lt;/entry&gt;&lt;/users&gt;&lt;/mgt-config&gt;&lt;shared&gt;&lt;application/&gt;&lt;application-group/&gt;&lt;service/&gt;&lt;service-group/&gt;&lt;botnet&gt;&lt;configuration&gt;&lt;http&gt;&lt;dynamic-dns&gt;&lt;enabled&gt;yes&lt;/enabled&gt;&lt;threshold&gt;5&lt;/threshold&gt;&lt;/dynamic-dns&gt;&lt;malware-sites&gt;&lt;enabled&gt;yes&lt;/enabled&gt;&lt;threshold&gt;5&lt;/threshold&gt;&lt;/malware-sites&gt;&lt;recent-domains&gt;&lt;enabled&gt;yes&lt;/enabled&gt;&lt;threshold&gt;5&lt;/threshold&gt;&lt;/recent-domains&gt;&lt;ip-domains&gt;&lt;enabled&gt;yes&lt;/enabled&gt;&lt;threshold&gt;10&lt;/threshold&gt;&lt;/ip-domains&gt;&lt;executables-from-unknown-sites&gt;&lt;enabled&gt;yes&lt;/enabled&gt;&lt;threshold&gt;5&lt;/threshold&gt;&lt;/executables-from-unknown-sites&gt;&lt;/http&gt;&lt;other-applications&gt;&lt;irc&gt;yes&lt;/irc&gt;&lt;/other-applications&gt;&lt;unknown-applications&gt;&lt;unknown-tcp&gt;&lt;destinations-per-hour&gt;10&lt;/destinations-per-hour&gt;&lt;sessions-per-hour&gt;10&lt;/sessions-per-hour&gt;&lt;session-length&gt;&lt;maximum-bytes&gt;100&lt;/maximum-bytes&gt;&lt;minimum-bytes&gt;50&lt;/minimum-bytes&gt;&lt;/session-length&gt;&lt;/unknown-tcp&gt;&lt;unknown-udp&gt;&lt;destinations-per-hour&gt;10&lt;/destinations-per-hour&gt;&lt;sessions-per-hour&gt;10&lt;/sessions-per-hour&gt;&lt;session-length&gt;&lt;maximum-bytes&gt;100&lt;/maximum-bytes&gt;&lt;minimum-bytes&gt;50&lt;/minimum-bytes&gt;&lt;/session-length&gt;&lt;/unknown-udp&gt;&lt;/unknown-applications&gt;&lt;/configuration&gt; ........</span></pre></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="5fc70e6" class="elementor-element elementor-element-5fc70e6 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="d958656" class="elementor-element elementor-element-d958656 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="aa607b2" class="elementor-element elementor-element-aa607b2 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Widzimy, że otrzymaliśmy ten sam plik xml. Teraz możemy spróbować napisać skrypt, który wykona tą operację za nas i zapisze taki plik na dysk, dla każdego z firewalli.</span></p><h5> </h5><h5><span style="color: #000000;">SKRYPT</span></h5></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="fed1942" class="elementor-element elementor-element-fed1942 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="296c5ed" class="elementor-element elementor-element-296c5ed elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="6e95d2c" class="elementor-element elementor-element-6e95d2c elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Skrypt jest bardzo prosty i wygląda nastepująco:</span></p><p><strong><span style="color: #000000;">backup_config.py</span></strong></p><pre><span style="color: #000000;">#!/usr/bin/python</span><br /><br /><span style="color: #000000;">import requests, datetime</span><br /><span style="color: #000000;">from lxml import etree</span><br /><br /><span style="color: #000000;">firewalls_ip = [</span><br /><span style="color: #000000;"> '192.168.0.201',</span><br /><span style="color: #000000;"> '192.168.0.202',</span><br /><span style="color: #000000;"> '192.168.0.203'</span><br /><span style="color: #000000;">]</span><br /><br /><span style="color: #000000;">date_1 = datetime.datetime.now().strftime("%Y-%m-%d_%H:%M")</span><br /><span style="color: #000000;">key = 'LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09'</span><br /><br /><span style="color: #000000;">params = (</span><br /><span style="color: #000000;"> ('type', 'export'),</span><br /><span style="color: #000000;"> ('category', 'configuration'),</span><br /><span style="color: #000000;"> ('key', key),</span><br /><span style="color: #000000;">)</span><br /><br /><span style="color: #000000;">for hostname in firewalls_ip:</span><br /><span style="color: #000000;"> print "Saving config for : %s" %hostname</span><br /><span style="color: #000000;"> url = "https://"+hostname+"/api/"</span><br /><span style="color: #000000;"> response = requests.get(url, params=params, verify=False)</span><br /><span style="color: #000000;"> xml_str = response.text</span><br /><span style="color: #000000;"> root = etree.fromstring(xml_str)</span><br /><br /><span style="color: #000000;"> filename = "running-config-"+hostname+"-"+date_1+".xml"</span><br /><span style="color: #000000;"> file = open(filename,"w")</span><br /><span style="color: #000000;"> file.write("""<!--?xml version="1.0"?-->\n""")</span><br /><span style="color: #000000;"> file.write(etree.tostring(root, pretty_print=True))</span><br /><span style="color: #000000;"> file.close()</span></pre><p style="text-align: justify;"><span style="color: #000000;">Sprawdźmy jego działanie w praktyce:</span></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="e7c6fc3" class="elementor-element elementor-element-e7c6fc3 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="1beea1b" class="elementor-element elementor-element-1beea1b elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="b0baaf8" class="elementor-element elementor-element-b0baaf8 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><pre><strong><span style="color: #000000;">root@NetworkAutomation-1:~# ./backup_config.py</span></strong><br /><span style="color: #000000;">Saving config for : 192.168.0.201</span><br /><span style="color: #000000;">/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings</span><br /><span style="color: #000000;"> InsecureRequestWarning)</span><br /><span style="color: #000000;">Saving config for : 192.168.0.202</span><br /><span style="color: #000000;">/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings</span><br /><span style="color: #000000;"> InsecureRequestWarning)</span><br /><span style="color: #000000;">Saving config for : 192.168.0.203</span><br /><span style="color: #000000;">/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings</span><br /><span style="color: #000000;"> InsecureRequestWarning)</span></pre></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="e5b9742" class="elementor-element elementor-element-e5b9742 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="d779413" class="elementor-element elementor-element-d779413 elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="c630b88" class="elementor-element elementor-element-c630b88 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Skrypt wykonał się z ostrzeżeniami, ale możemy je zignorować. Pojawiły się one, ponieważ wszystkie urządzenia posiadają domyślne certyfikaty, które nie są zaufane.</span></p><p style="text-align: justify;"><span style="color: #000000;">Sprawdźmy teraz jak wygląda katalog w którym jest skrypt:</span></p><pre><span style="color: #000000;">-rwxr-xr-x 1 root root 809 Dec 28 19:36 <strong>backup_config.py</strong></span><br /><span style="color: #000000;">-rw-r--r-- 1 root root 9161 Dec 28 19:36 running-config-192.168.0.201-2017-12-28_19:36.xml</span><br /><span style="color: #000000;">-rw-r--r-- 1 root root 9161 Dec 28 19:36 running-config-192.168.0.202-2018-12-28_19:36.xml</span><br /><span style="color: #000000;">-rw-r--r-- 1 root root 9161 Dec 28 19:36 running-config-192.168.0.203-2018-12-28_19:36.xml</span></pre><p style="text-align: justify;"><span style="color: #000000;">Widać, że stworzone zostały trzy pliki zgodnie z oczekiwaniami dla każdego z firewalli. Otwórzmy teraz jeden z nich i zobaczmy jak wygląda:</span></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="de8fae7" class="elementor-element elementor-element-de8fae7 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="963807b" class="elementor-element elementor-element-963807b elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="110b5a6" class="elementor-element elementor-element-110b5a6 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><pre><strong><span style="color: #000000;">root@NetworkAutomation-1:~# cat running-config-192.168.0.201-2017-12-28_19:36.xml</span></strong><br /><br /><span style="color: #000000;">&lt;?xml version="1.0"?&gt;</span><br /><span style="color: #000000;">&lt;config version="7.1.0" urldb="paloaltonetworks"&gt;</span><br /><span style="color: #000000;">  &lt;mgt-config&gt;</span><br /><span style="color: #000000;">    &lt;users&gt;</span><br /><span style="color: #000000;">      &lt;entry name="admin"&gt;</span><br /><span style="color: #000000;">         &lt;phash&gt;fnRL/G5lXVMug&lt;/phash&gt;</span><br /><span style="color: #000000;">         &lt;permissions&gt;</span><br /><span style="color: #000000;">           &lt;role-based&gt;</span><br /><span style="color: #000000;">             &lt;superuser&gt;yes&lt;/superuser&gt;</span><br /><span style="color: #000000;">           &lt;/role-based&gt;</span><br /><span style="color: #000000;">         &lt;/permissions&gt;</span><br /><span style="color: #000000;">      &lt;/entry&gt;</span><br /><span style="color: #000000;">    &lt;/users&gt;</span><br /><span style="color: #000000;">  &lt;/mgt-config&gt;</span><br /><span style="color: #000000;">  &lt;shared&gt;</span><br /><span style="color: #000000;">    &lt;application/&gt;</span><br /><span style="color: #000000;">    &lt;application-group/&gt;</span><br /><span style="color: #000000;">    &lt;service/&gt;</span><br /><span style="color: #000000;">    &lt;service-group/&gt;</span><br /><span style="color: #000000;">    &lt;botnet&gt;</span><br /><span style="color: #000000;">       &lt;configuration&gt;</span><br /><span style="color: #000000;">         &lt;http&gt;</span><br /><span style="color: #000000;">           &lt;dynamic-dns&gt;</span><br /><span style="color: #000000;">             &lt;enabled&gt;yes&lt;/enabled&gt;</span><br /><span style="color: #000000;">             &lt;threshold&gt;5&lt;/threshold&gt;</span><br /><span style="color: #000000;">           &lt;/dynamic-dns&gt;<br />     ...</span></pre><p> </p><h5><span style="color: #000000;">PODSUMOWANIE</span></h5></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
				<section data-id="f6d1c33" class="elementor-element elementor-element-f6d1c33 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="a3ba6ef" class="elementor-element elementor-element-a3ba6ef elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="61cf95e" class="elementor-element elementor-element-61cf95e elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #000000;">Jak widać API na urządzeniach Palo Alto umożliwia w łatwy sposób eksportować konfigurację, dzięki czemu w przypadku awarii urządzenia mamy kopię konfiguracji. Jest to bardzo przydatne zwłaszcza w sytuacji gdy mamy wiele firewalli do administracji. W kolejnych wpisach pokaże więcej możliwości wykorzystania API na urządzeniach Palo Alto.</span></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
						</div>
			</div>
		</div>
		]]></content:encoded>
			<wfw:commentRss>https://kubsoo.github.io/rsnet-website/palo-alto-api-backup-konfiguracji-python-skrypt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Skrypt python do zmiany serwerów ntp na CISCO</title>
		<link>https://kubsoo.github.io/rsnet-website/skrypt-python-do-zmiany-serwerow-ntp-na-cisco/</link>
		<comments>https://kubsoo.github.io/rsnet-website/skrypt-python-do-zmiany-serwerow-ntp-na-cisco/#respond</comments>
		<pubDate>Sun, 15 Oct 2017 20:38:08 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[cisco]]></category>
		<category><![CDATA[netmiko]]></category>
		<category><![CDATA[ntp]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=602</guid>
		<description><![CDATA[W poniższym wpisie pokażę prosty skrypt w Pythonie wykorzystujący bibliotekę netmiko oraz textfsm. Skrypt będzie łączył sie po ssh ze switchami CISCO i zmieniać adresy serwerów ntp na nowe. Wyobraźmy&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[		<div class="elementor elementor-602">
			<div class="elementor-inner">
				<div class="elementor-section-wrap">
							<section data-id="26968f8" class="elementor-element elementor-element-26968f8 elementor-section-boxed elementor-section-height-default elementor-section-height-default elementor-section elementor-top-section" data-element_type="section">
						<div class="elementor-container elementor-column-gap-default">
				<div class="elementor-row">
				<div data-id="2ffd70b" class="elementor-element elementor-element-2ffd70b elementor-column elementor-col-100 elementor-top-column" data-element_type="column">
			<div class="elementor-column-wrap elementor-element-populated">
					<div class="elementor-widget-wrap">
				<div data-id="3c40220" class="elementor-element elementor-element-3c40220 elementor-widget elementor-widget-text-editor" data-element_type="text-editor.default">
				<div class="elementor-widget-container">
					<div class="elementor-text-editor elementor-clearfix"><p style="text-align: justify;"><span style="color: #333333;">W poniższym wpisie pokażę prosty skrypt w Pythonie wykorzystujący bibliotekę netmiko oraz textfsm. Skrypt będzie łączył sie po ssh ze switchami CISCO i zmieniać adresy serwerów ntp na nowe.</span></p><p style="text-align: justify;"><span style="color: #333333;">Wyobraźmy sobie sytuację że mamy 20 switchy ze skonfigurowanymi następującymi adresami serwerów ntp:</span></p><pre><span style="color: #333333;">SWITCH-1#show run | in ntp</span><br /><span style="color: #333333;">ntp server 192.168.55.100</span><br /><span style="color: #333333;">ntp server 192.168.60.100</span></pre><p style="text-align: justify;"><span style="color: #333333;">Dostaliśmy informację, że niedługo nastąpi zmiana adresów IP serwerów ntp na nowe następujące adresy:</span></p><p><span style="color: #333333;">10.0.10.1, 10.0.10.2, 10.0.10.3</span></p><p style="text-align: justify;"><span style="color: #333333;">i musimy na wszystkich switchach zamienić adresy serwerów ntp. Możemy to zrobić ręcznie, logując się na każdy switch i wydając komendy:</span></p><p style="text-align: justify;"><span style="color: #333333;"> no ntp server &#8230; </span></p><p style="text-align: justify;"><span style="color: #333333;">ntp server..</span></p><p style="text-align: justify;"><span style="color: #333333;">albo wykorzystać skrypt, który zrobi to za nas. </span></p><p> </p><h5><strong>ZACZYNAMY</strong></h5><p style="text-align: justify;"><span style="color: #333333;">Skrypt realizujący to zadanie będzie działał następująco:</span></p><ol><li><span style="color: #333333;">Logowanie do urządzenia</span></li><li><span style="color: #333333;">Wykonanie komendy show run | in ntp i zapisanie wyników</span></li><li><span style="color: #333333;">Usunięcie starych serwerów ntp z wyników z punktu 2.</span></li><li><span style="color: #333333;">Ustawienie nowych serwerów ntp</span></li></ol><p style="text-align: justify;"><span style="color: #333333;">Skrypt będzie wykorzystywał pliki z komendami, dzięki czemu będziemy mogli go w łatwy sposób przerabiać do innych potrzeb (nie tylko do zmian serwerów ntp). Wystarczy wyedytować  pliki commands.txt i commands2.txt oraz zmienić plik textfsm, który parsuje wyniki polecenia z pliku commands2.txt. Zapraszam do przeczytania moich wpisów o <a href="https://kubsoo.github.io/rsnet-website/cisco-python-netmiko/">Netmiko</a> i <a href="https://kubsoo.github.io/rsnet-website/cisco-cli-textfsm/">TextFSM</a>, które napewno rozjaśnią poniższy skrypt.</span></p><p> </p><p><span style="color: #333333;"><strong>SKRYPT</strong></span></p><p><span style="color: #333333;">config_cisco.py </span></p><pre><span style="color: #333333;">#!/usr/bin/python</span><br /><br /><span style="color: #333333;">from netmiko import ConnectHandler</span><br /><span style="color: #333333;">import sys, textfsm</span><br /><br /><span style="color: #333333;">def check_cmd(ip, username, password,commands):</span><br /><span style="color: #333333;"> # nawiązanie połączenia do urządzenia</span><br /><span style="color: #333333;"> ssh_connection = ConnectHandler(</span><br /><span style="color: #333333;"> device_type='cisco_ios',</span><br /><span style="color: #333333;"> ip=ip,</span><br /><span style="color: #333333;"> username=username,</span><br /><span style="color: #333333;"> password=password,</span><br /><span style="color: #333333;"> )</span><br /><span style="color: #333333;"> result = ""</span><br /><span style="color: #333333;"> for i in commands:</span><br /><span style="color: #333333;">    result += ssh_connection.send_command(i)+"\n"</span><br /><span style="color: #333333;"> # zamknięcie połączenia</span><br /><span style="color: #333333;"> ssh_connection.disconnect()</span><br /><br /><span style="color: #333333;"> return result</span><br /><br /><span style="color: #333333;">def set_cmd(ip, username, password,commands):</span><br /><span style="color: #333333;"> # nawiązanie połączenia do urządzenia</span><br /><span style="color: #333333;"> ssh_connection = ConnectHandler(</span><br /><span style="color: #333333;"> device_type='cisco_ios',</span><br /><span style="color: #333333;"> ip=ip,</span><br /><span style="color: #333333;"> username=username,</span><br /><span style="color: #333333;"> password=password,</span><br /><span style="color: #333333;"> )</span><br /><span style="color: #333333;"> result = ssh_connection.send_config_set(commands)</span><br /><span style="color: #333333;"> # zamknięcie połączenia</span><br /><span style="color: #333333;"> ssh_connection.disconnect()</span><br /><br /><span style="color: #333333;"> return result</span><br /><br /><span style="color: #333333;">if __name__ == "__main__":</span><br /><span style="color: #333333;"> if len(sys.argv) != 4:</span><br /><span style="color: #333333;">   print("\nSkrypt do zmiany adresów serwerów ntp na urzadzeniach cisco:")</span><br /><span style="color: #333333;">   print("\tconfig_cisco.py &lt;device_ip&gt;,&lt;device_ip&gt; &lt;użytkownik&gt; &lt;hasło&gt; \n\n")</span><br /><span style="color: #333333;">   print("\tprzykładowe użycie: config_cisco.py 192.168.10.10,192.168.10.11 admin cisco123 \n\n")</span><br /><span style="color: #333333;">   sys.exit(0)</span><br /><br /><span style="color: #333333;"> devices = sys.argv[1]</span><br /><span style="color: #333333;"> username = sys.argv[2]</span><br /><span style="color: #333333;"> password = sys.argv[3]</span><br /><span style="color: #333333;"> set_file = "commands.txt"</span><br /><span style="color: #333333;"> get_file = "commands2.txt"</span><br /><br /><span style="color: #333333;"> f = open(set_file,'r')</span><br /><span style="color: #333333;"> commands = f.read().splitlines()</span><br /><span style="color: #333333;"> f.close</span><br /><br /><span style="color: #333333;"> f = open(get_file,'r')</span><br /><span style="color: #333333;"> commands2 = f.read().splitlines()</span><br /><span style="color: #333333;"> f.close</span><br /><br /><span style="color: #333333;"> device = devices.split(',')</span><br /><span style="color: #333333;"> re_table = textfsm.TextFSM(open("config_devices.textfsm"))</span><br /><br /><span style="color: #333333;"> for i in switch:</span><br /><span style="color: #333333;">   print "wykonywanie komend z pliku (%s) dla urządzenia %s" %(get_file,i)</span><br /><br /><span style="color: #333333;"> #sprawdzanie czy sa juz jakies ntp servery</span><br /><span style="color: #333333;"> #sprawdzenie odbywa sie przy pomocy komend z pliku get_file</span><br /><span style="color: #333333;"> check_out = check_cmd(i,username,password,commands2)</span><br /><span style="color: #333333;"> fsm_results = re_table.ParseText(check_out)</span><br /><br /><span style="color: #333333;"> commands3=[]</span><br /><span style="color: #333333;"> #sprawdzanie czy juz jest jakis ntp server, jesli jest to go usuwamy</span><br /><span style="color: #333333;"> for j in fsm_results:</span><br /><span style="color: #333333;">   commands3.append('no '+' '.join(j))</span><br /><span style="color: #333333;">   set_out = set_cmd(i,username,password,commands3)</span><br /><br /><span style="color: #333333;"> print "wykonywanie komend z pliku (%s) dla switcha %s" % (set_file,i)</span><br /><span style="color: #333333;"> #ustawienie nowych serwerow ntp, czyli komend z pliku set_file</span><br /><span style="color: #333333;"> set_out = set_cmd(i,username,password,commands)</span><br /><br /><span style="color: #333333;"> #koniec<br /> print "koniec"</span></pre><h5><span style="color: #333333;">Plik config_devices.textfsm</span></h5><pre><span style="color: #333333;">Value ntp (\S+)</span><br /><span style="color: #333333;">Value server (\S+)</span><br /><span style="color: #333333;">Value ip (.+)</span><br /><br /><span style="color: #333333;">Start</span><br /><span style="color: #333333;"> ^${ntp}\s+${server}\s+${ip} -&gt; Record</span></pre><h5><span style="color: #333333;">Pliki z komendami: </span></h5><p><span style="color: #333333;">commands.txt</span></p><pre><span style="color: #333333;">ntp server 10.0.10.1</span><br /><span style="color: #333333;">ntp server 10.0.10.2</span><br /><span style="color: #333333;">ntp server 10.0.10.3</span></pre><p><span style="color: #333333;">commands2.txt</span></p><pre><span style="color: #333333;">show run | in ntp server</span></pre><p><span style="color: #333333;">Skrypt uruchamiamy następującym poleceniem:</span></p><pre style="text-align: justify;"><span style="color: #333333;">config_devices.py 192.168.10.10,192.168.10.11,192.168.10.12,192.168.10.13,192.168.10.14,192.168.10.15,192.168.10.16,192.168.10.17,192.168.10.18,192.168.10.19,192.168.10.20,192.168.10.21,192.168.10.22,192.168.10.23,192.168.10.24,192.168.10.25,192.168.10.26,192.168.10.27,192.168.10.28,192.168.10.29 admin cisco123</span></pre><p style="text-align: justify;"><span style="color: #333333;">Oczywiście skrypt można napisać w inny sposób, nie korzystając z textfsm i plików z komendami, ale chciałem pokazać textfsm, bo uważam że jest to nieodzowna biblioteka przy pracy z urządzeniami Cisco i napewno będę publikował więcej skryptów z jej wykorzystaniem.</span></p></div>
				</div>
				</div>
						</div>
			</div>
		</div>
						</div>
			</div>
		</section>
						</div>
			</div>
		</div>
		]]></content:encoded>
			<wfw:commentRss>https://kubsoo.github.io/rsnet-website/skrypt-python-do-zmiany-serwerow-ntp-na-cisco/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CISCO ISE 2.x monitoring REST API</title>
		<link>https://kubsoo.github.io/rsnet-website/cisco-ise-2-x-monitoring-rest-api/</link>
		<comments>https://kubsoo.github.io/rsnet-website/cisco-ise-2-x-monitoring-rest-api/#respond</comments>
		<pubDate>Tue, 10 Oct 2017 19:58:55 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[cisco]]></category>
		<category><![CDATA[ISE]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rest api]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=446</guid>
		<description><![CDATA[Cisco ISE (Identity Services Engine) pozwala na bezpieczny dostęp urządzeń i użytkowników do sieci przewodowych, bezprzewodowych i do VPN. Więcej informacji na temat możliwości i zastosowań ISE można znaleźć na&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">Cisco <a href="https://www.cisco.com/c/en/us/products/security/identity-services-engine/index.html#~stickynav=1" title="">ISE</a> (Identity Services Engine) pozwala na bezpieczny dostęp urządzeń i użytkowników do sieci przewodowych, bezprzewodowych i do VPN. Więcej informacji na temat możliwości i zastosowań ISE można znaleźć na stronie Cisco.com. Ja skupię się na bardzo przydatnej funkcjonalności dostępnej w ISE a mianowicie REST API.</p>
<p style="text-align: justify;">Po podniesieniu wersji ISE z 2.2 do 2.3 napotkałem następujący problem. Po wejściu do interfejsu webowego do głównego menu nie wyświetla się lista aktywnych Endpointów. Mimo iż stacje końcowe są uwierzytelnione do sieci przez ISE.</p>
<p><a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_3.png" data-rel="lightbox-image-0" data-rl_title="" data-rl_caption="" title=""><img class="aligncenter wp-image-449 size-full" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_3.png" alt="" width="1182" height="249" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_3.png 1182w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_3-300x63.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_3-768x162.png 768w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_3-1024x216.png 1024w" sizes="(max-width: 1182px) 100vw, 1182px" /></a></p>
<p style="text-align: justify;">Problem można rozwiązać kontaktując się z supportem CISCO, albo skorzystać z dostępnego REST API.</p>
<p style="text-align: justify;">Do sprawdzenia ilości sesji posłużymy się <a href="https://www.cisco.com/c/en/us/td/docs/security/ise/2-0/api_ref_guide/api_ref_book/ise_api_ref_ch1.html" title="">Monitoring REST API</a>. W tym celu musimy najpierw stworzyć użytkownika w jednej z poniższych grup:</p>
<ul>
<li class="pBu1_Bullet1">Super Admin</li>
<li class="pBu1_Bullet1">System Admin</li>
<li class="pBu1_Bullet1">MnT Admin</li>
</ul>
<p style="text-align: justify;">Załóżmy że stworzymy sobie użytkownika mnt_admin w grupie MnT Admin, o haśle Cisco123!</p>
<p><a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_1.png" data-rel="lightbox-image-1" data-rl_title="" data-rl_caption="" title=""><img class="aligncenter wp-image-451 size-full" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_1.png" alt="" width="1224" height="321" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_1.png 1224w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_1-300x79.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_1-768x201.png 768w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_1-1024x269.png 1024w" sizes="(max-width: 1224px) 100vw, 1224px" /></a></p>
<p><a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_2.png" data-rel="lightbox-image-2" data-rl_title="" data-rl_caption="" title=""><img class="aligncenter wp-image-452 size-full" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_2.png" alt="" width="991" height="779" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_2.png 991w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_2-300x236.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/ise_2-768x604.png 768w" sizes="(max-width: 991px) 100vw, 991px" /></a></p>
<h4>TEST API</h4>
<p>Teraz możemy przetestować Monitoring REST API wpisując w przeglądarce:</p>
<p>https://&lt;/ ISE-Management-Node &gt;/API/mnt/Session/ActiveList</p>
<p style="text-align: justify;">Pojawi się ekran do logowania. W polu username wpisujemy stworzonego przez nas wcześniej usera: mnt_admin, w polu password hasło: Cisco123!. Po poprawnym uwierzytelnieniu powinniśmy zobaczyć plik xml o postaci:</p>
<pre>&lt;?xml version='1.0' encoding='UTF-8'?&gt;
&lt;activeList noOfActiveSession="226"&gt;
  &lt;activeSession&gt;
    &lt;user_name&gt;00:22:3C:0D:BA:26&lt;/user_name&gt;
    &lt;calling_station_id&gt;00:22:3C:0D:BA:26&lt;/calling_station_id&gt;
    &lt;nas_ip_address&gt;192.168.10.22&lt;/nas_ip_address&gt;
    &lt;acct_session_id&gt;0000001F&lt;/acct_session_id&gt;
    &lt;audit_session_id&gt;0A120A02000000D40135DECF&lt;/audit_session_id&gt;
    &lt;server&gt;ISE01&lt;/server&gt;
    &lt;framed_ip_address&gt;172.16.22.12&lt;/framed_ip_address&gt;
    &lt;framed_ipv6_address/&gt;
  &lt;/activeSession&gt;
  &lt;activeSession&gt;
    &lt;user_name&gt;00:F1:4C:47:B2:27&lt;/user_name&gt;
    &lt;calling_station_id&gt;00:F1:4C:47:B2:27&lt;/calling_station_id&gt;
    &lt;nas_ip_address&gt;192.168.10.22&lt;/nas_ip_address&gt;
    &lt;acct_session_id&gt;00000011&lt;/acct_session_id&gt;
    &lt;audit_session_id&gt;0A120A020000003B004E8945&lt;/audit_session_id&gt;
    &lt;server&gt;ISE01&lt;/server&gt;
    &lt;framed_ip_address&gt;172.16.22.16&lt;/framed_ip_address&gt;
    &lt;framed_ipv6_address/&gt;
  &lt;/activeSession&gt;

…

  &lt;activeSession&gt;
    &lt;user_name&gt;00:14:38:28:A9:12&lt;/user_name&gt;
    &lt;calling_station_id&gt;00:14:38:28:A9:12&lt;/calling_station_id&gt;
    &lt;nas_ip_address&gt;192.168.10.22&lt;/nas_ip_address&gt;
    &lt;acct_session_id&gt;000023B1&lt;/acct_session_id&gt;
    &lt;audit_session_id&gt;0A0C0AED000019DF4879AACD&lt;/audit_session_id&gt;
    &lt;server&gt;ISE01&lt;/server&gt;
    &lt;framed_ip_address&gt;172.16.22.32&lt;/framed_ip_address&gt;
    &lt;framed_ipv6_address/&gt;
  &lt;/activeSession&gt;
  &lt;activeSession&gt;
    &lt;user_name&gt;corp.local/jan.kowalski&lt;/user_name&gt;
    &lt;calling_station_id&gt;EC:F4:BA:17:AB:0D&lt;/calling_station_id&gt;
    &lt;nas_ip_address&gt;192.168.10.22&lt;/nas_ip_address&gt;
    &lt;acct_session_id&gt;00002BDD&lt;/acct_session_id&gt;
    &lt;audit_session_id&gt;0A0B02E200000DA7DF251399&lt;/audit_session_id&gt;
    &lt;server&gt;ISE01&lt;/server&gt;
    &lt;framed_ip_address&gt;172.16.24.12&lt;/framed_ip_address&gt;
    &lt;framed_ipv6_address/&gt;
  &lt;/activeSession&gt;
 &lt;/activeList&gt;</pre>
<p style="text-align: justify;">Wynikiem jest plik XML z kilkoma wartościami dla każdej aktywnej sesji: user_name (nazwa użytkownika), calling_station_id (adres MAC stacji końcowej), nas_ip_address (adres IP urządzenia sieciowego (NAD), do którego podięty jest użytkownik), acct_session_id, audit_session_id, server (instancja ISE do której należy dana sesja) i framed_ip_address (adres IP stacji końcowej)</p>
<p>Druga linijka wyniku zawiera informację o liczbie sesji:</p>
<p><strong>&lt;activeList noOfActiveSession=&#8221;226&#8243;&gt;</strong></p>
<p style="text-align: justify;">Napiszmy teraz skrypt, który oprócz wyświetlenia listy sesji wyświetli też metodę uwierzytelnienia MAB, albo 802.1X.</p>
<h4></h4>
<h4>Skrypt w Pythonie</h4>
<p style="text-align: justify;">Do stworzenia skryptu posłużymy się biblioteką requests, textfsm oraz lxml. Biblioteka requests umożliwi nam połączenie się z API.</p>
<p style="text-align: justify;">Skrypt wygląda następująco:</p>
<pre>#!/usr/bin/python
import requests, textfsm
from lxml import etree

user='mnt_admin'
password='Cisco123!'

r = requests.get('https://&lt;ISE-Management-Node&gt;/admin/API/mnt/Session/ActiveList',auth=(user, password))
utf8_parser = etree.XMLParser(encoding='utf-8')
node = etree.fromstring(r.text.encode('utf-8'), parser=utf8_parser)
xmlstr = etree.tostring(node, xml_declaration=True, encoding="UTF-8", pretty_print=True)

re_table = textfsm.TextFSM(open("ise_sessions.textfsm"))
fsm_results = re_table.ParseText(xmlstr)


total=mab=0
for i in fsm_results:
   total=total+1
   if i[0] == i[1]:
        mab=mab+1

dot1x=total-mab

print "---------------------------------"
print "Sessions per Method"
print "Active Sessions: "+str(total)
print "802.1X Session Count: "+str(dot1x)
print "MAB Session Count: "+str(mab)
print "---------------------------------"</pre>
<p>Plik z szablonem textfsm wygląda następująco:</p>
<pre>Value user_name (\S+)
Value calling_station (\S+)
Value nas_ip_address (\S+)

Start
  ^\s*&lt;activeSession&gt;\s* -&gt; Session

Session
  ^\s*&lt;user_name&gt;${user_name}&lt;\/user_name&gt;
  ^\s*&lt;calling_station_id&gt;${calling_station}&lt;\/calling_station_id&gt;
  ^\s*&lt;nas_ip_address&gt;${nas_ip_address}&lt;\/nas_ip_address&gt; -&gt; Record</pre>
<p>Wynik działania skryptu:</p>
<pre>root@vm01:~# ./ise_api.py

---------------------------------
Sessions per Method
Active Sessions: 226
802.1X Session Count: 85
MAB Session Count: 141
---------------------------------</pre>
<h4>Wyjaśnienie:</h4>
<p style="text-align: justify;">Skrypt wyciąga i zapisuje do tablicy fsm_results następujące informacje dla każdej sesji (username, adres MAC, adres IP). Następnie jest zliczana liczba pozycji w tabeli (total) a w przypadku gdy username = adres MAC, a następuje to w sytuacji gdy uwierzytelniono się do sieci używając MAB (MAC Authentication Bypass). Reszta wyników to uwierzytelnienia przy pomocy 802.1x.</p>
<p style="text-align: justify;">Jak widać liczba aktywnych sesji to 226, a nie tak jak pokazywało WEB GUI 0.</p>
]]></content:encoded>
			<wfw:commentRss>https://kubsoo.github.io/rsnet-website/cisco-ise-2-x-monitoring-rest-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DHCP Linux + TextFSM</title>
		<link>https://kubsoo.github.io/rsnet-website/dhcp-linux-textfsm/</link>
		<comments>https://kubsoo.github.io/rsnet-website/dhcp-linux-textfsm/#respond</comments>
		<pubDate>Thu, 05 Oct 2017 20:39:17 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[dhcp]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[textfsm]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=354</guid>
		<description><![CDATA[We wpisie Cisco CLI + TextFSM pokazałem jak można wykorzystać bibliotekę textfsm do obrabiania wyników komend na urządzeniach z Cisco IOS. W tym wpisie pokażę jak uniwersalna jest ta biblioteka&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">We wpisie <a href="https://kubsoo.github.io/rsnet-website/cisco-cli-textfsm/" title="">Cisco CLI + TextFSM</a> pokazałem jak można wykorzystać bibliotekę textfsm do obrabiania wyników komend na urządzeniach z Cisco IOS. W tym wpisie pokażę jak uniwersalna jest ta biblioteka na przykładzie serwera DHCP postawionego na systemie Linux i wyciągania danych z pliku konfiguracyjnego.</p>
<p style="text-align: justify;">Plik konfiguracyjny serwera <a href="https://www.isc.org/downloads/dhcp/" title="">ISC-DHCP</a> znajduje się domyślnie w /etc/dhcpd.conf i ma postać:</p>
<pre>ddns-update-style none;
log-facility local7;

subnet 10.99.10.0 netmask 255.255.255.0 {
        option routers                  10.99.10.1;
        option subnet-mask              255.255.255.0;
        option broadcast-address        10.99.10.255;
        option domain-name-servers      10.99.10.100;
        option ntp-servers              10.99.10.1;
        option netbios-name-servers     10.99.10.1;
        option netbios-node-type 2;
        default-lease-time 86400;
        max-lease-time 86400;

        host KOMPUTER_01 {hardware ethernet 28:d2:44:fa:2c:49;  fixed-address 10.99.10.11;}   #Komputer 01
        host KOMPUTER_02 {hardware ethernet 00:CC:D1:38:AC:45;  fixed-address 10.99.10.12;} #Komputer 02
        host KOMPUTER_03 {hardware ethernet 01:AC:D2:33:AA:41;  fixed-address 10.99.10.13;} #Komputer 03
        host KOMPUTER_04 {hardware ethernet 44:1E:A1:2F:62:A0;  fixed-address 10.99.10.14;} #Komputer 04
        host KOMPUTER_05 {hardware ethernet EC:F4:BB:47:0B:0D;  fixed-address 10.99.10.15;} #Komputer 05
        host KOMPUTER_06 {hardware ethernet f0:de:f1:61:c3:91;  fixed-address 10.99.10.16;} #Komputer 06
        host KOMPUTER_02 {hardware ethernet 50:7B:9D:04:CD:0D;  fixed-address 10.99.10.17;} #Komputer 07
        host KOMPUTER_02 {hardware ethernet C8:5B:76:5B:22:05;  fixed-address 10.99.10.18;} #Komputer 08
        #host KOMPUTER_02 {hardware ethernet 00:CC:D1:38:AC:45;  fixed-address 10.99.10.19;} #Komputer 09
}

subnet  10.152.187.0 netmask 255.255.255.0 {
        option routers                  10.152.187.1;
        option subnet-mask              255.255.255.0;
        option broadcast-address        10.152.187.255;
        option domain-name-servers      194.168.4.100;
        option ntp-servers              10.152.187.1;
        option netbios-name-servers     10.152.187.1;
        option netbios-node-type 2;
        default-lease-time 86400;
        max-lease-time 86400;

        host KOMPUTER_11 {hardware ethernet 00:22:AA:66:55:9B;    fixed-address 10.152.187.2;}     #Komputer 11
}</pre>
<p>Załóżmy że z tego pliku chcemy wyciągnąć takie informacje jak:</p>
<p>nazwa hosta, adres MAC, adres IP oraz komentarz.</p>
<p style="text-align: justify;">Możemy do tego celu użyć dostępnych w linuxie narzędzi do pracy z tekstem (grep, awk, cut), natomiast dużo łatwiej i szybciej możemy napisać skrypt w Pythonie wykorzystujący bibliotekę textFSM.</p>
<p>Skrypt realizujący to zdanie dhcp.py wygląda następująco:</p>
<pre>#!/usr/bin/python
import textfsm

file = open("/etc/dhcpd.conf","r")    
text = file.read()
file.close()
re_table = textfsm.TextFSM(open("dhcp.textfsm"))
fsm_results = re_table.ParseText(text)

for i in fsm_results:
   i[1] = i[1].lower()
   print i[0]+','+i[1]+','+i[2]+','+i[3]</pre>
<p style="text-align: justify;">Plik dhcp.textfsm zawierający szablon z wyrażeniami regularnymi ma postać:</p>
<pre>Value hostname (\S+)
Value mac ([^ ;]+)
Value ip ([^ ;]+)
Value description (.+)

Start
  ^\s*host\s+${hostname}\s+{hardware\s+ethernet\s+${mac}\S+\s+fixed-address\s+${ip}+\S+\s+#${description} -&gt; Record</pre>
<p>Wynik działania powyższego skryptu to:</p>
<pre>root@vm01:~# ./dhcp.py

KOMPUTER_01,28:d2:44:fa:2c:49,10.99.10.11,Komputer 01

KOMPUTER_02,00:cc:d1:38:ac:45,10.99.10.12,Komputer 02

KOMPUTER_03,01:ac:d2:33:aa:41,10.99.10.13,Komputer 03

KOMPUTER_04,44:1e:a1:2f:62:a0,10.99.10.14,Komputer 04

KOMPUTER_05,ec:f4:bb:47:0b:0d,10.99.10.15,Komputer 05

KOMPUTER_06,f0:de:f1:61:c3:91,10.99.10.16,Komputer 06

KOMPUTER_02,50:7b:9d:04:cd:0d,10.99.10.17,Komputer 07

KOMPUTER_02,c8:5b:76:5b:22:05,10.99.10.18,Komputer 08

KOMPUTER_11,00:22:aa:66:55:9b,10.152.187.2,Komputer 11</pre>
<p style="text-align: justify;">Otrzymaliśmy więc to co chcieliśmy, czyli nazwę hosta, adres MAC, adres IP, oraz komentarz. W celach kosmetycznych skrypt wypisuje wyniki na ekranie oddzielone przecinkami, czyli możemy sobie takie wyniki zaimportować np. do Excela.</p>
<h4></h4>
<p>&nbsp;</p>
<h4>OMÓWIENIE SKRYPTU dhcp.py</h4>
<p>Przejdźmy teraz do omówienia skryptu linijka po linijce.</p>
<p><strong><em>#!/usr/bin/python </em></strong>&#8212;&gt; powoduje uruchomienie pliku jako program w Pythonie</p>
<p><em><strong>import textfsm</strong> </em>&#8212;&gt;<em> </em>import biblioteki textfsm</p>
<p style="text-align: justify;"><em><strong>file=open(&#8222;/etc/dhcpd.conf&#8221;,&#8221;r&#8221;) </strong></em>&#8212;&gt; do otwarcia pliku wykorzystamy wbudowaną funkcję open, plik otwieramy do odczytu “r”</p>
<p style="text-align: justify;"><em><strong>text=file.read() </strong></em>&#8212;&gt; funkcja read() odczytuje zawartość pliku i przypisuje całą zawartość do zmiennej text</p>
<p><em><strong>file.close()</strong></em> &#8212;&gt; funkcja zamykająca plik</p>
<p style="text-align: justify;"><em><strong>re_table=textfsm.TextFSM(open(&#8222;dhcp.textfsm&#8221;)) </strong></em>&#8212;&gt;<em><strong> </strong></em>otwarcie pliku szablonu dhcp.textfsm przez textfsm</p>
<p style="text-align: justify;"><em><strong>fsm_results=re_table.ParseText(text) </strong></em>&#8212;&gt; wykonanie parsowania tekstu ze zmiennej text i przypisanie wyniku do listy fsm_results</p>
<p style="text-align: justify;"><em><strong>for i in fsm_results: </strong></em>&#8211;&gt; petla for, która przetwarza każdy element z listy fsm_results, przetwarzany element jest również listą</p>
<p style="text-align: justify; padding-left: 30px;"><em><strong>i[1] = i[1].lower() </strong></em>&#8212;&gt; dla elementu na drugiej pozycji przetwarzanej listy (w tym przypadku jest to adres MAC, który może być zarówno małymi jak i dużymi literami pisany) wykonaj funkcję lower(), czyli zamień duże na małe litery</p>
<p style="text-align: justify; padding-left: 30px;"><em><strong>print i[0]+’,&#8217;+i[1]+’,&#8217;+i[2]+’,&#8217;+i[3] </strong></em>&#8212;&gt; wypisanie na ekranie 4 elementów listy (hostname, adres mac, adres IP, komentarz) przedzielonych przecinkami</p>
<p>&nbsp;</p>
<h4>OMÓWIENIE SZABLONU dhcp.textfsm</h4>
<p style="text-align: justify;">W przypadku braku znajomości wyrażeń regularnych tworzenie szablonu dhcp.textfsm najlepiej wykonywać z wykorzystaniem strony <a href="http://regex101.com/" title="">regex101.com</a>. Poniżej screen z tej strony z wyrażeniem regularnych użytym w skrypcie dhcp.py:</p>
<p><a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/regex1-1.png" data-rel="lightbox-image-0" data-rl_title="" data-rl_caption="" title=""><img class="aligncenter wp-image-387 size-full" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/regex1-1.png" alt="" width="983" height="494" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/regex1-1.png 983w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/regex1-1-300x151.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/10/regex1-1-768x386.png 768w" sizes="(max-width: 983px) 100vw, 983px" /></a></p>
<p style="text-align: justify;">Z powyższego screena widać, że wszystkie interesujące nas informacje zostały dopasowane prawidłowo</p>
<ul>
<li>Group1 &#8211; kolor zielony &#8211; hostname</li>
<li>Group2 &#8211; kolor czerwony &#8211; adres MAC</li>
<li>Group3 &#8211; kolor pomarańczowy  &#8211; adres IP</li>
<li>Group4 &#8211; kolor fioletowy &#8211; komentarz</li>
</ul>
<p>Jeśli weźmiemy plik dhcp.textfsm:</p>
<pre>Value hostname (\S+) 
Value mac ([^ ;]+) 
Value ip ([^ ;]+) 
Value description (.+) 

Start
   ^\s*host\s+${hostname}\s+{hardware\s+ethernet\s+${mac}\S+\s+fixed-address\s+${ip}+\S+\s+#${description} -&gt; Record</pre>
<p style="text-align: justify;">i podstawimy do wyrażenia regularnego występującego po słowie Start wyrażenia regularne dla odpowiednich wartości, to otrzymamy dokładnie to wyrażenie które zostało użyte w polu REGULAR EXPRESSION na stronie regex101.com:</p>
<pre>^\s*host\s+(\S+)\s+{hardware\s+ethernet\s+([^ ;]+)\S+\s+fixed-address\s+([^ ;]+)+\S+\s+#(.+) -&gt; Record</pre>
<p style="text-align: justify;">W powyższym wyrażeniu regularnym korzystamy właściwie tylko z kombinacji znaków które występują w każdej linijce (typu: hardware, ethernet, host, fixed-address) oraz z następujących wzorców:</p>
<p>\s+    spacja występująca raz lub więcej razy</p>
<p>\S+   dowolny znak bez spacji występujących raz lub więcej razy</p>
<p>.+      dowolny znak występujący raz lub więcej razy</p>
<p style="text-align: justify;">[^ ;]+    dowolna kombinacja znaków nie zawierająca spacji oraz średnika występując raz lub więcej razy</p>
<p style="text-align: justify;">W pliku dhcp.textfsm po wyrażeniu regularnym w sekcji Start występuje coś takiego: &#8222;-&gt; Record&#8221;. Oznacza to tyle, że po znalezieniu dopasowania wyniki są zapisywane do tablicy i następuje analiza kolejnej linii. Dzięki temu możemy otrzymać wiele wyników, a nie tak jak we wpisie o <a href="https://kubsoo.github.io/rsnet-website/cisco-cli-textfsm/">Cisco CLI i textFSM</a> tylko jeden.</p>
<p style="text-align: justify;">Strona regex101.com jest bardzo pomocna w debugowaniu przyczyn błędnego wyciągania informacji przez textfsm. Jeśli nasze wyrażenie regularne po wklejeniu go na stronę oraz tekstu, na którym będzie wykonywanie to wyrażenie nie będzie dopasowywało tak jak tego oczekujemy, to tym bardziej nasz skrypt również tego nie dopasuje.</p>
]]></content:encoded>
			<wfw:commentRss>https://kubsoo.github.io/rsnet-website/dhcp-linux-textfsm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nmap w Pythonie</title>
		<link>https://kubsoo.github.io/rsnet-website/nmap-w-pythonie/</link>
		<pubDate>Fri, 29 Sep 2017 21:38:48 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[nmap]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=237</guid>
		<description><![CDATA[Nmap to potężne narzędzie do skanowania hostów, przydatne miedzy innymi przy wykonywaniu testów penetracyjnych. W poniższym wpisie pokażę jak możemy zautomatyzować pracę z nmapem wykorzystując pythona i bibliotekę python-nmap. Zacznijmy&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;"><a href="https://nmap.org/">Nmap</a> to potężne narzędzie do skanowania hostów, przydatne miedzy innymi przy wykonywaniu testów penetracyjnych. W poniższym wpisie pokażę jak możemy zautomatyzować pracę z nmapem wykorzystując pythona i bibliotekę <a href="https://bitbucket.org/xael/python-nmap">python-nmap</a>.</p>
<p><span id="more-237"></span></p>
<p>Zacznijmy od instalacji biblioteki python-nmap. W tym celu wykonujemy polecenie:</p>
<pre>pip install python-nmap

Collecting python-nmap
 Downloading python-nmap-0.6.1.tar.gz (41kB)
 100% |################################| 51kB 353kB/s
Installing collected packages: python-nmap
 Running setup.py install for python-nmap ... done
Successfully installed python-nmap-0.6.1</pre>
<p>Teraz możemy zaimportować bibliotekę do naszego skryptu:</p>
<pre>Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:25:58) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import nmap</pre>
<p>Przykładowe użycie modułu nmap.py wygląda następująco:</p>
<pre>nm = nmap.PortScanner() # stworzenie obiektu nmap.PortScanner
nm.scan('127.0.0.1', '22-443') # skanowanie portów od 22 do 443 hosta o adresie IP 127.0.0.1
nm.command_line() # wyświetlenie komendy użytej do skanowania : nmap -oX - -p 22-443 127.0.0.1
nm.scaninfo() # wyświetlenie informacji dotyczących skanowania {'tcp': {'services': '22-443', 'method': 'connect'}}
nm.all_hosts() # wyświetlenie listy wszystkich przeskanowanych hostów
nm['127.0.0.1'].hostname() # wyświetlenie nazwy hosta dla adresu 127.0.0.1
nm['127.0.0.1'].state() # wyświetlenie statusu hosta o adresie 127.0.0.1 (up|down|unknown|skipped)
nm['127.0.0.1'].has_tcp(135) # sprawdzenie czy są jakieś informacje o porcie tcp/135 hosta 127.0.0.1
nm['127.0.0.1'].all_tcp() # wyświetlenie wszystkich portów TCP (posortowanych)
nm['127.0.0.1'].all_udp() # wyświetlenie wszystkich portów UDP (posortowanych)
nm['127.0.0.1']['tcp'][135]['state'] # wyświetlenie stanu portu 135/tcp hosta 127.0.0.1 (open, closed, filtered)</pre>
<p>Sprawdźmy teraz jak to wygląda w praktyce:</p>
<pre>Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:25:58) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import nmap
&gt;&gt;&gt; nm = nmap.PortScanner()
&gt;&gt;&gt; nm.scan('127.0.0.1', '22-443')
{'nmap': {'scanstats': {'uphosts': '1', 'timestr': 'Fri Sep 29 21:11:16 2017', 'downhosts': '0', 'totalhosts': '1', 'elapsed': '21.87'}, 'scaninfo': {'tcp': {'services': '22-443', 'method': 'syn'}}, 'command_line': 'nmap -oX - -p 22-443 -sV 127.0.0.1'}, 'scan': {'127.0.0.1': {'status': {'state': 'up', 'reason': 'localhost-response'}, 'hostnames': [{'type': '', 'name': ''}], 'vendor': {}, 'addresses': {'ipv4': '127.0.0.1'}, 'tcp': {137: {'product': '', 'state': 'filtered', 'version': '', 'name': 'netbios-ns', 'conf': '3', 'extrainfo': '', 'reason': 'no-response', 'cpe': ''}, 135: {'product': 'Microsoft Windows RPC', 'state': 'open', 'version': '', 'name': 'msrpc', 'conf': '10', 'extrainfo': '', 'reason': 'syn-ack', 'cpe': 'cpe:/o:microsoft:windows'}}}}}
&gt;&gt;&gt; nm.command_line()
'nmap -oX - -p 22-443 -sV 127.0.0.1'
&gt;&gt;&gt; nm.scaninfo()
{'tcp': {'services': '22-443', 'method': 'syn'}}
&gt;&gt;&gt; nm.all_hosts()
['127.0.0.1']
&gt;&gt;&gt; nm['127.0.0.1'].hostname()
''
&gt;&gt;&gt; nm['127.0.0.1'].state()
'up'
&gt;&gt;&gt; nm['127.0.0.1'].has_tcp(22)
False
&gt;&gt;&gt; nm['127.0.0.1'].all_tcp()
[135, 137]
&gt;&gt;&gt; nm['127.0.0.1'].all_udp()
[]
&gt;&gt;&gt; nm['127.0.0.1']['tcp'][135]['state']
'open'
</pre>
<p>Wynik skanowania możemy również w łatwy sposób przedstawić w postaci CSV. W tym celu wykonujemy komendę:</p>
<pre>&gt;&gt;&gt; nm.csv()
'host;hostname;hostname_type;protocol;port;name;state;product;extrainfo;reason;version;conf;cpe\r\n127.0.0.1;;;tcp;135;msrpc;open;Microsoft Windows RPC;;syn-ack;;10;cpe:/o:microsoft:windows\r\n127.0.0.1;;;tcp;137;netbios-ns;filtered;;;no-response;;3;\r\n'</pre>
<p style="text-align: justify;">Napiszmy teraz skrypt, który dla każdego przeskanowanego hosta (w moim przypadku był to tylko jeden host 127.0.0.1) wypisze na ekranie IP, hostname (w moim przypadku hostname jest pusty) oraz status hosta (up/down). Dodatkowo dla każdego z zaskanowanych portów (22-443) skrypt wypisze status portu, oraz protokół tcp/udp.</p>
<pre>&gt;&gt; for host in nm.all_hosts():
...         print('----------------------------------------------------')
...         print('Host : %s (%s)' % (host, nm[host].hostname()))
...         print('State : %s' % nm[host].state())
...        for proto in nm[host].all_protocols():
...              print('----------')
...              print('Protocol : %s' % proto)
...
...              lport = nm[host][proto].keys()
...              lport.sort()
...              for port in lport:
...                     print ('port : %s\tstate : %s' % (port, nm[host][proto][port]['state']))</pre>
<pre>----------------------------------------------------
Host : 127.0.0.1 ()
State : up
----------
Protocol : tcp
port : 135 state : open
port : 137 state : filtered</pre>
<p>&nbsp;</p>
]]></content:encoded>
			</item>
		<item>
		<title>Cisco CLI + TextFSM</title>
		<link>https://kubsoo.github.io/rsnet-website/cisco-cli-textfsm/</link>
		<comments>https://kubsoo.github.io/rsnet-website/cisco-cli-textfsm/#respond</comments>
		<pubDate>Tue, 26 Sep 2017 19:41:12 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[cisco]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[netmiko]]></category>
		<category><![CDATA[paramiko]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[textfsm]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=198</guid>
		<description><![CDATA[W poprzednich wpisach pokazałem jak można wykorzystać Pythona i biblioteki Netmiko, Paramiko do wydawania komend w Cisco IOS. Tradycyjnie SSH jest używany do łączenia się z urządzeniem sieciowym, wydawania polecenia i&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">W poprzednich wpisach pokazałem jak można wykorzystać Pythona i biblioteki Netmiko, Paramiko do wydawania komend w Cisco IOS. Tradycyjnie SSH jest używany do łączenia się z urządzeniem sieciowym, wydawania polecenia i zrzutu wyników zwykłego tekstu z powrotem do użytkownika.</p>
<p style="text-align: justify;">W celu automatyzacji niektórych czynności musimy często wyniki z komend sformatować w sposób umożliwiający wydobywanie tylko niektórych informacji. W tym celu możemy posłużyć się biblioteką Pythona <a href="https://github.com/google/textfsm" title="">textFSM</a>.</p>
<p><span id="more-198"></span></p>
<p style="text-align: justify;">Zobaczmy jak korzystając z textFSM przetwarzać wyniki komend CISCO IOS. Do pracy z textFSM przyda się podstawowa wiedza z wyrażeń regularnych, jednak nie jest ona niezbędna. Pokaże jak szybko nauczyć się podstawowych wyrażeń regularnych. Budując wyrażenia regularne będziemy posługiwać się stroną <a href="http://regex101.com/" title="">regex101.com.</a></p>
<p>Przed przystąpieniem do pracy z textFSM musimy go zainstalować:</p>
<pre>pip install textfsm
Collecting textfsm
 Downloading textfsm-0.3.2.tar.gz
Installing collected packages: textfsm
 Running setup.py install for textfsm ... done
Successfully installed textfsm-0.3.2</pre>
<p>a następnie w skrypcie Pythona musimy go zaimportować:</p>
<pre>Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:25:58) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import textfsm</pre>
<p style="text-align: justify;">Załóżmy, że chcemy z routera Cisco wyciągnąć takie informacje jak:</p>
<ul>
<li style="text-align: justify;">hostname,</li>
<li style="text-align: justify;">model,</li>
<li style="text-align: justify;">uptime,</li>
<li style="text-align: justify;">serial number,</li>
<li style="text-align: justify;">ios,</li>
<li>software version.</li>
</ul>
<p style="text-align: justify;">Skrzystajmy więc z biblioteki netmiko i podłączmy się przez ssh do routera R1 o adresie IP 192.168.174.200 korzystając z użytkownika admin o haśle cisco i wydajmy polecenie show version.</p>
<pre>&gt;&gt;&gt; from netmiko import ConnectHandler
&gt;&gt;&gt; cisco = {'device_type':'cisco_ios','ip':'192.168.174.200','username':'admin','password':'cisco'}
&gt;&gt;&gt; net_connect = ConnectHandler(**cisco)
&gt;&gt;&gt; output = net_connect.send_command('show version') 
&gt;&gt;&gt; ssh_connection.disconnect()
&gt;&gt;&gt; print output</pre>
<p style="text-align: justify;">Wynik komendy show version najlepiej zapisać w notatniku,  bo przyda nam się do zbudowania wyrażeń regularnych:</p>
<pre>Cisco IOS Software, 7200 Software (C7200-JK9S-M), Version 12.4(13b), RELEASE SOFTWARE (fc3)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2007 by Cisco Systems, Inc.
Compiled Wed 25-Apr-07 03:18 by prod_rel_team

ROM: ROMMON Emulation Microcode
BOOTLDR: 7200 Software (C7200-JK9S-M), Version 12.4(13b), RELEASE SOFTWARE (fc3)

R1 uptime is 1 minute
System returned to ROM by unknown reload cause - suspect boot_data[BOOT_COUNT] 0x0, BOOT_COUNT 0, BOOTDATA 19
System image file is "tftp://255.255.255.255/unknown"



This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
export@cisco.com.

Cisco 7206VXR (NPE400) processor (revision A) with 491520K/32768K bytes of memory.
Processor board ID 4279256517
R7000 CPU at 150MHz, Implementation 39, Rev 2.1, 256KB L2 Cache
6 slot VXR midplane, Version 2.1

Last reset from power-on

PCI bus mb0_mb1 (Slots 0, 1, 3 and 5) has a capacity of 600 bandwidth points.
Current configuration on bus mb0_mb1 has a total of 600 bandwidth points.
This configuration is within the PCI bus capacity and is supported.

PCI bus mb2 (Slots 2, 4, 6) has a capacity of 600 bandwidth points.
Current configuration on bus mb2 has a total of 0 bandwidth points
This configuration is within the PCI bus capacity and is supported.

Please refer to the following document "Cisco 7200 Series Port Adaptor
Hardware Configuration Guidelines" on Cisco.com &lt;http://www.cisco.com&gt;/
for c7200 bandwidth points oversubscription and usage guidelines.



3 FastEthernet interfaces
509K bytes of NVRAM.

8192K bytes of Flash internal SIMM (Sector size 256K).
Configuration register is 0x2102</pre>
<p>Przykładowe użycie biblioteki wygląda następująco:</p>
<pre>&gt;&gt;&gt; re_table = textfsm.TextFSM(open("template.textfsm"))
&gt;&gt;&gt; fsm_results = re_table1.ParseText(output)</pre>
<p style="text-align: justify;">gdzie output to surowy tekst wyniku naszej komendy show version, a template.textfsm to plik zawierający szablon z wyrażeniami regularnymi dla naszej komendy show version i informacji które chcemy z niej wyciągnąć.</p>
<p>template.textfsm</p>
<pre>Value hostname (\S+)
Value model (\S+)
Value uptime (.+)
Value serial ([^ ,]+)
Value ios (\S+)
Value version ([^ ,]+)
Start
 ^.*Software.*Version\s+${version}
 ^${hostname}\s+uptime\s+is\s+${uptime}
 ^Cisco\s+${model}.+
 ^System\s+image\s+file\s+is\s+.${ios}.
 ^Processor\s+board\s+ID\s+${serial}</pre>
<p>Sprawdźmy co zawiera zmienna fsm_results:</p>
<pre>&gt;&gt;&gt; print fsm_results
[[u'R1', u'7206VXR', u'4 weeks, 1 day, 8 hours, 19 minutes', u'4279256517', u'tftp://255.255.255.255/unknown', u'12.4(13b)']]</pre>
<p style="text-align: justify;">Jest to tablica, z której w łatwy sposób możemy wyciągnać interesującą nas rzecz. Np. jeśli chcemy wyświetlić sam numer seryjny routera, wystarczy że wpiszemy:</p>
<pre>&gt;&gt; fsm_results[0][3]
u'4279256517'</pre>
<p>&nbsp;</p>
<p style="text-align: justify;">Pokażę teraz jak stworzyć zawartość pliku template.textfsm. Otwórzmy stronę <a href="http://regex101.com/" title="">regex101.com</a> i wklejmy w polu TEST STRING wynik komendy show version:</p>
<p><a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex1-1.png" data-rel="lightbox-image-0" data-rl_title="" data-rl_caption="" title=""><img class="alignnone wp-image-215 size-full" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex1-1.png" alt="" width="1227" height="747" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex1-1.png 1227w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex1-1-300x183.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex1-1-768x468.png 768w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex1-1-1024x623.png 1024w" sizes="(max-width: 1227px) 100vw, 1227px" /></a></p>
<p style="text-align: justify;">Strona powyższa pozwoli nam przetestować regex, który wyciąga odpowiednią informację. Najważniejsze regexy które należy znać to:</p>
<p>\s+    spacja występująca raz lub więcej razy</p>
<p>\S+   dowolny znak bez spacji występujących raz lub więcej razy</p>
<p>.+      dowolny znak występujący od 1 do nieskończoności razy</p>
<p style="text-align: justify;">Jeśli nie znamy wyrażeń regularnych możemy skorzystać z pomocy na stronie regex101.com. Weźmy wyrażenie regularne którego nie znamy, np. [^ ,]+ i wklejmy w pole REGULAR EXPRESSION, otrzymamy taki wynik:</p>
<p><a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex3.png" data-rel="lightbox-image-1" data-rl_title="" data-rl_caption="" title=""><img class="wp-image-229 size-full aligncenter" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex3.png" alt="" width="1507" height="275" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex3.png 1507w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex3-300x55.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex3-768x140.png 768w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex3-1024x187.png 1024w" sizes="(max-width: 1507px) 100vw, 1507px" /></a></p>
<p style="text-align: justify;">Po prawej stronie mamy wyjaśnienie (EXPLANATION) co robi dane wyrażenie regularne. W tym przypadku jest to dowolna znak, oprócz spacji i przecinka które występujący raz lub więcej razy.</p>
<p>&nbsp;</p>
<p>Wróćmy teraz do textFSM. Zawartość pliku template.textfsm wygląda następująco:</p>
<pre>Value   wartosc1     regex
Value   wartosc2     regex
Start
^regex    ${wartosc1}
^regex    ${wartosc2}</pre>
<p style="text-align: justify;">Domyślnie textFSM działa następująco.  Parser textFSM tworzy tablice wartości [wartosc1,wartosc2,..] na podstawie szablonu template.textfsm. Najpierw sprawdzana jest pierwsza linijka tekstu &#8211; w moim przypadku jest to tekst ze zmiennej output (re_table1.ParseText(output)) i sprawdzane są wyrażenia regularne po kolei (Start ^regex -&gt; ^regex &#8230;). Jeśli któreś wyrażenie regularne dla danej wartości pasuje, to zapisywana jest wartość wyrażenia regularnego do buforu. Następnie sprawdzana jest druga linijka i również dla drugiej linijki sprawdzane są wyrażenia regularne po kolei tak jak dla pierwszej linijki, jak któreś z nich pasuje, to zapisywana jest wartość tego wyrażenia do buforu. Na końcu bufor zawiera wartości dla pól Value, które są w takiej kolejności jak zadeklarowane wartości w pliku template.textfsm.</p>
<p style="text-align: justify;">Najlepiej pokazać tworzenie zawartości pliku textfsm na przykladzie. Weźmy teraz dla przykładu ios. Do wyciągnięcia informacji o pliku z systemem IOS musimy stworzyć regex o postaci:</p>
<p><a href="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex2.png" data-rel="lightbox-image-2" data-rl_title="" data-rl_caption="" title=""><img class="aligncenter wp-image-219 size-full" src="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex2.png" alt="" width="1215" height="604" srcset="https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex2.png 1215w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex2-300x149.png 300w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex2-768x382.png 768w, https://kubsoo.github.io/rsnet-website/wp-content/uploads/2017/09/regex2-1024x509.png 1024w" sizes="(max-width: 1215px) 100vw, 1215px" /></a></p>
<p style="text-align: justify;">Jak widać z powyższego zrzutu ekranu, dokładnie taki regex wyciągnie nam informacje o IOS.</p>
<pre>Value ios (\S+) 

^System\s+image\s+file\s+is\s+.${ios}.</pre>
<p style="text-align: justify;">Więcej gotowych szablonów dla różnych komend dla różnych urządzeń znajduje się pod poniższym <a href="https://github.com/networktocode/ntc-templates/tree/master/templates">linkiem</a>.</p>
<p style="text-align: justify;">Polecam naukę wyrażeń regularnych, bo przydają się one bardzo często, chociażby do takich czynności jak praca z textfsm, które jest bardzo pomocnym narzędziem do automatyzacji pracy z urządzeniami sieciowymi.</p>
]]></content:encoded>
			<wfw:commentRss>https://kubsoo.github.io/rsnet-website/cisco-cli-textfsm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CISCO + Python + Paramiko</title>
		<link>https://kubsoo.github.io/rsnet-website/cisco-python-paramiko/</link>
		<comments>https://kubsoo.github.io/rsnet-website/cisco-python-paramiko/#respond</comments>
		<pubDate>Thu, 21 Sep 2017 22:43:24 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[cisco]]></category>
		<category><![CDATA[paramiko]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=186</guid>
		<description><![CDATA[Python i biblioteka Paramiko umożliwiają korzystanie z połączeń SSH z urządzeniami CISCO. W poniższym wpisie pokaże jak wykonać dowolną komendę na urządzeniu z CISCO IOS przy pomocy skryptu Python z wykorzystaniem&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">Python i biblioteka <a href="http://www.paramiko.org/">Paramiko</a> umożliwiają korzystanie z połączeń SSH z urządzeniami CISCO. W poniższym wpisie pokaże jak wykonać dowolną komendę na urządzeniu z CISCO IOS przy pomocy skryptu Python z wykorzystaniem Paramiko.</p>
<p style="text-align: justify;">Przy pomocy biblioteki Paramiko jesteśmy w stanie osiągnąć ten sam efekt który opisywałem we wpisie o bibliotece Netmiko. Jedyna różnica jest taka, że biblioteka Netmiko umożliwiała również połączenia telnet, natomiast Paramiko wspiera tylko SSH.</p>
<p><span id="more-186"></span>W celu zainstalowania biblioteki paramiko wykonujemy następującą komendę:</p>
<pre>pip install paramiko
</pre>
<p><strong>PIERWSZY SKRYPT</strong></p>
<p dir="ltr" data-placeholder="Tłumaczenie">Najpierw musimy zaimportować bibliotekę paramiko, a następnie tworzymy obiekt SSHClient:</p>
<pre dir="ltr" data-placeholder="Tłumaczenie">Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:25:58) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import paramiko
&gt;&gt;&gt; ssh = paramiko.SSHClient()</pre>
<p dir="ltr" style="text-align: justify;" data-placeholder="Tłumaczenie">W moim przypadku chcę się podłączyć przez ssh do routera R1 o adresie IP 192.168.174.200 korzystając z użytkownika admin o haśle cisco:</p>
<pre dir="ltr" data-placeholder="Tłumaczenie">&gt;&gt;&gt; ssh.connect('192.168.174.200',port=22,username='admin',password='cisco')
Traceback (most recent call last):
 File "&lt;stdin&gt;", line 1, in &lt;module&gt;
 File "C:\Python27\lib\site-packages\paramiko\client.py", line 395, in connect
 self, server_hostkey_name, server_key
 File "C:\Python27\lib\site-packages\paramiko\client.py", line 752, in missing_host_key
 raise SSHException('Server %r not found in known_hosts' % hostname)
paramiko.ssh_exception.SSHException: Server '192.168.174.200' not found in known_hosts</pre>
<p style="text-align: justify;">Powyższa komenda zwróciła błąd, ponieważ przy używaniu metody connect paramiko sprawdza czy klucz publiczny hosta jest w pliku known_hosts, w tym przypadku go nie ma więc jest zwracany błąd. Możemy to obejść wykonując poniższą komendę:</p>
<pre>&gt;&gt;&gt; ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())</pre>
<p style="text-align: justify;">Po wydaniu tej komendy klucz dodawany jest automatycznie do pliku known_hosts. Spróbujmy się teraz połączyć do urządzenia:</p>
<pre><span style="font-family: Consolas, Monaco, monospace;">&gt;&gt;&gt; ssh.connect('192.168.174.200',port=22,username='admin',password='cisco')</span></pre>
<p style="text-align: justify;">Komenda nie zwróciła błędu, czyli nastąpiło połączenie ssh do routera, można to zweryfikować logując się na urządzenie i wydając komendę: show users</p>
<pre>R1#show users
 Line User Host(s) Idle Location
* 0 con 0 idle 00:00:00
 2 vty 0 admin idle 00:00:05 192.168.174.1

Interface User Mode Idle Peer Address</pre>
<p>Teraz możemy wykonać dowolną komendę i wypisać ją na ekranie:</p>
<pre>&gt;&gt; stdin, stdout, stderr = ssh.exec_command('show ip int brief')
&gt;&gt;&gt; output = stdout.readlines()
&gt;&gt;&gt; print output
[u'\r\n', u'Interface IP-Address OK? Method Status Protocol\r\n', u'FastEthernet0/0 192.168.174.200 YES NVRAM up up \r\n', u'FastEthernet1/0 10.0.10.1 YES NVRAM up up \r\n', u'FastEthernet1/1 unassigned YES NVRAM administratively down down ']</pre>
<p style="text-align: justify;">W wyniku otrzymaliśmy listę, w celu wypisania jej w bardziej przystępnej postaci na ekranie musimy użyć funkcji join</p>
<p>&gt;&gt;&gt; print &#8221;.join(output)</p>
<pre>Interface IP-Address OK? Method Status Protocol
FastEthernet0/0 192.168.174.200 YES NVRAM up up 
FastEthernet1/0 10.0.10.1 YES NVRAM up up 
FastEthernet1/1 unassigned YES NVRAM administratively down down</pre>
<p style="text-align: justify;">W dalszych wpisach pokażę więcej możliwości i przykładowe skrypty z wykorzystaniem biblioteki paramiko.</p>
]]></content:encoded>
			<wfw:commentRss>https://kubsoo.github.io/rsnet-website/cisco-python-paramiko/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CISCO + Python + Netmiko</title>
		<link>https://kubsoo.github.io/rsnet-website/cisco-python-netmiko/</link>
		<comments>https://kubsoo.github.io/rsnet-website/cisco-python-netmiko/#respond</comments>
		<pubDate>Wed, 20 Sep 2017 23:48:17 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Poradnik]]></category>
		<category><![CDATA[cisco]]></category>
		<category><![CDATA[netmiko]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">https://kubsoo.github.io/rsnet-website/?p=166</guid>
		<description><![CDATA[Python i biblioteka Netmiko mogą stanowić fantastyczne uzupełnienie codziennej pracy z urządzeniami CISCO. W poniższym wpisie pokaże jak wykonać dowolną komendę na urządzeniu z CISCO IOS przy pomocy skryptu Python.&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p style="text-align: justify;">Python i biblioteka <a href="https://github.com/ktbyers/netmiko">Netmiko</a> mogą stanowić fantastyczne uzupełnienie codziennej pracy z urządzeniami CISCO. W poniższym wpisie pokaże jak wykonać dowolną komendę na urządzeniu z CISCO IOS przy pomocy skryptu Python.</p>
<p style="text-align: justify;">Biblioteka netmiko wspiera oprócz urządzeń Cisco również masę innych produktów takich jak:</p>
<p>Regularly tested</p>
<p>Arista vEOS<br />
Cisco ASA<br />
Cisco IOS<br />
Cisco IOS-XE<br />
Cisco IOS-XR<br />
Cisco NX-OS<br />
Cisco SG300<br />
HP Comware7<br />
HP ProCurve<br />
Juniper Junos<br />
Linux</p>
<p><span id="more-166"></span>Limited testing</p>
<p>Alcatel AOS6/AOS8<br />
Avaya ERS<br />
Avaya VSP<br />
Brocade VDX<br />
Brocade ICX/FastIron<br />
Brocade MLX/NetIron<br />
Cisco WLC<br />
Dell-Force10 DNOS9<br />
Dell PowerConnect<br />
Huawei<br />
Mellanox<br />
Palo Alto PAN-OS<br />
Pluribus<br />
Ubiquiti EdgeOS<br />
Vyatta VyOS</p>
<p>Experimental</p>
<p>A10<br />
Accedian<br />
Alcatel-Lucent SR-OS<br />
Aruba<br />
Ciena SAOS<br />
Cisco Telepresence<br />
CheckPoint Gaia<br />
Enterasys<br />
Extreme EXOS<br />
Extreme Wing<br />
F5 LTM<br />
Fortinet<br />
MRV Communications OptiSwitch</p>
<p>W celu zainstalowania biblioteki netmiko wykonujemy następującą komendę:</p>
<pre>pip install netmiko
</pre>
<pre>Collecting netmiko
 Downloading netmiko-1.4.3.tar.gz (47kB)
 100% |################################| 51kB 287kB/s
Collecting paramiko&gt;=1.13.0 (from netmiko)
 Downloading paramiko-2.3.1-py2.py3-none-any.whl (182kB)
 100% |################################| 184kB 975kB/s
Collecting scp&gt;=0.10.0 (from netmiko)
 Downloading scp-0.10.2-py2.py3-none-any.whl
Collecting pyyaml (from netmiko)
 Downloading PyYAML-3.12-cp27-cp27m-win_amd64.whl (197kB)
 100% |################################| 204kB 1.2MB/s
Collecting pynacl&gt;=1.0.1 (from paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading PyNaCl-1.1.2-cp27-cp27m-win_amd64.whl (130kB)
 100% |################################| 133kB 1.2MB/s
Collecting cryptography&gt;=1.5 (from paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading cryptography-2.1.2-cp27-cp27m-win_amd64.whl (1.3MB)
 100% |################################| 1.3MB 660kB/s
Collecting bcrypt&gt;=3.1.3 (from paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading bcrypt-3.1.4-cp27-cp27m-win_amd64.whl
Collecting pyasn1&gt;=0.1.7 (from paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading pyasn1-0.3.7-py2.py3-none-any.whl (63kB)
 100% |################################| 71kB 2.5MB/s
Collecting six (from pynacl&gt;=1.0.1-&gt;paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading six-1.11.0-py2.py3-none-any.whl
Collecting cffi&gt;=1.4.1 (from pynacl&gt;=1.0.1-&gt;paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading cffi-1.11.2-cp27-cp27m-win_amd64.whl (163kB)
 100% |################################| 163kB 2.4MB/s
Collecting idna&gt;=2.1 (from cryptography&gt;=1.5-&gt;paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading idna-2.6-py2.py3-none-any.whl (56kB)
 100% |################################| 61kB 4.4MB/s
Collecting enum34; python_version &lt; "3" (from cryptography&gt;=1.5-&gt;paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading enum34-1.1.6-py2-none-any.whl
Collecting asn1crypto&gt;=0.21.0 (from cryptography&gt;=1.5-&gt;paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading asn1crypto-0.23.0-py2.py3-none-any.whl (99kB)
 100% |################################| 102kB 2.4MB/s
Collecting ipaddress; python_version &lt; "3" (from cryptography&gt;=1.5-&gt;paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading ipaddress-1.0.18-py2-none-any.whl
Collecting pycparser (from cffi&gt;=1.4.1-&gt;pynacl&gt;=1.0.1-&gt;paramiko&gt;=1.13.0-&gt;netmiko)
 Downloading pycparser-2.18.tar.gz (245kB)
 100% |################################| 256kB 2.6MB/s
Installing collected packages: six, pycparser, cffi, pynacl, idna, enum34, asn1crypto, ipaddress, cryptography, bcrypt, pyasn1, paramiko, scp, pyyaml, netmiko
 Running setup.py install for pycparser ... done
 Running setup.py install for netmiko ... done
Successfully installed asn1crypto-0.23.0 bcrypt-3.1.4 cffi-1.11.2 cryptography-2.1.2 enum34-1.1.6 idna-2.6 ipaddress-1.0.18 netmiko-1.4.3 paramiko-2.3.1 pyasn1-0.3.7 pycparser-2.18 pynacl-1.1.2 pyyaml-3.12 scp-0.10.2 six-1.11.0</pre>
<p><strong>PIERWSZY SKRYPT</strong></p>
<p dir="ltr" style="text-align: justify;" data-placeholder="Tłumaczenie">Najpierw musimy zaimportować funkcję ConnectHandler z biblioteki netmiko. <span lang="pl">Następnie definiujemy słownik urządzeń sieciowych składający się z typu urządzenia, adresu IP, nazwy użytkownika i hasła, który reprezentuje urządzenie do którego chcemy nawiązać połączenie ssh. (netmiko umożliwia również połączenia telnet, należy w tym celu zmienić device_type z cisco_ios na cisco_ios_telnet). </span></p>
<p dir="ltr" style="text-align: justify;" data-placeholder="Tłumaczenie">W moim przypadku chcę się podłączyć przez ssh do routera R1 o adresie IP 192.168.174.200 korzystając z użytkownika admin o haśle cisco.</p>
<pre>Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:25:58) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; from netmiko import ConnectHandler
&gt;&gt;&gt; cisco = {'device_type':'cisco_ios','ip':'192.168.174.200','username':'admin','password':'cisco'}
&gt;&gt;&gt; net_connect = ConnectHandler(**cisco)</pre>
<p style="text-align: justify;">Po wydaniu ostatniej komendy net_connect = ConnectHandler(**cisco) następuję połączenie ssh do routera, można to zweryfikować logując się na urządzenie i wydając komendę: show users</p>
<pre>R1#show users
 Line User Host(s) Idle Location
* 0 con 0 idle 00:00:00
 2 vty 0 admin idle 00:09:25 192.168.174.1

Interface User Mode Idle Peer Address</pre>
<p>Teraz możemy wykonać dowolną komendę i wypisać ją na ekranie:</p>
<pre>&gt;&gt;&gt; output = net_connect.send_command('show ip int brief')
&gt;&gt;&gt; print output
Interface IP-Address OK? Method Status Protocol
FastEthernet0/0 192.168.174.200 YES manual up up
FastEthernet1/0 10.0.10.1 YES NVRAM up up
FastEthernet1/1 unassigned YES NVRAM administratively down down</pre>
<p>&nbsp;</p>
<pre>&gt;&gt;&gt; output = net_connect.send_command('show run')
&gt;&gt;&gt; print output
 Building configuration...

Current configuration : 1175 bytes
 !
 ! Last configuration change at 17:59:31 UTC Wed Oct 25 2017
 !
 version 15.2
 service timestamps debug datetime msec
 service timestamps log datetime msec
 !
 hostname R1
 !
 boot-start-marker
 boot-end-marker
 !
 !
 !
 no aaa new-model
 no ip icmp rate-limit unreachable
 ip cef
 !
 !
 !
 no ip domain lookup
 ip domain name cisco
 no ipv6 cef
 !
 !
 multilink bundle-name authenticated
 !
 !
 !
 username admin privilege 15 secret 5 $1$EVqH$s80zvoLdjFQM88a6ifTpA/
 !
 !
 ip tcp synwait-time 5
 !
 !
 !
 interface FastEthernet0/0
 ip address 192.168.174.200 255.255.255.0
 duplex full
 !
 interface FastEthernet1/0
 ip address 10.0.10.1 255.255.255.0
 speed auto
 duplex auto
 !
 interface FastEthernet1/1
 no ip address
 shutdown
 speed auto
 duplex auto
 !
 ip forward-protocol nd
 !
 !
 ip http server
 no ip http secure-server
 ip route 0.0.0.0 0.0.0.0 192.168.174.1
 !
 !
 !
 control-plane
 !
 !
 line con 0
 exec-timeout 0 0
 privilege level 15
 logging synchronous
 stopbits 1
 line aux 0
 exec-timeout 0 0
 privilege level 15
 logging synchronous
 stopbits 1
 line vty 0 4
 login local
 transport input ssh
 !
 !
 end</pre>
<p>Kilka przydatnych metod dostępnych w netmiko:</p>
<ul>
<li>net_connect.config_mode() &#8212; Enter into config mode</li>
<li>net_connect.check_config_mode() &#8212; Check if you are in config mode, return a boolean</li>
<li>net_connect.exit_config_mode() &#8212; Exit config mode</li>
<li>net_connect.clear_buffer() &#8212; Clear the output buffer on the remote device</li>
<li>net_connect.enable() &#8212; Enter enable mode</li>
<li>net_connect.exit_enable_mode() &#8212; Exit enable mode</li>
<li>net_connect.find_prompt() &#8212; Return the current router prompt</li>
<li>net_connect.commit(arguments) &#8212; Execute a commit action on Juniper and IOS-XR</li>
<li>net_connect.disconnect() &#8212; Close the SSH connection</li>
<li>net_connect.send_command(arguments) &#8212; Send command down the SSH channel, return output back</li>
<li>net_connect.send_config_set(arguments) &#8212; Send a set of configuration commands to remote device</li>
<li>net_connect.send_config_from_file(arguments) &#8212; Send a set of configuration commands loaded from a file</li>
</ul>
<p>&nbsp;</p>
<p style="text-align: justify;">W dalszych wpisach pokażę więcej możliwości i przykładowe skrypty z wykorzystaniem biblioteki netmiko.</p>
]]></content:encoded>
			<wfw:commentRss>https://kubsoo.github.io/rsnet-website/cisco-python-netmiko/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
