<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Lauri's blog</title>
  <subtitle>Lauri's blog about open-source and ranting</subtitle>
  <link href="http://lauri.vosandi.com"/>
  <updated>2019-09-06T18:57:50Z</updated>
  
  <entry>
    <title>LEDE mass deployment</title>
    <summary>In this article a howto is outlined for mass deployment of LEDE on
commodity hardware:</summary>
    <link href="http://lauri.vosandi.com/2017/09/lede-mass-deployment.html"/>
    <content type="html"><![CDATA[<div class="document">


<!-- date: 2017-09-25 -->
<!-- tags: LEDE, Comfast, TP-Link, OpenWrt -->
<div class="section" id="lede-mass-deployment">
<div class="section" id="introduction">
<h2>Introduction</h2>
<p>In this article a howto is outlined for mass deployment of LEDE on
commodity hardware:</p>
<ul class="simple">
<li><p>TP-Link WDR3600 - 802.11an, 70&#8364;</p></li>
<li><p>TP-Link WDR4300 - 802.11an, 70&#8364;</p></li>
<li><p>TP-Link Archer C7 - 802.11ac, cost 100&#8364;</p></li>
<li><p>Comfast E380AC - 802.11ac, 48V PoE, cost 120&#8364;</p></li>
</ul>
<p>All of those devices use Atheros chipsets,
which means you get multiple SSID support and
good compatibility with various client devices.</p>
<p>With WDR3600/4300 you get about 150Mbps actual throughput on 5Ghz band
and 300-400Mbps with Comfast and Archer.
Note that some mobile devices may be utilize only half of the bandwidth
because of having only 1 receive stream available.</p>
<p>In noisy environment some of the devices drop to 2.4GHz band giving you
about 70Mbps throughput there.
5GHz and 2.4GHz bands in total can serve 30 iPads for sure.</p>
</div>
</div>
<div class="section" id="image-customization">
<h1>Image customization</h1>
<p>In order to include custom configuration within the flashable image
LEDE image builder can be used.</p>
<p>First fetch LEDE image builder:</p>
<pre class="code bash literal-block"><code>wget http://downloads.lede-project.org/releases/17.01.4/targets/ar71xx/generic/lede-imagebuilder-17.01.4-ar71xx-generic.Linux-x86_64.tar.xz
tar xvf lede-imagebuilder-17.01.4-ar71xx-generic.Linux-x86_64.tar.xz
<span class="nb">cd</span> lede-imagebuilder-17.01.4-ar71xx-generic.Linux-x86_64/
mkdir -p overlay/etc/uci-default</code></pre>
<p>To set colorful command prompt and window title in terminal emulator
drop following to overlay/etc/profile:</p>
<pre class="code bash literal-block"><code><span class="ch">#!/bin/sh
</span><span class="o">[</span> -f /etc/banner <span class="o">]</span> <span class="o">&amp;&amp;</span> cat /etc/banner
<span class="o">[</span> -e /tmp/.failsafe <span class="o">]</span> <span class="o">&amp;&amp;</span> cat /etc/banner.failsafe

<span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span>/usr/bin:/usr/sbin:/bin:/sbin
<span class="nb">export</span> <span class="nv">HOME</span><span class="o">=</span><span class="k">$(</span>grep -e <span class="s2">"^</span><span class="si">${</span><span class="nv">USER</span><span class="k">:-</span><span class="nv">root</span><span class="si">}</span><span class="s2">:"</span> /etc/passwd <span class="p">|</span> cut -d <span class="s2">":"</span> -f <span class="m">6</span><span class="k">)</span>
<span class="nb">export</span> <span class="nv">HOME</span><span class="o">=</span><span class="si">${</span><span class="nv">HOME</span><span class="k">:-</span><span class="p">/root</span><span class="si">}</span>
<span class="nb">export</span> <span class="nv">PS1</span><span class="o">=</span><span class="s1">'\u@\h:\w\$ '</span>

<span class="o">[</span> -z <span class="s2">"</span><span class="nv">$KSH_VERSION</span><span class="s2">"</span> -o <span class="se">\!</span> -s /etc/mkshrc <span class="o">]</span> <span class="o">||</span> . /etc/mkshrc
<span class="o">[</span> -x /bin/more <span class="o">]</span> <span class="o">||</span> <span class="nb">alias</span> <span class="nv">more</span><span class="o">=</span>less
<span class="o">[</span> -x /usr/bin/vim <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">alias</span> <span class="nv">vi</span><span class="o">=</span>vim <span class="o">||</span> <span class="nb">alias</span> <span class="nv">vim</span><span class="o">=</span>vi
<span class="o">[</span> -x /usr/bin/arp <span class="o">]</span> <span class="o">||</span> arp<span class="o">()</span> <span class="o">{</span> cat /proc/net/arp<span class="p">;</span> <span class="o">}</span>
<span class="o">[</span> -x /usr/bin/ldd <span class="o">]</span> <span class="o">||</span> ldd<span class="o">()</span> <span class="o">{</span> <span class="nv">LD_TRACE_LOADED_OBJECTS</span><span class="o">=</span><span class="m">1</span> <span class="nv">$*</span><span class="p">;</span> <span class="o">}</span>

<span class="nv">HOSTNAME</span><span class="o">=</span><span class="k">$(</span>uci get system.@system<span class="o">[</span><span class="m">0</span><span class="o">]</span>.hostname<span class="k">)</span>
<span class="nv">DOMAIN</span><span class="o">=</span><span class="k">$(</span>uci -q get dhcp.@dnsmasq<span class="o">[</span><span class="m">0</span><span class="o">]</span>.domain<span class="k">)</span>

<span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> -eq <span class="m">0</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
    <span class="nv">FQDN</span><span class="o">=</span><span class="nv">$HOSTNAME</span>.<span class="nv">$DOMAIN</span>
<span class="k">else</span>
    <span class="nv">FQDN</span><span class="o">=</span><span class="nv">$HOSTNAME</span>
<span class="k">fi</span>

<span class="nb">export</span> <span class="nv">PS1</span><span class="o">=</span><span class="s1">'\[\033[01;31m\]$FQDN\[\033[01;34m\] \W #\[\033[00m\] '</span>
<span class="k">case</span> <span class="s2">"</span><span class="nv">$TERM</span><span class="s2">"</span> in
    xterm*<span class="p">|</span>rxvt*<span class="o">)</span>
        <span class="nb">echo</span> -ne <span class="s2">"\033]0;</span><span class="si">${</span><span class="nv">USER</span><span class="si">}</span><span class="s2">@</span><span class="si">${</span><span class="nv">FQDN</span><span class="si">}</span><span class="s2">:</span><span class="si">${</span><span class="nv">PWD</span><span class="si">}</span><span class="s2">\007"</span>
    <span class="p">;;</span>
    *<span class="o">)</span>
    <span class="p">;;</span>
<span class="k">esac</span></code></pre>
<p>Generate unique hostname using overlay/etc/uci-defaults/40-hostname:</p>
<pre class="code bash literal-block"><code><span class="nv">MODEL</span><span class="o">=</span><span class="k">$(</span>cat /etc/board.json <span class="p">|</span> jsonfilter -e <span class="s1">'@["model"]["id"]'</span><span class="k">)</span>

<span class="c1"># Hostname prefix
</span><span class="k">case</span> <span class="nv">$MODEL</span> in
    tl-*<span class="p">|</span>archer-*<span class="o">)</span>  <span class="nv">VENDOR</span><span class="o">=</span>tplink <span class="p">;;</span>
    cf-*<span class="o">)</span> <span class="nv">VENDOR</span><span class="o">=</span>comfast <span class="p">;;</span>
    *<span class="o">)</span> <span class="nv">VENDOR</span><span class="o">=</span>ap <span class="p">;;</span>
<span class="k">esac</span>

<span class="c1"># Network interface with relevant MAC address
</span><span class="k">case</span> <span class="nv">$MODEL</span> in
    tl-wdr*<span class="o">)</span> <span class="nv">NIC</span><span class="o">=</span>wlan1 <span class="p">;;</span>
    archer-*<span class="o">)</span>  <span class="nv">NIC</span><span class="o">=</span>eth1 <span class="p">;;</span>
    cf-e380ac-v2<span class="o">)</span> <span class="nv">NIC</span><span class="o">=</span>eth0 <span class="p">;;</span>
    *<span class="o">)</span> <span class="nv">NIC</span><span class="o">=</span>wlan0 <span class="p">;;</span>
<span class="k">esac</span>

<span class="nv">HOSTNAME</span><span class="o">=</span><span class="nv">$VENDOR</span>-<span class="k">$(</span>cat /sys/class/net/<span class="nv">$NIC</span>/address <span class="p">|</span> cut -d : -f <span class="m">4</span>- <span class="p">|</span> sed -e <span class="s1">'s/://g'</span><span class="k">)</span>
uci <span class="nb">set</span> system.@system<span class="o">[</span><span class="m">0</span><span class="o">]</span>.hostname<span class="o">=</span><span class="nv">$HOSTNAME</span>
uci <span class="nb">set</span> network.lan.hostname<span class="o">=</span><span class="nv">$HOSTNAME</span></code></pre>
<p>Reconfigure device to work as access point overlay/etc/uci-defaults/50-access-point:</p>
<pre class="code bash literal-block"><code><span class="c1"># Disable DHCP servers
</span>/etc/init.d/odhcpd disable
/etc/init.d/dnsmasq disable

<span class="c1"># Remove firewall rules since AP bridges ethernet to wireless anyway
</span>uci delete firewall.@zone<span class="o">[</span><span class="m">1</span><span class="o">]</span>
uci delete firewall.@zone<span class="o">[</span><span class="m">0</span><span class="o">]</span>
uci delete firewall.@forwarding<span class="o">[</span><span class="m">0</span><span class="o">]</span>
<span class="k">for</span> j in <span class="k">$(</span>seq <span class="m">0</span> <span class="m">10</span><span class="k">)</span><span class="p">;</span> <span class="k">do</span> uci delete firewall.@rule<span class="o">[</span><span class="m">0</span><span class="o">]</span><span class="p">;</span> <span class="k">done</span>

<span class="c1"># Remove WAN interface
</span>uci delete network.wan
uci delete network.wan6

<span class="c1"># Reconfigure DHCP client for bridge over LAN and WAN ports
</span>uci delete network.lan.ipaddr
uci delete network.lan.netmask
uci delete network.lan.ip6assign
uci delete network.globals.ula_prefix
uci delete network.@switch_vlan<span class="o">[</span><span class="m">1</span><span class="o">]</span>
uci delete dhcp.@dnsmasq<span class="o">[</span><span class="m">0</span><span class="o">]</span>.domain
uci <span class="nb">set</span> network.lan.proto<span class="o">=</span>dhcp
uci <span class="nb">set</span> network.lan.ipv6<span class="o">=</span><span class="m">0</span>
uci <span class="nb">set</span> network.lan.ifname<span class="o">=</span><span class="s1">'eth0'</span>
uci <span class="nb">set</span> network.lan.stp<span class="o">=</span><span class="m">1</span>

<span class="c1"># Radio ordering differs among models
</span><span class="k">case</span> <span class="k">$(</span>uci get wireless.radio0.hwmode<span class="k">)</span> in
    11a<span class="o">)</span> uci rename wireless.radio0<span class="o">=</span>radio5ghz<span class="p">;;</span>
    11g<span class="o">)</span> uci rename wireless.radio0<span class="o">=</span>radio2ghz<span class="p">;;</span>
<span class="k">esac</span>
<span class="k">case</span> <span class="k">$(</span>uci get wireless.radio1.hwmode<span class="k">)</span> in
    11a<span class="o">)</span> uci rename wireless.radio1<span class="o">=</span>radio5ghz<span class="p">;;</span>
    11g<span class="o">)</span> uci rename wireless.radio1<span class="o">=</span>radio2ghz<span class="p">;;</span>
<span class="k">esac</span>

<span class="c1"># Reset virtual SSID-s
</span>uci delete wireless.@wifi-iface<span class="o">[</span><span class="m">1</span><span class="o">]</span>
uci delete wireless.@wifi-iface<span class="o">[</span><span class="m">0</span><span class="o">]</span>

<span class="c1"># Pseudorandomize channel selection, should work with 80MHz on 5GHz band
</span><span class="k">case</span> <span class="k">$(</span>uci get system.@system<span class="o">[</span><span class="m">0</span><span class="o">]</span>.hostname <span class="p">|</span> md5sum<span class="k">)</span> in
   <span class="m">1</span>*<span class="p">|</span><span class="m">2</span>*<span class="p">|</span><span class="m">3</span>*<span class="p">|</span><span class="m">4</span>*<span class="o">)</span> uci <span class="nb">set</span> wireless.radio2ghz.channel<span class="o">=</span><span class="m">1</span><span class="p">;</span> uci <span class="nb">set</span> wireless.radio5ghz.channel<span class="o">=</span><span class="m">36</span> <span class="p">;;</span>
   <span class="m">5</span>*<span class="p">|</span><span class="m">6</span>*<span class="p">|</span><span class="m">7</span>*<span class="p">|</span><span class="m">8</span>*<span class="o">)</span> uci <span class="nb">set</span> wireless.radio2ghz.channel<span class="o">=</span><span class="m">5</span><span class="p">;</span> uci <span class="nb">set</span> wireless.radio5ghz.channel<span class="o">=</span><span class="m">52</span> <span class="p">;;</span>
   <span class="m">9</span>*<span class="p">|</span><span class="m">0</span>*<span class="p">|</span>a*<span class="p">|</span>b*<span class="o">)</span> uci <span class="nb">set</span> wireless.radio2ghz.channel<span class="o">=</span><span class="m">9</span><span class="p">;</span> uci <span class="nb">set</span> wireless.radio5ghz.channel<span class="o">=</span><span class="m">100</span> <span class="p">;;</span>
   c*<span class="p">|</span>d*<span class="p">|</span>e*<span class="p">|</span>f*<span class="o">)</span> uci <span class="nb">set</span> wireless.radio2ghz.channel<span class="o">=</span><span class="m">13</span><span class="p">;</span> uci <span class="nb">set</span> wireless.radio5ghz.channel<span class="o">=</span><span class="m">132</span> <span class="p">;;</span>
<span class="k">esac</span>

<span class="c1"># Create bridge for guests
</span>uci <span class="nb">set</span> network.guest<span class="o">=</span>interface
uci <span class="nb">set</span> network.guest.proto<span class="o">=</span><span class="s1">'static'</span>
uci <span class="nb">set</span> network.guest.address<span class="o">=</span><span class="s1">'0.0.0.0'</span>
uci <span class="nb">set</span> network.guest.type<span class="o">=</span><span class="s1">'bridge'</span>
uci <span class="nb">set</span> network.guest.ifname<span class="o">=</span><span class="s1">'eth0.156'</span> <span class="c1"># tag id 156 for guest network
</span>uci <span class="nb">set</span> network.guest.ipaddr<span class="o">=</span><span class="s1">'0.0.0.0'</span>
uci <span class="nb">set</span> network.guest.ipv6<span class="o">=</span><span class="m">0</span>
uci <span class="nb">set</span> network.guest.stp<span class="o">=</span><span class="m">1</span>

<span class="c1"># Disable switch tagging and bridge all ports on TP-Link WDR3600/WDR4300
</span><span class="k">case</span> <span class="k">$(</span>cat /etc/board.json <span class="p">|</span> jsonfilter -e <span class="s1">'@["model"]["id"]'</span><span class="k">)</span> in
    tl-wdr*<span class="o">)</span>
        uci <span class="nb">set</span> network.@switch<span class="o">[</span><span class="m">0</span><span class="o">]</span>.enable_vlan<span class="o">=</span><span class="m">0</span>
        uci <span class="nb">set</span> network.@switch_vlan<span class="o">[</span><span class="m">0</span><span class="o">]</span>.ports<span class="o">=</span><span class="s1">'0 1 2 3 4 5 6'</span>
    <span class="p">;;</span>
    *<span class="o">)</span> <span class="p">;;</span>
<span class="k">esac</span></code></pre>
<p>Configure site-specific settings in
overlay/etc/uci-defaults/99-site-name:</p>
<pre class="code bash literal-block"><code><span class="c1"># Configure tagging
</span>uci <span class="nb">set</span> network.lan.ifname<span class="o">=</span><span class="s1">'eth0.3'</span> <span class="c1"># Password protected network VLAN3 tagged
</span>uci <span class="nb">set</span> network.guest.ifname<span class="o">=</span><span class="s1">'eth0.4'</span> <span class="c1"># Public network VLAN4 tagged
</span>
<span class="c1"># Configure wireless networks
</span><span class="k">for</span> band in 2ghz 5ghz<span class="p">;</span> <span class="k">do</span>
    uci delete wireless.radio<span class="nv">$band</span>.disabled
    uci <span class="nb">set</span> wireless.radio<span class="nv">$band</span>.country<span class="o">=</span>EE

    uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span><span class="o">=</span>wifi-iface
    uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.network<span class="o">=</span>lan
    uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.mode<span class="o">=</span>ap
    uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.device<span class="o">=</span>radio<span class="nv">$band</span>
    uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.encryption<span class="o">=</span>psk2+ccmp
    uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.ssid<span class="o">=</span>Robootikaklubi
    uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.key<span class="o">=</span><span class="s1">'salakala'</span>

    uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span><span class="o">=</span>wifi-iface
    uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.network<span class="o">=</span>guest
    uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.mode<span class="o">=</span>ap
    uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.device<span class="o">=</span>radio<span class="nv">$band</span>
    uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.encryption<span class="o">=</span>none
    uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.ssid<span class="o">=</span>RobootikaklubiAvalik

<span class="k">done</span>

<span class="c1"># Add Lauri's Yubikey
</span>cat &gt; /etc/dropbear/authorized_keys <span class="s">&lt;&lt; \EOF
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCb4iqSrJrA13ygAZTZb6ElPsMXrlXXrztxt3bcKuEbAiWOm9lR17puRLMZbM2tvAW+iwsDHfQAs0E6HDprP68nt+SGkQvItUtYeJBWDI405DbRodmDMySahmb6o6S3sqI4vryydOg1G+Z0DITksZzp91Ow+C++emk6aqWfXh7xATexCvKphfwXrBL+MDIwx6drIiN0FD08yd/zxGAlcQpR8o6uecmXdk32wL5W3+qqwbJrLjZmOweij5KSXuEARuQhM20KXzYzzQIAKqhIoALRSEX31L0bwxOqfVaotzk4TWKJSeetEhBOd7PtH0ZrmOHF+B20Ym+V3UkRY5P4calF
EOF</span>

<span class="c1"># Set root password to 'salakala'
</span>sed -i <span class="s1">'s|^root::|root:$1$LLo9T/Zr$cCp.dy5W.Om9oQ4LboQNz.:|'</span> /etc/shadow</code></pre>
<p>Use following command to build the image,
this shall include collectd, strongswan and some other useful utils:</p>
<pre class="code bash literal-block"><code><span class="nb">export</span> <span class="nv">PACKAGES</span><span class="o">=</span><span class="s2">"luci luci-app-commands \
    collectd collectd-mod-conntrack collectd-mod-interface \
    collectd-mod-iwinfo collectd-mod-load collectd-mod-memory \
    collectd-mod-network collectd-mod-protocols collectd-mod-tcpconns \
    collectd-mod-uptime \
    openssl-util curl ca-certificates \
    strongswan-mod-aes strongswan-mod-gmp strongswan-mod-hmac \
    strongswan-mod-kernel-netlink strongswan-mod-md5 strongswan-mod-random \
    strongswan-mod-sha1 strongswan-mod-updown strongswan-mod-curl \
    strongswan-mod-resolve strongswan-minimal \
    kmod-crypto-authenc kmod-crypto-cbc kmod-crypto-hmac \
    kmod-crypto-md5 kmod-crypto-sha1 \
    htop iftop tcpdump nmap nano -odhcp6c -odhcpd -dnsmasq \
    -luci-app-firewall \
    -pppd -luci-proto-ppp -kmod-ppp -ppp -ppp-mod-pppoe \
    -kmod-ip6tables -ip6tables -luci-proto-ipv6 -kmod-iptunnel6 -kmod-ipsec6"</span>

<span class="k">for</span> MODEL in tl-wdr3600-v1 tl-wdr4300-v1 archer-c7-v2 cf-e380ac-v2<span class="p">;</span> <span class="k">do</span>
    make image <span class="nv">PROFILE</span><span class="o">=</span><span class="nv">$MODEL</span> <span class="nv">FILES</span><span class="o">=</span>overlay/ <span class="nv">PACKAGES</span><span class="o">=</span><span class="s2">"</span><span class="nv">$PACKAGES</span><span class="s2">"</span>
<span class="k">done</span></code></pre>
</div>
<div class="section" id="image-deployment">
<h1>Image deployment</h1>
<p>I use Turris as my portable flashing unit since it has enough built in storage
to house all the images I need:</p>
<pre class="code bash literal-block"><code>mkdir -p /srv/tftpboot
uci <span class="nb">set</span> dhcp.@dnsmasq<span class="o">[</span><span class="m">0</span><span class="o">]</span>.enable_tftp<span class="o">=</span><span class="m">1</span>
uci <span class="nb">set</span> dhcp.@dnsmasq<span class="o">[</span><span class="m">0</span><span class="o">]</span>.tftp_root<span class="o">=</span>/srv/tftpboot
uci commit
/etc/init.d/dnsmasq restart</code></pre>
<p>Create IP aliases, I put this in /etc/rc.local:</p>
<pre class="code bash literal-block"><code>ifconfig br-lan:1 <span class="m">192</span>.168.0.66 <span class="c1"># WDR3600, WDR3400 uses 192.168.0.86
</span>ifconfig br-lan:2 <span class="m">192</span>.168.1.66 <span class="c1"># TP-Link Archer C7 uses 192.168.1.86
</span>ifconfig br-lan:3 <span class="m">192</span>.168.1.10 <span class="c1"># Comfast E380AC uses 192.168.1.1</span></code></pre>
<p>Copy image builder generated images to your TFTP server:</p>
<pre class="code bash literal-block"><code>scp bin/targets/ar71xx/generic/*-cf-e380ac-v2-squashfs-sysupgrade.bin <span class="se">\
</span>    root@router:/srv/tftpboot/
scp bin/targets/ar71xx/generic/*-archer-c7-v2-squashfs-factory-eu.bin <span class="se">\
</span>    root@router:/srv/tftpboot/
scp bin/targets/ar71xx/generic/*-tl-wdr4300-v1-squashfs-factory.bin <span class="se">\
</span>    root@router:/srv/tftpboot/
scp bin/targets/ar71xx/generic/*-tl-wdr3600-v1-squashfs-factory.bin <span class="se">\
</span>    root@router:/srv/tftpboot/</code></pre>
<p>The bootloaders of the devices expect to find firmware images on the TFTP by known filenames,
so rename the files:</p>
<pre class="code bash literal-block"><code><span class="nb">cd</span> /srv/tftpboot/
cp *-tl-wdr3600-v1-squashfs-factory.bin wdr3600v1_tp_recovery.bin
cp *-tl-wdr4300-v1-squashfs-factory.bin wdr4300v1_tp_recovery.bin
cp *-archer-c7-v2-squashfs-factory-eu.bin ArcherC7v2_tp_recovery.bin
cp *-cf-e380ac-v2-squashfs-sysupgrade.bin firmware_auto.bin</code></pre>
<p>TP-Link WDR3600 from v1.5 on expects u-boot prepended image,
to work around the issue you can prepend the u-boot blob from the original firmware:</p>
<pre class="code bash literal-block"><code>opkg update
opkg install unzip
wget http://www.tplink.com/res/down/soft/TL-WDR3600_V1_150518.zip
unzip -n TL-WDR3600_V1_150518.zip
dd <span class="k">if</span><span class="o">=</span><span class="s1">'wdr3600v1_en_3_14_3_up_boot(150518).bin'</span> <span class="nv">bs</span><span class="o">=</span><span class="m">512</span> <span class="nv">count</span><span class="o">=</span><span class="m">257</span> <span class="nv">of</span><span class="o">=</span>/tmp/recovery-header.bin
cat /tmp/recovery-header.bin *-tl-wdr3600-v1-squashfs-factory.bin  &gt; /tmp/concat.bin
dd <span class="k">if</span><span class="o">=</span>/tmp/concat.bin <span class="nv">of</span><span class="o">=</span>wdr3600v1_tp_recovery.bin <span class="nv">bs</span><span class="o">=</span><span class="m">512</span> <span class="nv">count</span><span class="o">=</span><span class="m">16001</span></code></pre>
<p>Same goes for TP-Link WDR4300:</p>
<pre class="code bash literal-block"><code>wget http://www.tplink.com/res/down/soft/TL-WDR4300_V1_150518.zip
unzip -n TL-WDR4300_V1_150518.zip
dd <span class="k">if</span><span class="o">=</span><span class="s1">'wdr4300v1_en_3_14_3_up_boot(150518).bin'</span> <span class="nv">bs</span><span class="o">=</span><span class="m">512</span> <span class="nv">count</span><span class="o">=</span><span class="m">257</span> <span class="nv">of</span><span class="o">=</span>/tmp/recovery-header.bin
cat /tmp/recovery-header.bin *-tl-wdr4300-v1-squashfs-factory.bin  &gt; /tmp/concat.bin
dd <span class="k">if</span><span class="o">=</span>/tmp/concat.bin <span class="nv">of</span><span class="o">=</span>wdr4300v1_tp_recovery.bin <span class="nv">bs</span><span class="o">=</span><span class="m">512</span> <span class="nv">count</span><span class="o">=</span><span class="m">16001</span></code></pre>
<p>To force device to flash itself from TFTP server:</p>
<ul class="simple">
<li><p>TP-Link Archer C7, WDR4300 - Plug network cable into one of the yellow ports, hold reset and power on the device</p></li>
<li><p>Comfast E380AC always tries to load firmware over TFTP during boot, on one hand this might look like a security flaw, yet again this makes updating image easier, just double flip the circuit braker</p></li>
</ul>
<p>Observe TFTP server log, in case of Turris:</p>
<pre class="code bash literal-block"><code>tail -f /var/log/messages <span class="p">|</span> grep dnsmasq
logread -f <span class="p">|</span> grep dnsmasq</code></pre>
<p>You should see something similar:</p>
<pre class="code literal-block"><code>2017-09-15T06:17:15+02:00 info dnsmasq-tftp[18681]: sent /srv/tftpboot/ArcherC7v2_tp_recovery.bin to 192.168.1.86
2017-09-15T07:59:16+02:00 info dnsmasq-tftp[22031]: sent /srv/tftpboot/wdr3600v1_tp_recovery.bin to 192.168.0.86
2017-09-15T08:30:10+02:00 info dnsmasq-tftp[22031]: sent /srv/tftpboot/firmware_auto.bin to 192.168.1.1</code></pre>
</div>
<div class="section" id="conclusion">
<h1>Conclusion</h1>
<p>For a budget wireless networks this is a competitive alternative.</p>
<div class="figure">
<img alt="img/lede-mass-deploy.jpg" src="/cache/a7f2e0c43b8ee598716a94f795ad5f22.jpg"/>
<p class="caption">TP-Link WDR3600 and WDR4300 being flashed similar fashion</p>
</div>
<p>Only missing bit is central management</p>
</div>
</div>
]]></content>
    
    <category term="OpenWrt"/>
    <category term="LEDE"/>
    <category term="TP-Link"/>
    <category term="Comfast"/>
    <updated>2017-09-25T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Ubuntu as hypervisor</title>
    <summary>Virtualization enables better utilization of hardware by
making it possible to run multiple operating systems on same computer.
Even in a small company you might need to run Active Directory on Windows Server and
WordPress on Ubuntu server, but purchasing two physical servers for each application is suboptimal.</summary>
    <link href="http://lauri.vosandi.com/lan/virtualization.html"/>
    <content type="html"><![CDATA[<div class="document">


<!-- date: 2017-09-10 -->
<!-- tags: libvirt, LXC, KVM, QEMU -->
<!-- tags: Windows, Microsoft, KVM, QEMU -->
<div class="section" id="ubuntu-as-hypervisor">
<div class="section" id="introduction">
<h2>Introduction</h2>
<p>Virtualization enables better utilization of hardware by
making it possible to run multiple operating systems on same computer.
Even in a small company you might need to run Active Directory on Windows Server and
WordPress on Ubuntu server, but purchasing two physical servers for each application is suboptimal.</p>
<p>The problem with virtualization is that it can refer to several
different approaches and nuances.
In classic terms virtualization usually refers to emulation of a whole computer
with all accompanying hardware - that means CPU, memory management unit,
storage, network, timers etc.</p>
<p>For example on IBM S390 processor and memory virtualization was supported
from the start whereas on Intel x86 CPU and memory virtualization were added
later incrementally.</p>
<p>VirtualBox and similar products made it possible to reach near-native speeds
by the means of dynamic translation even on processors without hardware support for CPU or memory virtualization,
but breakthrough for x86 was achieved in 2005, when Intel and AMD added hardware support.</p>
<p>In case of server consolidation the deduplication of memory and storage is important.
For example Linux supports <em>kernel samepage merging</em> since version 2009.
The kernel regularly scans the memory and calculates checksums for
memory blocks. Memory blocks with identical checksums are merged and marked
as copy-on-write. Running identical guest operating systems on such host
yields significant memory usage drop regardless of virtualization
software used.
To enable deduplication for storage an approrpiate filesystem should be used.
ZFS supports inline deduplication if enabled, this means that
once a block is written to filesystem the kernel looks up the checksum
of the block from RAM.</p>
</div>
<div class="section" id="qemu">
<h2>QEMU</h2>
<p>QEMU is a emulator created by Fabrice Bellard and at this
point it supports x86, MIPS, Sun SPARC, ARM, PowerPC and several other architectures.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 703 382" preserveAspectRatio="xMidYMid meet" style=""><line x1="260" y1="60" x2="260" y2="260" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="440" y1="60" x2="440" y2="260" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="620" y1="60" x2="620" y2="260" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="0" y="260" width="700" height="60" fill="#ffffff"/><rect x="0" y="260" width="700" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="293.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="293.9">Linux kernel</tspan></text></g><g><rect x="360" y="200" width="160.65" height="40" fill="#ffffff"/><rect x="360" y="200" width="160.65" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440.325" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440.325" y="223.9">qemu-system-i386</tspan></text></g><g><rect x="180" y="200" width="160.65" height="40" fill="#ffffff"/><rect x="180" y="200" width="160.65" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260.325" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260.325" y="223.9">qemu-system-arm</tspan></text></g><g><rect x="539.676" y="200" width="160.65" height="40" fill="#ffffff"/><rect x="539.676" y="200" width="160.65" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620.001" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620.001" y="223.9">qemu-system-x86_64</tspan></text></g><g><rect x="360" y="0" width="160" height="60" fill="#ffffff"/><rect x="360" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="25.9">Debian x86</tspan><tspan x="440" y="41.9">root</tspan></text></g><g><rect x="180" y="0" width="160" height="60" fill="#ffffff"/><rect x="180" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="25.9">Ubuntu armhf</tspan><tspan x="260" y="41.9">root</tspan></text></g><g><rect x="540" y="0" width="160" height="60" fill="#ffffff"/><rect x="540" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="33.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="33.9">Windows 2012</tspan></text></g><g><rect x="0" y="0" width="160" height="60" fill="#ffffff"/><rect x="0" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="80" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="25.9">Host</tspan><tspan x="80" y="41.9">root</tspan></text></g><line x1="350" y1="340" x2="350" y2="320" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="80" y1="60" x2="80" y2="260" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="540" y="140" width="160" height="40" fill="#ffffff"/><rect x="540" y="140" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="163.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="163.9">Virtual hardware</tspan></text></g><g><rect x="540" y="80" width="160" height="38" fill="#ffffff"/><rect x="540" y="80" width="160" height="38" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="102.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="102.9">NT kernel</tspan></text></g><g><rect x="360" y="140" width="160" height="40" fill="#ffffff"/><rect x="360" y="140" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="163.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="163.9">Virtual hardware</tspan></text></g><g><rect x="360" y="80" width="160" height="38" fill="#ffffff"/><rect x="360" y="80" width="160" height="38" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="102.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="102.9">Linux kernel</tspan></text></g><g><rect x="180" y="140" width="160" height="40" fill="#ffffff"/><rect x="180" y="140" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="163.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="163.9">Virtual hardware</tspan></text></g><g><rect x="180" y="80" width="160" height="38" fill="#ffffff"/><rect x="180" y="80" width="160" height="38" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="102.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="102.9">Linux kernel</tspan></text></g><g><rect x="480" y="340" width="220" height="40" fill="#ffffff"/><rect x="480" y="340" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="590" y="363.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="590" y="363.9">x86-64 processor</tspan></text></g><g><rect x="0" y="340" width="220" height="40" fill="#ffffff"/><rect x="0" y="340" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="363.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="363.9">Storage backend</tspan></text></g><g><rect x="240" y="340" width="220" height="40" fill="#ffffff"/><rect x="240" y="340" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="363.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="363.9">Physical memory</tspan></text></g><line x1="590" y1="320" x2="590" y2="340" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="110" y1="340" x2="110" y2="320" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></svg><p class="caption">QEMU supports a wide range of hardware</p>
</div>
</div>
<div class="section" id="kvm">
<h2>KVM</h2>
<p>With KVM project CPU and memory virtualization support was added to Linux
as a kernel module, hence the name <em>kernel virtual machine</em>.
Additionally QEMU was patched to take advantage of the
newly added functionality:</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -81 703 522" preserveAspectRatio="xMidYMid meet" style=""><line x1="260" y1="-20" x2="260" y2="260" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="440" y1="-20" x2="440" y2="260" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="620" y1="-20" x2="620" y2="260" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="0" y="260" width="700" height="60" fill="#ffffff"/><rect x="0" y="260" width="700" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="293.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="293.9">Linux kernel</tspan></text></g><g><rect x="360" y="120" width="160.65" height="54" fill="#ffffff"/><rect x="360" y="120" width="160.65" height="54" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440.325" y="142.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440.325" y="142.9">qemu-system-x86_64</tspan><tspan x="440.325" y="158.9">-enable-kvm</tspan></text></g><g><rect x="180" y="120" width="160.65" height="40" fill="#ffffff"/><rect x="180" y="120" width="160.65" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260.325" y="143.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260.325" y="143.9">qemu-system-arm</tspan></text></g><g><rect x="540" y="120" width="160.65" height="54" fill="#ffffff"/><rect x="540" y="120" width="160.65" height="54" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620.325" y="142.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620.325" y="142.9">qemu-system-x86_64</tspan><tspan x="620.325" y="158.9">-enable-kvm</tspan></text></g><g><rect x="360" y="-80" width="160" height="60" fill="#ffffff"/><rect x="360" y="-80" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="-54.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="-54.1">Debian x86</tspan><tspan x="440" y="-38.1">root</tspan></text></g><g><rect x="180" y="-80" width="160" height="60" fill="#ffffff"/><rect x="180" y="-80" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="-54.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="-54.1">Ubuntu armhf</tspan><tspan x="260" y="-38.1">root</tspan></text></g><g><rect x="540" y="-80" width="160" height="60" fill="#ffffff"/><rect x="540" y="-80" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="-46.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="-46.1">Windows 2012</tspan></text></g><g><rect x="0" y="-80" width="160" height="60" fill="#ffffff"/><rect x="0" y="-80" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="80" y="-54.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="-54.1">Host</tspan><tspan x="80" y="-38.1">root</tspan></text></g><line x1="350" y1="400" x2="350" y2="320" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="80" y1="-20" x2="80" y2="260" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="540" y="60" width="160" height="40" fill="#ffffff"/><rect x="540" y="60" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="83.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="83.9">Virtual hardware</tspan></text></g><g><rect x="540" y="0" width="160" height="38" fill="#ffffff"/><rect x="540" y="0" width="160" height="38" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="22.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="22.9">NT kernel</tspan></text></g><g><rect x="360" y="60" width="160" height="40" fill="#ffffff"/><rect x="360" y="60" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="83.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="83.9">Virtual hardware</tspan></text></g><g><rect x="360" y="0" width="160" height="38" fill="#ffffff"/><rect x="360" y="0" width="160" height="38" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="22.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="22.9">Linux kernel</tspan></text></g><g><rect x="180" y="60" width="160" height="40" fill="#ffffff"/><rect x="180" y="60" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="83.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="83.9">Virtual hardware</tspan></text></g><g><rect x="180" y="0" width="160" height="38" fill="#ffffff"/><rect x="180" y="0" width="160" height="38" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="22.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="22.9">Linux kernel</tspan></text></g><g><rect x="480" y="400" width="220" height="40" fill="#ffffff"/><rect x="480" y="400" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="590" y="423.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="590" y="423.9">x86-64 processor</tspan></text></g><g><rect x="0" y="400" width="220" height="40" fill="#ffffff"/><rect x="0" y="400" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="423.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="423.9">Storage backend</tspan></text></g><g><rect x="240" y="400" width="220" height="40" fill="#ffffff"/><rect x="240" y="400" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="423.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="423.9">Physical memory</tspan></text></g><line x1="590" y1="320" x2="590" y2="400" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="110" y1="400" x2="110" y2="320" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="360" y="200" width="340" height="40" fill="#ffffff"/><rect x="360" y="200" width="340" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="530" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="530" y="223.9">kvm.ko</tspan></text></g><g><rect x="480" y="340" width="220" height="40" fill="#ffffff"/><rect x="480" y="340" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="590" y="363.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="590" y="363.9">kvm-intel.ko / kvm-amd.ko</tspan></text></g></svg><p class="caption">KVM essentially turns Linux into ring -1 hypervisor</p>
</div>
<p>Under KVM unmodified Windows can be booted without significant performance loss.
To make sure KVM works as expected check that kvm-intel or kvm-amd appears in <em>lsmod</em>,
it might be that virtualization extensions are disabled in BIOS or
if BIOS battery is dead and motherboard keeps forgetting the settings.</p>
<p>To run local virtual machine with 1GB of RAM and dual core CPU on Ubuntu:</p>
<pre class="code bash literal-block"><code>apt install qemu-kvm
truncate -s 20G hdd.bin
qemu-kvm -m <span class="m">1024</span> -smp <span class="m">2</span> <span class="se">\
</span>    -hda hdd.bin <span class="se">\
</span>    -cdrom ubuntu-mate-16.04.2-desktop-amd64.iso</code></pre>
<p>By default QEMU emulates IDE controller for storage and
Intel network interface card (e1000).
QEMU also takes care of emulating a router with DHCP server,
so the virtual machine is assigned an IP address of 10.0.2.15 and
the router sits at 10.0.2.2.
The TCP and UDP network traffic generated by the guest OS appears as if it was generated
the QEMU process, note that with user-mode networking ping is not available.</p>
<p>For more complex networking scenarios TAP interface can be used,
in which case a virtual network interface is created in the host and guest's
network traffic appears on that interface. This can be used to talk to the host
or in conjuction with bridges can be used to expose virtual machines's traffic
to external network interfaces.</p>
</div>
<div class="section" id="paravirtualization">
<h2>Paravirtualization</h2>
<p>Paravirtualization is a technique which allows significant
performance boost for virtualized operating systems which are aware of
running on virtualized hardware.
Paravirtualization usually covers storage and networking, but
paravirtualization could also refer to <em>memory ballooning</em>,
which means that the guest OS marks unused memory blocks and the
host OS can reclaim those blocks.</p>
<p>In case of paravirtualization the guest operating system is presented
with hardware optimized for virtualization which in real life does not exist.
In many cases first guest OS is installed as usual presenting let's say
standard SATA controller and emulated Intel network card.
Once <em>guest additions</em> package provided by the virtualization software vendor is installed
the hypervisor swaps out the hardware presented to the guest OS.
In case of VMware for example VMnet is presented,
under KVM virtio network device by Red Hat is presented although Red Hat has never developed or manufactured any hardware.</p>
<p>The virtio paravirtualization framework is now used for storage and networking and
it is out of the box supported under Linux and BSD guests,
this means no additional drivers need to be installed for KVM based virtual machines.
Microsoft Hyper-V and VMware use similar but different approach, but are not virtio compatible.
Currently Linux guests should work out of the box under Hyper-V and ESXi.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 582 420" preserveAspectRatio="xMidYMid meet" style=""><line x1="50" y1="100" x2="50" y2="360" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="410" y1="100" x2="410" y2="360" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="530" y1="100" x2="530" y2="360" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="290" y1="40" x2="290" y2="380" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="170" y1="100" x2="170" y2="360" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="0" y="320" width="580" height="40" fill="#ffffff"/><rect x="0" y="320" width="580" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="290" y="343.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="290" y="343.9">qemu-system-x86_64 -enable-kvm</tspan></text></g><g><rect x="0" y="0" width="580" height="40" fill="#ffffff"/><rect x="0" y="0" width="580" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="290" y="23.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="290" y="23.9">Debian x86 root</tspan></text></g><g><rect x="240" y="220" width="100" height="80" fill="#ffffff"/><rect x="240" y="220" width="100" height="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="290" y="247.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="290" y="247.9">virtio</tspan><tspan x="290" y="263.9">block</tspan><tspan x="290" y="279.9">device</tspan></text></g><g><rect x="120" y="220" width="100" height="80" fill="#ffffff"/><rect x="120" y="220" width="100" height="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="170" y="255.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="170" y="255.9">Virtual</tspan><tspan x="170" y="271.9">hardware</tspan></text></g><g><rect x="0" y="60" width="580" height="40" fill="#ffffff"/><rect x="0" y="60" width="580" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="290" y="83.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="290" y="83.9">Guest operating system</tspan></text></g><g><rect x="0" y="220" width="100" height="80" fill="#ffffff"/><rect x="0" y="220" width="100" height="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="50" y="255.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="50" y="255.9">Native</tspan><tspan x="50" y="271.9">processor</tspan></text></g><g><rect x="360" y="220" width="100" height="80" fill="#ffffff"/><rect x="360" y="220" width="100" height="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="410" y="247.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="410" y="247.9">virtio</tspan><tspan x="410" y="263.9">network</tspan><tspan x="410" y="279.9">device</tspan></text></g><g><rect x="480" y="220" width="100" height="80" fill="#ffffff"/><rect x="480" y="220" width="100" height="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="530" y="247.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="530" y="247.9">virtio</tspan><tspan x="530" y="263.9">balloon</tspan><tspan x="530" y="279.9">device</tspan></text></g><g><rect x="240" y="120" width="100" height="80" fill="#ffffff"/><rect x="240" y="120" width="100" height="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="290" y="147.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="290" y="147.9">virtio</tspan><tspan x="290" y="163.9">block</tspan><tspan x="290" y="179.9">driver</tspan></text></g><g><rect x="360" y="120" width="100" height="80" fill="#ffffff"/><rect x="360" y="120" width="100" height="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="410" y="147.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="410" y="147.9">virtio</tspan><tspan x="410" y="163.9">network</tspan><tspan x="410" y="179.9">driver</tspan></text></g><g><rect x="480" y="120" width="100" height="80" fill="#ffffff"/><rect x="480" y="120" width="100" height="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="530" y="147.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="530" y="147.9">virtio</tspan><tspan x="530" y="163.9">balloon</tspan><tspan x="530" y="179.9">driver</tspan></text></g><g><rect x="0" y="380" width="580" height="38" fill="#ffffff"/><rect x="0" y="380" width="580" height="38" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="290" y="402.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="290" y="402.9">Linux kernel /w kvm.ko</tspan></text></g></svg></div>
<p>To enable network, storage and video output paravirtualization
for KVM based virtual machine started from command line:</p>
<pre class="code bash literal-block"><code>qemu-kvm -m <span class="m">1024</span> -smp <span class="m">2</span> -cpu host -boot <span class="nv">menu</span><span class="o">=</span>on <span class="se">\
</span>    -drive <span class="nv">file</span><span class="o">=</span>ubuntu-mate-16.04.2-desktop-amd64.iso,if<span class="o">=</span>virtio,media<span class="o">=</span>cdrom <span class="se">\
</span>    -drive <span class="nv">file</span><span class="o">=</span>hdd.bin,format<span class="o">=</span>raw,if<span class="o">=</span>virtio,discard<span class="o">=</span>unmap <span class="se">\
</span>    -net nic,vlan<span class="o">=</span><span class="m">42</span>,model<span class="o">=</span>virtio -net user,vlan<span class="o">=</span><span class="m">42</span> <span class="se">\
</span>    -balloon virtio <span class="se">\
</span>    -vga virtio</code></pre>
<p>In the past paravirtualization also referred to running modified guest operating systems
on hardware that didn't support for example CPU or memory virtualization.
For example Microsoft created a modified version of Windows suitable for running on Xen hypervisor.</p>
</div>
<div class="section" id="containers">
<h2>Containers</h2>
<p><a class="reference external" href="https://linuxcontainers.org/">LXC (Linux Containers)</a>
is essentially <a class="reference external" href="https://openvz.org/">OpenVZ</a> successor and
both of them are similar to <a class="reference external" href="https://www.freebsd.org/doc/en/books/handbook/jails.html">BSD Jails</a> and Solaris Zones.
Even Microsoft has added containers to
<a class="reference external broken" href="http://blogs.technet.com/b/server-cloud/archive/2015/04/08/microsoft-announces-new-container-technologies-for-the-next-generation-cloud.aspx">Windows Server</a>.
Docker used LXC in the past but now has moved to it's own direction whilst
making use of the same kernel infrastructure.</p>
<p>In case of containers the root filesystems are split, that is
folders which contain OS files are separate, but the kernel
which is used by the containers is same and hence shared.
Using control groups allows separation of processes and network interfaces.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 702 422" preserveAspectRatio="xMidYMid meet" style=""><g><rect x="0" y="140" width="700" height="40" fill="#ffffff"/><rect x="0" y="140" width="700" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="163.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="163.9">Linux tuum</tspan></text></g><g><rect x="180" y="0" width="160" height="60" fill="#ffffff"/><rect x="180" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="25.9">Debian</tspan><tspan x="260" y="41.9">juurfailis&#252;steem</tspan></text></g><g><rect x="360" y="0" width="160" height="60" fill="#ffffff"/><rect x="360" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="25.9">Ubuntu</tspan><tspan x="440" y="41.9">juurfailis&#252;steem</tspan></text></g><g><rect x="540" y="0" width="160" height="60" fill="#ffffff"/><rect x="540" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="25.9">Fedora</tspan><tspan x="620" y="41.9">juurfailis&#252;steem</tspan></text></g><g><rect x="0" y="0" width="160" height="60" fill="#ffffff"/><rect x="0" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="80" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="25.9">Host</tspan><tspan x="80" y="41.9">juurfailis&#252;steem</tspan></text></g><line x1="260" y1="60" x2="260" y2="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="440" y1="60" x2="440" y2="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="620" y1="60" x2="620" y2="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="620" y1="120" x2="620" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="440" y1="120" x2="440" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="260" y1="120" x2="260" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="80" y1="60" x2="80" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="350" y1="180" x2="350" y2="380" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="590" y1="180" x2="590" y2="380" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="240" y="200" width="220" height="40" fill="#ffffff"/><rect x="240" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="223.9">Virtuaalm&#228;lu</tspan></text></g><line x1="110" y1="380" x2="110" y2="180" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="240" y="380" width="220" height="40" fill="#ffffff"/><rect x="240" y="380" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="403.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="403.9">F&#252;&#252;siline m&#228;lu</tspan></text></g><g><rect x="180" y="80" width="160" height="40" fill="#ffffff"/><rect x="180" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="103.9">Konteiner #1</tspan></text></g><g><rect x="360" y="80" width="160" height="40" fill="#ffffff"/><rect x="360" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="103.9">Konteiner #2</tspan></text></g><g><rect x="540" y="80" width="160" height="40" fill="#ffffff"/><rect x="540" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="103.9">Konteiner #3</tspan></text></g><g><rect x="480" y="380" width="220" height="40" fill="#ffffff"/><rect x="480" y="380" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="590" y="403.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="590" y="403.9">Protsessor</tspan></text></g><g><rect x="0" y="200" width="220" height="40" fill="#ffffff"/><rect x="0" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="223.9">Virtuaalfailis&#252;steem</tspan></text></g><g><rect x="0" y="260" width="220" height="40" fill="#ffffff"/><rect x="0" y="260" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="283.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="283.9">Btrfs/ZFS/ext4 t&#252;&#252;rel</tspan></text></g><g><rect x="0" y="320" width="220" height="40" fill="#ffffff"/><rect x="0" y="320" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="343.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="343.9">Kettakontrolleri t&#252;&#252;rel</tspan></text></g><g><rect x="0" y="380" width="220" height="40" fill="#ffffff"/><rect x="0" y="380" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="403.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="403.9">Ketas ja SSD</tspan></text></g></svg><p class="caption">Kernel is shared, but root filesystems are separated</p>
</div>
<p>In case of LXC memory or disk space is not reserved for the container,
keeping the resource usage optimal accross the containers.</p>
<p>Process tree for such setup looks approximately something like following:</p>
<pre class="code literal-block"><code>systemd
  &#9500;&#9472;acpid
  &#9500;&#9472;agetty --noclear tty1 linux
  &#9500;&#9472;atd -f
  &#9500;&#9472;cron -f
  &#9500;&#9472;dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  &#9500;&#9472;dhclient -v -pf /run/dhclient.lxcbr0.pid -lf /var/lib/dhcp/dhclient.lxcbr0.leases lxcbr0
  &#9500;&#9472;lxc-start -d -n ubuntu-trusty-test
  &#9474;   &#9492;&#9472;init
  &#9474;       &#9500;&#9472;dbus-daemon --system --fork
  &#9474;       &#9500;&#9472;dhclient -1 -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
  &#9474;       &#9500;&#9472;getty -8 38400 console
  &#9474;       &#9500;&#9472;cron
  &#9474;       &#9500;&#9472;sshd -D
  &#9474;       &#9500;&#9472;systemd-logind
  &#9474;       &#9500;&#9472;systemd-udevd --daemon
  &#9474;       &#9500;&#9472;upstart-file-br --daemon
  &#9474;       &#9500;&#9472;upstart-socket- --daemon
  &#9474;       &#9492;&#9472;upstart-udev-br --daemon
  &#9500;&#9472;lxc-start -g debian-wheezy-test
  &#9474;   &#9492;&#9472;systemd
  &#9474;       &#9500;&#9472;dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  &#9474;       &#9500;&#9472;dhclient -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
  &#9474;       &#9500;&#9472;agetty --noclear -s console 115200 38400 9600
  &#9474;       &#9500;&#9472;cron
  &#9474;       &#9500;&#9472;sshd -D
  &#9474;       &#9500;&#9472;systemd-journal
  &#9474;       &#9500;&#9472;systemd-logind
  &#9474;       &#9492;&#9472;systemd-udevd
  &#9500;&#9472;lxc-start -d -n debian-jessie-test
  &#9474;   &#9492;&#9472;systemd
  &#9474;       &#9500;&#9472;dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  &#9474;       &#9500;&#9472;dhclient -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
  &#9474;       &#9500;&#9472;sshd -D
  &#9474;       &#9500;&#9472;systemd-journal
  &#9474;       &#9492;&#9472;systemd-logind
  &#9500;&#9472;sshd -D
  &#9500;&#9472;systemd-journal
  &#9500;&#9472;systemd-logind
  &#9492;&#9472;systemd-udevd</code></pre>
<p>Here it is seen that each container has it's own virtual eth0 interface
and DHCP client has been started in each container.
Since every container appears on the network with it's distinct IP address,
connecting to a container is as easy as installing OpenSSH server in the container.</p>
<p>Note that containers have security implications -
kernel vulnerabilities can make it possible to hijack the host machine.
Additionally each syscall needs to be aware whether any namespace restrictions apply.
For example as of this writing Btrfs syscalls haven't been refactored to
accommodate filesystem namespacing, executing following command in an
LXC container lists the subvolumes of the host machine as well, even though
you would assume it wouldn't.
Combining kernel vulnerability with short-sightedness of some kernel module
might have disasterous consequences.</p>
</div>
<div class="section" id="foreign-architecture-containers">
<h2>Foreign architecture containers</h2>
<p>User-mode emulation of QEMU allows executing binaries compiled for
foreign CPU architectures under Linux and Darwin/Mac OS X.
Note that in case of user-mode emulation only the code that runs in userspace
is translated, but syscalls which invoke kernelspace code are not.
This means that emulated architectures are slower than native binaries,
but not as slow as emulating the whole computer.
This for example enables <em>armhf</em> development on <em>x86-64</em>.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -61 702 302" preserveAspectRatio="xMidYMid meet" style=""><line x1="260" y1="0" x2="260" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="440" y1="0" x2="440" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="620" y1="0" x2="620" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="350" y1="180.977" x2="350" y2="200" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="590" y1="180" x2="590" y2="200" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="0" y="140" width="700" height="40" fill="#ffffff"/><rect x="0" y="140" width="700" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="163.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="163.9">Linux tuum</tspan></text></g><g><rect x="180" y="80" width="160" height="40" fill="#ffffff"/><rect x="180" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="103.9">Konteiner #1</tspan></text></g><g><rect x="360" y="80" width="160" height="40" fill="#ffffff"/><rect x="360" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="103.9">Konteiner #2</tspan></text></g><g><rect x="540" y="80" width="160" height="40" fill="#ffffff"/><rect x="540" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="103.9">Konteiner #3</tspan></text></g><g><rect x="180" y="-60" width="160" height="60" fill="#ffffff"/><rect x="180" y="-60" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="-34.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="-34.1">Debian x86</tspan><tspan x="260" y="-18.1">juurfailis&#252;steem</tspan></text></g><g><rect x="360" y="-60" width="160" height="60" fill="#ffffff"/><rect x="360" y="-60" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="-34.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="-34.1">Ubuntu x86-64</tspan><tspan x="440" y="-18.1">juurfailis&#252;steem</tspan></text></g><g><rect x="540" y="-60" width="160" height="60" fill="#ffffff"/><rect x="540" y="-60" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="-34.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="-34.1">Fedora armhf</tspan><tspan x="620" y="-18.1">juurfailis&#252;steem</tspan></text></g><g><rect x="0" y="-60" width="160" height="60" fill="#ffffff"/><rect x="0" y="-60" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="80" y="-34.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="-34.1">Host</tspan><tspan x="80" y="-18.1">root</tspan></text></g><line x1="110" y1="200" x2="110" y2="180" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="80" y1="0" x2="80" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="540" y="20" width="160" height="40" fill="#ffffff"/><rect x="540" y="20" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="43.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="43.9">qemu-arm-static</tspan></text></g><g><rect x="240" y="200" width="220" height="40" fill="#ffffff"/><rect x="240" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="223.9">M&#228;lu</tspan></text></g><g><rect x="480" y="200" width="220" height="40" fill="#ffffff"/><rect x="480" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="590" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="590" y="223.9">x86-64 protsessor</tspan></text></g><g><rect x="0" y="200" width="220" height="40" fill="#ffffff"/><rect x="0" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="223.9">Storage</tspan></text></g></svg><p class="caption">binfmt-support allows Linux to transparently execute binaries of foreign architecture</p>
</div>
<p>Static binaries can be executed with either enabling the execute bit on the binary
or supplying the binary as the argument for corresponding qemu command, eg qemu-arm-static.
With dynamically linked programs the situation is stickier because
the program will attempt to look up dependand shared libraries, so
using a LXC container is the easiest way to run dynamically linked foreign programs:</p>
<pre class="code bash literal-block"><code>apt install qemu-user-static binfmt-support
lxc-create -n fedora-arm-test -t download -- -d fedora -r <span class="m">25</span> -a armhf
cp /usr/bin/qemu-arm-static /var/lib/lxc/fedora-arm-test/rootfs/usr/bin/
lxc-start -d -n fedora-arm-test
lxc-attach -n fedora-arm-test</code></pre>
<p>Similarly it should be possible to run kfreebsd flavor of Debian or Ubuntu under
FreeBSD Jail.</p>
</div>
</div>
<div class="section" id="libvirt">
<h1>libvirt</h1>
<p>libvirt is a framework for managing hypervisors of different sorts -
VirtualBox, KVM, ESXi, LXC, Xen, bhyve etc.
It provides a daemon for creating, managing and deleting virtual machines and
API-s to talk that daemon over SSH connection.</p>
<p>To turn your clean Ubuntu server installation to remotely managed KVM hypervisor:</p>
<pre class="code bash literal-block"><code>apt install qemu-kvm libvirt-bin openssh-server bridge-utils vlan</code></pre>
<p>To connect virtual machines with eachother and to the external world,
reconfigure /etc/network/intefaces something similar to following:</p>
<pre class="code literal-block"><code># Management network to robotics club, replace address with unused IP
auto br-mgmt
iface br-mgmt inet static
        address 192.168.12.4
        netmask 255.255.255.0
        gateway 192.168.12.1
        dns-nameserver 192.168.12.1
        bridge_ports enp3s0

# Bridge to connect virtual machines to public internet,
# exposed on one of the NIC-s on the physical machine
auto br-wan
iface br-wan inet static
        address 0.0.0.0
        bridge_ports enp5s0

# Internal network to connect virtual machines to eachother,
# not exposed on any NIC on the physical machine
auto br-lan
iface br-lan inet static
        address 0.0.0.0
        bridge_ports none</code></pre>
<p>Set up public key based root access from your laptop to the machine and use virt-manager to connect to it.
In fact you can use same virt-manager instance on your laptop to connect to
several hypervisor machines:</p>
<div class="figure">
<img alt="img/virt-manager.png" src="/cache/6b9a3e6f5ae5568512baceed906b1325.png"/>
<p class="caption">virt-manager connected to three hypervisors</p>
</div>
<p>To get best out of the storage performance
add virtio SCSI controller and switch harddisk interfaces from SATA to SCSI.
More tweaking is required to reclaim free disk space in the host and have optimal performance for SSD-s
- see more information <a class="reference external" href="https://chrisirwin.ca/posts/discard-with-kvm/">here</a>.
For each network interface select virtio as model.
Note that on multi CPU installations it is also important to have NUMA configured correctly.</p>
</div>
</div>
]]></content>
    
    <category term="QEMU"/>
    <category term="Microsoft"/>
    <category term="KVM"/>
    <category term="Windows"/>
    <updated>2017-09-10T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Espressif WiSoC-s</title>
    <summary>ESP8266 is a WiSoC
running a custom 32bit RISC CPU core clocked at 80MHz
with 64KiB of RAM for instructions and 96KiB for data.</summary>
    <link href="http://lauri.vosandi.com/2017/06/espressif.html"/>
    <content type="html"><![CDATA[<div class="document" id="espressif-wisoc-s">
<!-- date: 2017-06-10 -->
<!-- tags: ESP32, ESP8266, Python, MicroPython, MCU, Espressif, &#1048;&#1053;-12&#1040;, &#1048;&#1053;-12&#1041; -->
<div class="section" id="wireless-system-on-chip">
<h1>Wireless System on Chip</h1>
<p>ESP8266 is a WiSoC
running a custom 32bit RISC CPU core clocked at 80MHz
with 64KiB of RAM for instructions and 96KiB for data.</p>
<div class="figure">
<img alt="http://www.signal.com.tr/img/lineimg/ESP8266.png" src="/cache/www.signal.com.tr/img/lineimg/ESP8266.png"/>
<p class="caption">ESP8266 is just the integrated circuit that incorporates CPU and wireless into one chip</p>
</div>
<p>ESP32 is ESP8266 successor running at 160MHz, includes 520KiB SRAM.</p>
<div class="figure">
<img alt="http://static3.tme.eu/products_pics/8/7/6/87675b4048f1952ce908c7b7384578c5/502170.jpg" src="/cache/static3.tme.eu/products_pics/8/7/6/87675b4048f1952ce908c7b7384578c5/502170.jpg"/>
<p class="caption">ESP32 is also just an integrated circuit</p>
</div>
<p>Both of them are basis for series of interesting SoM-s and development boards.</p>
</div>
<div class="section" id="system-on-module">
<h1>System on Module</h1>
<p>ESP-01 incorporates ESP8266 with 1MiB (8MBit) SPI Flash and PCB antenna.
It's sold at around 1.5 USD on AliExpress.
On ESP-01 two GPIO-s are available (numbered 0 and 2).
When more pins are needed it's possible to make use of UART pins (numbered 1 and 3).
Note that PWM is available only on pins 0 and 2.</p>
<div class="figure">
<img alt="https://acrobotic.com/media/wysiwyg/products/esp8266_esp01_horizontal-01.png" src="/cache/acrobotic.com/media/wysiwyg/products/esp8266_esp01_horizontal-01.png"/>
<p class="caption">ESP-01 uses ESP8266</p>
</div>
<p>ESP32 in very often packaged as ESP-WROOM-32 which
includes 4MiB (32MBit) of SPI Flash and it's sold at Aliexpress for 4 USD.</p>
<div class="figure">
<img alt="http://www.robotop.lv/1721-thickbox/esp-wroom-32.jpg" src="/cache/www.robotop.lv/1721-thickbox/esp-wroom-32.jpg"/>
<p class="caption">ESP-WROOM-32 is based on ESP32, but it's usually shielded so no guts are visible</p>
</div>
</div>
<div class="section" id="development-boards">
<h1>Development boards</h1>
<p>Both ESP8266 and ESP32 have development boards available for around 10 USD.
There are open source GCC toolchains and are suitable for building IoT devices.</p>
<p>NodeMCU is based on ESP-12 SOM and includes USB-UART bridge, 3.3V voltage regulator and PCB antenna</p>
<div class="figure">
<img alt="https://cdn3.bigcommerce.com/s-vt19phz/product_images/uploaded_images/pinout.png?t=1491966337" src="/cache/cdn3.bigcommerce.com/s-vt19phz/product_images/uploaded_images/pinout.png"/>
<p class="caption">NodeMCU</p>
</div>
<p>WeMos Lolin32 uses ESP-WROOM-32, includes LiPo charging circuit, voltage regulators and USB-UART bridge:</p>
<div class="figure">
<img alt="https://paradisetronic.com/media/images/org/LOLIN32_01.jpg" src="/cache/paradisetronic.com/media/images/org/LOLIN32_01.jpg"/>
<p class="caption">WeMos Lolin32</p>
</div>
<p>Note that board pin numbering rarely matches ESP-s pin numbering:</p>
<div class="figure">
<img alt="img/comparison-of-wemos-r2-vs-r1-pinouts.png" src="/cache/77674c66d3e2cadc9c05543ee05a66fa.png"/>
<p class="caption">WeMos D1 R1 vs R2</p>
</div>
<p>Even different revisions of the same board model have different pin mappings.</p>
</div>
<div class="section" id="flashing-micropython">
<h1>Flashing MicroPython</h1>
<p>MicroPython is Python 3 for microcontrollers that runs on bare metal (no OS)
and it implements a subset of the standard library.
It was originally developed for STM32F405RG microcontroller, but
later ported to others including ESP8266 and now ESP32 as well.</p>
<p>First install esptool, note that you need to upgrade to 2.x for ESP32 support:</p>
<pre class="code bash literal-block"><code>pip install esptool</code></pre>
<p>To install on ESP8266 based boards:</p>
<pre class="code bash literal-block"><code>wget http://micropython.org/resources/firmware/esp8266-20170612-v1.9.1.bin
esptool.py -p /dev/ttyUSB0 -b <span class="m">460800</span> erase_flash
esptool.py -p /dev/ttyUSB0 -b <span class="m">460800</span> write_flash <span class="m">0</span> esp8266-*.bin</code></pre>
<p>To install on ESP32 based boards:</p>
<pre class="code bash literal-block"><code>wget http://micropython.org/resources/firmware/esp32-20171206-v1.9.2-445-g84035f0f.bin
esptool.py -p /dev/ttyUSB0 -b <span class="m">460800</span> erase_flash
esptool.py -p /dev/ttyUSB0 -b <span class="m">460800</span> write_flash --flash_mode dio 0x1000 esp32-*.bin</code></pre>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>If your board doesn't have integrated USB-UART bridge, eg in case of ESP-01 you need a USB-UART bridge and to manually ground pin 0 to enable programming mode</p>
</div>
</div>
<div class="section" id="connecting-to-micropython-prompt">
<h1>Connecting to MicroPython prompt</h1>
<p>First use following to open up Python prompt from the device,
note that you can exit picocom by pressing Ctrl-A followed by Ctrl-Q:</p>
<pre class="code bash literal-block"><code>picocom -b115200 /dev/ttyUSB0</code></pre>
<p>First step is to press enter to see that Python interpreter is running,
it should return <cite>&gt;&gt;&gt;</cite> which is the indicator for Python prompt.</p>
<p>Next you can check what Python version is running:</p>
<pre class="code python literal-block"><code><span class="kn">import</span> <span class="nn">sys</span>
<span class="n">sys</span><span class="o">.</span><span class="n">version</span> <span class="c1"># This should return 3.4.0 at the moment</span></code></pre>
<p>To connect to wireless network, synchronize time and start web command prompt server
paste following statements to the Python prompt:</p>
<pre class="code python literal-block"><code><span class="c1"># Connect to wireless network as client</span>
<span class="kn">import</span> <span class="nn">network</span>
<span class="n">wlan</span> <span class="o">=</span> <span class="n">network</span><span class="o">.</span><span class="n">WLAN</span><span class="p">(</span><span class="n">network</span><span class="o">.</span><span class="n">STA_IF</span><span class="p">)</span>
<span class="n">wlan</span><span class="o">.</span><span class="n">active</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
<span class="n">wlan</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">"itcollege"</span><span class="p">)</span>

<span class="c1"># Synchronize clock</span>
<span class="kn">import</span> <span class="nn">ntptime</span>
<span class="n">ntptime</span><span class="o">.</span><span class="n">settime</span><span class="p">()</span>

<span class="c1"># Create a variable for hostname based on MAC address:</span>
<span class="kn">import</span> <span class="nn">ubinascii</span> <span class="kn">as</span> <span class="nn">binascii</span>
<span class="n">name</span> <span class="o">=</span> <span class="s2">"esp-</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">binascii</span><span class="o">.</span><span class="n">hexlify</span><span class="p">(</span><span class="n">wlan</span><span class="o">.</span><span class="n">config</span><span class="p">(</span><span class="s2">"mac"</span><span class="p">)[</span><span class="o">-</span><span class="mi">3</span><span class="p">:])</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"ascii"</span><span class="p">)</span>

<span class="c1"># Clean up</span>
<span class="kn">import</span> <span class="nn">gc</span>
<span class="n">gc</span><span class="o">.</span><span class="n">collect</span><span class="p">()</span></code></pre>
<p>Save the same snippet into boot.py and then use either
REPL over UART or
<a class="reference external" href="http://micropython.org/webrepl/">WebREPL client</a> upload the boot.py file.
Note that you have to disconnect picocom to use REPL over UART.</p>
<pre class="code python literal-block"><code><span class="n">pip</span> <span class="n">install</span> <span class="n">adafruit</span><span class="o">-</span><span class="n">ampy</span> <span class="c1"># Install Adafruit MicroPython Tool</span>
<span class="n">ampy</span> <span class="o">-</span><span class="n">p</span> <span class="o">/</span><span class="n">dev</span><span class="o">/</span><span class="n">ttyUSB0</span> <span class="n">put</span> <span class="n">boot</span><span class="o">.</span><span class="n">py</span> <span class="c1"># Upload boot.py over UART</span></code></pre>
<p>Next reboot the script will be automatically executed and you'll have
persistent connection to your wireless network.</p>
</div>
<div class="section" id="storage">
<h1>Storage</h1>
<p>MicroPython partitions the SPI Flash so the unused space is formatted as
FAT filesystem and exposed over Python's filesystem interfaces.
You can use WebREPL or REPL to list and upload files from your PC.
Within Micropython you can use <span class="docutils literal">os.listdir</span> to list files and
<span class="docutils literal">open</span> to manipulate file contents.</p>
<pre class="code python literal-block"><code><span class="kn">import</span> <span class="nn">os</span>
<span class="n">block_size</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">blocks</span><span class="p">,</span> <span class="n">blocks_free</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">statvfs</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s2">"Filesystem size: </span><span class="si">%d</span><span class="s2"> KiB"</span> <span class="o">%</span> <span class="p">(</span><span class="n">blocks</span> <span class="o">*</span> <span class="n">block_size</span> <span class="o">&gt;&gt;</span> <span class="mi">10</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="s2">"Free space: </span><span class="si">%d</span><span class="s2"> KiB"</span> <span class="o">%</span>  <span class="p">(</span><span class="n">blocks</span> <span class="o">*</span> <span class="n">blocks_free</span> <span class="o">&gt;&gt;</span> <span class="mi">10</span><span class="p">))</span></code></pre>
<p>You should have couple hundred kilobytes free space for
configuration files and some media files.</p>
</div>
<div class="section" id="blinking-led-s">
<h1>Blinking LED-s</h1>
<p>Machine specific interfaces are grouped to module <cite>machine</cite> at least on
ESP8266 and ESP32.
To blink on-board LED-s on WeMos D1:</p>
<pre class="code python literal-block"><code><span class="c1"># WeMos D1</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>
<span class="kn">from</span> <span class="nn">machine</span> <span class="kn">import</span> <span class="n">Pin</span>
<span class="n">som_led</span> <span class="o">=</span> <span class="n">Pin</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">OUT</span><span class="p">)</span>    <span class="c1"># D9 on Wemos D1, LED on the SOM</span>
<span class="n">sck_led</span> <span class="o">=</span> <span class="n">Pin</span><span class="p">(</span><span class="mi">14</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">OUT</span><span class="p">)</span>   <span class="c1"># D13 on Wemos D1, LED connected to SCK</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">10</span><span class="p">):</span>
    <span class="n">som_led</span><span class="o">.</span><span class="n">value</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># Polarity inverted, pin sinks 3.3v</span>
    <span class="n">sck_led</span><span class="o">.</span><span class="n">value</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># Pin sources voltage</span>
    <span class="n">sleep</span><span class="p">(</span><span class="mf">0.2</span><span class="p">)</span>
    <span class="n">som_led</span><span class="o">.</span><span class="n">value</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">sck_led</span><span class="o">.</span><span class="n">value</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">sleep</span><span class="p">(</span><span class="mf">0.2</span><span class="p">)</span></code></pre>
<p>Even ESP-01 has a LED hooked to serial transmit pin:</p>
<pre class="code python literal-block"><code><span class="c1"># ESP-01</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>
<span class="kn">from</span> <span class="nn">machine</span> <span class="kn">import</span> <span class="n">Pin</span><span class="p">,</span> <span class="n">reset</span>
<span class="n">tx</span> <span class="o">=</span> <span class="n">Pin</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">OUT</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">10</span><span class="p">):</span>
    <span class="n">tx</span><span class="o">.</span><span class="n">value</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># Polarity inverted, pin sinks 3.3v</span>
    <span class="n">sleep</span><span class="p">(</span><span class="mf">0.2</span><span class="p">)</span>
    <span class="n">tx</span><span class="o">.</span><span class="n">value</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">sleep</span><span class="p">(</span><span class="mf">0.2</span><span class="p">)</span>
<span class="n">reset</span><span class="p">()</span> <span class="c1"># UART transmit pin is dead by now, reset device to restore serial</span></code></pre>
</div>
<div class="section" id="reading-pins">
<h1>Reading pins</h1>
<p>In this case an external push button is connected to D8 on WeMos D1,
note that you can just use a jumper cable hanging freely and
to simulate a button press the other end is just clicked against the USB port shielding (the ground).</p>
<pre class="code python literal-block"><code><span class="kn">from</span> <span class="nn">machine</span> <span class="kn">import</span> <span class="n">Pin</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>
<span class="n">pin_led</span> <span class="o">=</span> <span class="n">Pin</span><span class="p">(</span><span class="mi">14</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">OUT</span><span class="p">)</span>    <span class="c1"># D13 on Wemos D1, on-board LED connected (SCK)</span>
<span class="n">pin_button</span> <span class="o">=</span>  <span class="n">Pin</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">IN</span><span class="p">)</span>  <span class="c1"># D8 on Wemos D1</span>
<span class="n">turned_on</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">pin_button</span><span class="o">.</span><span class="n">value</span><span class="p">():</span>
        <span class="n">turned_on</span> <span class="o">=</span> <span class="ow">not</span> <span class="n">turned_on</span>
    <span class="n">pin_led</span><span class="o">.</span><span class="n">value</span><span class="p">(</span><span class="n">turned_on</span><span class="p">)</span>
    <span class="n">sleep</span><span class="p">(</span><span class="mf">0.01</span><span class="p">)</span> <span class="c1"># Sleep for 10ms</span></code></pre>
<p>For other pins which dont have pull up resistors on-board
an internal pull up resistor (fused into the integrated circuit) may be used:</p>
<pre class="code python literal-block"><code><span class="n">pin</span> <span class="o">=</span> <span class="n">machine</span><span class="o">.</span><span class="n">Pin</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">machine</span><span class="o">.</span><span class="n">Pin</span><span class="o">.</span><span class="n">IN</span><span class="p">,</span> <span class="n">machine</span><span class="o">.</span><span class="n">Pin</span><span class="o">.</span><span class="n">PULL_UP</span><span class="p">)</span></code></pre>
<p>Note that on Wemos D1 pin 0 (D8) is connected via pull up to 3.3v rail to prevent
accidental boots into flashing mode.
This also keeps the voltage level high on the pin 0 (D8) if the wire is freely hanging.</p>
</div>
<div class="section" id="using-hardware-interrupts">
<h1>Using hardware interrupts</h1>
<p>Interrupts allow CPU to sleep for most time,
in following example LED is toggled when button is released.</p>
<pre class="code python literal-block"><code><span class="kn">from</span> <span class="nn">machine</span> <span class="kn">import</span> <span class="n">Pin</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>

<span class="n">pin_led</span> <span class="o">=</span> <span class="n">Pin</span><span class="p">(</span><span class="mi">14</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">OUT</span><span class="p">)</span>    <span class="c1"># D13 on Wemos D1, on-board LED connected (SCK)</span>
<span class="n">pin_button</span> <span class="o">=</span>  <span class="n">Pin</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">IN</span><span class="p">)</span>  <span class="c1"># D8 on Wemos D1</span>
<span class="n">turned_on</span> <span class="o">=</span> <span class="bp">False</span>

<span class="k">def</span> <span class="nf">callback</span><span class="p">(</span><span class="n">p</span><span class="p">):</span>
    <span class="k">global</span> <span class="n">turned_on</span>
    <span class="n">turned_on</span> <span class="o">=</span> <span class="ow">not</span> <span class="n">turned_on</span>
    <span class="n">pin_led</span><span class="p">(</span><span class="n">turned_on</span><span class="p">)</span>

<span class="n">pin_button</span><span class="o">.</span><span class="n">irq</span><span class="p">(</span><span class="n">trigger</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">IRQ_FALLING</span><span class="p">,</span> <span class="n">handler</span><span class="o">=</span><span class="n">callback</span><span class="p">)</span></code></pre>
<p>Note that most buttons don't have very realiable mechanics giving you
several falling edge events during button press.
Use capacitor on the switch pin to have more reliable operation
or add code for <a class="reference external" href="https://www.arduino.cc/en/Tutorial/Debounce">debounce</a>.</p>
</div>
<div class="section" id="using-timers">
<h1>Using timers</h1>
<p>Timers are sort of like interrupts but instead of being triggered by a pin,
they're triggered after certain amount of time.</p>
<pre class="code python literal-block"><code><span class="kn">from</span> <span class="nn">machine</span> <span class="kn">import</span> <span class="n">Pin</span><span class="p">,</span> <span class="n">Timer</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>

<span class="n">pin_led</span> <span class="o">=</span> <span class="n">Pin</span><span class="p">(</span><span class="mi">14</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">OUT</span><span class="p">)</span>    <span class="c1"># D13 on Wemos D1, on-board LED connected (SCK)</span>
<span class="n">pin_button</span> <span class="o">=</span>  <span class="n">Pin</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">IN</span><span class="p">)</span>  <span class="c1"># D8 on Wemos D1</span>
<span class="n">timer</span> <span class="o">=</span> <span class="n">Timer</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">timeout_callback</span><span class="p">(</span><span class="n">t</span><span class="p">):</span>
    <span class="n">pin_led</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">button_callback</span><span class="p">(</span><span class="n">p</span><span class="p">):</span>
    <span class="n">pin_led</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">timer</span><span class="o">.</span><span class="n">init</span><span class="p">(</span><span class="n">period</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Timer</span><span class="o">.</span><span class="n">ONE_SHOT</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="n">timeout_callback</span><span class="p">)</span>

<span class="n">pin_button</span><span class="o">.</span><span class="n">irq</span><span class="p">(</span><span class="n">trigger</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">IRQ_FALLING</span><span class="p">,</span> <span class="n">handler</span><span class="o">=</span><span class="n">button_callback</span><span class="p">)</span></code></pre>
<p>Timer that executes callback repeatedly can be initialized with
<span class="docutils literal">mode=Timer.PERIODIC</span>.</p>
</div>
<div class="section" id="dimming-led-s">
<h1>Dimming LED-s</h1>
<p>Both ESP-s have hardware PWM generators which means you can get
accurately timed squarewave signals which can be used to dim LED-s or drive motors.</p>
<pre class="code python literal-block"><code><span class="c1"># NodeMCU</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep_ms</span>
<span class="kn">from</span> <span class="nn">machine</span> <span class="kn">import</span> <span class="n">Pin</span><span class="p">,</span> <span class="n">PWM</span>
<span class="n">led</span> <span class="o">=</span> <span class="n">PWM</span><span class="p">(</span><span class="n">Pin</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">Pin</span><span class="o">.</span><span class="n">OUT</span><span class="p">),</span> <span class="n">freq</span><span class="o">=</span><span class="mi">400</span><span class="p">)</span> <span class="c1"># Initialize at 400Hz</span>

<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">10</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1023</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">10</span><span class="p">):</span>
        <span class="n">led</span><span class="o">.</span><span class="n">duty</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
        <span class="n">sleep_ms</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1024</span><span class="p">,</span> <span class="mi">10</span><span class="p">):</span>
        <span class="n">led</span><span class="o">.</span><span class="n">duty</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
        <span class="n">sleep_ms</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span></code></pre>
</div>
<div class="section" id="creating-a-webserver">
<h1>Creating a webserver</h1>
<p>MicroPython doesn't come with HTTP server wrapper classes,
but you can use Berkeley sockets style programming interfaces out of the box:</p>
<pre class="code python literal-block"><code><span class="kn">import</span> <span class="nn">socket</span>
<span class="kn">from</span> <span class="nn">machine</span> <span class="kn">import</span> <span class="n">Pin</span>

<span class="n">led_pin</span> <span class="o">=</span> <span class="n">Pin</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="n">Pin</span><span class="o">.</span><span class="n">OUT</span><span class="p">)</span>

<span class="n">CONTENT</span> <span class="o">=</span> <span class="s2">"""</span><span class="se">\
</span><span class="s2">HTTP/1.0 200 OK
Content-Type: text/html

&lt;html&gt;
  &lt;head&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;Hello #</span><span class="si">%d</span><span class="s2"> from MicroPython!&lt;/p&gt;
    &lt;a href="/toggle"&gt;Click here to toggle LED hooked to pin 5&lt;/a&gt;
  &lt;/body&gt;
&lt;/html&gt;
"""</span>

<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">s</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">()</span>
    <span class="n">ai</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">getaddrinfo</span><span class="p">(</span><span class="s2">"0.0.0.0"</span><span class="p">,</span> <span class="mi">8080</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s2">"Bind address info:"</span><span class="p">,</span> <span class="n">ai</span><span class="p">)</span>
    <span class="n">addr</span> <span class="o">=</span> <span class="n">ai</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>

    <span class="n">s</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_REUSEADDR</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
    <span class="n">s</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="n">addr</span><span class="p">)</span>
    <span class="n">s</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s2">"Listening, connect your browser to http://&lt;this_host&gt;:8080/"</span><span class="p">)</span>

    <span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
        <span class="n">sock</span><span class="p">,</span> <span class="n">addr</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
        <span class="k">print</span><span class="p">(</span><span class="s2">"Client address:"</span><span class="p">,</span> <span class="n">addr</span><span class="p">)</span>
        <span class="n">stream</span> <span class="o">=</span> <span class="n">sock</span><span class="o">.</span><span class="n">makefile</span><span class="p">(</span><span class="s2">"rwb"</span><span class="p">)</span>
        <span class="n">req</span> <span class="o">=</span> <span class="n">stream</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"ascii"</span><span class="p">)</span>
        <span class="n">method</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" "</span><span class="p">)</span>
        <span class="k">print</span><span class="p">(</span><span class="s2">"Got"</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="s2">"request for"</span><span class="p">,</span> <span class="n">path</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">path</span> <span class="o">==</span> <span class="s2">"/toggle"</span><span class="p">:</span>
            <span class="n">led_pin</span><span class="o">.</span><span class="n">value</span><span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="n">led_pin</span><span class="o">.</span><span class="n">value</span><span class="p">())</span>
        <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
            <span class="n">h</span> <span class="o">=</span> <span class="n">stream</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"ascii"</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
            <span class="k">if</span> <span class="n">h</span> <span class="o">==</span> <span class="s2">""</span><span class="p">:</span>
                <span class="k">break</span>
            <span class="k">print</span><span class="p">(</span><span class="s2">"Got HTTP header:"</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
        <span class="n">stream</span><span class="o">.</span><span class="n">write</span><span class="p">((</span><span class="n">CONTENT</span> <span class="o">%</span> <span class="n">counter</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"ascii"</span><span class="p">))</span>
        <span class="n">stream</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="n">counter</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="k">print</span><span class="p">()</span>

<span class="n">main</span><span class="p">()</span> <span class="c1"># Press Ctrl-C to stop web server</span></code></pre>
</div>
<div class="section" id="websockets">
<h1>WebSockets</h1>
<p>MicroPython has BSD sockets style API for IP-based networks.
For high level protocols such as HTTP and WebSockets modules are popping up.</p>
<p>In this example ESP is connected nchan enabled nginx web server.
The configuration of nginx/nchan looks something like this.
This configuration basically allows broadcasting messages between nodes
connected to same nginx server even if the nodes are behind
NAT or firewall:</p>
<pre class="code literal-block"><code>server {
    listen 80;
    server_name iot.koodur.com;
    root /var/www/iot;
    location ~ "^/ws/(.*?)" {
        nchan_channel_id $1;
        nchan_pubsub websocket;
        nchan_message_buffer_length 0;
    }
}</code></pre>
<p>Pull a Python module for creating websockets and upload it to ESP:</p>
<pre class="code python literal-block"><code><span class="n">wget</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">gist</span><span class="o">.</span><span class="n">githubusercontent</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">laurivosandi</span><span class="o">/</span><span class="mi">2983</span><span class="n">fe38ad7aff85a5e3b86be8f00718</span><span class="o">/</span><span class="n">raw</span><span class="o">/</span><span class="n">cfa52f739080d42029d21017c5ae2a7b97793b06</span><span class="o">/</span><span class="n">uwebsockets</span><span class="o">.</span><span class="n">py</span>
<span class="n">ampy</span> <span class="o">-</span><span class="n">p</span> <span class="o">/</span><span class="n">dev</span><span class="o">/</span><span class="n">ttyUSB0</span> <span class="n">put</span> <span class="n">uwebsockets</span><span class="o">.</span><span class="n">py</span></code></pre>
<p>Example code for ESP:</p>
<pre class="code python literal-block"><code><span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">uwebsockets</span>
<span class="kn">from</span> <span class="nn">machine</span> <span class="kn">import</span> <span class="n">Pin</span><span class="p">,</span> <span class="n">PWM</span>
<span class="n">led</span> <span class="o">=</span> <span class="n">PWM</span><span class="p">(</span><span class="n">Pin</span><span class="p">(</span><span class="mi">14</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">Pin</span><span class="o">.</span><span class="n">OUT</span><span class="p">),</span> <span class="n">freq</span><span class="o">=</span><span class="mi">400</span><span class="p">)</span> <span class="c1"># SCK LED on WeMos D1</span>
<span class="n">uri</span> <span class="o">=</span> <span class="s2">"ws://iot.koodur.com:80/ws/living-room-of-lauri"</span>
<span class="k">print</span><span class="p">(</span><span class="s2">"Connecting to:"</span><span class="p">,</span> <span class="n">uri</span><span class="p">)</span>
<span class="n">conn</span> <span class="o">=</span> <span class="n">uwebsockets</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s2">"alive"</span><span class="p">)</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="s2">"Reading message..."</span><span class="p">)</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">fin</span><span class="p">,</span> <span class="n">opcode</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">read_frame</span><span class="p">()</span>
    <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span> <span class="c1"># Connection timeout or reset</span>
        <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">()</span> <span class="c1"># Soft reset</span>
    <span class="k">if</span> <span class="n">data</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="sa">b</span><span class="s2">"duty:"</span><span class="p">):</span>
        <span class="n">led</span><span class="o">.</span><span class="n">duty</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="mi">5</span><span class="p">:]))</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s2">"Got unknown command:"</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span></code></pre>
<p>Relevant code for the web:</p>
<pre class="code html literal-block"><code><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span><span class="p">&gt;</span>
  <span class="kd">var</span> <span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="s2">"ws://iot.koodur.com:80/ws/living-room-of-lauri/"</span><span class="p">);</span>
  <span class="nx">ws</span><span class="p">.</span><span class="nx">onopen</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">info</span><span class="p">(</span><span class="s2">"websocket connected"</span><span class="p">);</span> <span class="p">};</span>
  <span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> <span class="p">}</span>
  <span class="kd">var</span> <span class="nx">lastValue</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
  <span class="kd">function</span> <span class="nx">duty</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">lastValue</span> <span class="o">==</span> <span class="nx">e</span><span class="p">.</span><span class="nx">value</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
    <span class="nx">lastValue</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">value</span><span class="p">;</span>
    <span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="s2">"duty:"</span> <span class="o">+</span> <span class="nx">e</span><span class="p">.</span><span class="nx">value</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
  <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">"range"</span> <span class="na">min</span><span class="o">=</span><span class="s">"0"</span> <span class="na">max</span><span class="o">=</span><span class="s">"1023"</span> <span class="na">step</span><span class="o">=</span><span class="s">"10"</span> <span class="na">onMouseMove</span><span class="o">=</span><span class="s">"duty(this);"</span> <span class="na">onTouchMove</span><span class="o">=</span><span class="s">"duty(this);"</span><span class="p">/&gt;</span>
<span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span></code></pre>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>Replace living-room-of-lauri with an unique string, otherwise you'll end up flicking switch in my living room</p>
</div>
</div>
<div class="section" id="unicast-websockets">
<h1>Unicast WebSockets</h1>
<p>In the example above the messages are broadcasted to all nodes connected
to the same WebSockets URI, including the message publisher itself.
For IoT lamp this is great, all lamps get the message and browsers as well -
this helps keeping things in sync.</p>
<p>If you want to have sort of unicast communications between two nodes,
you can try following nchan config:</p>
<pre class="code literal-block"><code>server {
    listen 80;
    server_name iot.koodur.com;
    root /var/www/iot;
    location ~ "^/p2p/([\w\d\-]+)/([\w\d\-]+)" {
        nchan_pubsub websocket;
        nchan_message_buffer_length 0;
        nchan_publisher_channel_id $1/$2;
        nchan_subscriber_channel_id $2/$1;
    }
}</code></pre>
<p>On the ESP end use:</p>
<pre class="code python literal-block"><code><span class="n">uri</span> <span class="o">=</span> <span class="s2">"ws://iot.koodur.com:80/p2p/lamp-123456/browser/"</span></code></pre>
<p>On the browser end use:</p>
<pre class="code javascript literal-block"><code><span class="kd">var</span> <span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="s2">"ws://iot.koodur.com:80/p2p/browser/lamp-123456/"</span><span class="p">);</span></code></pre>
<p>This config shall prevent echoing messages to publisher as well.</p>
</div>
<div class="section" id="driving-ssd1306-oled-screens">
<h1>Driving SSD1306 OLED screens</h1>
<p>Python module for driving such OLED screens can be pulled from MicroPython's Git repo:</p>
<pre class="code bash literal-block"><code>wget https://raw.githubusercontent.com/micropython/micropython/master/drivers/display/ssd1306.py
ampy -p /dev/ttyUSB0 put ssd1306.py</code></pre>
<p>Random ESP32 based board with a screen from AliExpress used I2C interface
but the chip also supports SPI interace.
In this case the I2C interace is bit banged on pins 4 and 5.</p>
<p>To paste chunks of indented text like the one below press Ctrl-E, paste the text as usual by
right clicking in the terminal and selecting Paste.
Once finished press Ctrl-D to tell Python interpreter that you're done.</p>
<pre class="code python literal-block"><code><span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep_ms</span>
<span class="kn">from</span> <span class="nn">machine</span> <span class="kn">import</span> <span class="n">Pin</span><span class="p">,</span> <span class="n">I2C</span>
<span class="kn">from</span> <span class="nn">ssd1306</span> <span class="kn">import</span> <span class="n">SSD1306_I2C</span>

<span class="n">i2c</span> <span class="o">=</span> <span class="n">I2C</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">Pin</span><span class="p">(</span><span class="mi">4</span><span class="p">),</span><span class="n">Pin</span><span class="p">(</span><span class="mi">5</span><span class="p">),</span><span class="n">freq</span><span class="o">=</span><span class="mi">400000</span><span class="p">)</span> <span class="c1"># Bitbanged I2C bus</span>
<span class="k">assert</span> <span class="mi">60</span> <span class="ow">in</span> <span class="n">i2c</span><span class="o">.</span><span class="n">scan</span><span class="p">(),</span> <span class="s2">"No OLED display detected!"</span>
<span class="n">oled</span> <span class="o">=</span> <span class="n">SSD1306_I2C</span><span class="p">(</span><span class="mi">128</span><span class="p">,</span> <span class="mi">64</span><span class="p">,</span> <span class="n">i2c</span><span class="p">)</span>
<span class="n">buf</span> <span class="o">=</span> <span class="s2">"wubba lubba dub dub  "</span>
<span class="n">oled</span><span class="o">.</span><span class="n">invert</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># White text on black background</span>
<span class="n">oled</span><span class="o">.</span><span class="n">contrast</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span> <span class="c1"># Maximum contrast</span>
<span class="n">j</span> <span class="o">=</span> <span class="mi">0</span>

<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
    <span class="n">oled</span><span class="o">.</span><span class="n">fill</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
    <span class="n">oled</span><span class="o">.</span><span class="n">text</span><span class="p">(</span><span class="n">buf</span><span class="p">[</span><span class="n">j</span><span class="o">%</span><span class="nb">len</span><span class="p">(</span><span class="n">buf</span><span class="p">):]</span><span class="o">+</span><span class="n">buf</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
    <span class="n">oled</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="n">sleep_ms</span><span class="p">(</span><span class="mi">20</span><span class="p">)</span>
    <span class="n">j</span> <span class="o">+=</span> <span class="mi">1</span></code></pre>
<p>And it works!</p>
<div class="figure">
<img alt="img/ssd1306.gif" src="/cache/3592efecd1deb17086f5e019f2ab1421.gif"/>
<p class="caption">Text scrolling on SSD1306 based OLED screen hooked to ESP32</p>
</div>
</div>
<div class="section" id="powering">
<h1>Powering</h1>
<p>According to datasheet ESP32 can be powered with 2.3V to 3.6V power source,
but fiddling around with bench power supply the basic functionality seemed to
be intact even with voltages from 2V to 4V drawing constantly 60mA.
Below 2V or over 4V the ESP32 cuts it's power consumption.</p>
</div>
<div class="section" id="summary">
<h1>Summary</h1>
<p>ESP8266 is just enough to build WiFi connected LED lights or a Nixie clock.
ESP32 is a bit beefier and suitable for building a sumorobot.
Schematics and up to date code of MicroPython based, NTP-synchronized and IN-12 based Nixie clock
can be found at <a class="reference external" href="http://github.com/laurivosandi/nixiesp12/">GitHub</a>.</p>
</div>
</div>
]]></content>
    
    <category term="MicroPython"/>
    <category term="ESP8266"/>
    <category term="Python"/>
    <category term="ИН-12Б"/>
    <category term="ИН-12А"/>
    <category term="ESP32"/>
    <category term="Espressif"/>
    <category term="MCU"/>
    <updated>2017-06-10T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>KiCad</title>
    <summary>KiCad is open source electronic design automation tool
with a long history starting from 1992.
CERN started supporting the project since 2013 which
has contributed to the maturity of the project considerably.</summary>
    <link href="http://lauri.vosandi.com/2017/05/kicad.html"/>
    <content type="html"><![CDATA[<div class="document" id="kicad">
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags: KiCad, Gerber, PCB, Nixie -->
<!-- date: 2017-05-24 -->
<div class="section" id="introduction">
<h1>Introduction</h1>
<p>KiCad is open source electronic design automation tool
with a long history starting from 1992.
CERN started supporting the project since 2013 which
has contributed to the maturity of the project considerably.</p>
<p>KiCad distinctly separates logical design and physical design.
First the electrical circuits are described with symbols.
Then footprints are associated with the components.
Footprints are then laid out on the PCB:</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0.950 0.950 23.684 20.250" preserveAspectRatio="xMidYMid meet" style=""><rect x="1.000" y="1.000" width="13.000" height="2.000" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="1.000" y="1.000" width="13.000" height="2.000" fill="none" stroke="#000000" stroke-width="0.100"/><text x="7.500" y="2.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
Design schematic</text><rect x="1.000" y="5.000" width="13.025" height="3.000" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="1.000" y="5.000" width="13.025" height="3.000" fill="none" stroke="#000000" stroke-width="0.100"/><text x="7.513" y="6.295" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
Associate components</text><text x="7.513" y="7.095" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
and footprints</text><rect x="1.000" y="14.000" width="13.000" height="2.000" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="1.000" y="14.000" width="13.000" height="2.000" fill="none" stroke="#000000" stroke-width="0.100"/><text x="7.500" y="15.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
Import netlist to layout editor</text><rect x="1.000" y="18.000" width="13.000" height="2.200" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="1.000" y="18.000" width="13.000" height="2.200" fill="none" stroke="#000000" stroke-width="0.100"/><text x="7.500" y="19.295" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
Place footprints &amp; tracks</text><rect x="1.000" y="10.000" width="13.000" height="2.000" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="1.000" y="10.000" width="13.000" height="2.000" fill="none" stroke="#000000" stroke-width="0.100"/><text x="7.500" y="11.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
Generate netlist</text><line x1="7.500" y1="12.049" x2="7.500" y2="13.464" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="7.500,13.839 7.250,13.339 7.500,13.464 7.750,13.339 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="7.500,13.839 7.250,13.339 7.500,13.464 7.750,13.339 "/><line x1="7.503" y1="3.048" x2="7.507" y2="4.464" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="7.508,4.839 7.256,4.339 7.507,4.464 7.756,4.338 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="7.508,4.839 7.256,4.339 7.507,4.464 7.756,4.338 "/><line x1="7.508" y1="8.050" x2="7.504" y2="9.465" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="7.503,9.840 7.255,9.339 7.504,9.465 7.755,9.341 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="7.503,9.840 7.255,9.339 7.504,9.465 7.755,9.341 "/><line x1="7.500" y1="16.050" x2="7.500" y2="17.464" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="7.500,17.839 7.250,17.339 7.500,17.464 7.750,17.339 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="7.500,17.839 7.250,17.339 7.500,17.464 7.750,17.339 "/><polygon fill="#FFFFFF" stroke="none" stroke-width="0.100" points="16.728,1.000 23.000,1.000 22.272,3.000 16.000,3.000 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="16.728,1.000 23.000,1.000 22.272,3.000 16.000,3.000 "/><text x="19.500" y="2.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
design.sch</text><polygon fill="#FFFFFF" stroke="none" stroke-width="0.100" points="16.728,18.000 23.634,18.000 22.906,20.000 16.000,20.000 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="16.728,18.000 23.634,18.000 22.906,20.000 16.000,20.000 "/><text x="19.817" y="19.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
design.kicad_pcb</text><line x1="14.050" y1="19.047" x2="15.835" y2="19.032" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="16.210,19.029 15.712,19.283 15.835,19.032 15.708,18.783 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="16.210,19.029 15.712,19.283 15.835,19.032 15.708,18.783 "/><polygon fill="#FFFFFF" stroke="none" stroke-width="0.100" points="16.728,10.000 23.000,10.000 22.272,12.000 16.000,12.000 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="16.728,10.000 23.000,10.000 22.272,12.000 16.000,12.000 "/><text x="19.500" y="11.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
design.net</text><line x1="14.045" y1="11.000" x2="15.845" y2="11.000" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="16.220,11.000 15.720,11.250 15.845,11.000 15.720,10.750 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="16.220,11.000 15.720,11.250 15.845,11.000 15.720,10.750 "/><line x1="14.045" y1="2.000" x2="15.845" y2="2.000" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="16.220,2.000 15.720,2.250 15.845,2.000 15.720,1.750 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="16.220,2.000 15.720,2.250 15.845,2.000 15.720,1.750 "/></svg></div>
</div>
<div class="section" id="schematic-design">
<h1>Schematic design</h1>
<div class="figure">
<img alt="img/kicad-eeschema.png" src="/cache/da9fdb98d72c9d315d05ac0981fc4c82.png"/>
<p class="caption">Eeschema is the schematic design tool of KiCad</p>
</div>
<p>Some important default keyboard shortcuts:</p>
<ul class="simple">
<li><p>M - Move component without affecting surrounding objects</p></li>
<li><p>G - Grab component while keeping wires intact</p></li>
<li><p>X - Flip component along X axis</p></li>
<li><p>Y - Flip component along Y axis</p></li>
<li><p>R - Rotate component</p></li>
<li><p>W - Insert wire</p></li>
<li><p>Del - Remove track object</p></li>
<li><p>F1 and F2 - Zoom in and out</p></li>
<li><p>V - Change value of component</p></li>
</ul>
</div>
<div class="section" id="assigning-footprints">
<h1>Assigning footprints</h1>
<p>From Eeschema main menu select <em>Tools -&gt; Assign Component Footprint</em>,
this will open up Cvpcb.
From the Cvpcb toolbar disable filtering footprints by keywords and
enable filtering by pin count and library.
Select categroy from leftmost panel, click on the middle panel
to select target component and double click in the rightmost panel to assign a footprint.</p>
<div class="figure">
<img alt="img/kicad-cvpcb.png" src="/cache/c4ae69f6285722910aec16840902f5b2.png"/>
<p class="caption">Cvpcb is used to associate schematic components with footprints</p>
</div>
</div>
<div class="section" id="laying-out-pcb">
<h1>Laying out PCB</h1>
<div class="figure">
<img alt="img/kicad-pcbnew.png" src="/cache/d05d95c19fd5f51cecade43a910fd5c5.png"/>
<p class="caption">Pcbnew is the PCB layout tool of KiCad</p>
</div>
<p>Some important default keyboard shortcuts:</p>
<ul class="simple">
<li><p>M - Move footprint without affecting surrounding objects</p></li>
<li><p>G - Grab footprint while keeping tracks intact</p></li>
<li><p>F - Flip a footprit to the other side of PCB</p></li>
<li><p>R - Rotate footprint</p></li>
<li><p>X - Insert track</p></li>
<li><p>Del - Remove track object</p></li>
<li><p>F1 and F2 - Zoom in and out</p></li>
<li><p>Alt-3 - Open 3D viewer</p></li>
<li><p>V - Swap layers, while inserting a track places via</p></li>
</ul>
<p>On the status bar Pcbnew shows absolute coordinates and also relative ones.
The relative coordinates are measured to point set by pressing the spacebar.
This comes very handy in ensuring that you place footprints correctly.</p>
<p>Once tracks have been placed it's time to specify cutout area for the PCB.
This will define the dimensions of your PCB.
Select Edge.Cuts layer from the layers combobox.
From the toolbar select <em>Add graphic line or polygon</em> and draw the rectangle
around your design.
Hit V to go back to copper layers.</p>
<p>It's possible to fill in rest of the PCB
with copper areas usually connected to ground.
This reduces the amount of solvent required when etching PCB-s later on.
From the main menu select <em>Place -&gt; Zone</em>,
click on the cutout corner and select GND as the net where zone shall be connected to.
Follow the corners of the cutout and doule click on the corner where you started.
Hit V to select the other copper layer and repeat the zone add procedure again.
Once both zones have been placed hit B to fill in the zones.
Filled zones make it harder to work with footprints,
use Ctrl-B to clear zones for the time being.</p>
</div>
<div class="section" id="autorouting">
<h1>Autorouting</h1>
<p>KiCad doesn't include tool for automatic routing,
instead integration with FreeRoute tool is provided.
From the main menu select <em>Tools -&gt; FreeRoute</em>,
in the toolbar in can be found by yellow icon.
In the dialog hit <em>Export a Specctra Design and Launch FreeRoute</em>.
Your PCB layout is exported to a .dsn file and opened with FreeRoute.
FreeRoute is a Java program so appropriate Java Runtime might have to be
additionally installed.</p>
<div class="figure">
<img alt="img/freerouting.png" src="/cache/65a031630e41c124d473b4f3793481fa.png"/>
</div>
<p>In FreeRouter click <em>Autorouter</em> button on the top, FreeRouting will
do it's magic and stop when ready.
Note that in certain corner cases it might get stuck between
two possible outcomes and you might have to stop the autorouting process manually.
Click <em>File -&gt; Export Specctra Session File</em> in the FreeRouting main menu
to export .ses file. Now in Pcbnew click <em>Back import the Specctra Session</em>.
Press B to refill zones.</p>
<div class="figure">
<img alt="img/kicad-routed.png" src="/cache/6dc6fc36b0dc91d88d3f397d4e5deaa1.png"/>
</div>
<p>If you want FreeRouter to use wider tracks make
necessary changes by opening Design Rules from Pcbnew main menu,
repeat the export .dsn process and reopen file with FreeRoute.
Note that it's perfectly okay to manually route some tracks before
running FreeRoute.</p>
</div>
<div class="section" id="d-view">
<h1>3D view</h1>
<p>In KiCad PCB layout editor press Alt-3 to open 3D viewer of the PCB.
From the 3D viewer <em>Preferences</em> menu enable <em>Realistic Mode</em>,
disable axes, hide grid and under <em>Render Options</em> enable everything.</p>
<div class="figure">
<img alt="img/kicad-3d-viewer.png" src="/cache/9efbb3d3ceb8df4a1584d65766d4d0ba.png"/>
</div>
</div>
<div class="section" id="gerber-export">
<h1>Gerber export</h1>
<p>Once PCB is laid out in KiCad, it can be converted to Gerber.
Gerber files basically describe polygons that need to be carved out of the copper layer.
You can use <cite>gerbview</cite> to view Gerber files, command to view all relevant files in
current directory:</p>
<pre class="code bash literal-block"><code>gerbview *.g*</code></pre>
<p>If the Gerbers look alright you can upload them to
PCB manufacturing company such as
<a class="reference external" href="https://oshpark.com/">OSH Park</a>,
<a class="reference external" href="http://dirtypcbs.com/store/pcbs">DirtyPCBs</a>,
<a class="reference external" href="https://www.seeedstudio.com/fusion_pcb.html">Seeed Studio</a> or probably many
others you can find on the internet.
Note that for cheap options the shipping time can be anywhere between 1 to 2 months.</p>
<p>Alternatively you can
<a class="reference external" href="/2016/07/linuxcnc.html">use a CNC machine to mill a PCB</a>.</p>
</div>
</div>
]]></content>
    
    <category term="PCB"/>
    <category term="Nixie"/>
    <category term="Gerber"/>
    <category term="KiCad"/>
    <updated>2017-05-24T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>VPN benchmarking</title>
    <summary>For anyone who were wondering how much throughput you might expect from
different hardware/software combinations.
In this case iperf was used to measure throughput,
for applications (eg. fileserver) your mileage will vary due to
WAN link latency etc.</summary>
    <link href="http://lauri.vosandi.com/2017/04/vpn-benchmarking.html"/>
    <content type="html"><![CDATA[<div class="document" id="vpn-benchmarking">
<!-- date: 2017-04-14 16:54:58 -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags: OpenVPN, StrongSwan, OpenWrt, Turris -->
<p>For anyone who were wondering how much throughput you might expect from
different hardware/software combinations.
In this case iperf was used to measure throughput,
for applications (eg. fileserver) your mileage will vary due to
WAN link latency etc.</p>
<table>
<colgroup>
<col style="width: 23%"/>
<col style="width: 21%"/>
<col style="width: 25%"/>
<col style="width: 16%"/>
<col style="width: 15%"/>
</colgroup>
<thead>
<tr><th class="head"><p>Device</p></th>
<th class="head"><p>OS</p></th>
<th class="head"><p>Software</p></th>
<th class="head"><p>CPU load</p></th>
<th class="head"><p>Throughput</p></th>
</tr>
</thead>
<tbody>
<tr><td><p>TP-Link Archer C7</p></td>
<td><p>OpenWrt 15.05.1</p></td>
<td><p>OpenVPN</p></td>
<td><p>100%</p></td>
<td><p>25Mbps</p></td>
</tr>
<tr><td><p>TP-Link Archer C7</p></td>
<td><p>OpenWrt 15.05.1</p></td>
<td><p>StrongSwan</p></td>
<td><p>100%</p></td>
<td><p>40Mbps</p></td>
</tr>
<tr><td><p>Omnia Turris</p></td>
<td><p>Turris OS</p></td>
<td><p>OpenVPN 2.4.0</p></td>
<td><p>100%</p></td>
<td><p>96Mbps</p></td>
</tr>
<tr><td><p>Omnia Turris</p></td>
<td><p>Turris OS</p></td>
<td><p>StrongSwan 5.3.5</p></td>
<td><p>100%</p></td>
<td><p>300Mbps</p></td>
</tr>
<tr><td><p>Intel i7-6500U</p></td>
<td><p>Linux 4.10</p></td>
<td><p>OpenVPN 2.3.10</p></td>
<td><p>100%</p></td>
<td><p>483Mbps</p></td>
</tr>
<tr><td><p>Intel i7-6500U</p></td>
<td><p>Linux 4.4</p></td>
<td><p>OpenVPN 2.3.10</p></td>
<td><p>100%</p></td>
<td><p>420Mbps</p></td>
</tr>
<tr><td><p>Intel i7-4770R</p></td>
<td><p>Linux 4.9</p></td>
<td><p>OpenVPN 2.4.1</p></td>
<td><p>85%</p></td>
<td><p>483Mbps</p></td>
</tr>
<tr><td><p>Intel i7-6500U</p></td>
<td><p>Linux 4.4</p></td>
<td><p>StrongSwan 5.3.5</p></td>
<td><p>20%</p></td>
<td><p>895Mbps</p></td>
</tr>
<tr><td><p>1GbE</p></td>
<td><p>N/A</p></td>
<td><p>none</p></td>
<td><p>&lt;1%</p></td>
<td><p>940Mbps</p></td>
</tr>
</tbody>
</table>
<p>Conclusions:</p>
<ul class="simple">
<li><p>StrongSwan throughput is double the the OpenVPN on average</p></li>
<li><p>Since TP-Link Archer C7 is running MIPS CPU at 720MHz and there is no hardware
acceleration for crypto the both StrongSwan and OpenVPN the CPU becomes the bottleneck</p></li>
<li><p>Omnia Turris can easily saturate 100MBps WAN link</p></li>
</ul>
<p>Note: Since all these applications are single-threaded CPU load means single core
CPU usage</p>
<p>Don't be hasty to draw conclusions on whether StrongSwan is better than OpenVPN or not,
both have pros and cons. StrongSwan heavily relies on Linux kernel modules,
from security perspecive IPSec is very intrusive and opens up whole lot of new
attack vectors while OpenVPN makes use of TUN/TAP driver and everything else
happens in userspace - if the OpenVPN process crashes it won't take your machine along.</p>
</div>
]]></content>
    
    <category term="StrongSwan"/>
    <category term="Turris"/>
    <category term="OpenWrt"/>
    <category term="OpenVPN"/>
    <updated>2017-04-14T16:54:58Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>E-posti krüpteerimine</title>
    <summary>Reaalsus on see, et kui saadad kirja, siis juhtub umbest&#228;pselt midagi s&#228;&#228;rast:</summary>
    <link href="http://lauri.vosandi.com/2017/03/encrypted-email.html"/>
    <content type="html"><![CDATA[<div class="document" id="e-posti-krupteerimine">
<!-- tags: Interneti P&#228;ev 2017, Kr&#252;ptopidu -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- date: 2017-03-30 -->
<div class="section" id="sissejuhatus">
<h1>Sissejuhatus</h1>
<p>Reaalsus on see, et kui saadad kirja, siis juhtub umbest&#228;pselt midagi s&#228;&#228;rast:</p>
<pre class="code literal-block"><code>              HTTPS               SMTP              IMAP (POP3)
Veebiliides --------&gt; 1. server -------&gt; 2. server -------&gt; E-posti tarkvara
                         ^                     |
                         |                     |
E-posti tarkvara --------+                     +-------------&gt; Veebiliides
                   SMTP                           HTTP</code></pre>
<p>Igal sammul on erinevad puudused,
veebiliidese puhul ei ole kindel kas veebiliidesele minnakse ligi HTTPS abil (turvatuna).
E-posti serverite vahel liiguvad kirjad p&#228;ris tihti kr&#252;pteerimata.
E-post ei kao nii pea kuskile kuna
<a class="reference external" href="https://xkcd.com/1810/">kiirsuhtlusplatvormid on &#228;&#228;rmiselt fragmenteerunud</a> ning
otspunktist-otspunkti sisu kr&#252;pteerimine on toetatud varieeruva eduga.</p>
<p>E-posti turvamise juures on meil kaks aspekti:</p>
<ul class="simple">
<li><p>Kr&#252;pteerimine, et keegi teine sidet pealt kuulates ei saaks s&#245;numit lugeda</p></li>
<li><p>Allkirjastamine saatja identiteedi t&#245;endamiseks</p></li>
</ul>
<p>Otspunktide vahel m&#245;lemi jaoks on sisuliselt kolm varianti:</p>
<ul class="simple">
<li><p>ID-kaardi abil, kasutades ID-kaardi tarkvara</p></li>
<li><p>S/MIME abil (ID-kaart e-posti klienttarkvaras v&#245;i ise genereeritud X.509 sertifikaadid)</p></li>
<li><p>PGP/GPG abil, t&#252;kk maad keerukam aga fooliumm&#252;tsikestele k&#245;ige sobivam</p></li>
</ul>
</div>
<div class="section" id="e-posti-klienttarkvara">
<h1>E-posti klienttarkvara</h1>
<p>E-posti tarkvara on vajalik selleks et suhelda e-posti serveriga.
Gmaili puhul on p&#245;hiline postkastile ligisaamise viis veebiliides ise.
Suuremates ettev&#245;tetes on kasutusel Microsoft Outlook.
Aga need ei ole ainsad viisid postkastile ligi p&#228;&#228;semiseks,
&#252;ks populaarsemaid avatud l&#228;htekoodiga programme on Mozilla Thunderbird.
E-postiserverid kasutavad SMTP protokolli kirjade saatmiseks ning IMAP protokolli kirjade lugemiseks serverist.
POP protokolli t&#228;nap&#228;eval kasutada pole m&#245;istlik kuna inimesel on rohkem kui &#252;ks seade.
Thunderbirdi nii nagu pea suvalise e-posti tarkvara saab seadistada
kirju alla laadima e-posti serverist IMAP protokolli abil ning saatma SMTP protokolli abil.</p>
<p>Kui kasutad veebiliidest veendu et l&#228;hed veebilehele ligi HTTPS abil, indikaatoriks roheline tabalukk aadressiribal</p>
<p>E-posti tarbimiseks kohalikust masinast paigalda Mozilla Thunderbird,
seadistamisel veendu et kasutad SMTPS/IMAPS (TLS abil turvatud variante SMTP/IMAP protokollidest):</p>
<ul class="simple">
<li><p>Windows, Mac OS X puhul aadressilt <a class="reference external" href="https://www.mozilla.org/et/thunderbird/">https://www.mozilla.org/et/thunderbird/</a></p></li>
<li><p>Ubuntu, Debian puhul: apt install thunderbird</p></li>
<li><p>Fedora, Red Hat puhul: dnf install thunderbird</p></li>
</ul>
<p>Isegi kui kasutad praegu kolmanda osapoole e-posti serverit siis proovi oma
arvutis seadistada e-posti klienttarkvara seadistada.</p>
</div>
<div class="section" id="gpg">
<h1>GPG</h1>
<p>PGP ehk Pretty Good Privacy oli 1991 aastal loodud tarkvara s&#245;numite kr&#252;pteerimiseks ja allkirjastamiseks.
Sellest tarkvarast loodi tagasiulatuvalt OpenPGP avalik standard.
GPG ehk GNU Privacy Guard on PGP protokolli avatud l&#228;htekoodiga realisatsioon.
GPG kasutab RSA v&#245;tmeid, k&#245;ige suurem vaev ongi v&#245;tmete &#252;les seadmine ning oma usaldusv&#245;rgustiku ehitamine.
N&#228;iteks minu GPG v&#245;tme s&#245;rmej&#228;lg on E1BC859AFC900AA925F1BAF33E1E3B1EE82AD8C0,
v&#245;tmeserverist saad alla laadida minu v&#245;tme E82AD8C0 l&#252;hendi j&#228;rgi,
so viimased 8 s&#252;mbolit v&#245;tme s&#245;rmej&#228;ljest.
Enne kui asud allkirjastama minu v&#245;tit (s&#252;mboliseerib sinu usaldust minu v&#245;tmemajanduse vastu)
peaksid enne allkirjastamist veenduma et selle v&#245;tmega on t&#245;epoolest seotud
minu identiteet - helista, tule k&#252;lla vms.</p>
<p>Paigalda v&#245;tmete haldamiseks tarkvara:</p>
<ul class="simple">
<li><p>Windows puhul <a class="reference external" href="https://www.gpg4win.org/thanks-for-download.html">GPG4Win</a></p></li>
<li><p>Mac OS X puhul <a class="reference external" href="http://gpgtools.org/">GPG Suite</a></p></li>
<li><p>Linuxiliste puhul k&#245;ige lihtsam piirduda k&#228;surea t&#246;&#246;riistadega: apt install gpg2</p></li>
</ul>
<p>Paigalda Thunderbirdi pistikprogramm:</p>
<ul class="simple">
<li><p>Windows puhul ava peamen&#252;&#252;st Lisad ning paigalda Enigmail</p></li>
<li><p>Ubuntu, Debian puhul: apt install thunderbird-enigmail</p></li>
<li><p>Fedora, Red Hat puhul: dnf install thunderbird-enigmail</p></li>
</ul>
<p>Pikemas perspektiivis otstarbekas hankida riistvaraline seade v&#245;tmete hoiustamiseks a'la Yubikey,
selle kohta leiab juhendi
<a class="reference external" href="/2017/03/yubikey-for-gpg.html">siitsamast blogist</a>.</p>
</div>
<div class="section" id="kuidas-taiesti-oma-postkast-teha">
<h1>Kuidas t&#228;iesti oma postkast teha</h1>
<p>Tehtav kui on juba kuskil avalikus internetis tiksumas m&#245;ni Linuxiga arvuti,
nt <a class="reference external" href="https://www.zone.ee/et/teenus/pilveserver/">Zone pilveserver</a> (~10&#8364;/kuu),
<a class="reference external" href="https://www.digitalocean.com/pricing/">DigitalOcean virtuaalmasin</a> (5USD/kuu).
&#213;iged h&#228;kkerid on v&#228;hemalt kord elus k&#228;ima pannud
Linuxi serveri oma koduse ruuteri taha, selle jaoks piisab SMTP ja IMAP portide ringi suunamisest (port forward),
hea oleks kui on staatiline IP aadressiga interneti&#252;hendus (~6&#8364;/kuu).</p>
<p>Lisaks on vaja registreerida domeen (~8-9&#8364; aastas).
Domeeni registrari DNS serverisse lisa <a class="reference external" href="https://en.wikipedia.org/wiki/MX_record">MX kirje</a> mis &#252;tleb missugune masin
sinu domeeni e-posti teenindab ning
<a class="reference external" href="https://en.wikipedia.org/wiki/Sender_Policy_Framework">SPF kirje</a>,
et teised kirju vastu v&#245;tvad serverid oskaks kindlaks teha,
et sinu domeeniga saadetud kirjad t&#245;epoolest sinu serverist p&#228;rinevad.</p>
<p>Paigalda ning seadista <a class="reference external" href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-postfix-e-mail-server-with-dovecot">Postfix ja Dovecot</a>.
Seadista Postfixi jaoks sp&#228;mmifiltrid a'la <a class="reference external" href="https://www.spamhaus.org/">Spamhaus</a>.
Seadista TLS sertifikaadid <a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a> abil,
et sinu serverisse kirju &#252;ldse saaks saata &#252;le turvatud kanali.</p>
<p>Kui sul on juba olemas domeenikontroller (Microsoft Active Directory v&#245;i Samba 4.x)
liida e-posti server domeeni
<a class="reference external" href="https://www.freedesktop.org/software/realmd/docs/guide-active-directory-join.html">realmd</a> abil, vastasel korral
loo kohalikud kasutajakontod kes postkasti kasutada saavad.</p>
<p>Kui &#252;ksi teha tundub &#252;le m&#245;istuse ehk oleks vaja luua kommuun s&#228;&#228;rase teenuse jaoks a'la
nagu rootslastel on <a class="reference external" href="https://fripost.org/">Fripost</a>.</p>
<p>Kui oma postkasti ei julge teha siis uuri <a class="reference external" href="https://protonmail.com/">Protonmail</a> teenuse kohta.</p>
</div>
</div>
]]></content>
    
    <category term="Interneti Päev 2017"/>
    <category term="Krüptopidu"/>
    <updated>2017-03-30T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>LEDE on Comfast E380AC</title>
    <summary>Comfast E380AC is a pretty neat 802.11ac capable AP sold on AliExpress
that comes Atheros chipsets and 48V POE support.</summary>
    <link href="http://lauri.vosandi.com/2017/03/comfast-e380ac.html"/>
    <content type="html"><![CDATA[<div class="document" id="lede-on-comfast-e380ac">
<!-- date: 2017-03-22 -->
<!-- tags: OpenWrt, LEDE, Comfast, POE, 802.11ac, WiFi -->
<div class="section" id="introduction">
<h1>Introduction</h1>
<p>Comfast E380AC is a pretty neat 802.11ac capable AP sold on AliExpress
that comes Atheros chipsets and 48V POE support.</p>
<div class="figure">
<img alt="https://sc01.alicdn.com/kf/HTB1UbNFLpXXXXcyXVXX760XFXXX7/201681808/HTB1UbNFLpXXXXcyXVXX760XFXXX7.png" src="/cache/sc01.alicdn.com/kf/HTB1UbNFLpXXXXcyXVXX760XFXXX7/201681808/HTB1UbNFLpXXXXcyXVXX760XFXXX7.png"/>
<p class="caption">Comfast E380AC</p>
</div>
<p>Right now the price is around 110&#8364; VAT inclusive.
OpenWrt builds for this device are not available yet,
but LEDE (OpenWrt fork) has stable build for this device.</p>
</div>
<div class="section" id="installing-third-party-firmware">
<h1>Installing third-party firmware</h1>
<p>To install LEDE on the device hold reset button while powering up the device.
Device boots into recovery mode where firmware can be overwritten.
Assign static IP address to your laptop, eg 192.168.1.2 and upload
the firmware:</p>
<pre class="code bash literal-block"><code>wget https://downloads.lede-project.org/releases/17.01.0/targets/ar71xx/generic/lede-17.01.0-r3205-59508e3-ar71xx-generic-cf-e380ac-v2-squashfs-sysupgrade.bin
curl -F <span class="nv">firmware</span><span class="o">=</span>@lede-17.01.0-r3205-59508e3-ar71xx-generic-cf-e380ac-v2-squashfs-sysupgrade.bin <span class="m">192</span>.168.1.1</code></pre>
<p>Alternatively original firmware can be booted up and
third party firmware can also be loaded via the regular web interface
as firmware upgrade.</p>
</div>
<div class="section" id="configuring-firmware">
<h1>Configuring firmware</h1>
<p>Current LEDE release configures the only ethernet port as LAN interface
meaning there is DHCP server running.
To make the device work actually like a access point we need to tweak the configuration a little bit.
Connect to the command line via ssh:</p>
<pre class="code bash literal-block"><code>ssh root@192.168.1.1</code></pre>
<p>Apply following configuration:</p>
<pre class="code bash literal-block"><code><span class="c1"># Disable DHCP server(s)
</span>/etc/init.d/dnsmasq stop
/etc/init.d/dnsmasq disable
/etc/init.d/odhcpd stop
/etc/init.d/odhcpd disable

<span class="c1"># AP gets IP address via DHCP
</span>uci <span class="nb">set</span> network.lan.proto<span class="o">=</span>dhcp
uci delete network.lan.ipaddr
uci delete network.lan.netmask
uci delete network.lan.ip6assign

<span class="c1"># Remove firewall rules since AP bridges ethernet to wireless anyway
</span>uci delete firewall.@zone<span class="o">[</span><span class="m">1</span><span class="o">]</span>
uci delete firewall.@zone<span class="o">[</span><span class="m">0</span><span class="o">]</span>
uci delete firewall.@forwarding<span class="o">[</span><span class="m">0</span><span class="o">]</span>
<span class="k">for</span> j in <span class="k">$(</span>seq <span class="m">0</span> <span class="m">10</span><span class="k">)</span><span class="p">;</span> <span class="k">do</span> uci delete firewall.@rule<span class="o">[</span><span class="m">0</span><span class="o">]</span><span class="p">;</span> <span class="k">done</span>

<span class="c1"># Set unique hostname
</span>uci <span class="nb">set</span> system.@system<span class="o">[</span><span class="m">0</span><span class="o">]</span>.hostname<span class="o">=</span>comfast-<span class="k">$(</span>cat /sys/class/net/eth0/address <span class="p">|</span> cut -d : -f <span class="m">4</span>- <span class="p">|</span> sed -e <span class="s1">'s/://g'</span><span class="k">)</span>
uci <span class="nb">set</span> network.lan.hostname<span class="o">=</span><span class="k">$(</span>uci get system.@system<span class="o">[</span><span class="m">0</span><span class="o">]</span>.hostname<span class="k">)</span>

<span class="c1"># Reconfigure 2.4GHz and 5GHz radios
</span><span class="k">for</span> i in <span class="m">0</span> <span class="m">1</span><span class="p">;</span> <span class="k">do</span>
  uci delete wireless.radio<span class="nv">$i</span>.disabled
  uci <span class="nb">set</span> wireless.default_radio<span class="nv">$i</span>.encryption<span class="o">=</span>psk2+ccmp
  uci <span class="nb">set</span> wireless.default_radio<span class="nv">$i</span>.ssid<span class="o">=</span>Akvaarium
  uci <span class="nb">set</span> wireless.default_radio<span class="nv">$i</span>.key<span class="o">=</span>salakala
<span class="k">done</span>

<span class="c1"># Save changes and reboot
</span>uci commit
reboot</code></pre>
<p>OpenWrt/LEDE image builder can be used to generate custom firmware
which already incorporates your network SSID and pre-shared key
so post-installation tweaking is not necessary.</p>
</div>
<div class="section" id="summary">
<h1>Summary</h1>
<p>After reboot the wireless network should be visible.
With Google Nexus 5X at 5GHz band throughput between 400MBps-500MBps was
benchmarked with <a class="reference external" href="http://speedtest.net">Speedtest.net</a>.
Considering that on-board QCA9880 has 3 spatial streams,
throughput between 600MBps-750MBps should be possible with fancier client devices.
For this price Comfast E380AC has very good open-source third party firmware support,
and proves again that picking device based on the chipset yields good results.</p>
</div>
</div>
]]></content>
    
    <category term="POE"/>
    <category term="802.11ac"/>
    <category term="LEDE"/>
    <category term="OpenWrt"/>
    <category term="WiFi"/>
    <category term="Comfast"/>
    <updated>2017-03-22T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>FreeBSD 11.0 for Ubuntu users</title>
    <summary>I tried to boot regular FreeBSD ISO as described in some older versions
of documentation, for FreeBSD 11.0 none of them worked as expected -
kernel gets booted but when it wishes to mount root filesystem that never works.</summary>
    <link href="http://lauri.vosandi.com/2017/03/freebsd-pxe-install.html"/>
    <content type="html"><![CDATA[<div class="document" id="freebsd-11-0-for-ubuntu-users">
<!-- date: 2017-03-20 -->
<!-- tags: FreeBSD, Ubuntu, Samba, LTSP, PXE, X11, PulseAudio -->
<div class="section" id="intalling-from-pxe">
<h1>Intalling from PXE</h1>
<p>I tried to boot regular FreeBSD ISO as described in some older versions
of documentation, for FreeBSD 11.0 none of them worked as expected -
kernel gets booted but when it wishes to mount root filesystem that never works.</p>
<p>Instead I resorted to downloading another version which is completely loaded to memory:</p>
<pre class="code bash literal-block"><code>wget http://mfsbsd.vx.sk/files/iso/11/amd64/mfsbsd-se-11.0-RELEASE-amd64.iso <span class="se">\
</span>    -O /var/lib/tftpboot/mfsbsd-se-11.0-RELEASE-amd64.iso</code></pre>
<p>Create following entry at your PXE host:</p>
<pre class="code bash literal-block"><code>label freebsd110
menu label FreeBSD <span class="m">11</span>.0
keeppxe
linux memdisk
initrd mfsbsd-se-11.0-RELEASE-amd64.iso
append iso raw</code></pre>
<p>Boot the machine from PXE and let it start up, once started up log in with <strong>root</strong> and <strong>mfsroot</strong>.</p>
<p>Use following command to figure out what is the /dev/blah corresponding to  your disk:</p>
<pre class="code bash literal-block"><code>geom disk list</code></pre>
<p>In my case the disk was at /dev/da0 exposed via SAS HBA, to perform install using ZFS filesystem:</p>
<pre class="code bash literal-block"><code>zfsinstall -d /dev/da0</code></pre>
</div>
<div class="section" id="post-installation-steps">
<h1>Post installation steps</h1>
<p>Log in with root, no password should be prompted.
Change password for user root:</p>
<pre class="code bash literal-block"><code>passwd</code></pre>
<p>Set hostname:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="nv">hostname</span><span class="o">=</span>bsd.example.lan &gt;&gt; /etc/rc.conf</code></pre>
<p>List network interfaces:</p>
<pre class="code bash literal-block"><code>ifconfig</code></pre>
<p>Acquire IP address for one of the interfaces, in my case bce0 was the interface:</p>
<pre class="code bash literal-block"><code>dhclient -v bce0
<span class="nb">echo</span> <span class="s1">'ifconfig_bce0="DHCP"'</span> &gt;&gt; /etc/rc.conf</code></pre>
<p>Install OpenSSH server:</p>
<pre class="code bash literal-block"><code>pkg install openssh</code></pre>
<p>Note that <strong>pkg install</strong> is basically equivalent to <strong>apt install</strong> or <strong>yum install</strong>.
Ports is somewhat like Portage in Gentoo and AUR in ArchLinux.</p>
<p>Enable familiar /proc:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"proc /proc procfs rw,auto 0 0"</span> &gt;&gt; /etc/fstab
mount /proc</code></pre>
<p>Add SSD as read cache device:</p>
<pre class="code bash literal-block"><code>zpool add tank cache da1</code></pre>
<p>Add another SSD as write log, this speeds up synchronous writes to the pool:</p>
<pre class="code bash literal-block"><code>zpool add tank log da2</code></pre>
<p>Enable online block-level deduplication on the ZFS pool:</p>
<pre class="code bash literal-block"><code>zfs <span class="nb">set</span> <span class="nv">dedup</span><span class="o">=</span>on tank</code></pre>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>Enabling deduplication later will only affect newly written data, also you should plan for at least 20GB of system RAM per TB of pool data</p>
</div>
<p>To monitor usage:</p>
<pre class="code bash literal-block"><code>zpool list -v <span class="m">2</span> <span class="c1"># Press Ctrl-C to stop</span></code></pre>
<p>Monitor harddisks</p>
<pre class="code bash literal-block"><code>pkg install smartmontools
/usr/local/sbin/smartctl -a /dev/da0</code></pre>
</div>
<div class="section" id="joining-ad-domain">
<h1>Joining AD domain</h1>
<p>There is no realmd so some steps have to be done manually.</p>
<p>Install Samba 4.4 software suite:</p>
<pre class="code bash literal-block"><code>pkg install samba44</code></pre>
<p>Edit /usr/local/etc/smb4.conf, most notably there is no <strong>nogroup</strong> group,
instead it's <strong>nobody</strong>:</p>
<pre class="code ini literal-block"><code><span class="k">[global]</span>
<span class="na">invalid users</span> <span class="o">=</span> <span class="s">administrator root krbtgt guest</span>
<span class="na">security</span> <span class="o">=</span> <span class="s">ads</span>
<span class="na">netbios name</span> <span class="o">=</span> <span class="s">BSD</span>
<span class="na">workgroup</span> <span class="o">=</span> <span class="s">EXAMPLE</span>
<span class="na">realm</span> <span class="o">=</span> <span class="s">EXAMPLE.LAN</span>

<span class="na">kerberos method</span> <span class="o">=</span> <span class="s">system keytab</span>
<span class="na">winbind trusted domains only</span> <span class="o">=</span> <span class="s">no</span>
<span class="na">winbind use default domain</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">winbind refresh tickets</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">winbind enum users</span>  <span class="o">=</span> <span class="s">yes</span>
<span class="na">winbind enum groups</span> <span class="o">=</span> <span class="s">yes</span>

<span class="na">map acl inherit</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">store dos attributes</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">template homedir</span> <span class="o">=</span> <span class="s">/home/%U</span>
<span class="na">template shell</span> <span class="o">=</span> <span class="s">/bin/bash</span>
<span class="na">idmap config *:backend</span> <span class="o">=</span> <span class="s">rid</span>
<span class="na">allow dns updates</span> <span class="o">=</span> <span class="s">disabled</span>
<span class="na">idmap config *:range</span> <span class="o">=</span> <span class="s">1000000-16777216</span>

<span class="k">[shared]</span>
<span class="na">path</span> <span class="o">=</span> <span class="s">/home/shared</span>
<span class="na">writable</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">guest ok</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">writable</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">force user</span> <span class="o">=</span> <span class="s">nobody</span>
<span class="na">force group</span> <span class="o">=</span> <span class="s">nobody</span>
<span class="na">create mask</span> <span class="o">=</span> <span class="s">0666</span>
<span class="na">directory mask</span> <span class="o">=</span> <span class="s">2777</span></code></pre>
<p>Authenticate with domain administrator account:</p>
<pre class="code bash literal-block"><code>kinit administrator@EXAMPLE.COM</code></pre>
<p>Proceed to join domain:</p>
<pre class="code bash literal-block"><code>net ads join -k</code></pre>
<p>Start the service:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt;&gt; /etc/rc.conf
samba_server_enable="YES"
smbd_enable="YES"
nmbd_enable="YES"
winbindd_enable="YES"
EOF</span>
service samba_server restart</code></pre>
<p>Reconfigure user lookup:</p>
<pre class="code bash literal-block"><code>sed -i -e <span class="s2">"s/^passwd_compat:.*/passwd: compat winbind/"</span> /etc/nsswitch.conf
sed -i -e <span class="s2">"s/^group_compat:.*/group: compat winbind/"</span> /etc/nsswitch.conf</code></pre>
<p>This should suffice to be used as fileserver,
if you need SSH login for AD accounts tweaking /etc/pam.d/sshd is necessary.</p>
</div>
<div class="section" id="running-mate-desktop-session-over-ssh">
<h1>Running MATE desktop session over SSH</h1>
<p>On the FreeBSD server:</p>
<pre class="code bash literal-block"><code>pkg install mate-desktop mate xauth <span class="se">\
</span>  firefox pulseaudio vlc mpv <span class="se">\
</span>  pavucontrol paratype virt-manager</code></pre>
<p>On a local Ubuntu or Fedora machine:</p>
<pre class="code bash literal-block"><code>Xephyr -resizeable :1 <span class="p">&amp;</span>
<span class="nv">DISPLAY</span><span class="o">=</span>:1 ssh -X username@bsd.example.lan mate-session</code></pre>
</div>
<div class="section" id="using-freebsd-as-ltsp-server">
<h1>Using FreeBSD as LTSP server</h1>
<p>FreeBSD has SSH and desktop applications are compiled with X11 support
as you would expect on any other Ubuntu machine such as LTSP server.
Firefox package for FreeBSD even includes PulseAudio support so audio works.
VLC and mpv unfortunately come without PulseAudio support.</p>
<p>Tricky part is that there is no ldminfod package available for FreeBSD
which is serving the list of languages and desktop sessions available on the
server. But we can easily emulate that behaviour.</p>
<p>On your FreeBSD box append into your /etc/inetd.conf:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> ldminfo <span class="m">9571</span>/tcp &gt;&gt; /etc/services
ldminfo     stream  tcp     nowait  nobody  /usr/libexec/tcpd       /bin/cat /etc/ldminfo</code></pre>
<p>You can extract current configuration from the LTSP server and store it to be served by internet superserver:</p>
<pre class="code bash literal-block"><code>telnet ltsp.example.lan <span class="m">9571</span> &gt; /etc/ldminfo</code></pre>
<p>Edit /etc/ldminfo, in this case following was the result:</p>
<pre class="code bash literal-block"><code>language:et_EE.UTF-8
session:mate-session
session-with-name:MATE:mate-session
xsession:/etc/X11/Xsession
rating:99</code></pre>
<p>Create very basic /etc/X11/Xsession:</p>
<pre class="code bash literal-block"><code><span class="ch">#!/bin/sh
</span>
<span class="c1"># redirect errors to a file in user's home directory if we can
</span><span class="nv">errfile</span><span class="o">=</span><span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/.xsession-errors"</span>
<span class="k">if</span> <span class="o">(</span> <span class="nb">umask</span> <span class="m">077</span> <span class="o">&amp;&amp;</span> cp /dev/null <span class="s2">"</span><span class="nv">$errfile</span><span class="s2">"</span> <span class="m">2</span>&gt; /dev/null <span class="o">)</span>
<span class="k">then</span>
        <span class="nb">exec</span> &gt; <span class="s2">"</span><span class="nv">$errfile</span><span class="s2">"</span> <span class="m">2</span>&gt;<span class="p">&amp;</span><span class="m">1</span>
<span class="k">else</span>
        <span class="nv">mktemp</span><span class="o">=</span>/usr/bin/mktemp
        <span class="k">for</span> errfile in <span class="s2">"</span><span class="si">${</span><span class="nv">TMPDIR</span><span class="p">-/tmp</span><span class="si">}</span><span class="s2">/xses-</span><span class="nv">$USER</span><span class="s2">"</span> <span class="s2">"/tmp/xses-</span><span class="nv">$USER</span><span class="s2">"</span>
        <span class="k">do</span>
                <span class="k">if</span> <span class="nv">ef</span><span class="o">=</span><span class="s2">"</span><span class="k">$(</span> <span class="nb">umask</span> <span class="m">077</span> <span class="o">&amp;&amp;</span> <span class="nv">$mktemp</span> <span class="s2">"</span><span class="nv">$errfile</span><span class="s2">.XXXXXX"</span> <span class="m">2</span>&gt; /dev/null<span class="k">)</span><span class="s2">"</span>
                <span class="k">then</span>
                        <span class="nb">exec</span> &gt; <span class="s2">"</span><span class="nv">$ef</span><span class="s2">"</span> <span class="m">2</span>&gt;<span class="p">&amp;</span><span class="m">1</span>
                        mv <span class="s2">"</span><span class="nv">$ef</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$errfile</span><span class="s2">"</span> <span class="m">2</span>&gt; /dev/null
                        <span class="nb">break</span>
                <span class="k">fi</span>
        <span class="k">done</span>
<span class="k">fi</span>

<span class="nb">exec</span> /usr/local/bin/mate-session

<span class="c1"># The startup script is not intended to have arguments.
</span><span class="nv">startup</span><span class="o">=</span><span class="nv">$HOME</span>/.xsession
<span class="nv">resources</span><span class="o">=</span><span class="nv">$HOME</span>/.Xresources
<span class="k">if</span> <span class="o">[</span> -s <span class="s2">"</span><span class="nv">$startup</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
        <span class="k">if</span> <span class="o">[</span> -x <span class="s2">"</span><span class="nv">$startup</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
                <span class="nb">exec</span> <span class="s2">"</span><span class="nv">$startup</span><span class="s2">"</span>
        <span class="k">else</span>
                <span class="nb">exec</span> /bin/sh <span class="s2">"</span><span class="nv">$startup</span><span class="s2">"</span>
        <span class="k">fi</span>
<span class="k">else</span>
        <span class="k">if</span> <span class="o">[</span> -r <span class="s2">"</span><span class="nv">$resources</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
                /usr/local/bin/xrdb -load <span class="s2">"</span><span class="nv">$resources</span><span class="s2">"</span>
        <span class="k">fi</span>
        <span class="nb">exec</span> /usr/local/bin/xsm
<span class="k">fi</span></code></pre>
<p>Start internet superserver:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="nv">inetd_enable</span><span class="o">=</span>yes &gt;&gt; /etc/rc.conf
service inetd start</code></pre>
<p>In your lts.conf usually located at /var/lib/tftpboot/ltsp/lts.conf
add additional LTSP servers like this:</p>
<pre class="code bash literal-block"><code><span class="nv">LDM_SERVER</span><span class="o">=</span>bsd.example.lan ltsp.example.lan</code></pre>
<p>Additionally FreeBSD password prompt is slightly different from Ubuntu's,
so LDM which is trying to log in on behalf of the user goes nuts.
Again we can fix that easily by modifying /etc/pam.d/sshd on the FreeBSD box:</p>
<pre class="code bash literal-block"><code>sed -E -e <span class="s1">'s/^auth[[:space:]]+required[[:space:]]+pam_unix.so[[:space:]]+.*/auth required pam_unix.so no_warn try_first_pass authtok_prompt=Enter\ password,\ please:\\ /'</span> -i.bak /etc/pam.d/sshd</code></pre>
<!-- comment: http://bazaar.launchpad.net/~ltsp-upstream/ltsp/ldm-trunk/view/head:/src/plugins/ssh/ssh.c#L423 -->
<p>Over at your LTSP server add additional SSH server keys to LTSP client known hosts file:</p>
<pre class="code bash literal-block"><code>ssh-keyscan ltsp.example.lan bsd.example.lan <span class="p">|</span> tee /opt/ltsp/*/etc/ssh_known_hosts
ltsp-update-image</code></pre>
<p>Pics or it didn't happen:</p>
<div class="figure">
<img alt="img/freebsd-as-ltsp-server.png" src="/cache/ef3ae38bd7ea8d1d9d0502af9720b67a.png"/>
<p class="caption">LTSP client connected to FreeBSD 11.0 server</p>
</div>
</div>
</div>
]]></content>
    
    <category term="Ubuntu"/>
    <category term="LTSP"/>
    <category term="PXE"/>
    <category term="PulseAudio"/>
    <category term="FreeBSD"/>
    <category term="Samba"/>
    <category term="X11"/>
    <updated>2017-03-20T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Yubikey as hardware token for GPG</title>
    <summary>GPG is most often used to encrypt and sign e-mails
within software developer communities and cyberpunk circles.
You also find that GPG is used to verify packages when
you install software on your Ubuntu or Fedora box.
GPG keyring can also be used for authenticating SSH connections.</summary>
    <link href="http://lauri.vosandi.com/2017/03/yubikey-for-gpg.html"/>
    <content type="html"><![CDATA[<div class="document" id="yubikey-as-hardware-token-for-gpg">
<!-- date: 2017-03-19 -->
<!-- tags: SSH, GPG, Yubikey -->
<div class="section" id="introduction">
<h1>Introduction</h1>
<p>GPG is most often used to encrypt and sign e-mails
within software developer communities and cyberpunk circles.
You also find that GPG is used to verify packages when
you install software on your Ubuntu or Fedora box.
GPG keyring can also be used for authenticating SSH connections.</p>
<p>Yubikey 4 Nano is one of the tiniest OpenPGP compatible hardware tokens on the market.
With hardware token the your RSA private keys used by the GPG are not
readable in the filesystem as it would usually be under ~/.gnupg directory.</p>
<div class="figure">
<img alt="https://www.yubico.com/wp-content/uploads/2012/09/molded_nanos-1.png" src="/cache/www.yubico.com/wp-content/uploads/2012/09/molded_nanos-1.png"/>
<p class="caption">Yubikey 4 Nano can be left in the USB port without damaging the key or the port</p>
</div>
<p>Using GPG to send encrypted/signed e-mail can be done via variety
of applications each one coming with a different support level for hardware tokens such as Yubikey:</p>
<ul class="simple">
<li><p>Encrypting on command line as shown below works perfectly with Yubikey, but is cumbersome to use for newbies.</p></li>
<li><p>Evolution has full GPG support built-in on Fedora, supports hardware tokens such as Yubikey for signing and encrypting. Retrieving correspondent's keys and setting trust level still has to be performed on command-line as shown below.</p></li>
<li><p>Enigmail is a GPG plugin for Mozilla Thunderbird, supports hardware tokens, good user interface integration - untrusted senders key can easily be signed.</p></li>
<li><p>Mailvelope generates keys internally and currently can't make use of hardware token</p></li>
</ul>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>PIV and PGP modes can't be used simultaneously</p>
</div>
<p>scdaemon which is used by GPG as backend to access smartcards exclusively
locks the card even if configured to use PCSC-Lite as backend.
Firefox similarily wants to have exclusive access to the token
when there are valid certificates present in the PIV applet.
This means that currently PGP and PIV modes can't be used simultaneously.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>GPG has most often two versions installed: gpg and gpg2</p>
</div>
<p>Following guide focuses on gpg2 only. When gpg command happens to be
executed accidentally at wrong time gpg-agent could be started with
flags incompatible with gpg2, in that case kill gpg-agent process.</p>
</div>
<div class="section" id="setting-up-yubikey">
<h1>Setting up Yubikey</h1>
<p>Install GPG v2.x if it hasn't been installed yet:</p>
<pre class="code bash literal-block"><code>apt install gnupg2</code></pre>
<p>First check whether GPG detects your token:</p>
<pre class="code bash literal-block"><code>gpg2 --card-status</code></pre>
<p>If you have Estonian ID-card reader hooked up to the computer
you might have conflicts with web browsers, so it's a good idea to
tell GPG reader name:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; \EOF &gt;&gt; ~/.gnupg/scdaemon.conf
reader-port "Yubico Yubikey 4 CCID"
EOF</span></code></pre>
<p>Set up Yubikey, this is roughly equivalent to <strong>gpg2 --full-gen-key</strong>:</p>
<pre class="code bash literal-block"><code>gpg2 --card-edit
admin
generate</code></pre>
<p>Add identities, eg. when you use multiple e-mail addresses
or aliases and set the trust level to <cite>ultimate</cite> for all of your identities:</p>
<pre class="code bash literal-block"><code>gpg2 --edit-key first.last@example.com
adduid
trust</code></pre>
<p>Export your public keys and upload it to a HTTP(S) accessible URL:</p>
<pre class="code bash literal-block"><code>gpg2  --export --armor &gt; lauri.asc</code></pre>
</div>
<div class="section" id="adding-trusted-people">
<h1>Adding trusted people</h1>
<p>As the root of trust is your own key, everything that is to be
implicitly trusted has to be signed by yourself -
hence to trust someone you first need to retreive their public key:</p>
<pre class="code bash literal-block"><code>wget https://www.koodur.com/lauri.asc</code></pre>
<p>Import it to your keyring located in your home directory (~/.gnupg/keyring.kbx):</p>
<pre class="code bash literal-block"><code>gpg2 --import lauri.asc</code></pre>
<p>Verify that the 40-character fingerprint of the imported key matches
via other means eg. by giving a call via phone, meeting face to face or taking part of a keysigning party.
Finally sign the public key identified by e-mail address:</p>
<pre class="code bash literal-block"><code>gpg2 --sign-key lauri.vosandi@gmail.com</code></pre>
<p>Alternatively keys can be fetched and imported from publicly operated keyservers,
in that case 40-character key fingerprint and keyserver hostname is required.
For example in order to import key used to sign CERT-EE (RIA) e-mails following commands should suffice.
In this case pgp.mit.edu is keyserver operated by Massachusetts Institute of Technology:</p>
<pre class="code bash literal-block"><code>gpg2 --keyserver pgp.mit.edu --recv 48319D213649047F197EA9CD86C6D4D43601B6D1
gpg2 --sign-key cert@cert.ee</code></pre>
</div>
<div class="section" id="publishing-your-key">
<h1>Publishing your key</h1>
<p>Use following to list your keys, your key fingerprint is the 40-character
string just above your identities and e-mail addresses:</p>
<pre class="code bash literal-block"><code>gpg2 --list-keys</code></pre>
<p>Most commonly used keyservers can be found at
<a class="reference external" href="https://en.wikipedia.org/wiki/Key_server_(cryptographic)#Keyserver_examples">Wikipedia</a>.
To prevent key collision attacks it might be good idea to upload your key
to all of the listed servers there as it is very common that
users specify only last 8 digits of the fingerprint to import keys.</p>
<pre class="code bash literal-block"><code>gpg2 --keyserver pgp.mit.edu --send-key E1BC859AFC900AA925F1BAF33E1E3B1EE82AD8C0</code></pre>
</div>
<div class="section" id="encrypting-and-decrypting-arbitrary-files">
<h1>Encrypting and decrypting arbitrary files</h1>
<p>To encrypt a file you need to have recipient's public key in your keyring as shown above.
To encrypt a file and output it in ASCII armored format:</p>
<pre class="code bash literal-block"><code>gpg2 -r lauri@koodur.com -a -o encrypted.asc -e plain.txt</code></pre>
<p>To dump decrypted document on command line:</p>
<pre class="code bash literal-block"><code>gpg2 -d encrypted.asc</code></pre>
<p>To save it into a file:</p>
<pre class="code bash literal-block"><code>gpg2 -d encrypted.asc -o decrypted.txt</code></pre>
</div>
<div class="section" id="using-gpg-authentication-keypair-for-ssh">
<h1>Using GPG authentication keypair for SSH</h1>
<p>Following starts up GPG agent and exports SSH agent environment variables
for currently running shell:</p>
<pre class="code bash literal-block"><code><span class="nb">eval</span> <span class="sb">`</span>gpg-agent --daemon --enable-ssh-support<span class="sb">`</span></code></pre>
<p>To export public keys from the GPG applet on Yubikey in SSH format use following command,
you should see Yubikey keys with comment <cite>cardno: 000123456789</cite> where the
number is your Yubikey serial number:</p>
<pre class="code bash literal-block"><code>ssh-add -L</code></pre>
<p>As usual copy the public key to your server's ~/.ssh/authorized_keys.</p>
<p>When attempting to log into the server you're supposed to be prompted with a
graphical PIN code dialog.
Any subsequent login attempts in the same shell should proceed without having to ask for the PIN code.</p>
</div>
<div class="section" id="permanent-configuration-for-gpg-agent">
<h1>Permanent configuration for GPG agent</h1>
<p>It's very tricky to get this right.
Following was tested on Fedora 25.</p>
<p>GPG agent wants to show PIN dialog on demand so it has to get graphical
session environment variables right ($DISPLAY, $WAYLAND_DISPLAY etc).</p>
<p>Easiest way is to create autostart file:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; \EOF &gt; ~/.config/autostart/gpg-agent.desktop
[Desktop Entry]
Type=Application
Name=gpg-agent
Comment=Autostart GPG agent
Exec=/usr/bin/gpg-connect-agent /bye
Terminal=false
EOF</span></code></pre>
<p>Tell gpg-agent to export ssh-agent compatible socket:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; \EOF &gt;&gt; ~/.gnupg/gpg-agent.conf
enable-ssh-support
default-cache-ttl 90
ignore-cache-for-signing
EOF</span></code></pre>
<p>Override environment variables when terminal is opened:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; \EOF &gt;&gt; ~/.bashrc
unset SSH_AGENT_PID
export SSH_AUTH_SOCK="${XDG_RUNTIME_DIR}/gnupg/S.gpg-agent.ssh"
EOF</span></code></pre>
<p>Kill all the relevant processes, log out and log in again. When attempting
to ssh to a remote box PIN dialog should pop up.</p>
</div>
<div class="section" id="using-same-yubikey-on-another-computer">
<h1>Using same Yubikey on another computer</h1>
<p>Import your public keyring, eg in my case:</p>
<pre class="code bash literal-block"><code>gpg2 --keyserver pgp.mit.edu --recv-key E1BC859AFC900AA925F1BAF33E1E3B1EE82AD8C0</code></pre>
<p>On the first computer export secrets, in Yubikey case this should
export only stubs which tell GPG to look for the key on a hardware token:</p>
<pre class="code bash literal-block"><code>gpg2 --export-secret-keys -a -o secrets</code></pre>
<p>Copy the file to new machine:</p>
<pre class="code bash literal-block"><code>scp secrets new-machine:</code></pre>
<p>On the new machine:</p>
<pre class="code bash literal-block"><code>gpg2 --import secrets</code></pre>
</div>
</div>
]]></content>
    
    <category term="SSH"/>
    <category term="GPG"/>
    <category term="Yubikey"/>
    <updated>2017-03-19T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Yubikey as SSH and HTTPS client authentication token</title>
    <summary>On Ubuntu you might want to try to use PPA maintaned by folks at Yubikey.
On Fedora install following packages:</summary>
    <link href="http://lauri.vosandi.com/2017/03/yubikey-for-ssh-auth.html"/>
    <content type="html"><![CDATA[<div class="document" id="yubikey-as-ssh-and-https-client-authentication-token">
<!-- date: 2017-03-09 -->
<!-- tags: SSH, PKI, HTTPS, TLS, SSL, Yubikey, CCID, PKCS#11 -->
<p>On Ubuntu you might want to try to use PPA maintaned by folks at Yubikey.
On Fedora install following packages:</p>
<pre class="code bash literal-block"><code>yum install libykneomgr libu2f-host yubico-piv-tool
pip install yubikey-neo-manager</code></pre>
<p>To start Yubikey Neo Manager:</p>
<pre class="code bash literal-block"><code>neoman</code></pre>
<p>Disable OTP and U2F, otherwise touching Yubikey causes one time passwords to be typed.
Leaving CCID on provides still GPG and PKI applets.
In this example PKI token mode is explored.</p>
<div class="section" id="setting-up-key-pair">
<h1>Setting up key pair</h1>
<p>First let Yubikey generate the private key and dump the corresponding public
key to a file.</p>
<pre class="code bash literal-block"><code>yubico-piv-tool -s 9a -a generate -o pubkey.pem</code></pre>
<p>In case you have a Certifiate Authority set up and you want to use
Yubikey for HTTPS authentication create certificate signing request.
Send the resulting <span class="docutils literal">req.pem</span> to your CA administrator and wait for
signed certificate file, store it in <span class="docutils literal">cert.pem</span> and proceed with
certificate import below:</p>
<pre class="code bash literal-block"><code>yubico-piv-tool -s 9a -a verify -a request <span class="se">\
</span>  -S /CN<span class="o">=</span><span class="nv">$USER</span> <span class="se">\
</span>  -i pubkey.pem <span class="se">\
</span>  -o req.pem</code></pre>
<p>In case you're not operating CA or you're only interested in using
Yubikey for SSH authentication sign the public key with the same private key and PIN code (default 123456),
this is just to satisfy the quirks of the device used as PKI token even
though SSH doesn't care about certificates in that sense:</p>
<pre class="code bash literal-block"><code>yubico-piv-tool -a verify-pin -a selfsign-certificate -s 9a -S <span class="s2">"/CN=SSH key/"</span> -i public.pem -o cert.pem</code></pre>
<p>Finally import the signed certificate back to Yubikey:</p>
<pre class="code bash literal-block"><code>yubico-piv-tool -a import-certificate -s 9a -i cert.pem</code></pre>
<p>Now check the status of your Yubikey:</p>
<pre class="code bash literal-block"><code>yubico-piv-tool -a status</code></pre>
</div>
<div class="section" id="setting-up-ssh">
<h1>Setting up SSH</h1>
<p>Extract public keys on the Yubikey in the SSH format:</p>
<pre class="code bash literal-block"><code>ssh-keygen -D opensc-pkcs11.so -e</code></pre>
<p>Copy the public key and paste it to server's ~/.ssh/authorized_keys file.</p>
<p>Test logging in with following, the default PIN is 123456:</p>
<pre class="code bash literal-block"><code>ssh -I opensc-pkcs11.so username@hostname</code></pre>
</div>
<div class="section" id="setting-up-ssh-agent">
<h1>Setting up SSH agent</h1>
<p>Getting SSH agent to work is a bit tricky because ssh-agent
wants to set up some environment variables used by <cite>ssh-agent</cite>,
so far the easiest way to achieve it is this:</p>
<pre class="code bash literal-block"><code><span class="nb">eval</span> <span class="sb">`</span>ssh-agent -s<span class="sb">`</span>
ssh-add -s /usr/lib64/opensc-pkcs11.so</code></pre>
<p>To make it sort-of permanent add an alias into your shell configuration:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; \EOF &gt;&gt; ~/.bashrc
alias y='eval `ssh-agent -s`; ssh-add -s /usr/lib64/opensc-pkcs11.so'
EOF</span></code></pre>
<p>Spawn a new shell session and use alias <cite>y</cite> to load keys and enter PIN code for
the hardware token.</p>
</div>
<div class="section" id="setting-up-web-browser">
<h1>Setting up web browser</h1>
<p>Assuming all packages have been installed no configuration should be necessary.
When accessing properly configured web server where client validation is required
the browser should automatically try to offer certificate stored on Yubikey,
just enter pin code to unlock the token:</p>
<div class="figure">
<img alt="img/firefox-pin-dialog.png" src="/cache/75892bc6eed386de61179b8bfcc57789.png"/>
<p class="caption">Enter pin code to unlock authentication certificate, default pin is 123456</p>
</div>
<p>If multiple certificates can be offered certificate selection is prompted:</p>
<div class="figure">
<img alt="img/firefox-certificate-selection.png" src="/cache/559451010e2e2b2dc04e42fbd1b3644a.png"/>
<p class="caption">Select which certificate should be presented for TLS handshake</p>
</div>
</div>
<div class="section" id="conclusion">
<h1>Conclusion</h1>
<p>Using Yubikey reduces the risk of leaking private RSA keys from your
computer via malware or losing access to servers when ransomware hits your computer.
If keylogger happens to be installed PIN codes can easily be captured and recognized,
so if token happens to be lost corresponding certificates should still be immideately revoked and
public keys removed from SSH server (s).
If attacker has gained access to a computer where Yubikey is used
he can still from there on hop to the servers accessible using the key
without having physical access to the key assuming
that knowledge about the PIN code has been gained or ssh-agent is used.</p>
<p>Also Yubikey has tool for managing the PKI applet, might become handy:</p>
<pre class="code bash literal-block"><code>pip install yubikey-piv-manager
pivman</code></pre>
</div>
</div>
]]></content>
    
    <category term="HTTPS"/>
    <category term="PKCS#11"/>
    <category term="PKI"/>
    <category term="TLS"/>
    <category term="SSL"/>
    <category term="SSH"/>
    <category term="Yubikey"/>
    <category term="CCID"/>
    <updated>2017-03-09T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Samba fileserver</title>
    <summary><a class="reference external" href="https://en.wikipedia.org/wiki/Server_Message_Block">CIFS</a>
(common internet filesystem) is the official name of the fileserver protocol
used by Windows filesharing subsystem.
It's very similar to <a class="reference external" href="https://en.wikipedia.org/wiki/Network_File_System">NFS</a>
(network filesystem) developed by Sun which is commonly
found in UNIX-based systems.
<a class="reference external" href="https://wiki.samba.org/">Samba</a> software suite provides CIFS support
for UNIX-like systems such as Linux and Mac OS X.</summary>
    <link href="http://lauri.vosandi.com/2017/03/samba-fileserver.html"/>
    <content type="html"><![CDATA[<div class="document" id="samba-fileserver">
<!-- date: 2017-03-06 -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags: CIFS, SMB, Samba, NFS, Kerberos -->
<div class="section" id="introduction">
<h1>Introduction</h1>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Server_Message_Block">CIFS</a>
(common internet filesystem) is the official name of the fileserver protocol
used by Windows filesharing subsystem.
It's very similar to <a class="reference external" href="https://en.wikipedia.org/wiki/Network_File_System">NFS</a>
(network filesystem) developed by Sun which is commonly
found in UNIX-based systems.
<a class="reference external" href="https://wiki.samba.org/">Samba</a> software suite provides CIFS support
for UNIX-like systems such as Linux and Mac OS X.</p>
<p>CIFS can make use of Kerberos protocol for authentication when
used in conjunction with a domain controller software such as
Active Directory or with another Samba instance configured to work as
domain controller.</p>
<p>In this tutorial Samba fileserver setup on Ubuntu 16.04 and Fedora 25 is outlined.</p>
</div>
<div class="section" id="setting-up-anonymous-shares">
<h1>Setting up anonymous shares</h1>
<p>In this case no Kerberos or Active Directory is involved.
The fileserver becomes local master for the Network Neighbourhood search
and advertises WORKGROUP named workgroup, this is NetBIOS name lookup and
it's pretty much specific to Windows only because modern name lookup is done with DNS.
Share accesses are not authenticated (guest),
file and directory creation modes are overridden and
filesystem interactions on the server are mapped to local user <span class="docutils literal">nobody</span> and group <span class="docutils literal">nogroup</span>,
note that on Fedora there is no group <span class="docutils literal">nogroup</span>, use <span class="docutils literal">nobody</span> instead.</p>
<p>First install software packages:</p>
<pre class="code bash literal-block"><code>apt install samba <span class="c1"># Debian/Ubuntu
</span>dnf install samba <span class="c1"># Fedora</span></code></pre>
<p>Create configuration file /etc/samba/smb.conf:</p>
<pre class="code ini literal-block"><code><span class="k">[global]</span>
<span class="na">workgroup</span> <span class="o">=</span> <span class="s">WORKGROUP</span>
<span class="na">netbios name</span> <span class="o">=</span> <span class="s">CUBIETRUCK</span>
<span class="na">server string</span> <span class="o">=</span> <span class="s">1TB WD storage</span>
<span class="na">map to guest</span> <span class="o">=</span> <span class="s">Bad User</span>
<span class="na">guest account</span> <span class="o">=</span> <span class="s">nobody</span>

<span class="k">[shared]</span>
<span class="na">comment</span> <span class="o">=</span> <span class="s">Shared folder for anonymous users</span>
<span class="na">path</span> <span class="o">=</span> <span class="s">/home/shared</span>
<span class="na">guest ok</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">writable</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">force user</span> <span class="o">=</span> <span class="s">nobody</span>
<span class="na">force group</span> <span class="o">=</span> <span class="s">nogroup</span>
<span class="na">create mask</span> <span class="o">=</span> <span class="s">0666</span>
<span class="na">directory mask</span> <span class="o">=</span> <span class="s">2777</span></code></pre>
<p>Create the directory:</p>
<pre class="code bash literal-block"><code>mkdir -p /home/shared
chmod <span class="m">777</span> /home/shared
chcon -t samba_share_t /home/shared <span class="c1"># Change SELinux policy on Fedora</span></code></pre>
<p>Restart service:</p>
<pre class="code bash literal-block"><code>systemctl restart smbd nmbd <span class="c1"># Ubuntu, Debian
</span>systemctl restart smb nmb <span class="c1"># Fedora</span></code></pre>
<p>Enable for next boot:</p>
<pre class="code bash literal-block"><code>systemctl <span class="nb">enable</span> smbd nmbd <span class="c1"># Ubuntu, Debian
</span>systemctl <span class="nb">enable</span> smb nmb <span class="c1"># Fedora</span></code></pre>
<p>This should be suitable where the network is trusted and no access control is
enforced, for example home network or small office.</p>
<p>Note that on Fedora firewalld will probably block all incoming traffic.
In case you're running Samba on a workstation, open up Wired Settings -&gt; Identity -&gt; Firewall zone and
select Trusted for interfaces you want to allow access to fileserver.
Alternatively if there is only one network interface on the machine you could
disable firewall altogether:</p>
<pre class="code bash literal-block"><code>systemctl stop firewalld
systemctl disable firewalld</code></pre>
</div>
<div class="section" id="fileserver-as-domain-member">
<h1>Fileserver as domain member</h1>
<p>In this case users accessing the shares are identified by
Kerberos credentials eg. when accessing from domain computers.
If Kerberos credentials are not available fallback to NTLM is provided and
username and password is prompted upon network share access.</p>
<p>First install software components:</p>
<pre class="code bash literal-block"><code>apt install packagekit samba samba-vfs-modules krb5-user <span class="se">\
</span>  realmd libnss-winbind libpam-winbind</code></pre>
<p>Create /etc/realmd.conf, this will tell realmd to make use of winbind when
joining the domain. Also it switches off fully qualified usernames (<a class="reference external" href="mailto:username@realm">username@realm</a>)
and use the short ones instead (username), this of course assumes no
local user accounts will be created:</p>
<pre class="code bash literal-block"><code><span class="o">[</span>active-directory<span class="o">]</span>
default-client <span class="o">=</span> winbind

<span class="o">[</span>users<span class="o">]</span>
default-home<span class="o">=</span>/home/%U

<span class="o">[</span>office.lan<span class="o">]</span>
default-shell<span class="o">=</span>/bin/bash
fully-qualified-names<span class="o">=</span>no</code></pre>
<p>Join the machine to domain, this will do several things:
create /etc/krb5.keytab, generate /etc/samba/smb.conf,
reconfigure PAM modules,
create machine account in the domain controller,
create host principal in the domain controller and
add DNS record for the fully qualified hostname:</p>
<pre class="code bash literal-block"><code>realm join office.lan -U administrator</code></pre>
<p>Reconfigure /etc/samba/smb.conf, keep <cite>netbios name</cite>, <cite>workgroup</cite> and <cite>realm</cite>
as the ones generated by <cite>realm join</cite>:</p>
<pre class="code ini literal-block"><code><span class="k">[global]</span>
<span class="c1"># Server operates as domain member server</span>
<span class="na">security</span> <span class="o">=</span> <span class="s">ads</span>
<span class="na">netbios name</span> <span class="o">=</span> <span class="s">DEV</span>
<span class="na">workgroup</span> <span class="o">=</span> <span class="s">OFFICE</span>
<span class="na">realm</span> <span class="o">=</span> <span class="s">OFFICE.LAN</span>
<span class="na">kerberos method</span> <span class="o">=</span> <span class="s">system keytab</span>
<span class="na">winbind trusted domains only</span> <span class="o">=</span> <span class="s">no</span>
<span class="na">winbind use default domain</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">winbind refresh tickets</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">winbind enum users</span>  <span class="o">=</span> <span class="s">yes</span>
<span class="na">winbind enum groups</span> <span class="o">=</span> <span class="s">yes</span>

<span class="c1"># Bind nmbd, smbd services on certain interface, eg when others go to WAN</span>
<span class="na">interfaces</span> <span class="o">=</span> <span class="s">ens3</span>
<span class="na">bind interfaces only</span> <span class="o">=</span> <span class="s">yes</span>

<span class="c1"># How AD accounts are mapped to POSIX accounts on the fileserver</span>
<span class="na">obey pam restrictions</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">guest account</span> <span class="o">=</span> <span class="s">nobody</span>
<span class="na">invalid users</span> <span class="o">=</span> <span class="s">root krbtgt guest</span>
<span class="na">template homedir</span> <span class="o">=</span> <span class="s">/home/%U</span>
<span class="na">template shell</span> <span class="o">=</span> <span class="s">/bin/bash</span>
<span class="na">idmap config *:backend</span> <span class="o">=</span> <span class="s">rid</span>
<span class="na">idmap config *:range</span> <span class="o">=</span> <span class="s">1000000-16777216</span>

<span class="k">[homes]</span>
<span class="na">comment</span> <span class="o">=</span> <span class="s">Home Directories</span>
<span class="na">valid users</span> <span class="o">=</span> <span class="s">%S</span>
<span class="na">writable</span> <span class="o">=</span> <span class="s">yes</span>

<span class="k">[shared]</span>
<span class="na">comment</span> <span class="o">=</span> <span class="s">Shared folder for authenticated users</span>
<span class="na">writable</span> <span class="o">=</span> <span class="s">yes</span>
<span class="na">path</span> <span class="o">=</span> <span class="s">/shared</span></code></pre>
<p>The winbind support in realmd is still a bit quirky, make sure name services
are reconfigured so usernames and groups are looked up via winbind:</p>
<pre class="code bash literal-block"><code>sed -i -e <span class="s2">"s/^passwd:.*/passwd: compat winbind/"</span> /etc/nsswitch.conf
sed -i -e <span class="s2">"s/^group:.*/group: compat winbind/"</span> /etc/nsswitch.conf
sed -i -e <span class="s2">"s/^shadow:.*/shadow: compat/"</span> /etc/nsswitch.conf</code></pre>
<p>Also home directories need to be created on the fly.
On Debian following file is missing completely and
for Ubuntu a slightly incorrect version is supplied,
but this file can easily be reset:</p>
<pre class="code bash literal-block"><code>cat &gt; /usr/share/pam-configs/mkhomedir <span class="s">&lt;&lt; EOF
Name: Create home directory on login
Default: no
Priority: 0
Session-Type: Additional
Session:
        optional                    pam_mkhomedir.so
EOF</span></code></pre>
<p>Ubuntu and Debian ship with following command, use spacebar to tick
'Create home directory on login' and press enter:</p>
<pre class="code bash literal-block"><code>pam-auth-update</code></pre>
<p>Restart services or just reboot the box.
It is of course possible to add anonymous shares as shown in the previous example,
and it is possible to create shares where authentication is required.
In case of authenticated shares Samba will try to do it's best to map
Windows permissions to POSIX permissions and ACL-s.</p>
<p>Once machine is up check that both commands list the users from AD:</p>
<pre class="code bash literal-block"><code>wbinfo -u
getent passwd</code></pre>
<p>Create shared directory and reset permissions:</p>
<pre class="code bash literal-block"><code>mkdir -p /shared
chown administrator:<span class="s2">"domain users"</span> /shared
chmod <span class="m">775</span> /shared/</code></pre>
</div>
<div class="section" id="accessing-shares">
<h1>Accessing shares</h1>
<p>To list shares on command-line:</p>
<pre class="code bash literal-block"><code>smbclient -L dev.office.lan -U guest%</code></pre>
<p>To mount into local filesystem:</p>
<pre class="code bash literal-block"><code>mkdir -p /mnt/shared
mount.cifs -o guest //dev.office.lan/shared/ /mnt/shared</code></pre>
<p>To access shares on Ubuntu open file browser (nautilus), press Ctrl-L
and insert <a class="reference external" href="smb://dev.office.lan">smb://dev.office.lan</a>:</p>
<div class="figure">
<img alt="img/cifs-fileshare-on-ubuntu.png" src="/cache/bf55dc184c7fdc47a44220b35b692488.png"/>
<p class="caption">File shares on Ubuntu</p>
</div>
<p>To access shares on Windows open file explorer, press Ctrl-L
and insert \dev.office.lan:</p>
<div class="figure">
<img alt="img/cifs-fileshare-on-windows.png" src="/cache/7dc7e5085fa6597e3fec2aac7ef8130d.png"/>
<p class="caption">File shares on Windows</p>
</div>
<p>To use Kerberos single sign-on and prevent credential prompt from appearing
every time you try to access shares
either join the end user computer to domain
or use following to authenticate on command line:</p>
<pre class="code bash literal-block"><code>kinit username@OFFICE.LAN</code></pre>
</div>
<div class="section" id="auditing">
<h1>Auditing</h1>
<p>Depending on your organization's needs it might be that when
files get overwritten or deleted it is necessary to have the logs about
who did it and when.
In the 'global' section of /etc/samba/smb.conf add following:</p>
<pre class="code ini literal-block"><code><span class="na">vfs objects</span> <span class="o">=</span> <span class="s">full_audit</span>
<span class="na">full_audit:prefix</span> <span class="o">=</span> <span class="s">%u|%I|%m|%S</span>
<span class="na">full_audit:success</span> <span class="o">=</span> <span class="s">rename unlink rmdir pwrite</span>
<span class="na">full_audit:failure</span> <span class="o">=</span> <span class="s">none</span>
<span class="na">full_audit:facility</span> <span class="o">=</span> <span class="s">local7</span>
<span class="na">full_audit:priority</span> <span class="o">=</span> <span class="s">NOTICE</span></code></pre>
<p>Also configure syslog to forward events to your
<a class="reference external" href="https://en.wikipedia.org/wiki/Security_information_and_event_management">SIEM</a>.</p>
</div>
<div class="section" id="debugging">
<h1>Debugging</h1>
<p>As usual stop the service and start it up in interactive mode with raised verbosity level.</p>
<p>For fileserver portion:</p>
<pre class="code bash literal-block"><code>systemctl stop smbd
smbd -d3 -i</code></pre>
<p>For user mapping:</p>
<pre class="code bash literal-block"><code>systemctl stop winbind
winbindd -d3 -i</code></pre>
</div>
</div>
]]></content>
    
    <category term="CIFS"/>
    <category term="Samba"/>
    <category term="SMB"/>
    <category term="Kerberos"/>
    <category term="NFS"/>
    <updated>2017-03-06T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Reconfiguring OpenWrt as dummy access point</title>
    <summary>After installing OpenWrt on TP-Link WDR3600/4300 or Archer C7
following script can be used to convert the machine to a dummy access
point which does not serve DHCP, but just bridges wireless and wired ports on the device.</summary>
    <link href="http://lauri.vosandi.com/2017/01/reconfiguring-openwrt-as-dummy-ap.html"/>
    <content type="html"><![CDATA[<div class="document" id="reconfiguring-openwrt-as-dummy-access-point">
<!-- tags: OpenWrt, TP-Link -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- date: 2017-01-22 -->
<p>After installing OpenWrt on TP-Link WDR3600/4300 or Archer C7
following script can be used to convert the machine to a dummy access
point which does not serve DHCP, but just bridges wireless and wired ports on the device.</p>
<p>Guest wireless network is also enabled and it's tagged as VLAN 156 on the ethernet ports.</p>
<pre class="code bash literal-block"><code><span class="c1"># Disable DHCP servers
</span>/etc/init.d/odhcpd disable
/etc/init.d/dnsmasq disable

<span class="c1"># Remove all firewall rules
</span>uci delete firewall.@zone<span class="o">[</span><span class="m">2</span><span class="o">]</span>
uci delete firewall.@zone<span class="o">[</span><span class="m">1</span><span class="o">]</span>
uci delete firewall.@zone<span class="o">[</span><span class="m">0</span><span class="o">]</span>
uci delete firewall.@forwarding<span class="o">[</span><span class="m">0</span><span class="o">]</span>
<span class="k">for</span> j in <span class="k">$(</span>seq <span class="m">0</span> <span class="m">20</span><span class="k">)</span><span class="p">;</span> <span class="k">do</span> uci delete firewall.@rule<span class="o">[</span><span class="m">0</span><span class="o">]</span><span class="p">;</span> <span class="k">done</span>

<span class="c1"># Remove WAN interface
</span>uci delete network.wan
uci delete network.wan6

<span class="c1"># Reconfigure DHCP client for bridge over LAN and WAN ports
</span>uci delete network.lan.ipaddr
uci delete network.lan.netmask
uci delete network.lan.ip6assign
uci delete network.globals.ula_prefix
uci delete network.@switch_vlan<span class="o">[</span><span class="m">1</span><span class="o">]</span>
uci <span class="nb">set</span> network.lan.proto<span class="o">=</span>dhcp
uci <span class="nb">set</span> network.lan.ipv6<span class="o">=</span><span class="m">0</span>
uci <span class="nb">set</span> network.lan.ifname<span class="o">=</span><span class="s1">'eth0 eth1'</span>
uci <span class="nb">set</span> network.lan.stp<span class="o">=</span><span class="m">1</span>

<span class="c1"># Disable switch tagging and bridge all ports
</span>uci <span class="nb">set</span> network.@switch<span class="o">[</span><span class="m">0</span><span class="o">]</span>.enable_vlan<span class="o">=</span><span class="m">0</span>
uci <span class="nb">set</span> network.@switch_vlan<span class="o">[</span><span class="m">0</span><span class="o">]</span>.ports<span class="o">=</span><span class="s1">'0 1 2 3 4 5 6'</span>

<span class="c1"># Enable wireless
</span>uci delete wireless.radio0.disabled
uci delete wireless.radio1.disabled

<span class="c1"># Radio ordering differs among models
</span><span class="k">case</span> <span class="k">$(</span>uci get wireless.radio0.hwmode<span class="k">)</span> in
  11a<span class="o">)</span> uci rename wireless.radio0<span class="o">=</span>radio5ghz<span class="p">;;</span>
  11g<span class="o">)</span> uci rename wireless.radio0<span class="o">=</span>radio2ghz<span class="p">;;</span>
<span class="k">esac</span>
<span class="k">case</span> <span class="k">$(</span>uci get wireless.radio1.hwmode<span class="k">)</span> in
  11a<span class="o">)</span> uci rename wireless.radio1<span class="o">=</span>radio5ghz<span class="p">;;</span>
  11g<span class="o">)</span> uci rename wireless.radio1<span class="o">=</span>radio2ghz<span class="p">;;</span>
<span class="k">esac</span>

<span class="c1"># Reset virtual SSID-s
</span>uci delete wireless.@wifi-iface<span class="o">[</span><span class="m">1</span><span class="o">]</span>
uci delete wireless.@wifi-iface<span class="o">[</span><span class="m">0</span><span class="o">]</span>
<span class="k">for</span> band in 2ghz 5ghz<span class="p">;</span> <span class="k">do</span>
uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span><span class="o">=</span>wifi-iface
uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.mode<span class="o">=</span>ap
uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.device<span class="o">=</span>radio<span class="nv">$band</span>
uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.encryption<span class="o">=</span>psk2
uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.ssid<span class="o">=</span>KoodurProtected
uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.key<span class="o">=</span><span class="s1">'salakala'</span>
uci <span class="nb">set</span> wireless.lan<span class="nv">$band</span>.network<span class="o">=</span>lan
<span class="k">done</span>

<span class="c1"># Generate unique hostname based on wireless MAC
</span>uci <span class="nb">set</span> system.@system<span class="o">[</span><span class="m">0</span><span class="o">]</span>.hostname<span class="o">=</span>tp-link-<span class="k">$(</span>cat /sys/class/net/wlan1/address <span class="p">|</span> cut -d : -f <span class="m">4</span>- <span class="p">|</span> sed -e <span class="s1">'s/://g'</span><span class="k">)</span>
uci <span class="nb">set</span> network.lan.hostname<span class="o">=</span><span class="k">$(</span>uci get system.@system<span class="o">[</span><span class="m">0</span><span class="o">]</span>.hostname<span class="k">)</span>

<span class="c1"># Commit changes
</span>uci commit

<span class="c1"># Skip following to keep guests network disabled
</span>
<span class="c1"># Create bridge for guests
</span>uci <span class="nb">set</span> network.guest<span class="o">=</span>interface
uci <span class="nb">set</span> network.guest.proto<span class="o">=</span><span class="s1">'static'</span>
uci <span class="nb">set</span> network.guest.address<span class="o">=</span><span class="s1">'0.0.0.0'</span>
uci <span class="nb">set</span> network.guest.type<span class="o">=</span><span class="s1">'bridge'</span>
uci <span class="nb">set</span> network.guest.ifname<span class="o">=</span><span class="s1">'eth0.156 eth1.156'</span> <span class="c1"># tag id 156 for guest network
</span>uci <span class="nb">set</span> network.guest.ipaddr<span class="o">=</span><span class="s1">'0.0.0.0'</span>
uci <span class="nb">set</span> network.guest.ipv6<span class="o">=</span><span class="m">0</span>
uci <span class="nb">set</span> network.guest.stp<span class="o">=</span><span class="m">1</span>

<span class="c1"># Add guest SSID-s
</span><span class="k">for</span> band in 2ghz 5ghz<span class="p">;</span> <span class="k">do</span>
uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span><span class="o">=</span>wifi-iface
uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.mode<span class="o">=</span>ap
uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.device<span class="o">=</span>radio<span class="nv">$band</span>
uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.encryption<span class="o">=</span>none
uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.ssid<span class="o">=</span>KoodurPublic
uci <span class="nb">set</span> wireless.guest<span class="nv">$band</span>.network<span class="o">=</span>guest
<span class="k">done</span>

uci commit</code></pre>
<p>For lazy people convenience hack for adding SSH keys:</p>
<pre class="code bash literal-block"><code><span class="c1"># Create script for fetching SSH keys once interface goes up
</span>cat &gt; /etc/hotplug.d/iface/update-ssh-authorized-keys <span class="s">&lt;&lt; EOF
wget https://www.koodur.com/authorized_keys -O /etc/dropbear/authorized_keys.part
mv /etc/dropbear/authorized_keys.part /etc/dropbear/authorized_keys
EOF</span>

opkg update
opkg install openssl-util nano htop</code></pre>
</div>
]]></content>
    
    <category term="TP-Link"/>
    <category term="OpenWrt"/>
    <updated>2017-01-22T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>ZBT WG2626</title>
    <summary>The router is based on <a class="reference external" href="https://wikidevi.com/wiki/ZBT_WG2626">Mediatek MT7621</a> dual core SoC
clocked at 880MHz
with
16MiB SPI Flash chip and
512MiB DDR3 RAM chip.
There are
two MT7662E wireless chipsets and
ASMedia ASM1062 SATA controller soldered onboard and connected via PCI lanes.</summary>
    <link href="http://lauri.vosandi.com/2016/12/zbt-wg2626.html"/>
    <content type="html"><![CDATA[<div class="document" id="zbt-wg2626">
<!-- date: 2016-12-29 -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags: OpenWrt, ZBT, Mediatek, MT7662E, MT7621, 3G, DLNA -->
<div class="section" id="intro">
<h1>Intro</h1>
<p>The router is based on <a class="reference external" href="https://wikidevi.com/wiki/ZBT_WG2626">Mediatek MT7621</a> dual core SoC
clocked at 880MHz
with
16MiB SPI Flash chip and
512MiB DDR3 RAM chip.
There are
two MT7662E wireless chipsets and
ASMedia ASM1062 SATA controller soldered onboard and connected via PCI lanes.</p>
<div class="figure">
<img alt="https://wiki.openwrt.org/_media/media/zbt/wg2626.png" src="/cache/wiki.openwrt.org/_media/media/zbt/wg2626.png"/>
<p class="caption">Motherboard of WG2626</p>
</div>
<p>This router can be purchased from AliExpress for 80USD,
bulk orders from Alibaba should decrease item price considerably.</p>
</div>
<div class="section" id="flashing-openwrt">
<h1>Flashing OpenWrt</h1>
<p>The device comes already with OpenWrt albeit an older version.
Gain access to command line and use following to update the firmware.</p>
<p>Older OpenWrt firmware, 3.18.x kernel, 3G works, illegal instruction and core dumps under high load,
poor SATA throughput:</p>
<pre class="code bash literal-block"><code><span class="nb">cd</span> /tmp
wget http://downloads.openwrt.org/chaos_calmer/15.05.1/ramips/mt7621/openwrt-15.05.1-ramips-mt7621-zbt-wg2626-squashfs-sysupgrade.bin
sysupgrade openwrt-15.05.1-ramips-mt7621-zbt-wg2626-squashfs-sysupgrade.bin</code></pre>
<p>Newer OpenWrt firmware, 4.4.x kernel, QMI based 3G cards fail, old school USB-to-serial based 3G cards work, installing microSD card support crashes router:</p>
<pre class="code bash literal-block"><code><span class="nb">cd</span> /tmp
wget http://downloads.openwrt.org/snapshots/trunk/ramips/mt7621/openwrt-ramips-mt7621-zbt-wg2626-squashfs-sysupgrade.bin
sysupgrade openwrt-ramips-mt7621-zbt-wg2626-squashfs-sysupgrade.bin</code></pre>
<p>LEDE based firmware, 4.4.x kernel, QMI untested, old school 3G works, microSD card support unsable, SATA performance okay (50MB/s):</p>
<pre class="code bash literal-block"><code><span class="nb">cd</span> /tmp
http://downloads.lede-project.org/snapshots/targets/ramips/mt7621/lede-ramips-mt7621-zbt-wg2626-squashfs-sysupgrade.bin
sysupgrade lede-ramips-mt7621-zbt-wg2626-squashfs-sysupgrade.bin</code></pre>
<!-- comment: http://downloads.lede-project.org/releases/17.01.1/targets/ramips/mt7621/lede-17.01.1-ramips-mt7621-zbt-wg2626-squashfs-sysupgrade.bin -->
</div>
<div class="section" id="software-packages">
<h1>Software packages</h1>
<p>Once router is up and running with OpenWrt update package lists:</p>
<pre class="code bash literal-block"><code>opkg update</code></pre>
<p>Install software packages:</p>
<pre class="code bash literal-block"><code>opkg install comgt fdisk htop  kmod-atm kmod-mii kmod-usb-acm kmod-usb-atm kmod-usb-net kmod-usb-net-qmi-wwan kmod-usb-serial kmod-usb-serial-option kmod-usb-serial-wwan kmod-usb-wdm kmod-usb2 kmod-usb3 luci mc nano usbutils pciutils</code></pre>
<p>For 3G/LTE support:</p>
<pre class="code bash literal-block"><code>opkg install luci-proto-3g luci-proto-ppp luci-proto-qmi ppp uclient-fetch uqmi usb-modeswitch wwan

opkg install luci-proto-qmi_git-17.130.58552-d04f667-1_all.ipk</code></pre>
<p>If you don't have ethernet connectivity, on your laptop:</p>
<pre class="code bash literal-block"><code>wget http://downloads.lede-project.org/releases/17.01.1/targets/ramips/mt7621/packages/kmod-usb-net-qmi-wwan_4.4.61-1_mipsel_24kc.ipk
wget http://downloads.lede-project.org/releases/17.01.1/targets/ramips/mt7621/packages/uqmi_2016-12-19-8ceeab69-1_mipsel_24kc.ipk
wget http://downloads.openwrt.org/snapshots/trunk/ramips/mt7620/packages/luci/luci-proto-qmi_git-17.130.58552-d04f667-1_all.ipk
wget http://downloads.lede-project.org/releases/17.01.1/targets/ramips/mt7621/packages/kmod-usb-wdm_4.4.61-1_mipsel_24kc.ipk
wget http://downloads.lede-project.org/releases/17.01.1/targets/ramips/mt7621/packages/kmod-usb-net_4.4.61-1_mipsel_24kc.ipk
scp *.ipk root@192.168.1.1:/tmp/
ssh root@192.168.1.1 opkg install /tmp/*.ipk</code></pre>
<p>For fileserver and DLNA:</p>
<pre class="code bash literal-block"><code>opkg install luci-app-samba minidlna</code></pre>
<p>For storage in general:</p>
<pre class="code bash literal-block"><code>opkg install kmod-scsi-generic blkid block-mount kmod-fs-btrfs kmod-fs-ext4 kmod-fs-vfat btrfs-progs</code></pre>
<p>For USB storage:</p>
<pre class="code bash literal-block"><code>opkg install kmod-usb-storage kmod-usb-storage-extras</code></pre>
<p>For SATA:</p>
<pre class="code bash literal-block"><code>opkg install kmod-ata-core kmod-ata-ahci</code></pre>
<p>For microSD card support:</p>
<pre class="code bash literal-block"><code>opkg install kmod-sdhci-mt7620</code></pre>
<p>For OpenVPN:</p>
<pre class="code bash literal-block"><code>opkg install openvpn-openssl luci-app-openvpn</code></pre>
</div>
<div class="section" id="configuring-3g">
<h1>Configuring 3G</h1>
<p>Insert 3G card to mini PCI express, attach antennas and insert SIM card to the
slot underneath the mini PCI express slot.
In this case Ericsson F3507G Mobile Broadband Module salvaged from an old Thinkpad was used.
Append following to <span class="docutils literal">/etc/config/network</span>, adjust apn accordingly and reboot the box:</p>
<pre class="code bash literal-block"><code>config interface <span class="s1">'wwan'</span>
        option proto <span class="s1">'3g'</span>
        option device <span class="s1">'/dev/ttyACM0'</span>
        option apn <span class="s1">'internet.tele2.ee'</span>
        option delegate <span class="s1">'0'</span>
        option ipv6 <span class="s1">'0'</span>
        option service <span class="s1">'umts_only'</span>
        option pppd_options <span class="s1">'noipdefault'</span>
        option dialnumber <span class="s1">'*99#'</span></code></pre>
</div>
<div class="section" id="summary">
<h1>Summary</h1>
<p>Mediatek support in mainline kernel needs still some time to mature but
otherwise Mediatek based devices look promising alternative to Qualcomm/Atheros.</p>
</div>
</div>
]]></content>
    
    <category term="MT7621"/>
    <category term="OpenWrt"/>
    <category term="Mediatek"/>
    <category term="3G"/>
    <category term="DLNA"/>
    <category term="MT7662E"/>
    <category term="ZBT"/>
    <updated>2016-12-29T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Sniffing wireless beacon signal strength</title>
    <summary>Install scapy module:</summary>
    <link href="http://lauri.vosandi.com/2016/09/wifi-sniffer.html"/>
    <content type="html"><![CDATA[<div class="document" id="sniffing-wireless-beacon-signal-strength">
<!-- date: 2016-09-26 -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags: Python, scapy -->
<p>Install scapy module:</p>
<pre class="code bash literal-block"><code>apt install python-scapy</code></pre>
<p>Create monitoring interface to capture 802.11 packets:</p>
<pre class="code bash literal-block"><code>iw wlan0 interface add mon0 <span class="nb">type</span> monitor
ifconfig mon0 up</code></pre>
<p>Run the script:</p>
<pre class="code python literal-block"><code><span class="kn">from</span> <span class="nn">scapy.all</span> <span class="kn">import</span> <span class="o">*</span>

<span class="k">def</span> <span class="nf">PacketHandler</span><span class="p">(</span><span class="n">pkt</span><span class="p">)</span> <span class="p">:</span>
  <span class="k">if</span> <span class="n">pkt</span><span class="o">.</span><span class="n">haslayer</span><span class="p">(</span><span class="n">Dot11</span><span class="p">)</span> <span class="p">:</span>
    <span class="k">if</span> <span class="n">pkt</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">pkt</span><span class="o">.</span><span class="n">subtype</span> <span class="o">==</span> <span class="mi">8</span> <span class="p">:</span>
      <span class="k">if</span> <span class="n">pkt</span><span class="o">.</span><span class="n">haslayer</span><span class="p">(</span><span class="n">Dot11Beacon</span><span class="p">)</span> <span class="ow">or</span> <span class="n">pkt</span><span class="o">.</span><span class="n">haslayer</span><span class="p">(</span><span class="n">Dot11ProbeResp</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">extra</span> <span class="o">=</span> <span class="n">pkt</span><span class="o">.</span><span class="n">notdecoded</span>
            <span class="n">rssi</span> <span class="o">=</span> <span class="o">-</span><span class="p">(</span><span class="mi">256</span><span class="o">-</span><span class="nb">ord</span><span class="p">(</span><span class="n">extra</span><span class="p">[</span><span class="o">-</span><span class="mi">4</span><span class="p">:</span><span class="o">-</span><span class="mi">3</span><span class="p">]))</span>
        <span class="k">except</span><span class="p">:</span>
            <span class="n">rssi</span> <span class="o">=</span> <span class="o">-</span><span class="mi">100</span>
        <span class="k">print</span> <span class="s2">"WiFi signal strength:"</span><span class="p">,</span> <span class="n">rssi</span><span class="p">,</span> <span class="s2">"dBm of"</span><span class="p">,</span> <span class="n">pkt</span><span class="o">.</span><span class="n">addr2</span><span class="p">,</span> <span class="n">pkt</span><span class="o">.</span><span class="n">info</span>

<span class="n">sniff</span><span class="p">(</span><span class="n">iface</span><span class="o">=</span><span class="s2">"mon0"</span><span class="p">,</span> <span class="n">prn</span> <span class="o">=</span> <span class="n">PacketHandler</span><span class="p">)</span></code></pre>
</div>
]]></content>
    
    <category term="Python"/>
    <category term="scapy"/>
    <updated>2016-09-26T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Ubuntu 16.04, LTSP ja ID-kaart</title>
    <summary>Juhend eeldab <a class="reference external" href="http://releases.ubuntu.com/16.04.1/">Ubuntu 16.04 server</a>  paigaldust.</summary>
    <link href="http://lauri.vosandi.com/2016/09/xenial-ltsp-ja-id-kaart.html"/>
    <content type="html"><![CDATA[<div class="document" id="ubuntu-16-04-ltsp-ja-id-kaart">
<!-- title: Ubuntu 16.04, LTSP ja ID-kaart -->
<!-- author: Arti Zirk <arti.zirk@gmail.com> -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags: LTSP, Ubuntu, Debian, Cubietruck, PKCS#11, OpenSC, pcscd, PCSC-Lite, ID-card, ID-kaart, NBD, OpenSSH, opensc-tool -->
<!-- date: 2016-09-11 -->
<p>Juhend eeldab <a class="reference external" href="http://releases.ubuntu.com/16.04.1/">Ubuntu 16.04 server</a>  paigaldust.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="79 -113 231 324" preserveAspectRatio="xMidYMid meet" style=""><g><rect x="140.841" y="150.091" width="40.339" height="30.2542" fill="#b3b3b3"/><rect x="140.841" y="150.091" width="40.339" height="30.2542" fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="145.211" y="154.461" width="31.5989" height="20.8418" fill="#000000"/><polygon points="146.303,180.345 167.061,180.345 167.061,185.051 147.396,185.051 " fill="#b3b3b3"/><polygon points="146.303,180.345 167.061,180.345 167.061,185.051 147.396,185.051 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><polygon points="167.061,180.345 175.717,180.345 174.625,185.051 167.061,185.051 " fill="#b3b3b3"/><polygon points="167.061,180.345 175.717,180.345 174.625,185.051 167.061,185.051 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="168.473" y="181.757" width="1.88249" height="1.88249" fill="#ffffff"/><rect x="168.473" y="181.757" width="1.88249" height="1.88249" fill="none" fill-opacity="0" stroke-width="0.5" stroke="#000000"/><polygon points="156.976,185.051 165.044,185.051 165.044,187.404 169.078,187.404 169.078,189.757 152.943,189.757 152.943,187.404 156.976,187.404 " fill="#b3b3b3"/><polygon points="156.976,185.051 165.044,185.051 165.044,187.404 169.078,187.404 169.078,189.757 152.943,189.757 152.943,187.404 156.976,187.404 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><text font-size="12.7998" x="161.01" y="203.102" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="161.01" y="203.102"/></text></g><g><rect x="80.8409" y="150.091" width="40" height="30" fill="#b3b3b3"/><rect x="80.8409" y="150.091" width="40" height="30" fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="85.1742" y="154.424" width="31.3333" height="20.6667" fill="#000000"/><polygon points="86.2576,180.091 106.841,180.091 106.841,184.757 87.3409,184.757 " fill="#b3b3b3"/><polygon points="86.2576,180.091 106.841,180.091 106.841,184.757 87.3409,184.757 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><polygon points="106.841,180.091 115.424,180.091 114.341,184.757 106.841,184.757 " fill="#b3b3b3"/><polygon points="106.841,180.091 115.424,180.091 114.341,184.757 106.841,184.757 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="108.241" y="181.491" width="1.86667" height="1.86667" fill="#ffffff"/><rect x="108.241" y="181.491" width="1.86667" height="1.86667" fill="none" fill-opacity="0" stroke-width="0.5" stroke="#000000"/><polygon points="96.8409,184.757 104.841,184.757 104.841,187.091 108.841,187.091 108.841,189.424 92.8409,189.424 92.8409,187.091 96.8409,187.091 " fill="#b3b3b3"/><polygon points="96.8409,184.757 104.841,184.757 104.841,187.091 108.841,187.091 108.841,189.424 92.8409,189.424 92.8409,187.091 96.8409,187.091 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><text font-size="12.7998" x="100.841" y="202.757" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="100.841" y="202.757"/></text></g><g><rect x="260.841" y="150.091" width="40.678" height="30.5085" fill="#b3b3b3"/><rect x="260.841" y="150.091" width="40.678" height="30.5085" fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="265.248" y="154.497" width="31.8644" height="21.0169" fill="#000000"/><polygon points="266.349,180.599 287.282,180.599 287.282,185.345 267.451,185.345 " fill="#b3b3b3"/><polygon points="266.349,180.599 287.282,180.599 287.282,185.345 267.451,185.345 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><polygon points="287.282,180.599 296.01,180.599 294.909,185.345 287.282,185.345 " fill="#b3b3b3"/><polygon points="287.282,180.599 296.01,180.599 294.909,185.345 287.282,185.345 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="288.705" y="182.023" width="1.89831" height="1.89831" fill="#ffffff"/><rect x="288.705" y="182.023" width="1.89831" height="1.89831" fill="none" fill-opacity="0" stroke-width="0.5" stroke="#000000"/><polygon points="277.112,185.345 285.248,185.345 285.248,187.718 289.315,187.718 289.315,190.091 273.044,190.091 273.044,187.718 277.112,187.718 " fill="#b3b3b3"/><polygon points="277.112,185.345 285.248,185.345 285.248,187.718 289.315,187.718 289.315,190.091 273.044,190.091 273.044,187.718 277.112,187.718 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><text font-size="12.7998" x="281.18" y="203.447" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="281.18" y="203.447"/></text></g><g><rect x="200.841" y="150.091" width="40.339" height="30.2542" fill="#b3b3b3"/><rect x="200.841" y="150.091" width="40.339" height="30.2542" fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="205.211" y="154.461" width="31.5989" height="20.8418" fill="#000000"/><polygon points="206.303,180.345 227.061,180.345 227.061,185.051 207.396,185.051 " fill="#b3b3b3"/><polygon points="206.303,180.345 227.061,180.345 227.061,185.051 207.396,185.051 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><polygon points="227.061,180.345 235.717,180.345 234.625,185.051 227.061,185.051 " fill="#b3b3b3"/><polygon points="227.061,180.345 235.717,180.345 234.625,185.051 227.061,185.051 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="228.473" y="181.757" width="1.88249" height="1.88249" fill="#ffffff"/><rect x="228.473" y="181.757" width="1.88249" height="1.88249" fill="none" fill-opacity="0" stroke-width="0.5" stroke="#000000"/><polygon points="216.976,185.051 225.044,185.051 225.044,187.404 229.078,187.404 229.078,189.757 212.943,189.757 212.943,187.404 216.976,187.404 " fill="#b3b3b3"/><polygon points="216.976,185.051 225.044,185.051 225.044,187.404 229.078,187.404 229.078,189.757 212.943,189.757 212.943,187.404 216.976,187.404 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><text font-size="12.7998" x="221.01" y="203.102" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="221.01" y="203.102"/></text></g><g><rect x="116.418" y="-63.5911" width="44.1388" height="102.99" fill="#b3b3b3"/><rect x="116.418" y="-63.5911" width="44.1388" height="102.99" fill="none" fill-opacity="0" stroke-width="1.6" stroke="#000000"/><rect x="120.832" y="-57.4116" width="35.311" height="11.7703" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="120.832" y="-45.6413" width="35.311" height="11.7703" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="120.832" y="-33.871" width="35.311" height="11.7703" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="120.832" y="-22.1006" width="35.311" height="11.7703" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="120.832" y="-7.97622" width="22.0694" height="7.0622" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><ellipse cx="153.936" cy="-6.79919" rx="1.54486" ry="1.54486" fill="#00ff00"/><ellipse cx="153.936" cy="-6.79919" rx="1.54486" ry="1.54486" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><ellipse cx="153.936" cy="-2.09106" rx="1.54486" ry="1.54486" fill="#ffff00"/><ellipse cx="153.936" cy="-2.09106" rx="1.54486" ry="1.54486" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="145.108" y="-5.62216" width="5.29665" height="4.70813" fill="#ffffff"/><rect x="145.108" y="-5.62216" width="5.29665" height="4.70813" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 123.775 8.50224 L 123.775,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 131.131 8.50224 L 131.131,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 138.488 8.50224 L 138.488,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 145.844 8.50224 L 145.844,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 153.2 8.50224 L 153.2,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 160.557 8.50224 L 160.557,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><polygon points="107.59,48.2271 116.418,30.5716 116.418,39.3994 160.557,39.3994 160.557,30.5716 172.327,48.2271 " fill="#999999"/><polygon points="107.59,48.2271 116.418,30.5716 116.418,39.3994 160.557,39.3994 160.557,30.5716 172.327,48.2271 " fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><text font-size="12.7998" x="139.959" y="63.1697" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="139.959" y="63.1697"/></text></g><g><path d="M 229.683 -41.7566 C 221.659,-41.9548 206.097,-37.7928 208.286,-28.8741 C 210.474,-19.9553 220.93,-17.9735 225.307,-20.5499 C 229.683,-23.1264 218.498,-8.06382 239.896,-4.09995 C 261.294,-0.136082 272.236,-6.47827 269.075,-11.0367 C 265.914,-15.5952 287.798,-0.334276 298.01,-9.05479 C 308.223,-17.7753 287.555,-26.0993 291.931,-24.9102 C 296.308,-23.721 309.682,-25.3066 305.305,-40.1711 C 300.928,-55.0356 261.537,-43.5404 265.914,-45.7205 C 270.29,-47.9006 259.348,-58.8013 245.732,-56.6212 C 232.115,-54.441 231.149,-50.4849 229.69,-41.7644 L 229.683,-41.7566z" fill="#ffffff"/><path d="M 229.683 -41.7566 C 221.659,-41.9548 206.097,-37.7928 208.286,-28.8741 C 210.474,-19.9553 220.93,-17.9735 225.307,-20.5499 C 229.683,-23.1264 218.498,-8.06382 239.896,-4.09995 C 261.294,-0.136082 272.236,-6.47827 269.075,-11.0367 C 265.914,-15.5952 287.798,-0.334276 298.01,-9.05479 C 308.223,-17.7753 287.555,-26.0993 291.931,-24.9102 C 296.308,-23.721 309.682,-25.3066 305.305,-40.1711 C 300.928,-55.0356 261.537,-43.5404 265.914,-45.7205 C 270.29,-47.9006 259.348,-58.8013 245.732,-56.6212 C 232.115,-54.441 231.149,-50.4849 229.69,-41.7644 L 229.683,-41.7566" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260.666" y="-24.4345" fill="#000000" text-anchor="middle" font-family="FreeSans" font-style="normal" font-weight="normal"><tspan x="260.666" y="-24.4345">Internet</tspan></text></g><g><path d="M 105.877 -7.6268 C 59.4446,-7.55165 62.5922,87.0287 212.478,79.0548" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="113.377,-7.63894 103.385,-2.62276 105.877,-7.6268 103.369,-12.6228 " fill="#000000"/><polygon points="113.377,-7.63894 103.385,-2.62276 105.877,-7.6268 103.369,-12.6228 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="219.967,78.6563 210.247,84.1805 212.478,79.0548 209.716,74.1947 " fill="#000000"/><polygon points="219.967,78.6563 210.247,84.1805 212.478,79.0548 209.716,74.1947 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><rect x="223" y="60" width="75" height="33" fill="#b3b3b3"/><rect x="223" y="60" width="75" height="33" fill="none" fill-opacity="0" stroke-width="1.6" stroke="#000000"/><rect x="230.5" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="238" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="245.5" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="253" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="260.5" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="268" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="275.5" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="283" y="71.25" width="3.75" height="3.6" fill="#000000"/><text font-size="12.7998" x="260.5" y="106.5" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260.5" y="106.5"/></text></g><g><polyline points="260.5,93 280,120 280.468,139.855 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="280.644,147.353 275.41,137.474 280.468,139.855 285.407,137.238 " fill="#000000"/><polygon points="280.644,147.353 275.41,137.474 280.468,139.855 285.407,137.238 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><polyline points="260.5,93 220,120 220.402,139.853 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="220.554,147.352 215.352,137.455 220.402,139.853 225.35,137.253 " fill="#000000"/><polygon points="220.554,147.352 215.352,137.455 220.402,139.853 225.35,137.253 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><polyline points="260.5,93 160,120 160.402,139.853 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="160.554,147.352 155.352,137.455 160.402,139.853 165.35,137.253 " fill="#000000"/><polygon points="160.554,147.352 155.352,137.455 160.402,139.853 165.35,137.253 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><polyline points="260.5,93 100,120 98.7455,131 99.2256,139.881 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="99.6305,147.37 94.0979,137.654 99.2256,139.881 104.083,137.115 " fill="#000000"/><polygon points="99.6305,147.37 94.0979,137.654 99.2256,139.881 104.083,137.115 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><text font-size="12.7998" x="80" y="40" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="40"/></text><g><path d="M 171.03 -11.3282 C 203.192,-15.1026 200.444,24.1072 225.115,1.03729" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="163.581,-10.4541 172.93,-16.5856 171.03,-11.3282 174.095,-6.65371 " fill="#000000"/><polygon points="163.581,-10.4541 172.93,-16.5856 171.03,-11.3282 174.095,-6.65371 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="230.593,-4.0853 226.704,6.39686 225.115,1.03729 219.874,-0.907204 " fill="#000000"/><polygon points="230.593,-4.0853 226.704,6.39686 225.115,1.03729 219.874,-0.907204 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><text font-size="12.7998" x="80" y="-100" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="-100"/></text><text font-size="12.8" x="93.2722" y="-70.6364" fill="#000000" text-anchor="start" font-family="FreeSans" font-style="normal" font-weight="normal"><tspan x="93.2722" y="-70.6364">Terminal Server</tspan></text><text font-size="12.8" x="161.044" y="208.15" fill="#000000" text-anchor="start" font-family="FreeSans" font-style="normal" font-weight="normal"><tspan x="161.044" y="208.15">Terminals</tspan></text><text font-size="12.7998" x="216.632" y="54.6364" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="216.632" y="54.6364">Hub or switch</tspan></text><text font-size="12.237" x="86.4722" y="-18.7955" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="86.4722" y="-18.7955">eth0</tspan></text><text font-size="12.237" x="161.95" y="-19.5758" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="161.95" y="-19.5758">eth1</tspan></text></svg></div>
<div class="section" id="iseseisva-serveri-seadistamine">
<h1>Iseseisva serveri seadistamine</h1>
<p>Iseseisev (standalone) server antud kontekstis t&#228;hendab seda,
et LTSP serveril on kaks v&#245;rguliidest, millest &#252;ks vaatab Interneti poole ning
teine on &#252;hendatud eraldatud v&#245;rgusegmenti kus terminalid asuvad.
Sellisel juhul serveeritakse terminalide v&#245;rku k&#245;iki vajalikke teenuseid:
DHCP, TFTP, NBD, SSH, LDM jne.</p>
<p>Esiteks uuenda pakette:</p>
<pre class="code bash literal-block"><code>apt update
apt full-upgrade</code></pre>
<p>Paigalda LTSP metapakett, see seadistab k&#245;ik teenused mis on LTSP toimimiseks
vajalikud:</p>
<pre class="code bash literal-block"><code>apt install -y ltsp-server-standalone wget ca-certificates apt-transport-https</code></pre>
<p>Seadista v&#245;rk failis /etc/network/interfaces, asenda 192.168.77.1 omale sobiliku sisev&#245;rgu aadressiga:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /etc/network/interfaces
auto lo
iface lo inet loopback

auto en1
iface en1 inet dhcp

auto en0
iface en0 inet static
    address 192.168.77.1
    netmask 255.255.255.0
EOF</span></code></pre>
<p>Asenda vaikimisi alamv&#245;rk 192.168.0.0/24 ka DHCP serveri seadistustes:</p>
<pre class="code bash literal-block"><code>sed -i <span class="s2">"s/192\.168\.0\./192.168.77./g"</span> /etc/ltsp/dhcpd.conf</code></pre>
<p>Taask&#228;ivita teenused:</p>
<pre class="code bash literal-block"><code>systemctl restart networking
systemctl restart network-manager
systemctl restart isc-dhcp-server
systemctl restart nbd-server</code></pre>
</div>
<div class="section" id="ltsp-serveri-lisamine-olemasolevasse-vorku">
<h1>LTSP serveri lisamine olemasolevasse v&#245;rku</h1>
<p>Kui sul on juba toimiv DHCP server v&#245;id asendada <span class="docutils literal"><span class="pre">ltsp-server-standalone</span></span>
paketi <span class="docutils literal"><span class="pre">ltsp-server</span></span> paketiga:</p>
<pre class="code bash literal-block"><code>apt install -y ltsp-server ltspfs wget ca-certificates apt-transport-https</code></pre>
<p>Sellisel juhul pead vajalikud teenused, nagu n&#228;iteks TFTP ise seadistama:</p>
<pre class="code bash literal-block"><code>apt install -y tftpd-hpa
sed -e <span class="s1">'s/TFTP_ADDRESS=.*/TFTP_ADDRESS=":69"/'</span> /etc/default/tftpd-hpa</code></pre>
<p>Kontrolli &#252;le, et ka muud teenused oleks k&#228;ttesaadavad terminalidele.</p>
</div>
<div class="section" id="toolaua-keskkonna-paigaldus">
<h1>T&#246;&#246;laua keskkonna paigaldus</h1>
<p>Ubuntu t&#246;&#246;laud on &#252;sna resursin&#245;udlik ning terminal-serveri puhul &#228;&#228;rmiselt
aeglane, kuna pilt liigub &#252;le v&#245;rgu.
Terminal-serverile on soovitatud paigaldada MATE t&#246;&#246;laud:</p>
<pre class="code bash literal-block"><code>apt update
apt full-upgrade
apt install -y mate-desktop-environment-extras</code></pre>
<p>Kui serverisse on paigaldatud mitu erinevat t&#246;&#246;laua keskkonda, saab vaikimisi
t&#246;&#246;lauda vahetada j&#228;rgnevalt:</p>
<pre class="code bash literal-block"><code>update-alternatives --config x-session-manager</code></pre>
<p>Lisa ka Eesti ID-kaardi baastarkvara varamu:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"deb https://installer.id.ee/media/ubuntu/ xenial main"</span> &gt; /etc/apt/sources.list.d/ria-repository.list
wget https://installer.id.ee/media/install-scripts/ria-public.key -O - <span class="p">|</span> apt-key add -
wget https://installer.id.ee/media/install-scripts/C6C83D68.pub -O - <span class="p">|</span> apt-key add -
apt update
apt install -y open-eid</code></pre>
<p>Lisa Xsession skript mis n&#228;itab uut PCSC-lite sokkli asukohta:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"export PCSCLITE_CSOCK_NAME=\$HOME/.pcscd.comm"</span> &gt; /etc/X11/Xsession.d/80-pcsclite</code></pre>
</div>
<div class="section" id="pc-baasil-terminalid">
<h1>PC-baasil terminalid</h1>
<p>Enamus PC riistvara toetab PXE-alglaadimist.
Alusta terminali tarkvara juurfailis&#252;steemi loomisega:</p>
<pre class="code bash literal-block"><code><span class="nv">MIRROR</span><span class="o">=</span><span class="s2">"http://ee.archive.ubuntu.com/ubuntu/"</span> <span class="se">\
</span><span class="nv">LANG</span><span class="o">=</span>C <span class="se">\
</span><span class="nv">ARCH</span><span class="o">=</span>i386 <span class="se">\
</span>ltsp-build-client</code></pre>
<p>ID-kaardi jaoks vajalike komponentide paigaldamiseks sisene terminali juurfailis&#252;steemi:</p>
<pre class="code bash literal-block"><code>chroot /opt/ltsp/i386 /bin/bash</code></pre>
<p>Paigalda PCSC-Lite deemon:</p>
<pre class="code bash literal-block"><code>apt install -y pcscd</code></pre>
<p>Lisa SSH kliendi seadistused, t&#228;rni v&#245;ib asendada oma serveri IP-ga:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /etc/ssh/ssh_config
Host *
SendEnv LANG LC_*
PermitLocalCommand yes
LocalCommand /bin/sh -c "sh -c \"ssh -S /var/run/ldm_socket_* -l %r server rm .pcscd.comm; ssh -S /var/run/ldm_socket_* -O forward -R /home/%r/.pcscd.comm:/run/pcscd/pcscd.comm -l %r server\"&amp;"
EOF</span></code></pre>
<p>VIA terminalide UniChrome graafika t&#252;&#252;relite seis on suht halb seega ma l&#252;litaks v&#228;lja ka 3D kiirenduse:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /etc/X11/xorg.conf
Section "Module"
    Disable "glx"
    Disable "dri"
EndSection
EOF</span></code></pre>
<p>M&#228;lupulkade haakimiseks paigalda ka NTFS ning exFAT jaoks vajalikud komponendid:</p>
<pre class="code bash literal-block"><code>apt install -y ntfs-3g exfat-fuse</code></pre>
<p>V&#228;lju terminali juurikast:</p>
<pre class="code bash literal-block"><code><span class="nb">exit</span></code></pre>
<p>Uuenda terminali juurfailis&#252;steemi SquashFS t&#245;mmist:</p>
<pre class="code bash literal-block"><code>ltsp-update-image</code></pre>
</div>
<div class="section" id="rdp-sessiooni-lisamine">
<h1>RDP sessiooni lisamine</h1>
<p>Lisa terminali juurikasse rdesktop pakett:</p>
<pre class="code bash literal-block"><code>chroot /opt/ltsp/i386 apt install -y rdesktop</code></pre>
<p>Genereeri uuendatud t&#245;mmis:</p>
<pre class="code bash literal-block"><code>ltsp-update-image</code></pre>
<p>Seadista ringi <span class="docutils literal">/var/lib/tftpboot/ltsp/i386/lts.conf</span>:</p>
<pre class="code ini literal-block"><code><span class="k">[default]</span>
<span class="na">SCREEN_07</span><span class="o">=</span><span class="s">"rdesktop -x l -k et -u '' -f -r scard -r sound -r disk:floppy=/run/drives aken.edu.ee"</span>
<span class="na">SCREEN_08</span><span class="o">=</span><span class="s">"ldm"</span></code></pre>
<p>Sisselogimisdialoogi aegumise v&#228;ltimiseks ava Windowsi register
ning lisa <span class="docutils literal">HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal <span class="pre">Server\WinStations\RDP-Tcp</span></span>
alla DWORD t&#252;&#252;pi LogonTimeout=0xffffffff v&#245;ti-v&#228;&#228;rtus paar <a class="footnote-reference brackets" href="#login-timeout" id="id1">2</a>.</p>
<dl class="footnote brackets">
<dt class="label" id="cursor-shadow"><span class="brackets">1</span></dt>
<dd><p><a class="reference external" href="http://www.thewindowsclub.com/enable-disable-mouse-pointer-shadow-windows">http://www.thewindowsclub.com/enable-disable-mouse-pointer-shadow-windows</a></p>
</dd>
<dt class="label" id="login-timeout"><span class="brackets"><a class="fn-backref" href="#id1">2</a></span></dt>
<dd><p><a class="reference external" href="http://serverfault.com/questions/422770/changing-the-login-timeout-for-windows-remote-desktop-services">http://serverfault.com/questions/422770/changing-the-login-timeout-for-windows-remote-desktop-services</a></p>
</dd>
</dl>
</div>
<div class="section" id="cubietrucki-ette-valmistamine">
<h1>Cubietrucki ette valmistamine</h1>
<p>Kuna PXE on x86 platvormi spetsiifiline siis s&#228;&#228;rast v&#245;imekust n&#228;iteks
Cubietrucki kasutada ei saa.
K&#252;ll aga saab Cubietruckile k&#245;rvetada p&#252;sivara, mis analoogselt PXE-le
laadib v&#245;rgust alla tuuma, initrd ning j&#228;takb operatsioonis&#252;steemi alglaadimisega.</p>
<p>Esmalt paigalda QEMU emulatsioonikiht:</p>
<pre class="code bash literal-block"><code>apt install -y qemu-user-static binfmt-support</code></pre>
<p>Keela OMAP4 tuuma paigaldus, see pole naguinii enam k&#228;ttesaadav tarkvaravaramutest:</p>
<pre class="code bash literal-block"><code>sed -i -e <span class="s1">'s/KERNEL_ARCH="omap4"/KERNEL_ARCH=""/'</span> /usr/share/ltsp/plugins/ltsp-build-client/Ubuntu/020-kernel-selection</code></pre>
<p>Loo ARM juurfailis&#252;steem:</p>
<pre class="code bash literal-block"><code><span class="nv">DEBOOTSTRAP</span><span class="o">=</span>qemu-debootstrap <span class="nv">ARCH</span><span class="o">=</span>armhf <span class="nv">LANG</span><span class="o">=</span>C ltsp-build-client</code></pre>
<p>Lisa serveri SSH v&#245;ti:</p>
<pre class="code bash literal-block"><code>ltsp-update-sshkeys</code></pre>
<p>Sisene Cubietrucki juurfailis&#252;steemi:</p>
<pre class="code bash literal-block"><code>chroot /opt/ltsp/armhf /bin/bash</code></pre>
<p>Cubietrucki jaoks paigalda <a class="reference external" href="http://www.armbian.com/cubietruck/">Igori 3.4.x tuum</a>
ja moodulid kuhu sai k&#252;lge poogitud LTSP jaoks vajalik <em>overlayfs</em>:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"deb http://apt.armbian.com xenial main"</span> &gt; /etc/apt/sources.list.d/armbian.list
apt-key adv --keyserver keys.gnupg.net --recv-keys 0x93D6889F9F0E78D5
apt update
apt install -y linux-image-sun7i</code></pre>
<p>Uuenda pakettide nimekirju:</p>
<pre class="code bash literal-block"><code>apt update</code></pre>
<p>Paigalda kohandatud OpenSSH, PCSC-deemon, LTSP-kliendi metapakett ja muu tilu-lilu:</p>
<pre class="code bash literal-block"><code>apt install -y openssh-client pcscd</code></pre>
<p>Lisa SSH kliendi seadistused, et terminal v&#245;imaldaks serveris ligip&#228;&#228;su
terminalis jooksvale PCSC deemonile, vajadusel asenda t&#228;rn oma serveri IP-ga:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /etc/ssh/ssh_config
Host *
SendEnv LANG LC_*
PermitLocalCommand yes
LocalCommand /bin/sh -c "sh -c \"ssh -S /var/run/ldm_socket_* -l %r server rm .pcscd.comm; ssh -S /var/run/ldm_socket_* -O forward -R /home/%r/.pcscd.comm:/run/pcscd/pcscd.comm -l %r server\"&amp;"
EOF</span></code></pre>
<p>Kui soovid kasutada ka RDP sessioone siis uuendatud RDP kliendi paigaldamiseks:</p>
<pre class="code bash literal-block"><code>apt install -y rdesktop</code></pre>
<p>M&#228;lupulkade haakimiseks paigalda ka NTFS ning exFAT jaoks vajalikud komponendid:</p>
<pre class="code bash literal-block"><code>apt install -y ntfs-3g exfat-fuse</code></pre>
<p>V&#228;lju juurikast:</p>
<pre class="code bash literal-block"><code><span class="nb">exit</span></code></pre>
<p>Uuenda NBD kaudu serveeritavat t&#245;mmist:</p>
<pre class="code bash literal-block"><code>ltsp-update-image</code></pre>
</div>
<div class="section" id="cubietruck-tuuma-pakendamine">
<h1>Cubietruck tuuma pakendamine</h1>
<p>Paigalda esmalt u-boot t&#246;&#246;riistad:</p>
<pre class="code bash literal-block"><code>apt install -y u-boot-tools</code></pre>
<p>Sikuta Cubietrucki riistvara konfiguratsioon, mis paneb
VGA pesa k&#228;ima resolutsioonil 1024x768 ja l&#252;litab v&#228;lja terminali jaoks ebaolulised
komponendid (WiFi, Bluetooth jms):</p>
<pre class="code bash literal-block"><code>wget https://www.koodur.com/cubietruck/1024x768.bin -O /var/lib/tftpboot/ltsp/armhf/1024x768.bin</code></pre>
<p>Loo u-boot jaoks skript mis laeb tuuma, initrd ning riistvara konfiguratsiooni:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /var/lib/tftpboot/ltsp/armhf/1024x768.scr
setenv bootm_boot_mode sec
setenv bootargs 'ro init=/sbin/init-ltsp init=/sbin/init-ltsp root=/dev/nbd0'
tftp 0x43000000 /ltsp/armhf/1024x768.bin
tftp 0x42000000 /ltsp/armhf/uImage
tftp 0x50000000 /ltsp/armhf/initramfs.uImage
bootm 0x42000000 0x50000000
EOF</span></code></pre>
<p>Genereeri u-boot t&#245;mmised:</p>
<pre class="code bash literal-block"><code>mkimage -A arm -O linux -T script -C none -n boot.scr -d <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/1024x768.scr <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/1024x768.scr.uimg
mkimage -A arm -T ramdisk -C none -n uInitrd -d <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/initrd.img-3.4.*-sun7i <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/initramfs.uImage
mkimage -A arm -O linux -T kernel -C none -n Linux -a <span class="m">42000000</span> -e <span class="m">42000000</span> -d <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/vmlinuz-3.4.*-sun7i <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/uImage</code></pre>
<p>Seadista ringi ka DHCP serverit failis /etc/ltsp/dhcpd.conf,
siinkohal on v&#228;lja nopitud Cubietruckid millel on 1024x768 resolutsiooniga ekraanid
ning m&#245;ned mis on 1280x1024 resolutsiooniga ekraanid. &#220;lej&#228;&#228;nud masinad
sooritavad x86 terminali alglaadimise PXE abil:</p>
<pre class="code literal-block"><code>authoritative;

group {
    filename "ltsp/armhf/1024x768.scr.uimg";
    host term1 { hardware ethernet 02:c1:08:c3:10:9f; }
    host term2 { hardware ethernet 02:8d:06:c0:c5:36; }
    host term3 { hardware ethernet 02:15:07:c2:ff:cc; }
}

group {
    filename "ltsp/armhf/1280x1024.scr.uimg";
    host term4 { hardware ethernet 02:c1:0a:01:d3:0f; }
    host term5 { hardware ethernet 02:c1:08:82:f6:9f; }
    host term6 { hardware ethernet 02:c8:07:c1:cc:93; }
}

subnet 192.168.77.0 netmask 255.255.255.0 {
    range 192.168.77.100 192.168.77.250;
    option routers 192.168.77.1;
    option domain-name-servers 192.168.77.1;
    option domain-name "ltsp";
    filename "pxelinux.0";
}</code></pre>
</div>
<div class="section" id="cubietrucki-vorgust-alglaetavaks-tegemine">
<h1>Cubietrucki v&#245;rgust alglaetavaks tegemine</h1>
<p>Viimase sammuna peab Cubietrucki jaoks ette valmistama m&#228;lukaardi
mis oskab v&#245;rgust alglaadimist sooritada.
Laadi alla selle jaoks sobilik u-boot ning kirjuta see microSD m&#228;lukaardile.</p>
<pre class="code bash literal-block"><code>wget http://os.archlinuxarm.org/os/sunxi/boot/cubietruck/u-boot-sunxi-with-spl.bin
sudo dd <span class="k">if</span><span class="o">=</span>/dev/zero <span class="nv">of</span><span class="o">=</span>/dev/sdX <span class="nv">bs</span><span class="o">=</span>1M <span class="nv">count</span><span class="o">=</span><span class="m">8</span>
sudo dd <span class="k">if</span><span class="o">=</span>u-boot-sunxi-with-spl.bin <span class="nv">of</span><span class="o">=</span>/dev/sdX <span class="nv">bs</span><span class="o">=</span><span class="m">1024</span> <span class="nv">seek</span><span class="o">=</span><span class="m">8</span></code></pre>
<p>Sisemisele m&#228;lule modernse u-booti kirjutamine on j&#228;tkuvalt problemaatiline,
MLC m&#228;lukivi kasutuse t&#245;ttu kipub selle sisu korrumpeeruma andmete lugemisel.</p>
</div>
<div class="section" id="malupulkade-haakimine">
<h1>M&#228;lupulkade haakimine</h1>
<p>M&#228;lupulkade haakimine peaks toimima automaatselt, kui see pole nii kontrolli et serveris oleks paigaldatud ltspfs pakett.</p>
<pre class="code bash literal-block"><code>apt install ltspfs</code></pre>
<p>Terminali juurfailis&#252;steemis kontrolli, et oleks paigaldatud tarkvara NTFS ning exFAT failis&#252;steemide haakimiseks:</p>
<pre class="code bash literal-block"><code>apt purge -y flash-kernel <span class="c1"># armhf juurikas muidu p&#252;&#252;ab kernelit flashima hakata
</span>apt install ntfs-3g exfat-fuse</code></pre>
</div>
</div>
]]></content>
    
    <category term="Ubuntu"/>
    <category term="pcscd"/>
    <category term="ID-card"/>
    <category term="LTSP"/>
    <category term="ID-kaart"/>
    <category term="NBD"/>
    <category term="OpenSSH"/>
    <category term="PKCS#11"/>
    <category term="Debian"/>
    <category term="Cubietruck"/>
    <category term="opensc-tool"/>
    <category term="PCSC-Lite"/>
    <category term="OpenSC"/>
    <updated>2016-09-11T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
    <author>
      <name>Arti Zirk</name>
      <email>arti.zirk@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>LinuxCNC</title>
    <summary>LinuxCNC is a Debian based distribution which includes
realtime kernel for running stepper drivers connected to a parallel port,
EMC2 the graphical user interface for working with CNC machines.
This howto assumes you have already produced Gerber files,
eg by plotting your KiCad PCB layout.</summary>
    <link href="http://lauri.vosandi.com/2016/07/linuxcnc.html"/>
    <content type="html"><![CDATA[<div class="document" id="linuxcnc">
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags: KiCad, CNC, PCB, LinuxCNC, Gerber -->
<!-- date: 2016-07-07 -->
<div class="section" id="introduction">
<h1>Introduction</h1>
<p>LinuxCNC is a Debian based distribution which includes
realtime kernel for running stepper drivers connected to a parallel port,
EMC2 the graphical user interface for working with CNC machines.
This howto assumes you have already produced Gerber files,
eg by plotting your KiCad PCB layout.</p>
</div>
<div class="section" id="converting-gerbers-to-toolpaths">
<h1>Converting Gerbers to toolpaths</h1>
<p>Utility for converting  Gerber files to .ngc files which are understood by LinuxCNC.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0.950 0.950 45.050 13.050" preserveAspectRatio="xMidYMid meet" style=""><rect x="1.000" y="5.000" width="7.000" height="2.000" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="1.000" y="5.000" width="7.000" height="2.000" fill="none" stroke="#000000" stroke-width="0.100"/><text x="4.500" y="6.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
Plot Gerber</text><line x1="4.500" y1="3.049" x2="4.500" y2="4.464" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="4.500,4.839 4.250,4.339 4.500,4.464 4.750,4.339 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="4.500,4.839 4.250,4.339 4.500,4.464 4.750,4.339 "/><rect x="20.000" y="8.000" width="6.000" height="2.000" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="20.000" y="8.000" width="6.000" height="2.000" fill="none" stroke="#000000" stroke-width="0.100"/><text x="23.000" y="9.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
pcb2gcode</text><polygon fill="#FFFFFF" stroke="none" stroke-width="0.100" points="10.728,5.000 17.634,5.000 16.906,7.000 10.000,7.000 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="10.728,5.000 17.634,5.000 16.906,7.000 10.000,7.000 "/><text x="13.817" y="6.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
design-B.Cu.gbl</text><polygon fill="#FFFFFF" stroke="none" stroke-width="0.100" points="10.728,8.000 17.634,8.000 16.906,10.000 10.000,10.000 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="10.728,8.000 17.634,8.000 16.906,10.000 10.000,10.000 "/><text x="13.817" y="9.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
design-F.Cu.gtl</text><polygon fill="#FFFFFF" stroke="none" stroke-width="0.100" points="10.728,11.000 17.634,11.000 16.906,13.000 10.000,13.000 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="10.728,11.000 17.634,11.000 16.906,13.000 10.000,13.000 "/><text x="13.817" y="12.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
design.drl</text><line x1="8.050" y1="6.000" x2="9.845" y2="6.000" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="10.220,6.000 9.720,6.250 9.845,6.000 9.720,5.750 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="10.220,6.000 9.720,6.250 9.845,6.000 9.720,5.750 "/><line x1="17.302" y1="9.000" x2="19.464" y2="9.000" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="19.839,9.000 19.339,9.250 19.464,9.000 19.339,8.750 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="19.839,9.000 19.339,9.250 19.464,9.000 19.339,8.750 "/><rect x="1.000" y="11.000" width="7.000" height="2.000" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="1.000" y="11.000" width="7.000" height="2.000" fill="none" stroke="#000000" stroke-width="0.100"/><text x="4.500" y="12.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
Generate Drill File</text><line x1="4.500" y1="7.050" x2="4.500" y2="10.464" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="4.500,10.839 4.250,10.339 4.500,10.464 4.750,10.339 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="4.500,10.839 4.250,10.339 4.500,10.464 4.750,10.339 "/><line x1="8.050" y1="12.000" x2="9.845" y2="12.000" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="10.220,12.000 9.720,12.250 9.845,12.000 9.720,11.750 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="10.220,12.000 9.720,12.250 9.845,12.000 9.720,11.750 "/><polygon fill="#FFFFFF" stroke="none" stroke-width="0.100" points="28.728,5.000 35.634,5.000 34.906,7.000 28.000,7.000 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="28.728,5.000 35.634,5.000 34.906,7.000 28.000,7.000 "/><text x="31.817" y="6.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
back.ngc</text><polygon fill="#FFFFFF" stroke="none" stroke-width="0.100" points="28.728,8.000 35.634,8.000 34.906,10.000 28.000,10.000 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="28.728,8.000 35.634,8.000 34.906,10.000 28.000,10.000 "/><text x="31.817" y="9.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
front.ngc</text><polyline fill="none" stroke="#000000" stroke-width="0.100" points="17.301,6.000 21.500,6.000 21.500,7.513 "/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="21.500,7.888 21.250,7.388 21.500,7.513 21.750,7.388 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="21.500,7.888 21.250,7.388 21.500,7.513 21.750,7.388 "/><polyline fill="none" stroke="#000000" stroke-width="0.100" points="17.301,12.000 21.500,12.000 21.500,10.487 "/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="21.500,10.112 21.750,10.612 21.500,10.487 21.250,10.612 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="21.500,10.112 21.750,10.612 21.500,10.487 21.250,10.612 "/><polyline fill="none" stroke="#000000" stroke-width="0.100" points="6.250,7.000 6.250,9.000 9.877,9.000 "/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="10.252,9.000 9.752,9.250 9.877,9.000 9.752,8.750 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="10.252,9.000 9.752,9.250 9.877,9.000 9.752,8.750 "/><polyline fill="none" stroke="#000000" stroke-width="0.100" points="24.500,8.000 24.500,6.000 27.877,6.000 "/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="28.252,6.000 27.752,6.250 27.877,6.000 27.752,5.750 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="28.252,6.000 27.752,6.250 27.877,6.000 27.752,5.750 "/><line x1="26.049" y1="9.000" x2="27.846" y2="9.000" stroke="#000000" stroke-width="0.100"/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="28.221,9.000 27.721,9.250 27.846,9.000 27.721,8.750 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="28.221,9.000 27.721,9.250 27.846,9.000 27.721,8.750 "/><polygon fill="#FFFFFF" stroke="none" stroke-width="0.100" points="28.728,11.000 35.634,11.000 34.906,13.000 28.000,13.000 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="28.728,11.000 35.634,11.000 34.906,13.000 28.000,13.000 "/><text x="31.817" y="12.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
drill.ngc</text><polyline fill="none" stroke="#000000" stroke-width="0.100" points="24.500,10.000 24.500,12.000 27.877,12.000 "/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="28.252,12.000 27.752,12.250 27.877,12.000 27.752,11.750 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="28.252,12.000 27.752,12.250 27.877,12.000 27.752,11.750 "/><rect x="37.000" y="1.000" width="8.000" height="2.000" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="37.000" y="1.000" width="8.000" height="2.000" fill="none" stroke="#000000" stroke-width="0.100"/><text x="41.000" y="2.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
LinuxCNC/EMC2</text><rect x="1.000" y="1.000" width="7.000" height="2.000" fill="#FFFFFF" stroke="none" stroke-width="0"/><rect x="1.000" y="1.000" width="7.000" height="2.000" fill="none" stroke="#000000" stroke-width="0.100"/><text x="4.500" y="2.195" fill="#000000" text-anchor="middle" font-size="0.80" font-family="Cabin Condensed" font-style="normal" font-weight="400">
Kicad PCB layout</text><polyline fill="none" stroke="#000000" stroke-width="0.100" points="35.270,12.000 43.000,12.000 43.000,7.525 43.000,7.525 43.000,3.550 "/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="43.250,3.550 43.000,3.050 42.750,3.550 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="43.250,3.550 43.000,3.050 42.750,3.550 "/><polyline fill="none" stroke="#000000" stroke-width="0.100" points="35.270,9.000 41.000,9.000 41.000,6.025 41.000,6.025 41.000,3.550 "/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="41.250,3.550 41.000,3.050 40.750,3.550 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="41.250,3.550 41.000,3.050 40.750,3.550 "/><polyline fill="none" stroke="#000000" stroke-width="0.100" points="35.270,6.000 39.000,6.000 39.000,4.525 39.000,4.525 39.000,3.550 "/><polygon fill="#000000" stroke="none" stroke-width="0.100" points="39.250,3.550 39.000,3.050 38.750,3.550 "/><polygon fill="none" stroke="#000000" stroke-width="0.100" points="39.250,3.550 39.000,3.050 38.750,3.550 "/></svg></div>
<p>To install pcb2gcode on Fedora 25:</p>
<pre class="code bash literal-block"><code>dnf install pcb2gcode</code></pre>
<p>To install pcb2gcode on LinuxCNC itself or a Ubuntu workstation:</p>
<pre class="code bash literal-block"><code>apt install pcb2gcode</code></pre>
<p>Following generates front.ngc, back.ngc, drill.ngc toolpath files
with coordinates reset to resulting toolpaths instead of original PCB layout coordinates.
All drilling is squashed into single tool path, in our case we used only 1mm drill.
The design will not be tiled, increase tile-x and tile-y to cut multiple
identical copies of the design.</p>
<pre class="code bash literal-block"><code>pcb2gcode <span class="se">\
</span>    --zero-start <span class="se">\
</span>    --onedrill <span class="se">\
</span>    --software linuxcnc <span class="se">\
</span>    --tile-x <span class="m">1</span> <span class="se">\
</span>    --tile-y <span class="m">1</span> <span class="se">\
</span>    --front *-F.Cu.g* <span class="se">\
</span>    --back *-B.Cu.g* <span class="se">\
</span>    --drill *.drl <span class="se">\
</span>    --front-output front.ngc <span class="se">\
</span>    --back-output back.ngc <span class="se">\
</span>    --drill-output drill.ngc <span class="se">\
</span>    --metric <span class="se">\
</span>    --zwork <span class="m">0</span> --offset <span class="m">0</span>.2 <span class="se">\
</span>    --zsafe <span class="m">3</span> --zchange <span class="m">40</span> <span class="se">\
</span>    --mill-feed <span class="m">500</span> <span class="se">\
</span>    --mill-speed <span class="m">6000</span> <span class="se">\
</span>    --zdrill -3 <span class="se">\
</span>    --drill-feed <span class="m">500</span> <span class="se">\
</span>    --drill-speed <span class="m">6000</span></code></pre>
<p>Milling depth is set to 0mm, make sure you home Z axis to desired cutting depth before executing the toolpath.
Milling offset is 0.2mm, that is to compensate for the milling bit cut width.
When moving between paths tool is raised 3mm above the surface.
Drilling depth is set to 5mm, make sure you home Z axis before drilling to the surface of the PCB.
Milling and drilling feed is set to 500mm/minute.
Milling and drilling speed is set to 6000rpm if your setup supports setting
spindle speed.</p>
</div>
<div class="section" id="installing-linuxcnc">
<h1>Installing LinuxCNC</h1>
<p>To use LinuxCNC in production you need realtime capable kernel.
Folks at LinuxCNC have packaged it up and it's installable as a separate ISO file.
To download it and copy to a memory stick, make sure you replace sdz with
the device corresponding to the block device of your memory stick:</p>
<pre class="code bash literal-block"><code>wget http://www.linuxcnc.org/linuxcnc-2.7-wheezy.iso
cat linuxcnc-2.7-wheezy.iso <span class="p">|</span> pv &gt; /dev/sdz</code></pre>
<p>Install it to a PC which has parallel port,
USB-parallel port converters we tried didn't have drivers for
the rather outdated realtime kernel included with LinuxCNC.</p>
</div>
<div class="section" id="assembling-cnc-machine">
<h1>Assembling CNC machine</h1>
<p>Following is not going to go in depth with CNC frame construction.
CNC frames can be ordered from AliExpress for reasonable price,
<a class="reference external" href="https://www.aliexpress.com/item/FREE-SHIPPING-CNC-router-DIY-CNC-frame-for-small-engraving-machine-engraving-machine-rack-suitable-for/1306441090.html">3020T</a>
has (trapezoidal) lead screw and can be ordered for around 500USD.
Note that lead screw is cheaper and requires less torque to hold
the position whereas ball screw is more precise but expensive and
might need more powerful stepper motors to hold position,
see pros and cons
<a class="reference external broken" href="http://blog.helixlinear.com/bid/224687/Lead-Screws-vs-Ball-Screws-It-s-All-about-the-Application">here</a>.</p>
<p>Use a breakout board to make it easier to connect stepper drivers
to the parallel port.
Note that the breakout board does not include any essential functionality,
it simply makes things more convenient,
has a relay for turning the spindle on and off and
as a cherry on the top uses optocouplers to electrically separate parallel
port from the rest of the machinery to protect the PC in case of a disaster.</p>
<div class="figure">
<img alt="http://www.sunrom.com/media/content/493/images/cnc-wiring.gif" src="/cache/www.sunrom.com/media/content/493/images/cnc-wiring.gif"/>
<p class="caption">Wiring diagram for breakout board</p>
</div>
<p>Poor man's solution is to simply use a printer cable,
connect individual wires to the stepper drivers.
In our case we used Toshiba TB6600 based stepper drivers:</p>
<div class="figure">
<img alt="https://d1j1kxp9fqehmk.cloudfront.net/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/0/1/01_95.jpg" src="/cache/d1j1kxp9fqehmk.cloudfront.net/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/0/1/01_95.jpg"/>
<p class="caption">TB6600 based stepper drivers</p>
</div>
<p>For 3020T the NEMA 23 stepper motors were suitable,
NEMA 17 steppers were also tested but didn't deliver enough torque to drive the CNC.
Note that
<a class="reference external" href="http://reprap.org/wiki/NEMA_17_Stepper_motor">NEMA 17</a> and
<a class="reference external" href="http://reprap.org/wiki/NEMA_23_Stepper_motor">NEMA 23</a> in reality refer
to the mounting hole dimensions,
there are variety of motors made by different manufacturers and slightly
different dimensions and electrical characteristics.</p>
<div class="figure">
<img alt="https://www.poscope.com/wp-content/uploads/2016/02/nema23.jpg" src="/cache/www.poscope.com/wp-content/uploads/2016/02/nema23.jpg"/>
<p class="caption">NEMA 23</p>
</div>
<p>Note that in certain configurations the CNC frame comes without
stepper mounting bracket. You can try your luck with threaded rod
or use a <a class="reference external" href="https://grabcad.com/library/nema-23-cnc-bracket-1">3D printer to print one</a>.
Also shaft couplers are required to connect NEMA motors to the CNC frame's
lead screws:</p>
<div class="figure">
<img alt="http://cdn.shopify.com/s/files/1/1625/4675/products/24_1_ae9403e7-3f4b-4488-a508-ce81b12dafd2_grande.jpg?v=1492328443" src="/cache/cdn.shopify.com/s/files/1/1625/4675/products/24_1_ae9403e7-3f4b-4488-a508-ce81b12dafd2_grande.jpg"/>
</div>
<p>Note that it is probably easier to purchase whole kit
which includes at least steppers and spindle.</p>
</div>
<div class="section" id="milling-and-drilling-bits">
<h1>Milling and drilling bits</h1>
<p>Most PCB milling and drilling bits have 1/8 inch (3.175mm) diameter shank,
that's the end mounted to spindle.</p>
<p>After experimenting with 90&#176;, 60&#176;, 30&#176;, 10&#176; mill bits and
different drill bits it eventually boiled down to two.</p>
<p>For milling traces 60&#176; carbide mill bit is suitable:</p>
<div class="figure">
<img alt="https://img1.banggood.com/thumb/view/upload/2015/07/SKU234361%20(1).jpg" src="/cache/img1.banggood.com/thumb/view/upload/2015/07/SKU234361 (1).jpg"/>
</div>
<p>For most drilling holes 1mm drill bit is enough:</p>
<div class="figure">
<img alt="https://s-media-cache-ak0.pinimg.com/736x/48/e0/c8/48e0c86e341af43aa2418bcf77afe091.jpg" src="/cache/s-media-cache-ak0.pinimg.com/736x/48/e0/c8/48e0c86e341af43aa2418bcf77afe091.jpg"/>
</div>
<p>The pcb2gcode command example merges all drill tool paths so
you can leave the machine unattended during the drilling job,
otherwise tool change is requested while moving to a drilling hole of different size.</p>
</div>
<div class="section" id="milling-pcb-with-linuxcnc">
<h1>Milling PCB with LinuxCNC</h1>
<p>Place PCB on the sacrificial material and use paper tape to fix it to the board.
Make sure spindle is stopped and insert 60 degree mill bit.
Press F1 to toggle <em>Emergency Stop</em> and press F2 to turn on stepper drivers.
Use up, down, left, right arrow and Page Up/Down buttons to drive
the CNC head along X, Y and Z axes.
Slide <em>Jog speed</em> to the max to move faster.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>Press Shift-1 to switch between imperial (inch) and metric systems (mm).</p>
</div>
<p>Move the head along X and Y axes to the starting point.
Select X axis hit Home button, select Y axis and hit Home again.
Press Page Down to drive the mill bit into the copper layer into desired cutting depth.
Select Z axis and hit Home button.
Press Page Up to drive mill bit away.</p>
<p>Open front.ngc, press R to begin executing the current file:</p>
<div class="figure">
<img alt="img/linuxcnc-front.png" src="/cache/ab452f46146c7a7858a6a3318436a051.png"/>
<p class="caption">LinuxCNC milling front layer</p>
</div>
<p>Once the milling is ready do not power down the steppers as you
would lose the X and Y axis alignment.
If you have manually controlled spindle simply stop the spindle.
Replace the mill bit with drill bit.
Use Page Up and Page Down to drive the drill bit near the copper surface,
but not into it.
Select Z axis and hit Home button to rehome Z axis for drill bit.</p>
<div class="figure">
<img alt="img/linuxcnc-drill.png" src="/cache/026aa5d0131400da5166e0f7cdf0df82.png"/>
<p class="caption">LinuxCNC drilling holes</p>
</div>
<p>Move the head away while making sure you don't accidentally run into
the frame limits as this would again lose the X and Y alignment.</p>
<p>Use cordless drill to cut though some of the mounting holes into the
sacrificial material, preferably the ordermost ones.
Remove mounting tapes, flip the PCB along Y axis.
Use bolts to align flipped PCB to the holes in sacrificial material.
Retape the PCB and remove bolts.</p>
<div class="figure">
<img alt="img/linuxcnc-back.png" src="/cache/b0fa49a0b861b2429f05e357891f8edc.png"/>
<p class="caption">LinuxCNC milling back layer</p>
</div>
</div>
<div class="section" id="emc2-on-ubuntu-or-fedora">
<h1>EMC2 on Ubuntu or Fedora</h1>
<p>It might become handy to run EMC2  the graphical user interface of
LinuxCNC on your daily driver distro simply to test your <a href="#id1"><span class="problematic" id="id2">*</span></a>.ngc files,
but there are no packages available for Ubuntu or Fedora.
The graphical user interface can still be fortunately compiled from source.</p>
<div class="system-message" id="id1">
<p class="system-message-title">System Message: WARNING/2 (<span class="docutils literal">./posts/./linuxcnc.rst</span>, line 227); <em><a href="#id2">backlink</a></em></p>
<p>Inline emphasis start-string without end-string.</p>
</div>
<p>To install dependencies on Fedora 25:</p>
<pre class="code bash literal-block"><code>dnf install libudev-devel libmodbus-devel libusb-devel gtk2-devel bwidget <span class="se">\
</span>    tkimg-devel tclx boost-devel libXmu-devel autoconf git gcc-c++ <span class="se">\
</span>    readline-devel pygtk2</code></pre>
<p>To install dependencies on Ubuntu 14.04:</p>
<pre class="code bash literal-block"><code>apt install libudev-dev libmodbus-dev libusb-1.0-0-dev tcl-dev tk-dev <span class="se">\
</span>    bwidget libtk-img tclx  libboost-python-dev libxmu-dev libreadline-dev <span class="se">\
</span>    freeglut3-dev libglib2.0-dev libgtk2.0-dev autoconf git</code></pre>
<p>Fetch source code:</p>
<pre class="code bash literal-block"><code>git clone https://github.com/LinuxCNC/linuxcnc
<span class="nb">cd</span> linuxcnc/</code></pre>
<p>Compile from source:</p>
<pre class="code bash literal-block"><code><span class="nb">cd</span> src/
./autogen.sh
./configure --enable-non-distributable<span class="o">=</span>yes
make -j4
<span class="nb">cd</span> ..</code></pre>
<p>Run from source tree without installing to system:</p>
<pre class="code bash literal-block"><code>./scripts/rip-environment linuxcnc</code></pre>
<p>In the menu select <em>axis</em> and click OK.</p>
</div>
</div>
]]></content>
    
    <category term="LinuxCNC"/>
    <category term="Gerber"/>
    <category term="PCB"/>
    <category term="KiCad"/>
    <category term="CNC"/>
    <updated>2016-07-07T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Central logging with Rsyslog</title>
    <summary>Nowadays it's not realistic to observe logs on different machines manually.
Instead log messages should be collected at a central logging server and
not stored on individual servers at all to reduce disk space usage and disk writes.</summary>
    <link href="http://lauri.vosandi.com/lan/rsyslog.html"/>
    <content type="html"><![CDATA[<div class="document" id="central-logging-with-rsyslog">
<!-- tags: rsyslog, syslog -->
<!-- date: 2016-03-08 -->
<div class="section" id="introduction">
<h1>Introduction</h1>
<p>Nowadays it's not realistic to observe logs on different machines manually.
Instead log messages should be collected at a central logging server and
not stored on individual servers at all to reduce disk space usage and disk writes.</p>
</div>
<div class="section" id="server-configuration">
<h1>Server configuration</h1>
<p>Install rsyslog daemon:</p>
<pre class="code bash literal-block"><code>apt-get install rsyslog</code></pre>
<p>Create /etc/rsyslog.d/server.conf with following content:</p>
<pre class="code bash literal-block"><code><span class="c1"># Provide UDP syslog reception
</span><span class="nv">$ModLoad</span> imudp
<span class="nv">$UDPServerRun</span> <span class="m">514</span>

<span class="c1"># Provide TCP syslog reception
</span><span class="nv">$ModLoad</span> imtcp
<span class="nv">$InputTCPServerRun</span> <span class="m">514</span>

<span class="c1"># Use custom filenaming scheme
</span><span class="nv">$template</span> FILENAME,<span class="s2">"/var/log/remote/%HOSTNAME%.log"</span>
*.* ?FILENAME

<span class="nv">$PreserveFQDN</span> on</code></pre>
<p>Restart service:</p>
<pre class="code bash literal-block"><code>service rsyslog restart</code></pre>
<p>Make sure your network equipment of server firewall won't filter TCP 514 traffic.</p>
</div>
<div class="section" id="workstation-configuration">
<h1>Workstation configuration</h1>
<p>Again, install rsyslog daemon:</p>
<pre class="code bash literal-block"><code>apt-get install rsyslog</code></pre>
<p>Create /etc/rsyslog.d/client.conf and substitute 1.2.3.4 with your log server IP-aadress:</p>
<pre class="code bash literal-block"><code><span class="nv">$PreserveFQDN</span> on
<span class="nv">$ActionQueueType</span> LinkedList
<span class="nv">$ActionQueueFileName</span> srvrfwd
<span class="nv">$ActionResumeRetryCount</span> -1
<span class="nv">$ActionQueueSaveOnShutdown</span> on
*.* @@1.2.3.4:514</code></pre>
<p>Such configuration makes sure no messages will be lost due to network glitches or reboots.</p>
<p>Finally restart the service:</p>
<pre class="code bash literal-block"><code>service rsyslog restart</code></pre>
</div>
<div class="section" id="testing">
<h1>Testing</h1>
<p>On server leave following running:</p>
<pre class="code bash literal-block"><code>tail -f /var/log/remote/*.log</code></pre>
<p>On workstation:</p>
<pre class="code bash literal-block"><code>logger -s <span class="s2">"Hello world"</span></code></pre>
</div>
</div>
]]></content>
    
    <category term="syslog"/>
    <category term="rsyslog"/>
    <updated>2016-03-08T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Publishing HTML5 video using FFMPEG</title>
    <summary>Nowadays the web browser are capable of playing back video without additional
plugins. As a content publisher you just have to make it sure that
the videos are available in supported formats.
Mozilla Firefox relies on royality-free OGG Theora and OGG Vorbis codecs for video and audio.
For Google Chrome you need to use h264 video codec and AAC or MP3 audio codec.
Note that in US where software patents apply, you need to pay license fee for
using these patented codecs even if you're using open-source implementation!</summary>
    <link href="http://lauri.vosandi.com/2016/02/html5-video-with-ffmpeg.html"/>
    <content type="html"><![CDATA[<div class="document" id="publishing-html5-video-using-ffmpeg">
<!-- tags: HTML5, FFMPEG, Bash, h264, MP3, AAC, Xiph, Vorbis, Theora, OGG -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- date: 2016-02-27 -->
<p>Nowadays the web browser are capable of playing back video without additional
plugins. As a content publisher you just have to make it sure that
the videos are available in supported formats.
Mozilla Firefox relies on royality-free OGG Theora and OGG Vorbis codecs for video and audio.
For Google Chrome you need to use h264 video codec and AAC or MP3 audio codec.
Note that in US where software patents apply, you need to pay license fee for
using these patented codecs even if you're using open-source implementation!</p>
<pre class="code bash literal-block"><code><span class="nv">VIDEO_HEIGHT</span><span class="o">=</span><span class="m">720</span>

<span class="k">for</span> j in <span class="nv">$@</span><span class="p">;</span> <span class="k">do</span> <span class="se">\
</span>    <span class="c1"># Transcode for Firefox
</span>    ffmpeg -i <span class="nv">$j</span> <span class="se">\
</span>        -vcodec libtheora  -q:v <span class="m">5</span> -vf <span class="nv">scale</span><span class="o">=</span>-2:<span class="nv">$VIDEO_HEIGHT</span> <span class="se">\
</span>        -acodec libvorbis <span class="se">\
</span>        transcode/<span class="k">$(</span>basename <span class="nv">$j</span> .mov<span class="k">)</span>.ogv
    <span class="c1"># Transcode for Chrome
</span>    ffmpeg -i <span class="nv">$j</span> <span class="se">\
</span>        -c:v libx264 -preset veryslow -tune film -vf <span class="nv">scale</span><span class="o">=</span>-2:<span class="nv">$VIDEO_HEIGHT</span> <span class="se">\
</span>        -c:a copy <span class="se">\
</span>        transcode/<span class="k">$(</span>basename <span class="nv">$j</span> .mov<span class="k">)</span>.mp4
    <span class="c1"># You might want to add WebM here as well, but oh well
</span><span class="k">done</span></code></pre>
<p>Another script for generating nice looking index.html for listing the video files.
Also make sure your webserver reports Content-Type header properly,
see the mimetypes below in the HTML snippet.</p>
<pre class="code bash literal-block"><code><span class="nv">POSTER_WIDTH</span><span class="o">=</span><span class="m">384</span>
<span class="nv">POSTER_HEIGHT</span><span class="o">=</span><span class="m">216</span>

cat <span class="s">&lt;&lt; EOF &gt; transcode/index.html
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8"/&gt;
    &lt;meta name="viewport" content="width=device-width, user-scalable=no"/&gt;
  &lt;/head&gt;
  &lt;body&gt;
EOF</span>

<span class="k">for</span> j in korgem_kvaliteet/*/*<span class="p">;</span> <span class="k">do</span> <span class="se">\
</span>    <span class="c1"># Generate poster for the video
</span>    ffmpeg -i <span class="nv">$j</span> <span class="se">\
</span>        -ss <span class="m">15</span> -vframes <span class="m">1</span> -q:v <span class="m">2</span> -vf <span class="nv">scale</span><span class="o">=</span>-2:<span class="nv">$POSTER_HEIGHT</span> <span class="se">\
</span>        -y transcode/<span class="k">$(</span>basename <span class="nv">$j</span> .mov<span class="k">)</span>.jpg

    cat <span class="s">&lt;&lt; EOF &gt;&gt; transcode/index.html
    &lt;div style="display: inline-block; float:left; width: 400px; height: 250px;"&gt;
    &lt;h&gt;$(basename $j .mov)&lt;/h&gt;
    &lt;br/&gt;
    &lt;video width="$POSTER_WIDTH" height="$POSTER_HEIGHT" controls poster="$(basename $j .mov).jpg"&gt;
      &lt;source src="$(basename $j .mov).ogv" type="video/ogg"&gt;
      &lt;source src="$(basename $j .mov).mp4" type="video/mp4"&gt;
    &lt;/video&gt;
    &lt;/div&gt;
EOF</span>
<span class="k">done</span>

cat <span class="s">&lt;&lt; EOF &gt;&gt; transcode/index.html
  &lt;/body&gt;
&lt;/html&gt;
EOF</span></code></pre>
</div>
]]></content>
    
    <category term="AAC"/>
    <category term="Xiph"/>
    <category term="MP3"/>
    <category term="h264"/>
    <category term="Theora"/>
    <category term="Vorbis"/>
    <category term="FFMPEG"/>
    <category term="Bash"/>
    <category term="HTML5"/>
    <category term="OGG"/>
    <updated>2016-02-27T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Pythoni LDAP liides</title>
    <summary>Microsoft Active Directory'st ning Samba-baasil domeenikontrollerist saab andmeid
p&#228;rida &#252;le LDAP protokolli. M&#245;lemad toetavad ka GSSAPI-t, mis v&#245;imaldab
autentida osapooli ning kr&#252;pteerida liiklust.</summary>
    <link href="http://lauri.vosandi.com/lan/python-ldap.html"/>
    <content type="html"><![CDATA[<div class="document" id="pythoni-ldap-liides">
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags:  LDAP, GSSAPI, Python, Kerberos -->
<!-- date: 2016-02-25 -->
<div class="section" id="sissejuhatus">
<h1>Sissejuhatus</h1>
<p>Microsoft Active Directory'st ning Samba-baasil domeenikontrollerist saab andmeid
p&#228;rida &#252;le LDAP protokolli. M&#245;lemad toetavad ka GSSAPI-t, mis v&#245;imaldab
autentida osapooli ning kr&#252;pteerida liiklust.</p>
<p>Python 3.x jaoks pole veel saadaval LDAP-i moodulit mis toetaks Kerberost
ja GSSAPI-t.
Python 2.x jaoks saab s&#228;&#228;rase mooduli paigaldada:</p>
<pre class="code bash literal-block"><code>apt-get install python-ldap</code></pre>
<p>Igaks juhuks veendu, et ka vastavad SASL moodulid ning Kerberose t&#246;&#246;riistad on paigaldatud:</p>
<pre class="code bash literal-block"><code>apt-get install krb5-user libsasl2-modules-gssapi-heimdal</code></pre>
</div>
<div class="section" id="kasutaja-kontoga">
<h1>Kasutaja kontoga</h1>
<p>J&#228;rgnevas n&#228;ites k&#252;sitakse kasutajate nimed ja e-posti aadressid AD-st &#252;le LDAP-i
kasutades SASL teeke autentimiseks ning ka transportkihi kr&#252;pteerimiseks analoogselt
<span class="docutils literal">ldapsearch</span> k&#228;sule. N&#228;ide eeldab et on autenditud Kerberosega -- logi sisse domeeni kontoga
v&#245;i tee lihtsalt:</p>
<pre class="code bash literal-block"><code>kinit kasutaja@EXAMPLE.COM</code></pre>
<p>Pista j&#228;rgnev .py faili ning k&#228;ivita see Python abil:</p>
<pre class="code python literal-block"><code><span class="ch">#!/usr/bin/python2</span>
<span class="kn">import</span> <span class="nn">ldap</span><span class="o">,</span> <span class="nn">ldap.sasl</span>
<span class="n">conn</span> <span class="o">=</span> <span class="n">ldap</span><span class="o">.</span><span class="n">initialize</span><span class="p">(</span><span class="s1">'ldap://dc1.example.com'</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">set_option</span><span class="p">(</span><span class="n">ldap</span><span class="o">.</span><span class="n">OPT_REFERRALS</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">sasl_interactive_bind_s</span><span class="p">(</span><span class="s1">''</span><span class="p">,</span> <span class="n">ldap</span><span class="o">.</span><span class="n">sasl</span><span class="o">.</span><span class="n">gssapi</span><span class="p">())</span>
<span class="n">attribs</span> <span class="o">=</span> <span class="s1">'cn'</span><span class="p">,</span><span class="s1">'mail'</span><span class="p">,</span> <span class="s1">'userPrincipalName'</span>
<span class="n">search_filter</span> <span class="o">=</span> <span class="s1">'(&amp;(objectClass=user)(objectCategory=person))'</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">search_s</span><span class="p">(</span><span class="s1">'dc=example,dc=com'</span><span class="p">,</span> <span class="n">ldap</span><span class="o">.</span><span class="n">SCOPE_SUBTREE</span><span class="p">,</span> <span class="n">search_filter</span><span class="p">,</span> <span class="n">attribs</span><span class="p">)</span>
<span class="k">for</span> <span class="n">dn</span><span class="p">,</span><span class="n">entry</span> <span class="ow">in</span> <span class="n">r</span><span class="p">:</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">dn</span><span class="p">:</span> <span class="k">continue</span>
    <span class="n">full_name</span><span class="p">,</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"cn"</span><span class="p">)</span>
    <span class="n">mail</span><span class="p">,</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"mail"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"userPrincipalName"</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="bp">None</span><span class="p">,)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">mail</span><span class="p">:</span> <span class="k">continue</span>
    <span class="k">print</span> <span class="s2">"</span><span class="si">%s</span><span class="s2"> &lt;</span><span class="si">%s</span><span class="s2">&gt;, "</span> <span class="o">%</span> <span class="p">(</span><span class="n">full_name</span><span class="p">,</span> <span class="n">mail</span><span class="p">),</span></code></pre>
</div>
<div class="section" id="masina-kontoga">
<h1>Masina kontoga</h1>
<p>Arvuti domeeni liitmisel luuakse /etc/krb5.keytab, mille abil saab masin end
tuvastada domeenikontrollerile.
T&#228;ielikult automatiseeritud variant mida peab k&#228;itama root kasutaja &#245;igustes ning
mille saab n&#228;iteks croni pista oleks j&#228;rgnev:</p>
<pre class="code python literal-block"><code><span class="kn">import</span> <span class="nn">ldap</span><span class="o">,</span> <span class="nn">ldap.sasl</span>
<span class="kn">from</span> <span class="nn">subprocess</span> <span class="kn">import</span> <span class="n">call</span>
<span class="kn">from</span> <span class="nn">ConfigParser</span> <span class="kn">import</span> <span class="n">ConfigParser</span>

<span class="n">cp</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="p">()</span>
<span class="n">cp</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="s2">"/etc/samba/smb.conf"</span><span class="p">)</span>
<span class="n">domain</span> <span class="o">=</span> <span class="n">cp</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"global"</span><span class="p">,</span> <span class="s2">"realm"</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="n">base</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s2">"dc="</span> <span class="o">+</span> <span class="n">j</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">domain</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"."</span><span class="p">)])</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="s2">"kinit"</span><span class="p">,</span> <span class="s2">"-k"</span><span class="p">,</span> <span class="n">cp</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"global"</span><span class="p">,</span> <span class="s2">"netbios name"</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"$"</span>
<span class="n">call</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>

<span class="n">conn</span> <span class="o">=</span> <span class="n">ldap</span><span class="o">.</span><span class="n">initialize</span><span class="p">(</span><span class="s1">'ldap://'</span> <span class="o">+</span> <span class="n">domain</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">set_option</span><span class="p">(</span><span class="n">ldap</span><span class="o">.</span><span class="n">OPT_REFERRALS</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">sasl_interactive_bind_s</span><span class="p">(</span><span class="s1">''</span><span class="p">,</span> <span class="n">ldap</span><span class="o">.</span><span class="n">sasl</span><span class="o">.</span><span class="n">gssapi</span><span class="p">())</span>

<span class="n">attribs</span> <span class="o">=</span> <span class="s1">'cn'</span><span class="p">,</span><span class="s1">'mail'</span><span class="p">,</span> <span class="s1">'userPrincipalName'</span>
<span class="n">search_filter</span> <span class="o">=</span> <span class="s1">'(&amp;(objectClass=user)(objectCategory=person))'</span>

<span class="k">for</span> <span class="n">dn</span><span class="p">,</span><span class="n">entry</span> <span class="ow">in</span> <span class="n">conn</span><span class="o">.</span><span class="n">search_s</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">ldap</span><span class="o">.</span><span class="n">SCOPE_SUBTREE</span><span class="p">,</span> <span class="n">search_filter</span><span class="p">,</span> <span class="n">attribs</span><span class="p">):</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">dn</span><span class="p">:</span> <span class="k">continue</span>
    <span class="n">full_name</span><span class="p">,</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"cn"</span><span class="p">)</span>
    <span class="n">mail</span><span class="p">,</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"mail"</span><span class="p">)</span> <span class="ow">or</span> <span class="n">entry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"userPrincipalName"</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="bp">None</span><span class="p">,)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">mail</span><span class="p">:</span> <span class="k">continue</span>
    <span class="k">print</span> <span class="s2">"</span><span class="si">%s</span><span class="s2"> &lt;</span><span class="si">%s</span><span class="s2">&gt;, "</span> <span class="o">%</span> <span class="p">(</span><span class="n">full_name</span><span class="p">,</span> <span class="n">mail</span><span class="p">),</span></code></pre>
</div>
<div class="section" id="kokkuvote">
<h1>Kokkuv&#245;te</h1>
<p>K&#228;esolevatele koodijuppidele v&#245;ib leida tosin huvitavat rakendusala -
sisselogimisel v&#245;rguketaste lisamine j&#228;rjehoidjatesse, printerite lisamine
grupipoliitika alusel vms aga sellest juba j&#228;rgmine kord.</p>
</div>
</div>
]]></content>
    
    <category term="GSSAPI"/>
    <category term="Python"/>
    <category term="LDAP"/>
    <category term="Kerberos"/>
    <updated>2016-02-25T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Fixing Broadcom BCM5762 for Ubuntu 14.04</title>
    <summary>Broadcom is continuously doing terrible work with their wired and wireless cards,
basically any other hardware vendor is doing better job maintaining open-source
drivers than Broadcom.</summary>
    <link href="http://lauri.vosandi.com/2016/02/fixing-broadcom-bcm5762-on-ubuntu.html"/>
    <content type="html"><![CDATA[<div class="document" id="fixing-broadcom-bcm5762-for-ubuntu-14-04">
<!-- tags: Ubuntu, Linux, Broadcom, ethtool -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- date: 2016-02-20 -->
<p>Broadcom is continuously doing terrible work with their wired and wireless cards,
basically any other hardware vendor is doing better job maintaining open-source
drivers than Broadcom.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>Avoid procuring Broadcom equipment</p>
</div>
<p><a class="reference external" href="http://www8.hp.com/us/en/ads/elite-amd-products/elitedesk-705-sff.html">HP EliteDesk 705 G1 SFF</a>
contains
<a class="reference external" href="https://www.broadcom.com/products/ethernet-communication-and-switching/ethernet-controllers/bcm5762">Broadcom BCM5762</a> (14e4:1687) wired ethernet and at least with kernels
from 3.13 up to 4.1 the machine loses connectivity if there is high load on the
network interface <a class="footnote-reference brackets" href="#bug1447664" id="id1">1</a>.</p>
<p>It took several days to come up with a workaround for the issue and here it is.
Following disables some fancy DMA functionality on the card keeping it at least usable:</p>
<pre class="code bash literal-block"><code>ethtool -K eth0 highdma off</code></pre>
<p>Create /etc/udev/rules.d/80-tg3-fix.rules with following content to make the changes permanent:</p>
<pre class="code bash literal-block"><code><span class="nv">ACTION</span><span class="o">==</span><span class="s2">"add"</span>, <span class="nv">SUBSYSTEM</span><span class="o">==</span><span class="s2">"net"</span>, ATTRS<span class="o">{</span>vendor<span class="o">}==</span><span class="s2">"0x14e4"</span>, ATTRS<span class="o">{</span>device<span class="o">}==</span><span class="s2">"0x1687"</span>, <span class="nv">RUN</span><span class="o">+=</span><span class="s2">"/sbin/ethtool -K %k highdma off"</span></code></pre>
<p>If you're using Puppet simply add following to your manifest:</p>
<pre class="code puppet literal-block"><code><span class="k">file</span> <span class="p">{</span> <span class="s">"/etc/udev/rules.d/80-tg3-fix.rules"</span><span class="p">:</span>
    <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">present</span><span class="p">,</span>
    <span class="na">mode</span> <span class="o">=&gt;</span> <span class="mi">644</span><span class="p">,</span>
    <span class="na">owner</span> <span class="o">=&gt;</span> <span class="na">root</span><span class="p">,</span>
    <span class="na">group</span> <span class="o">=&gt;</span> <span class="na">root</span><span class="p">,</span>
    <span class="na">content</span> <span class="o">=&gt;</span> <span class="s">'ACTION=="add", SUBSYSTEM=="net", ATTRS{vendor}=="0x14e4", ATTRS{device}=="0x1687", RUN+="/sbin/ethtool -K %k highdma off"'</span>
<span class="p">}</span></code></pre>
<p>Hopefully the fix will be merged upstream soon.</p>
<dl class="footnote brackets">
<dt class="label" id="bug1447664"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
<dd><p><a class="reference external" href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1447664">https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1447664</a></p>
</dd>
</dl>
</div>
]]></content>
    
    <category term="Ubuntu"/>
    <category term="Linux"/>
    <category term="Broadcom"/>
    <category term="ethtool"/>
    <updated>2016-02-20T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Ubuntu 14.04 riistvara toe uuendamine</title>
    <summary>Ubuntu 14.04 kaasa pandud riistvara tugi hakkab tasapisi ajast maha j&#228;&#228;ma
ning n&#228;iteks
AMD A10 ja A8 APU-dega varustatud masinates peaks paigaldama v&#228;rskemad
Ubuntu 15.10 videokaardi draiverid:</summary>
    <link href="http://lauri.vosandi.com/2016/02/trusty-hardware-enablement-stack.html"/>
    <content type="html"><![CDATA[<div class="document" id="ubuntu-14-04-riistvara-toe-uuendamine">
<!-- tags: Ubuntu, Linux, AMD, Xorg -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- date: 2016-02-19 -->
<p>Ubuntu 14.04 kaasa pandud riistvara tugi hakkab tasapisi ajast maha j&#228;&#228;ma
ning n&#228;iteks
AMD A10 ja A8 APU-dega varustatud masinates peaks paigaldama v&#228;rskemad
Ubuntu 15.10 videokaardi draiverid:</p>
<pre class="code bash literal-block"><code>sudo apt-get install -y <span class="se">\
</span>    xserver-xorg-core-lts-wily <span class="se">\
</span>    xserver-xorg-lts-wily <span class="se">\
</span>    xserver-xorg-video-all-lts-wily <span class="se">\
</span>    xserver-xorg-input-all-lts-wily <span class="se">\
</span>    mesa-vdpau-drivers-lts-wily <span class="se">\
</span>    libwayland-egl1-mesa-lts-wily <span class="se">\
</span>    libgl1-mesa-glx-lts-wily <span class="se">\
</span>    libgl1-mesa-glx-lts-wily:i386 <span class="se">\
</span>    libglapi-mesa-lts-wily:i386 <span class="se">\
</span>    libgles2-mesa-lts-wily <span class="se">\
</span>    libgles1-mesa-lts-wily <span class="se">\
</span>    xserver-xorg-video-qxl-lts-wily</code></pre>
<p>Paigalda ka v&#228;rske LTS tuum, see pole veel Ubuntu repodesse maandunud:</p>
<pre class="code bash literal-block"><code>wget -c <span class="se">\
</span>    http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.4.2-wily/linux-headers-4.4.2-040402_4.4.2-040402.201602171633_all.deb <span class="se">\
</span>    http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.4.2-wily/linux-headers-4.4.2-040402-generic_4.4.2-040402.201602171633_amd64.deb <span class="se">\
</span>    http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.4.2-wily/linux-image-4.4.2-040402-generic_4.4.2-040402.201602171633_amd64.deb
sudo dpkg -i <span class="se">\
</span>    linux-headers-4.4.2-040402_4.4.2-040402.201602171633_all.deb <span class="se">\
</span>    linux-headers-4.4.2-040402-generic_4.4.2-040402.201602171633_amd64.deb <span class="se">\
</span>    linux-image-4.4.2-040402-generic_4.4.2-040402.201602171633_amd64.deb
sudo rm -fv <span class="se">\
</span>    linux-headers-4.4.2-040402_4.4.2-040402.201602171633_all.deb <span class="se">\
</span>    linux-headers-4.4.2-040402-generic_4.4.2-040402.201602171633_amd64.deb <span class="se">\
</span>    linux-image-4.4.2-040402-generic_4.4.2-040402.201602171633_amd64.deb</code></pre>
<p>L&#245;puks tee masinale taask&#228;ivitus.</p>
</div>
]]></content>
    
    <category term="Ubuntu"/>
    <category term="Linux"/>
    <category term="Xorg"/>
    <category term="AMD"/>
    <updated>2016-02-19T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Installing printers with Puppet</title>
    <summary>This guide is for anyone interested in installing printers remotely using
Puppet for Ubuntu 14.04.</summary>
    <link href="http://lauri.vosandi.com/cfgmgmt/puppet-cups.html"/>
    <content type="html"><![CDATA[<div class="document" id="installing-printers-with-puppet">
<!-- tags: Puppet, CUPS, Ubuntu, Lexmark, HP -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- date: 2016-02-14 -->
<div class="section" id="introduction">
<h1>Introduction</h1>
<p>This guide is for anyone interested in installing printers remotely using
Puppet for Ubuntu 14.04.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>Avoid procuring Canon printers</p>
</div>
<p>So far I haven't seen a sane way to install Canon printers.
A reasonable printer doesn't need local drivers/filters and
uses platform independent protocol such as
<a class="reference external" href="https://en.wikipedia.org/wiki/Internet_Printing_Protocol">Internet Printing Protocol</a>.</p>
</div>
<div class="section" id="dependencies">
<h1>Dependencies</h1>
<p>First install the <a class="reference external" href="https://github.com/mosen/puppet-cups">CUPS module for Puppet</a> on the Puppetmaster:</p>
<pre class="code bash literal-block"><code>puppet module install mosen-cups</code></pre>
<p>For the workstations add some packages to enable printing stack:</p>
<pre class="code puppet literal-block"><code><span class="c"># Install CUPS and filters</span>
<span class="k">package</span> <span class="p">{</span> <span class="s">"system-config-printer-gnome"</span><span class="p">:</span> <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">installed</span> <span class="p">}</span>
<span class="k">package</span> <span class="p">{</span> <span class="s">"cups"</span><span class="p">:</span> <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">installed</span> <span class="p">}</span>
<span class="k">package</span> <span class="p">{</span> <span class="s">"ghostscript"</span><span class="p">:</span> <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">installed</span> <span class="p">}</span>
<span class="k">package</span> <span class="p">{</span> <span class="s">"unpaper"</span><span class="p">:</span> <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">installed</span> <span class="p">}</span>
<span class="k">package</span> <span class="p">{</span> <span class="s">"printer-driver-all"</span> <span class="o">=&gt;</span> <span class="k">installed</span> <span class="p">}</span><span class="c">

# PPD-s</span>
<span class="k">package</span> <span class="p">{</span> <span class="s">"openprinting-ppds"</span><span class="p">:</span> <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">installed</span> <span class="p">}</span>
<span class="k">package</span> <span class="p">{</span> <span class="s">"hpijs-ppds"</span><span class="p">:</span> <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">installed</span> <span class="p">}</span>
<span class="k">package</span> <span class="p">{</span> <span class="s">"hp-ppd"</span><span class="p">:</span> <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">installed</span> <span class="p">}</span>
<span class="k">package</span> <span class="p">{</span> <span class="s">"foomatic-db-compressed-ppds"</span><span class="p">:</span> <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">installed</span> <span class="p">}</span></code></pre>
</div>
<div class="section" id="detecting-printers">
<h1>Detecting printers</h1>
<p>Following should discover printers sitting on the network as well as ones connected via USB:</p>
<pre class="code bash literal-block"><code>lpinfo -v</code></pre>
<p>If that's not helpful use nmap to discover the ports on the printer's IP-address:</p>
<pre class="code bash literal-block"><code>nmap <span class="m">192</span>.168.?.?</code></pre>
</div>
<div class="section" id="installing-hp-laserjet-2100">
<h1>Installing HP LaserJet 2100</h1>
<p>This printer uses JetDirect protocol which means the document has to prepared
locally on the computer and then sent via TCP 9100 port to the printer.
Use the vendor name and model name bits to figure out which is the most
suitable PPD for the printer:</p>
<pre class="code bash literal-block"><code>lpinfo -m <span class="p">|</span> grep HP <span class="p">|</span> grep Laser <span class="p">|</span> grep <span class="m">2100</span> <span class="p">|</span> grep recommended</code></pre>
<p>Corresponding Puppet snippet:</p>
<pre class="code puppet literal-block"><code><span class="na">printer</span> <span class="p">{</span> <span class="s">"HP-LaserJet-2100"</span><span class="p">:</span>
    <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">present</span><span class="p">,</span>
    <span class="na">uri</span> <span class="o">=&gt;</span> <span class="s">'socket://192.168.2.12'</span><span class="p">,</span>
    <span class="na">description</span> <span class="o">=&gt;</span> <span class="s">'HP LaserJet 2100'</span><span class="p">,</span>
    <span class="na">model</span> <span class="o">=&gt;</span> <span class="s">'foomatic-db-compressed-ppds:0/ppd/foomatic-ppd/HP-LaserJet_2100-pxlmono.ppd'</span><span class="p">,</span>
    <span class="na">page_size</span> <span class="o">=&gt;</span> <span class="s">'A4'</span>
<span class="p">}</span></code></pre>
<p>In <span class="docutils literal">lpinfo <span class="pre">-v</span></span> you can identify such printers by <span class="docutils literal"><span class="pre">socket://</span></span> protocol
used in the URI.</p>
</div>
<div class="section" id="installing-lexmark-410dn">
<h1>Installing Lexmark 410dn</h1>
<p>This printer uses Internet Printing Protocol over TCP port 631.
In this case the document is sent over network in PostScript format and
printer takes care of the rest.
Printer definition file still has to supply some information
about the supported page sizes,
<a class="reference external" href="https://en.wikipedia.org/wiki/Duplex_printing">duplex support</a> etc.</p>
<pre class="code puppet literal-block"><code><span class="na">printer</span> <span class="p">{</span> <span class="s">"Lexmark-MS410dn"</span><span class="p">:</span>
    <span class="na">ensure</span>      <span class="o">=&gt;</span> <span class="k">present</span><span class="p">,</span>
    <span class="na">uri</span>         <span class="o">=&gt;</span> <span class="s">'ipp://10.254.201.50:631/ipp'</span><span class="p">,</span>
    <span class="na">description</span> <span class="o">=&gt;</span> <span class="s">'Lexmark MS410dn'</span><span class="p">,</span>
    <span class="na">model</span>       <span class="o">=&gt;</span> <span class="s">'foomatic-db-compressed-ppds:0/ppd/foomatic-ppd/Lexmark-MS410dn-Postscript.ppd'</span><span class="p">,</span>
    <span class="na">page_size</span>    <span class="o">=&gt;</span> <span class="s">'A4'</span>
<span class="p">}</span></code></pre>
<p>In <span class="docutils literal">lpinfo <span class="pre">-v</span></span> you can identify such printers by <span class="docutils literal"><span class="pre">ipp://</span></span> protocol
used in the URI.</p>
</div>
<div class="section" id="installing-usb-printers">
<h1>Installing USB printers</h1>
<p>Here are some examples how USB printers are installed.
In most cases <span class="docutils literal">lpinfo <span class="pre">-v</span></span> was used to
determine the device URI and <span class="docutils literal">lpinfo <span class="pre">-m</span></span> was grepped to identify
suitable printer model:</p>
<p>HP LaserJet 1505:</p>
<pre class="code puppet literal-block"><code><span class="na">printer</span> <span class="p">{</span> <span class="s">"HP-LaserJet-1505n"</span><span class="p">:</span>
    <span class="na">ensure</span>      <span class="o">=&gt;</span> <span class="k">present</span><span class="p">,</span>
    <span class="na">uri</span>         <span class="o">=&gt;</span> <span class="s">"usb://HP/LaserJet%20P1505n?serial=KQ154T9"</span><span class="p">,</span>
    <span class="na">description</span> <span class="o">=&gt;</span> <span class="s">"HP LaserJet 1505n"</span><span class="p">,</span>
    <span class="na">model</span>       <span class="o">=&gt;</span> <span class="s">"foo2zjs:0/ppd/foo2zjs/HP-LaserJet_P1505n.ppd"</span><span class="p">,</span>
    <span class="na">page_size</span>    <span class="o">=&gt;</span> <span class="s">'A4'</span>
<span class="p">}</span></code></pre>
<p>HP LaserJet 1200:</p>
<pre class="code puppet literal-block"><code><span class="na">printer</span> <span class="p">{</span> <span class="s">"HP-LaserJet-1200"</span><span class="p">:</span>
    <span class="na">ensure</span>      <span class="o">=&gt;</span> <span class="k">present</span><span class="p">,</span>
    <span class="na">uri</span>         <span class="o">=&gt;</span> <span class="s">'usb://HP/LaserJet%201200?serial=00CNBP009193'</span><span class="p">,</span>
    <span class="na">description</span> <span class="o">=&gt;</span> <span class="s">'HP LaserJet 1200'</span><span class="p">,</span>
    <span class="na">model</span>       <span class="o">=&gt;</span> <span class="s">'lsb/usr/hplip/HP/hp-laserjet_1200n-hpijs.ppd'</span><span class="p">,</span>
    <span class="na">page_size</span>    <span class="o">=&gt;</span> <span class="s">'A4'</span>
<span class="p">}</span></code></pre>
<p>HP DeskJet 2540:</p>
<pre class="code puppet literal-block"><code><span class="na">printer</span> <span class="p">{</span> <span class="s">"HP-DeskJet-2540"</span><span class="p">:</span>
    <span class="na">ensure</span> <span class="o">=&gt;</span> <span class="k">present</span><span class="p">,</span>
    <span class="na">uri</span> <span class="o">=&gt;</span> <span class="s">'usb://HP/Deskjet%202540%20series?serial=CN4CO5F38C0604&amp;interface=1'</span><span class="p">,</span>
    <span class="na">description</span> <span class="o">=&gt;</span> <span class="s">'HP DeskJet 2540'</span><span class="p">,</span>
    <span class="na">model</span> <span class="o">=&gt;</span> <span class="s">'lsb/usr/hplip/HP/hp-deskjet_2540_series-hpijs.ppd'</span><span class="p">,</span>
    <span class="na">page_size</span> <span class="o">=&gt;</span> <span class="s">'A4'</span>
<span class="p">}</span></code></pre>
</div>
</div>
]]></content>
    
    <category term="Lexmark"/>
    <category term="Ubuntu"/>
    <category term="CUPS"/>
    <category term="HP"/>
    <category term="Puppet"/>
    <updated>2016-02-14T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>OpenWrt paigaldus x86 masinasse</title>
    <summary>OpenWrt on t&#252;&#252;piliselt paigaldatud MIPS v&#245;i ARM protsessoriga
miniarvutitesse nagu Mikrotik, Gateworks, Compex ja
OpenWrt on saadaval ka paljudele <em>off-the-shelf</em> marsruuteritele.
Samas v&#245;ib OpenWrt paigaldada ka tavalisele x86 riistvarale.
K&#228;esolevas blogipostituses on kirjeldatud kolm viisi OpenWrt
paigalduseks x86 raual: otse f&#252;&#252;silisele,
virtuaalmasinale VirtualBoxis ning virtuaalmasinale KVM-is.
Esimene v&#245;rguliides on &#252;hendatud sisev&#245;rgu tsooni ning teine v&#245;rguliides
k&#252;sib DHCP-ga aadressi v&#228;ljapoolt.</summary>
    <link href="http://lauri.vosandi.com/lan/openwrt-install.html"/>
    <content type="html"><![CDATA[<div class="document" id="openwrt-paigaldus-x86-masinasse">
<!-- date: 2016-01-20 -->
<!-- tags: OpenWrt, KVM, VirtualBox, VDI, qemu-img -->
<div class="section" id="sissejuhatus">
<h1>Sissejuhatus</h1>
<p>OpenWrt on t&#252;&#252;piliselt paigaldatud MIPS v&#245;i ARM protsessoriga
miniarvutitesse nagu Mikrotik, Gateworks, Compex ja
OpenWrt on saadaval ka paljudele <em>off-the-shelf</em> marsruuteritele.
Samas v&#245;ib OpenWrt paigaldada ka tavalisele x86 riistvarale.
K&#228;esolevas blogipostituses on kirjeldatud kolm viisi OpenWrt
paigalduseks x86 raual: otse f&#252;&#252;silisele,
virtuaalmasinale VirtualBoxis ning virtuaalmasinale KVM-is.
Esimene v&#245;rguliides on &#252;hendatud sisev&#245;rgu tsooni ning teine v&#245;rguliides
k&#252;sib DHCP-ga aadressi v&#228;ljapoolt.</p>
<p>Laadi alla OpenWrt k&#245;vakettat&#245;mmis ning paki see lahti:</p>
<pre class="code bash literal-block"><code>wget https://downloads.openwrt.org/chaos_calmer/15.05.1/x86/generic/openwrt-15.05.1-x86-generic-combined-ext4.img.gz
gunzip openwrt-15.05.1-x86-generic-combined-ext4.img.gz</code></pre>
</div>
<div class="section" id="fuusilisse-masinasse-paigaldus">
<h1>F&#252;&#252;silisse masinasse paigaldus</h1>
<p>Paigaldada saad n&#228;iteks olles teinud alglaadimise Ubuntu LiveCD-lt.</p>
<p>Kirjuta t&#245;mmis esimesele kettale:</p>
<pre class="code bash literal-block"><code>umount /dev/sda*
cat openwrt-15.05-x86-generic-combined-ext4.img &gt; /dev/sda</code></pre>
<p>Suurenda viimane <em>ext4</em> failis&#252;steem ketta suuruseks.</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"d\n2"</span> <span class="p">|</span> fdisk /dev/sda
resize2fs /dev/sda2</code></pre>
<p>Tee taask&#228;ivitus k&#245;vakettalt.</p>
</div>
<div class="section" id="vmware-esxi-voi-workstation">
<h1>VMware ESXi v&#245;i Workstation</h1>
<p>Kas nimeta fail &#252;mber <span class="docutils literal">.raw</span> l&#245;puliseks:</p>
<pre class="code bash literal-block"><code>mv openwrt-15.05-x86-generic-combined-ext4.img <span class="se">\
</span>    openwrt-15.05-x86-generic-combined-ext4.raw</code></pre>
<p>V&#245;i teisenda VMware formaati &#252;mber:</p>
<pre class="code bash literal-block"><code>qemu-img convert <span class="se">\
</span>    -f raw openwrt-15.05-x86-generic-combined-ext4.img <span class="se">\
</span>    -O vmdk openwrt-15.05-x86-generic-combined-ext4.vmdk</code></pre>
</div>
<div class="section" id="virtualbox">
<h1>VirtualBox</h1>
<p>VirtualBox tahab kettat&#245;mmist saada VirtualBoxile s&#246;&#246;davas formaadis,
mist&#245;ttu 1:1 kettat&#245;mmis tuleb esmalt teisendada VDI failiks:</p>
<pre class="code bash literal-block"><code>qemu-img convert <span class="se">\
</span>    -f raw openwrt-15.05-x86-generic-combined-ext4.img <span class="se">\
</span>    -O vdi openwrt-15.05-x86-generic-combined-ext4.vdi</code></pre>
<p>Seej&#228;rel tuleb luua marsruuteri jaoks virtuaalmasin,
selle jaoks piisab t&#228;iesti &#252;hest tuumast ning 32MB m&#228;lust.
&#220;lal teisendatud kettat&#245;mmis m&#228;&#228;ra esimeseks k&#245;vakettaks.</p>
</div>
<div class="section" id="kvm">
<h1>KVM</h1>
<p>Laadi alla KVM jaoks kohandatud t&#245;mmis</p>
<pre class="code bash literal-block"><code>wget https://downloads.openwrt.org/chaos_calmer/15.05.1/x86/kvm_guest/openwrt-15.05.1-x86-kvm_guest-combined-ext4.img.gz
gunzip openwrt-15.05.1-x86-kvm_guest-combined-ext4.img.gz</code></pre>
<p>K&#228;ivitamiseks KVM virtuaalmasinas loo esmalt sild mille k&#252;lge
&#252;hendada sisev&#245;rk:</p>
<pre class="code bash literal-block"><code>brctl addbr br0</code></pre>
<p>Seej&#228;rel loo skript /etc/qemu-ifup millega virtuaalmasin silla k&#252;lge &#252;hendatakse:</p>
<pre class="code bash literal-block"><code><span class="ch">#!/bin/bash
</span>ifconfig <span class="nv">$1</span> <span class="m">0</span>.0.0.0 promisc up
brctl addif br0 <span class="nv">$1</span></code></pre>
<p>Tee see ka k&#228;ivitatavaks:</p>
<pre class="code bash literal-block"><code>chmod +x /etc/qemu-ifup</code></pre>
<p>Seej&#228;rel k&#228;ivita virtuaalmasin:</p>
<pre class="code bash literal-block"><code>kvm -smp <span class="m">2</span> -m <span class="m">32</span> <span class="se">\
</span>    -hda openwrt-15.05-x86-generic-combined-ext4.img <span class="se">\
</span>    -netdev tap,script<span class="o">=</span>/etc/qemu-ifup,id<span class="o">=</span>lan -device e1000,netdev<span class="o">=</span>lan <span class="se">\
</span>    -netdev user,id<span class="o">=</span>wan -device e1000,netdev<span class="o">=</span>wan</code></pre>
<p>Antud juhul esimene v&#245;rguliides &#252;hendatakse br0 sillaga ning
teisele v&#245;rguliidesele teeb QEMU ise NAT-i.</p>
</div>
</div>
]]></content>
    
    <category term="VirtualBox"/>
    <category term="KVM"/>
    <category term="OpenWrt"/>
    <category term="VDI"/>
    <category term="qemu-img"/>
    <updated>2016-01-20T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Ubuntu 14.04, LTSP ja ID-kaart</title>
    <summary>class="admonition-title">Important</summary>
    <link href="http://lauri.vosandi.com/cfgmgmt/trusty-ltsp-ja-id-kaart.html"/>
    <content type="html"><![CDATA[<div class="document" id="ubuntu-14-04-ltsp-ja-id-kaart">
<!-- title: Ubuntu 14.04, LTSP ja ID-kaart -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags: LTSP, Ubuntu, Debian, Cubietruck, PKCS#11, OpenSC, pcscd, PCSC-Lite, ID-card, ID-kaart, NBD, OpenSSH, opensc-tool -->
<!-- redirect_from: /cfgmgmt/ubuntu-vivid-vervet-ltsp-ja-id-kaart.html -->
<!-- date: 2016-01-19 -->
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>K&#228;esolev juhend on aegunud, Ubuntu 16.04 jaoks sobiv juhend on aadressil <a class="reference external" href="http://lauri.vosandi.com/2016/09/xenial-ltsp-ja-id-kaart.html">http://lauri.vosandi.com/2016/09/xenial-ltsp-ja-id-kaart.html</a></p>
</div>
<p>Juhend eeldab <a class="reference external" href="http://releases.ubuntu.com/14.04.3/">Ubuntu 14.04 server</a>  paigaldust.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="79 -113 231 324" preserveAspectRatio="xMidYMid meet" style=""><g><rect x="140.841" y="150.091" width="40.339" height="30.2542" fill="#b3b3b3"/><rect x="140.841" y="150.091" width="40.339" height="30.2542" fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="145.211" y="154.461" width="31.5989" height="20.8418" fill="#000000"/><polygon points="146.303,180.345 167.061,180.345 167.061,185.051 147.396,185.051 " fill="#b3b3b3"/><polygon points="146.303,180.345 167.061,180.345 167.061,185.051 147.396,185.051 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><polygon points="167.061,180.345 175.717,180.345 174.625,185.051 167.061,185.051 " fill="#b3b3b3"/><polygon points="167.061,180.345 175.717,180.345 174.625,185.051 167.061,185.051 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="168.473" y="181.757" width="1.88249" height="1.88249" fill="#ffffff"/><rect x="168.473" y="181.757" width="1.88249" height="1.88249" fill="none" fill-opacity="0" stroke-width="0.5" stroke="#000000"/><polygon points="156.976,185.051 165.044,185.051 165.044,187.404 169.078,187.404 169.078,189.757 152.943,189.757 152.943,187.404 156.976,187.404 " fill="#b3b3b3"/><polygon points="156.976,185.051 165.044,185.051 165.044,187.404 169.078,187.404 169.078,189.757 152.943,189.757 152.943,187.404 156.976,187.404 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><text font-size="12.7998" x="161.01" y="203.102" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="161.01" y="203.102"/></text></g><g><rect x="80.8409" y="150.091" width="40" height="30" fill="#b3b3b3"/><rect x="80.8409" y="150.091" width="40" height="30" fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="85.1742" y="154.424" width="31.3333" height="20.6667" fill="#000000"/><polygon points="86.2576,180.091 106.841,180.091 106.841,184.757 87.3409,184.757 " fill="#b3b3b3"/><polygon points="86.2576,180.091 106.841,180.091 106.841,184.757 87.3409,184.757 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><polygon points="106.841,180.091 115.424,180.091 114.341,184.757 106.841,184.757 " fill="#b3b3b3"/><polygon points="106.841,180.091 115.424,180.091 114.341,184.757 106.841,184.757 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="108.241" y="181.491" width="1.86667" height="1.86667" fill="#ffffff"/><rect x="108.241" y="181.491" width="1.86667" height="1.86667" fill="none" fill-opacity="0" stroke-width="0.5" stroke="#000000"/><polygon points="96.8409,184.757 104.841,184.757 104.841,187.091 108.841,187.091 108.841,189.424 92.8409,189.424 92.8409,187.091 96.8409,187.091 " fill="#b3b3b3"/><polygon points="96.8409,184.757 104.841,184.757 104.841,187.091 108.841,187.091 108.841,189.424 92.8409,189.424 92.8409,187.091 96.8409,187.091 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><text font-size="12.7998" x="100.841" y="202.757" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="100.841" y="202.757"/></text></g><g><rect x="260.841" y="150.091" width="40.678" height="30.5085" fill="#b3b3b3"/><rect x="260.841" y="150.091" width="40.678" height="30.5085" fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="265.248" y="154.497" width="31.8644" height="21.0169" fill="#000000"/><polygon points="266.349,180.599 287.282,180.599 287.282,185.345 267.451,185.345 " fill="#b3b3b3"/><polygon points="266.349,180.599 287.282,180.599 287.282,185.345 267.451,185.345 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><polygon points="287.282,180.599 296.01,180.599 294.909,185.345 287.282,185.345 " fill="#b3b3b3"/><polygon points="287.282,180.599 296.01,180.599 294.909,185.345 287.282,185.345 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="288.705" y="182.023" width="1.89831" height="1.89831" fill="#ffffff"/><rect x="288.705" y="182.023" width="1.89831" height="1.89831" fill="none" fill-opacity="0" stroke-width="0.5" stroke="#000000"/><polygon points="277.112,185.345 285.248,185.345 285.248,187.718 289.315,187.718 289.315,190.091 273.044,190.091 273.044,187.718 277.112,187.718 " fill="#b3b3b3"/><polygon points="277.112,185.345 285.248,185.345 285.248,187.718 289.315,187.718 289.315,190.091 273.044,190.091 273.044,187.718 277.112,187.718 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><text font-size="12.7998" x="281.18" y="203.447" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="281.18" y="203.447"/></text></g><g><rect x="200.841" y="150.091" width="40.339" height="30.2542" fill="#b3b3b3"/><rect x="200.841" y="150.091" width="40.339" height="30.2542" fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="205.211" y="154.461" width="31.5989" height="20.8418" fill="#000000"/><polygon points="206.303,180.345 227.061,180.345 227.061,185.051 207.396,185.051 " fill="#b3b3b3"/><polygon points="206.303,180.345 227.061,180.345 227.061,185.051 207.396,185.051 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><polygon points="227.061,180.345 235.717,180.345 234.625,185.051 227.061,185.051 " fill="#b3b3b3"/><polygon points="227.061,180.345 235.717,180.345 234.625,185.051 227.061,185.051 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><rect x="228.473" y="181.757" width="1.88249" height="1.88249" fill="#ffffff"/><rect x="228.473" y="181.757" width="1.88249" height="1.88249" fill="none" fill-opacity="0" stroke-width="0.5" stroke="#000000"/><polygon points="216.976,185.051 225.044,185.051 225.044,187.404 229.078,187.404 229.078,189.757 212.943,189.757 212.943,187.404 216.976,187.404 " fill="#b3b3b3"/><polygon points="216.976,185.051 225.044,185.051 225.044,187.404 229.078,187.404 229.078,189.757 212.943,189.757 212.943,187.404 216.976,187.404 " fill="none" fill-opacity="0" stroke-width="1" stroke="#000000"/><text font-size="12.7998" x="221.01" y="203.102" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="221.01" y="203.102"/></text></g><g><rect x="116.418" y="-63.5911" width="44.1388" height="102.99" fill="#b3b3b3"/><rect x="116.418" y="-63.5911" width="44.1388" height="102.99" fill="none" fill-opacity="0" stroke-width="1.6" stroke="#000000"/><rect x="120.832" y="-57.4116" width="35.311" height="11.7703" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="120.832" y="-45.6413" width="35.311" height="11.7703" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="120.832" y="-33.871" width="35.311" height="11.7703" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="120.832" y="-22.1006" width="35.311" height="11.7703" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="120.832" y="-7.97622" width="22.0694" height="7.0622" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><ellipse cx="153.936" cy="-6.79919" rx="1.54486" ry="1.54486" fill="#00ff00"/><ellipse cx="153.936" cy="-6.79919" rx="1.54486" ry="1.54486" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><ellipse cx="153.936" cy="-2.09106" rx="1.54486" ry="1.54486" fill="#ffff00"/><ellipse cx="153.936" cy="-2.09106" rx="1.54486" ry="1.54486" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><rect x="145.108" y="-5.62216" width="5.29665" height="4.70813" fill="#ffffff"/><rect x="145.108" y="-5.62216" width="5.29665" height="4.70813" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 123.775 8.50224 L 123.775,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 131.131 8.50224 L 131.131,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 138.488 8.50224 L 138.488,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 145.844 8.50224 L 145.844,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 153.2 8.50224 L 153.2,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><path d="M 160.557 8.50224 L 160.557,34.2499" fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><polygon points="107.59,48.2271 116.418,30.5716 116.418,39.3994 160.557,39.3994 160.557,30.5716 172.327,48.2271 " fill="#999999"/><polygon points="107.59,48.2271 116.418,30.5716 116.418,39.3994 160.557,39.3994 160.557,30.5716 172.327,48.2271 " fill="none" fill-opacity="0" stroke-width="0.2" stroke="#000000"/><text font-size="12.7998" x="139.959" y="63.1697" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="139.959" y="63.1697"/></text></g><g><path d="M 229.683 -41.7566 C 221.659,-41.9548 206.097,-37.7928 208.286,-28.8741 C 210.474,-19.9553 220.93,-17.9735 225.307,-20.5499 C 229.683,-23.1264 218.498,-8.06382 239.896,-4.09995 C 261.294,-0.136082 272.236,-6.47827 269.075,-11.0367 C 265.914,-15.5952 287.798,-0.334276 298.01,-9.05479 C 308.223,-17.7753 287.555,-26.0993 291.931,-24.9102 C 296.308,-23.721 309.682,-25.3066 305.305,-40.1711 C 300.928,-55.0356 261.537,-43.5404 265.914,-45.7205 C 270.29,-47.9006 259.348,-58.8013 245.732,-56.6212 C 232.115,-54.441 231.149,-50.4849 229.69,-41.7644 L 229.683,-41.7566z" fill="#ffffff"/><path d="M 229.683 -41.7566 C 221.659,-41.9548 206.097,-37.7928 208.286,-28.8741 C 210.474,-19.9553 220.93,-17.9735 225.307,-20.5499 C 229.683,-23.1264 218.498,-8.06382 239.896,-4.09995 C 261.294,-0.136082 272.236,-6.47827 269.075,-11.0367 C 265.914,-15.5952 287.798,-0.334276 298.01,-9.05479 C 308.223,-17.7753 287.555,-26.0993 291.931,-24.9102 C 296.308,-23.721 309.682,-25.3066 305.305,-40.1711 C 300.928,-55.0356 261.537,-43.5404 265.914,-45.7205 C 270.29,-47.9006 259.348,-58.8013 245.732,-56.6212 C 232.115,-54.441 231.149,-50.4849 229.69,-41.7644 L 229.683,-41.7566" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260.666" y="-24.4345" fill="#000000" text-anchor="middle" font-family="FreeSans" font-style="normal" font-weight="normal"><tspan x="260.666" y="-24.4345">Internet</tspan></text></g><g><path d="M 105.877 -7.6268 C 59.4446,-7.55165 62.5922,87.0287 212.478,79.0548" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="113.377,-7.63894 103.385,-2.62276 105.877,-7.6268 103.369,-12.6228 " fill="#000000"/><polygon points="113.377,-7.63894 103.385,-2.62276 105.877,-7.6268 103.369,-12.6228 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="219.967,78.6563 210.247,84.1805 212.478,79.0548 209.716,74.1947 " fill="#000000"/><polygon points="219.967,78.6563 210.247,84.1805 212.478,79.0548 209.716,74.1947 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><rect x="223" y="60" width="75" height="33" fill="#b3b3b3"/><rect x="223" y="60" width="75" height="33" fill="none" fill-opacity="0" stroke-width="1.6" stroke="#000000"/><rect x="230.5" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="238" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="245.5" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="253" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="260.5" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="268" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="275.5" y="71.25" width="3.75" height="3.6" fill="#000000"/><rect x="283" y="71.25" width="3.75" height="3.6" fill="#000000"/><text font-size="12.7998" x="260.5" y="106.5" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260.5" y="106.5"/></text></g><g><polyline points="260.5,93 280,120 280.468,139.855 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="280.644,147.353 275.41,137.474 280.468,139.855 285.407,137.238 " fill="#000000"/><polygon points="280.644,147.353 275.41,137.474 280.468,139.855 285.407,137.238 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><polyline points="260.5,93 220,120 220.402,139.853 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="220.554,147.352 215.352,137.455 220.402,139.853 225.35,137.253 " fill="#000000"/><polygon points="220.554,147.352 215.352,137.455 220.402,139.853 225.35,137.253 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><polyline points="260.5,93 160,120 160.402,139.853 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="160.554,147.352 155.352,137.455 160.402,139.853 165.35,137.253 " fill="#000000"/><polygon points="160.554,147.352 155.352,137.455 160.402,139.853 165.35,137.253 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><polyline points="260.5,93 100,120 98.7455,131 99.2256,139.881 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="99.6305,147.37 94.0979,137.654 99.2256,139.881 104.083,137.115 " fill="#000000"/><polygon points="99.6305,147.37 94.0979,137.654 99.2256,139.881 104.083,137.115 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><text font-size="12.7998" x="80" y="40" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="40"/></text><g><path d="M 171.03 -11.3282 C 203.192,-15.1026 200.444,24.1072 225.115,1.03729" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="163.581,-10.4541 172.93,-16.5856 171.03,-11.3282 174.095,-6.65371 " fill="#000000"/><polygon points="163.581,-10.4541 172.93,-16.5856 171.03,-11.3282 174.095,-6.65371 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="230.593,-4.0853 226.704,6.39686 225.115,1.03729 219.874,-0.907204 " fill="#000000"/><polygon points="230.593,-4.0853 226.704,6.39686 225.115,1.03729 219.874,-0.907204 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><text font-size="12.7998" x="80" y="-100" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="-100"/></text><text font-size="12.8" x="93.2722" y="-70.6364" fill="#000000" text-anchor="start" font-family="FreeSans" font-style="normal" font-weight="normal"><tspan x="93.2722" y="-70.6364">Terminal Server</tspan></text><text font-size="12.8" x="161.044" y="208.15" fill="#000000" text-anchor="start" font-family="FreeSans" font-style="normal" font-weight="normal"><tspan x="161.044" y="208.15">Terminals</tspan></text><text font-size="12.7998" x="216.632" y="54.6364" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="216.632" y="54.6364">Hub or switch</tspan></text><text font-size="12.237" x="86.4722" y="-18.7955" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="86.4722" y="-18.7955">eth0</tspan></text><text font-size="12.237" x="161.95" y="-19.5758" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="161.95" y="-19.5758">eth1</tspan></text></svg></div>
<div class="section" id="iseseisva-serveri-seadistamine">
<h1>Iseseisva serveri seadistamine</h1>
<p>Iseseisev (standalone) server antud kontekstis t&#228;hendab seda,
et LTSP serveril on kaks v&#245;rguliidest, millest &#252;ks vaatab Interneti poole ning
teine on &#252;hendatud eraldatud v&#245;rgusegmenti kus terminalid asuvad.
Sellisel juhul serveeritakse terminalide v&#245;rku k&#245;iki vajalikke teenuseid:
DHCP, TFTP, NBD, SSH, LDM jne.</p>
<p>Esiteks uuenda pakette:</p>
<pre class="code bash literal-block"><code>apt-get update
apt-get dist-upgrade</code></pre>
<p>Paigalda LTSP metapakett, see seadistab k&#245;ik teenused mis on LTSP toimimiseks
vajalikud:</p>
<pre class="code bash literal-block"><code>apt-get install -y ltsp-server-standalone wget ca-certificates apt-transport-https</code></pre>
<p>Seadista v&#245;rk failis /etc/network/interfaces, asenda 192.168.77.1 omale sobiliku sisev&#245;rgu aadressiga:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth1
iface eth1 inet dhcp

auto eth0
iface eth0 inet static
    address 192.168.77.1
    netmask 255.255.255.0
EOF</span></code></pre>
<p>Asenda vaikimisi alamv&#245;rk 192.168.0.0/24 ka DHCP serveri seadistustes:</p>
<pre class="code bash literal-block"><code>sed -i <span class="s2">"s/192\.168\.0\./192.168.77./g"</span> /etc/ltsp/dhcpd.conf</code></pre>
<p>Taask&#228;ivita teenused:</p>
<pre class="code bash literal-block"><code>/etc/init.d/networking restart
/etc/init.d/network-manager restart
/etc/init.d/isc-dhcp-server restart
/etc/init.d/nbd-server restart</code></pre>
</div>
<div class="section" id="ltsp-serveri-lisamine-olemasolevasse-vorku">
<h1>LTSP serveri lisamine olemasolevasse v&#245;rku</h1>
<p>Kui sul on juba toimiv DHCP server v&#245;id asendada <span class="docutils literal"><span class="pre">ltsp-server-standalone</span></span>
paketi <span class="docutils literal"><span class="pre">ltsp-server</span></span> paketiga:</p>
<pre class="code bash literal-block"><code>apt-get install -y ltsp-server wget ca-certificates apt-transport-https</code></pre>
<p>Sellisel juhul pead vajalikud teenused, nagu n&#228;iteks TFTP ise seadistama:</p>
<pre class="code bash literal-block"><code>apt-get install -y tftpd-hpa
sed -e <span class="s1">'s/TFTP_ADDRESS=.*/TFTP_ADDRESS=":69"/'</span> /etc/default/tftpd-hpa</code></pre>
<p>Kontrolli &#252;le, et ka muud teenused oleks k&#228;ttesaadavad terminalidele.</p>
</div>
<div class="section" id="toolaua-keskkonna-paigaldus">
<h1>T&#246;&#246;laua keskkonna paigaldus</h1>
<p>Ubuntu t&#246;&#246;laud on &#252;sna resursin&#245;udlik ning terminal-serveri puhul &#228;&#228;rmiselt
aeglane, kuna pilt liigub &#252;le v&#245;rgu.
Terminal-serverile on soovitatud paigaldada MATE t&#246;&#246;laud:</p>
<pre class="code bash literal-block"><code>sudo apt-add-repository ppa:ubuntu-mate-dev/ppa
sudo apt-add-repository ppa:ubuntu-mate-dev/trusty-mate
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y mate-desktop-environment-extras</code></pre>
<p>Kui serverisse on paigaldatud mitu erinevat t&#246;&#246;laua keskkonda, saab vaikimisi
t&#246;&#246;lauda vahetada j&#228;rgnevalt:</p>
<pre class="code bash literal-block"><code>update-alternatives --config x-session-manager</code></pre>
<p>Lisa ka Eesti ID-kaardi baastarkvara varamu:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"deb https://installer.id.ee/media/ubuntu/ trusty main"</span> &gt; /etc/apt/sources.list.d/ria-repository.list
wget https://installer.id.ee/media/install-scripts/ria-public.key -O - <span class="p">|</span> apt-key add -
apt-get update
apt-get install -y estonianidcard</code></pre>
<p>Lisa Xsession skript mis n&#228;itab uut PCSC-lite sokkli asukohta:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"export PCSCLITE_CSOCK_NAME=\$HOME/.pcscd.comm"</span> &gt; /etc/X11/Xsession.d/80-pcsclite</code></pre>
<p>Lisa minu tarkvara varamu, kust saab kohandatud OpenSSH serveri mis oskab
&#252;mber suunatud ID-kaardi tarkvara sokleid vastu v&#245;tta:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"deb http://packages.koodur.com trusty main ltsp"</span> &gt; /etc/apt/sources.list.d/koodur.list
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 054C36F8
apt-get update
apt-get upgrade</code></pre>
</div>
<div class="section" id="pc-baasil-terminalid">
<h1>PC-baasil terminalid</h1>
<p>Enamus PC riistvara toetab PXE-alglaadimist.
Alusta terminali tarkvara juurfailis&#252;steemi loomisega:</p>
<pre class="code bash literal-block"><code><span class="nv">MIRROR</span><span class="o">=</span><span class="s2">"http://ee.archive.ubuntu.com/ubuntu/"</span> <span class="se">\
</span><span class="nv">LANG</span><span class="o">=</span>C <span class="se">\
</span><span class="nv">ARCH</span><span class="o">=</span>i386 <span class="se">\
</span>ltsp-build-client</code></pre>
<p>ID-kaardi jaoks vajalike komponentide paigaldamiseks sisene terminali juurfailis&#252;steemi:</p>
<pre class="code bash literal-block"><code>chroot /opt/ltsp/i386 /bin/bash</code></pre>
<p>Lisa minu tarkvara varamu, kust saab kohandatud OpenSSH kliendi mis oskab
ID-kaardi sokleid serverisse suunata:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"deb http://packages.koodur.com trusty main ltsp"</span> &gt; /etc/apt/sources.list.d/koodur.list
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 054C36F8</code></pre>
<p>Paigalda PCSC-Lite deemon:</p>
<pre class="code bash literal-block"><code>apt-get install -y pcscd</code></pre>
<p>Lisa SSH kliendi seadistused, t&#228;rni v&#245;ib asendada oma serveri IP-ga:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /etc/ssh/ssh_config
Host *
SendEnv LANG LC_*
RemoteForward ~/.pcscd.comm /run/pcscd/pcscd.comm
EOF</span></code></pre>
<p>VIA terminalide UniChrome graafika t&#252;&#252;relite seis on suht halb seega ma l&#252;litaks v&#228;lja ka 3D kiirenduse:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /etc/X11/xorg.conf
Section "Module"
    Disable "glx"
    Disable "dri"
EndSection
EOF</span></code></pre>
<p>V&#228;lju terminali juurikast:</p>
<pre class="code bash literal-block"><code><span class="nb">exit</span></code></pre>
<p>Uuenda terminali juurfailis&#252;steemi SquashFS t&#245;mmist:</p>
<pre class="code bash literal-block"><code>ltsp-update-image</code></pre>
</div>
<div class="section" id="rdp-sessiooni-lisamine">
<h1>RDP sessiooni lisamine</h1>
<p>Lisa terminali juurikasse rdesktop pakett:</p>
<pre class="code bash literal-block"><code>chroot /opt/ltsp/i386 apt-get install -y rdesktop</code></pre>
<p>Genereeri uuendatud t&#245;mmis:</p>
<pre class="code bash literal-block"><code>ltsp-update-image</code></pre>
<p>Seadista ringi <span class="docutils literal">/var/lib/tftpboot/ltsp/i386/lts.conf</span>:</p>
<pre class="code ini literal-block"><code><span class="k">[default]</span>
<span class="na">SCREEN_07</span><span class="o">=</span><span class="s">"rdesktop -x l -k et -u '' -f -r scard -r sound -r disk:floppy=/run/drives aken.edu.ee"</span>
<span class="na">SCREEN_08</span><span class="o">=</span><span class="s">"ldm"</span></code></pre>
<p>Ubuntu 14.04 baasil terminalist Windows 2012 serveri pihta k&#228;ies on
mingi h&#228;da kursorite kadumisega, sellest
saab m&#246;&#246;da kui Windowsi poolel v&#228;lja l&#252;litada kursori vari <a class="footnote-reference brackets" href="#cursor-shadow" id="id1">1</a> v&#245;i
terminali juurikasse paigaldada uuendatud RDP klient:</p>
<pre class="code bash literal-block"><code>chroot /opt/ltsp/i386 apt-get install -y libgssglue1
chroot /opt/ltsp/i386 wget http://launchpadlibrarian.net/193620368/rdesktop_1.8.3-1_i386.deb
chroot /opt/ltsp/i386 dpkg -i rdesktop_1.8.3-1_i386.deb
chroot /opt/ltsp/i386 rm -fv rdesktop_1.8.3-1_i386.deb
<span class="nv">ARCH</span><span class="o">=</span>i386 ltsp-update-image</code></pre>
<p>Sisselogimisdialoogi aegumise v&#228;ltimiseks ava Windowsi register
ning lisa <span class="docutils literal">HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal <span class="pre">Server\WinStations\RDP-Tcp</span></span>
alla DWORD t&#252;&#252;pi LogonTimeout=0xffffffff v&#245;ti-v&#228;&#228;rtus paar <a class="footnote-reference brackets" href="#login-timeout" id="id2">2</a>.</p>
<dl class="footnote brackets">
<dt class="label" id="cursor-shadow"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
<dd><p><a class="reference external" href="http://www.thewindowsclub.com/enable-disable-mouse-pointer-shadow-windows">http://www.thewindowsclub.com/enable-disable-mouse-pointer-shadow-windows</a></p>
</dd>
<dt class="label" id="login-timeout"><span class="brackets"><a class="fn-backref" href="#id2">2</a></span></dt>
<dd><p><a class="reference external" href="http://serverfault.com/questions/422770/changing-the-login-timeout-for-windows-remote-desktop-services">http://serverfault.com/questions/422770/changing-the-login-timeout-for-windows-remote-desktop-services</a></p>
</dd>
</dl>
</div>
<div class="section" id="cubietrucki-ette-valmistamine">
<h1>Cubietrucki ette valmistamine</h1>
<p>Kuna PXE on x86 platvormi spetsiifiline siis s&#228;&#228;rast v&#245;imekust n&#228;iteks
Cubietrucki kasutada ei saa.
K&#252;ll aga saab Cubietruckile k&#245;rvetada p&#252;sivara, mis analoogselt PXE-le
laadib v&#245;rgust alla tuuma, initrd ning j&#228;takb operatsioonis&#252;steemi alglaadimisega.</p>
<p>Esmalt paigalda QEMU emulatsioonikiht:</p>
<pre class="code bash literal-block"><code>apt-get install -y qemu-user-static binfmt-support</code></pre>
<p>Keela OMAP4 tuuma paigaldus, see pole naguinii enam k&#228;ttesaadav tarkvaravaramutest:</p>
<pre class="code bash literal-block"><code>sed -i -e <span class="s1">'s/KERNEL_ARCH="omap4"/KERNEL_ARCH=""/'</span> /usr/share/ltsp/plugins/ltsp-build-client/Ubuntu/020-kernel-selection</code></pre>
<p>Loo ARM juurfailis&#252;steem:</p>
<pre class="code bash literal-block"><code><span class="nv">DEBOOTSTRAP</span><span class="o">=</span>qemu-debootstrap <span class="nv">ARCH</span><span class="o">=</span>armhf <span class="nv">LANG</span><span class="o">=</span>C ltsp-build-client</code></pre>
<p>Lisa serveri SSH v&#245;ti:</p>
<pre class="code bash literal-block"><code>ltsp-update-sshkeys</code></pre>
<p>Sisene Cubietrucki juurfailis&#252;steemi:</p>
<pre class="code bash literal-block"><code>chroot /opt/ltsp/armhf /bin/bash</code></pre>
<p>Cubietrucki jaoks paigalda <a class="reference external" href="http://www.armbian.com/cubietruck/">Igori 3.4.x tuum</a>
ja moodulid kuhu sai k&#252;lge poogitud LTSP jaoks vajalik <em>overlayfs</em>:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"deb http://apt.armbian.com trusty main"</span> &gt; /etc/apt/sources.list.d/armbian.list
apt-key adv --keyserver keys.gnupg.net --recv-keys 0x93D6889F9F0E78D5
apt-get update
apt-get install -y linux-image-sun7i</code></pre>
<p>Lisa minu tarkvara varamu, kust saab kohandatud OpenSSH kliendi mis oskab
ID-kaardi sokleid serverisse suunata:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"deb http://packages.koodur.com trusty main ltsp"</span> &gt; /etc/apt/sources.list.d/koodur.list
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 054C36F8</code></pre>
<p>Uuenda pakettide nimekirju:</p>
<pre class="code bash literal-block"><code>apt-get update</code></pre>
<p>Paigalda kohandatud OpenSSH, PCSC-deemon, LTSP-kliendi metapakett ja muu tilu-lilu:</p>
<pre class="code bash literal-block"><code>apt-get install -y openssh-client pcscd xf86-video-fbturbo</code></pre>
<p>Lisa SSH kliendi seadistused, et terminal v&#245;imaldaks serveris ligip&#228;&#228;su
terminalis jooksvale PCSC deemonile, vajadusel asenda t&#228;rn oma serveri IP-ga:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /etc/ssh/ssh_config
Host *
SendEnv LANG LC_*
RemoteForward ~/.pcscd.comm /run/pcscd/pcscd.comm
EOF</span></code></pre>
<p>Kui soovid kasutada ka RDP sessioone siis uuendatud RDP kliendi paigaldamiseks:</p>
<pre class="code bash literal-block"><code>apt-get install -y libgssglue1
wget http://launchpadlibrarian.net/193620260/rdesktop_1.8.3-1_armhf.deb
dpkg -i rdesktop_1.8.3-1_armhf.deb
rm -fv rdesktop_1.8.3-1_armhf.deb</code></pre>
<p>V&#228;lju juurikast:</p>
<pre class="code bash literal-block"><code><span class="nb">exit</span></code></pre>
<p>Uuenda NBD kaudu serveeritavat t&#245;mmist:</p>
<pre class="code bash literal-block"><code>ltsp-update-image</code></pre>
</div>
<div class="section" id="cubietruck-tuuma-pakendamine">
<h1>Cubietruck tuuma pakendamine</h1>
<p>Paigalda esmalt u-boot t&#246;&#246;riistad:</p>
<pre class="code bash literal-block"><code>apt-get install -y u-boot-tools</code></pre>
<p>Sikuta Cubietrucki riistvara konfiguratsioon, mis paneb
VGA pesa k&#228;ima resolutsioonil 1024x768 ja l&#252;litab v&#228;lja terminali jaoks ebaolulised
komponendid (WiFi, Bluetooth jms):</p>
<pre class="code bash literal-block"><code>wget https://www.koodur.com/cubietruck/1024x768.bin -O /var/lib/tftpboot/ltsp/armhf/1024x768.bin</code></pre>
<p>Loo u-boot jaoks skript mis laeb tuuma, initrd ning riistvara konfiguratsiooni:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF &gt; /var/lib/tftpboot/ltsp/armhf/1024x768.scr
setenv bootm_boot_mode sec
setenv bootargs 'ro init=/sbin/init-ltsp init=/sbin/init-ltsp root=/dev/nbd0'
tftp 0x43000000 /ltsp/armhf/1024x768.bin
tftp 0x42000000 /ltsp/armhf/uImage
tftp 0x50000000 /ltsp/armhf/initramfs.uImage
bootm 0x42000000 0x50000000
EOF</span></code></pre>
<p>Genereeri u-boot t&#245;mmised:</p>
<pre class="code bash literal-block"><code>mkimage -A arm -O linux -T script -C none -n boot.scr -d <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/1024x768.scr <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/1024x768.scr.uimg
mkimage -A arm -T ramdisk -C none -n uInitrd -d <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/initrd.img-3.4.110-sun7i <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/initramfs.uImage
mkimage -A arm -O linux -T kernel -C none -n Linux -a <span class="m">42000000</span> -e <span class="m">42000000</span> -d <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/vmlinuz-3.4.110-sun7i <span class="se">\
</span>    /var/lib/tftpboot/ltsp/armhf/uImage</code></pre>
<p>Seadista ringi ka DHCP serverit failis /etc/ltsp/dhcpd.conf:</p>
<pre class="code literal-block"><code>authoritative;
subnet 192.168.77.0 netmask 255.255.255.0 {
    range 192.168.77.20 192.168.77.250;
    option domain-name "ltsp";
    option domain-name-servers 8.8.8.8;
    option broadcast-address 192.168.77.255;
    option routers 192.168.77.1;
    next-server 192.168.77.1;
    option subnet-mask 255.255.255.0;
    if substring( option vendor-class-identifier, 0, 3 ) = "PXE" {
        filename "/ltsp/i386/pxelinux.0";
        option root-path "/opt/ltsp/i386";
    } else {
        filename "/ltsp/armhf/1024x768.scr.uimg";
        option root-path "/opt/ltsp/armhf";
    }
}</code></pre>
</div>
<div class="section" id="cubietruck-alglaaduri-uuendamine">
<h1>Cubietruck alglaaduri uuendamine</h1>
<p>Viimase sammuna peab Cubietruckile peale laskma uue u-booti mis p&#252;&#252;ab v&#245;rku
seadistada DHCP-ga ning siis sealt TFTP-ga skripti alla sikutada.
IT Kolled&#382;i Robootikaklubist saab laenutada SD-kaarti millel on <a class="reference external" href="http://plaes.org/">Priit Laes</a> kirjutatud
skript, mis uue u-booti kirjutab Cubietrucki sisemisele m&#228;lule, nii et eraldi m&#228;lukaarti hiljem vaja pole:</p>
<pre class="code bash literal-block"><code><span class="c1"># Seda tuleb siis Cubietrucki peal jooksutada ;)
</span>wget -c https://www.koodur.com/cubietruck/u-boot-sunxi-with-spl.bin -O /root/u-boot-sunxi-with-spl.bin
<span class="nb">echo</span> nand-disk &gt;/sys/class/leds/cubietruck<span class="se">\:</span>blue<span class="se">\:</span>usr/trigger
flash_erase -N /dev/mtd0 <span class="m">0</span> <span class="m">0</span> <span class="o">&amp;&amp;</span> <span class="se">\
</span>nandwrite -p /dev/mtd0 /root/u-boot-sunxi-with-spl.bin <span class="o">&amp;&amp;</span> <span class="se">\
</span>flash_erase -N /dev/mtd1 <span class="m">0</span> <span class="m">0</span> <span class="o">&amp;&amp;</span> <span class="se">\
</span>nandwrite -p /dev/mtd1 /root/u-boot-sunxi-with-spl.bin <span class="o">&amp;&amp;</span> <span class="se">\
</span><span class="nb">echo</span> <span class="m">1</span> &gt; /sys/class/leds/cubietruck<span class="se">\:</span>orange<span class="se">\:</span>usr/brightness <span class="o">&amp;&amp;</span> <span class="se">\
</span>sync <span class="o">&amp;&amp;</span> <span class="se">\
</span><span class="nb">echo</span> <span class="m">0</span> &gt; /sys/class/leds/cubietruck<span class="se">\:</span>orange<span class="se">\:</span>usr/brightness <span class="o">&amp;&amp;</span> <span class="se">\
</span><span class="nb">echo</span> <span class="m">1</span> &gt; /sys/class/leds/cubietruck<span class="se">\:</span>green<span class="se">\:</span>usr/brightness</code></pre>
</div>
</div>
]]></content>
    
    <category term="Ubuntu"/>
    <category term="pcscd"/>
    <category term="ID-card"/>
    <category term="LTSP"/>
    <category term="ID-kaart"/>
    <category term="NBD"/>
    <category term="OpenSSH"/>
    <category term="PKCS#11"/>
    <category term="Debian"/>
    <category term="Cubietruck"/>
    <category term="opensc-tool"/>
    <category term="PCSC-Lite"/>
    <category term="OpenSC"/>
    <updated>2016-01-19T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Statistika kogumine collectd abil</title>
    <summary>Linux-p&#245;histe serverite monitoorimiseks leiab mitmesuguseid
vahendeid Nagiosest Zabbixini.
T&#252;&#252;pilise monitooringu lahenduse jaoks on vaja s&#228;ttida &#252;les andmebaas ning
monitooringutarkvara reguaarselt uuendada.
K&#228;esolevas n&#228;ites on v&#228;lja toodud <span class="docutils literal">collectd</span>, mis on minimalistik
statistika kogumise tarkvara, mis kasutab RRD-p&#245;hist andmebaasi
ning millel on palju erinevaid pistikprogramme
funktsionaalsuse laiendamiseks.</summary>
    <link href="http://lauri.vosandi.com/lan/collectd.html"/>
    <content type="html"><![CDATA[<div class="document">


<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- license: cc-by-3 -->
<!-- tags: collectd, monitoring, statistika -->
<!-- date: 2016-01-03 -->
<div class="section" id="statistika-kogumine-collectd-abil">
<div class="section" id="sissejuhatus">
<h2>Sissejuhatus</h2>
<p>Linux-p&#245;histe serverite monitoorimiseks leiab mitmesuguseid
vahendeid Nagiosest Zabbixini.
T&#252;&#252;pilise monitooringu lahenduse jaoks on vaja s&#228;ttida &#252;les andmebaas ning
monitooringutarkvara reguaarselt uuendada.
K&#228;esolevas n&#228;ites on v&#228;lja toodud <span class="docutils literal">collectd</span>, mis on minimalistik
statistika kogumise tarkvara, mis kasutab RRD-p&#245;hist andmebaasi
ning millel on palju erinevaid pistikprogramme
funktsionaalsuse laiendamiseks.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>RRD andmebaasi majutamiseks on k&#245;ige sobilikum SSD, kirjutades RRD andmebaasi p&#246;&#246;rlevatele ketastele v&#245;ib kogu masin talumatult aeglaseks muutuda!</p>
</div>
</div>
<div class="section" id="paigaldus">
<h2>Paigaldus</h2>
<pre class="code bash literal-block"><code>apt-get install collectd</code></pre>
<p>Esmalt l&#228;htesta <span class="docutils literal">collectd</span> konfiguratsioon failis <span class="docutils literal">/etc/collectd/collectd.conf</span> j&#228;rgnevalt:</p>
<pre class="code apache literal-block"><code><span class="nb">FQDNLookup</span> true

<span class="nb">LoadPlugin</span> logfile
<span class="nb">LoadPlugin</span> syslog
<span class="nb">LoadPlugin</span> cpu             # Protsessori kasutus
<span class="nb">LoadPlugin</span> df              # Kettakasutus
<span class="nb">LoadPlugin</span> disk            # Ketaste koormus
<span class="nb">LoadPlugin</span> interface       # V&#245;rguliidesed
<span class="nb">LoadPlugin</span> load            # S&#252;steemi koormus
<span class="nb">LoadPlugin</span> memory          # M&#228;lukasutus
<span class="nb">LoadPlugin</span> network
<span class="nb">LoadPlugin</span> processes
<span class="nb">LoadPlugin</span> swap            # Saaleala
<span class="nb">LoadPlugin</span> uptime
<span class="nb">LoadPlugin</span> users

<span class="nt">&lt;Plugin</span> <span class="s">syslog</span><span class="nt">&gt;</span>
        <span class="nb">LogLevel</span> err
<span class="nt">&lt;/Plugin&gt;</span>

<span class="nt">&lt;Plugin</span> <span class="s">df</span><span class="nt">&gt;</span>
        <span class="nb">FSType</span> rootfs
        <span class="nb">FSType</span> sysfs
        <span class="nb">FSType</span> proc
        <span class="nb">FSType</span> devtmpfs
        <span class="nb">FSType</span> devpts
        <span class="nb">FSType</span> tmpfs
        <span class="nb">FSType</span> fusectl
        <span class="nb">FSType</span> cgroup
        <span class="nb">IgnoreSelected</span> true
<span class="nt">&lt;/Plugin&gt;</span>

<span class="nt">&lt;Plugin</span> <span class="s">disk</span><span class="nt">&gt;</span>
        <span class="nb">Disk</span> <span class="s2">"/[sv]d[a-z]/"</span>    # Raporteeri ainult SATA ja VirtIO kettaid
<span class="nt">&lt;/Plugin&gt;</span>

<span class="nt">&lt;Include</span> <span class="s">"/etc/collectd/collectd.conf.d"</span><span class="nt">&gt;</span>
        <span class="nb">Filter</span> <span class="s2">"*.conf"</span>
<span class="nt">&lt;/Include&gt;</span></code></pre>
<p>Vaikimisi seadetega kirjutatakse RRD andmebaas v&#228;lja /var/lib/collectd kataloogi.
Kasutades Btrfs failis&#252;steemi tuleks <cite>copy-on-write</cite> funktsionaalsus v&#228;lja l&#252;litada:</p>
<pre class="code bash literal-block"><code>chattr +C -Rf /var/lib/collectd</code></pre>
<p>L&#245;puks tuleks teenus ka k&#228;ivitada:</p>
<pre class="code bash literal-block"><code>sudo service collectd restart</code></pre>
</div>
<div class="section" id="keskne-statistika-kogumine">
<h2>Keskne statistika kogumine</h2>
<p>Statistikat saatvates masinates lisa t&#228;iendav konfiguratsioon:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF | sudo tee /etc/collectd/collectd.conf.d/client.conf
&lt;Plugin network&gt;
Server "serveri.aadress.siia.ee"
&lt;/Plugin&gt;
EOF</span></code></pre>
<p>Statistikat vastu v&#245;tvas masinas lisa vastav konfiguratsioon:</p>
<pre class="code bash literal-block"><code>cat <span class="s">&lt;&lt; EOF | sudo tee /etc/collectd/collectd.conf.d/server.conf
&lt;Plugin network&gt;
Listen "0.0.0.0"
&lt;/Plugin&gt;
EOF</span></code></pre>
<p>T&#228;helepanu peaks p&#246;&#246;rama sellele, et vaikimisi seadetega on v&#245;imatu tuvastada
kes statistikat saadab. Kohtv&#245;rgus v&#245;ib see aksepteeritav olla, kuid
&#252;le Interneti saates peaks v&#228;hemasti tulem&#252;&#252;ris blokeerima v&#245;&#245;rad aadressid,
turvama &#252;hendust VPN abil v&#245;i kasutama paroole/sertifikaate &#252;henduse autentimiseks.</p>
</div>
<div class="section" id="sensorite-sisse-lulitamine">
<h2>Sensorite sisse l&#252;litamine</h2>
<p>Esmalt paigalda <span class="docutils literal"><span class="pre">lm-sensors</span></span> tarkvarapakett:</p>
<pre class="code bash literal-block"><code>sudo apt-get install lm-sensors</code></pre>
<p>Vaikimisi seadetega tuvastab <span class="docutils literal"><span class="pre">lm-sensors</span></span> juba &#228;ra p&#228;ris palju riistvara:</p>
<pre class="code bash literal-block"><code>sensors</code></pre>
<p>T&#228;iendavate sensorite tuvastamiseks:</p>
<pre class="code bash literal-block"><code>sudo sensors-detect</code></pre>
<p>Selleks, et <span class="docutils literal">collectd</span> neid n&#228;ite raporteeriks tuleb t&#228;iendada <span class="docutils literal">collectd</span> konfiguratsiooni:</p>
<pre class="code bash literal-block"><code><span class="nb">echo</span> <span class="s2">"LoadPlugin sensors"</span> <span class="p">|</span> sudo tee /etc/collectd/collectd.conf.d/sensors.conf</code></pre>
<p>Seej&#228;rel taask&#228;ivita teenus:</p>
<pre class="code bash literal-block"><code>sudo service collect restart</code></pre>
</div>
</div>
<div class="section" id="veebiliides">
<h1>Veebiliides</h1>
<p>Kuna <span class="docutils literal">collectd</span> on tarkvara puhtalt andmete kogumiseks, ei sisaldu selles
ka veebiliidest. <a class="reference external" href="https://github.com/pommi/CGP">Collectd Graph Panel</a> on
PHP-s kirjutatud veebiliides <span class="docutils literal">collectd</span> graafikute kuvamiseks,
selle saab paigaldada j&#228;rgnevalt:</p>
<pre class="code bash literal-block"><code>sudo apt-get install apache2 libapache2-mod-php5
sudo git clone https://github.com/pommi/CGP /var/www/html/cgp</code></pre>
</div>
</div>
]]></content>
    
    <category term="statistika"/>
    <category term="monitoring"/>
    <category term="collectd"/>
    <updated>2016-01-03T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Blokeerimine riikide järgi</title>
    <summary>Teadup&#228;rast on IPv4 aadressid seostatavad geograafiliste asukohtadega.
GeoIP andmebaas v&#245;imaldab IP-aadressidest tuletada &#252;henduse l&#228;hteriik.</summary>
    <link href="http://lauri.vosandi.com/lan/geoip.html"/>
    <content type="html"><![CDATA[<div class="document" id="blokeerimine-riikide-jargi">
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- license: cc-by-3 -->
<!-- tags: GeoIP, iptables -->
<!-- date: 2015-12-20 -->
<div class="section" id="sissejuhatus">
<h1>Sissejuhatus</h1>
<p>Teadup&#228;rast on IPv4 aadressid seostatavad geograafiliste asukohtadega.
GeoIP andmebaas v&#245;imaldab IP-aadressidest tuletada &#252;henduse l&#228;hteriik.</p>
</div>
<div class="section" id="paigaldus">
<h1>Paigaldus</h1>
<pre class="code bash literal-block"><code>apt-get install -y --no-install-recommends xtables-addons-common libtext-csv-xs-perl wget unzip</code></pre>
<p>Laadi alla GeoIP andmebaas ning genereeri andmed tulem&#252;&#252;rimise jaoks:</p>
<pre class="code bash literal-block"><code>mkdir -p /usr/share/xt_geoip
<span class="nb">cd</span> /usr/share/xt_geoip <span class="o">&amp;&amp;</span> /usr/lib/xtables-addons/xt_geoip_dl
/usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip/ /usr/share/xt_geoip/*.csv</code></pre>
<p>Lisaks on vaja paigaldada t&#228;iendavad tuuma moodulid,
kui tahad reegleid rakendada LXC konteineris, siis selle peab paigaldama
emamasinas:</p>
<pre class="code bash literal-block"><code>apt-get install xtables-addons-dkms
modprobe ip_tables xt_geoip</code></pre>
<p>Reegli lisamiseks:</p>
<pre class="code bash literal-block"><code>iptables -I INPUT -p tcp --dport <span class="m">22</span> -m geoip --src-cc EE -m comment --comment <span class="s2">"Allow SSH from Estonia"</span> -j ACCEPT
iptables -I INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -I INPUT -s <span class="m">127</span>.0.0.0/8 -i lo -j ACCEPT
iptables -P INPUT DROP</code></pre>
<p>Tee tulem&#252;&#252;rireeglid p&#252;sivaks:</p>
<pre class="code bash literal-block"><code>apt-get install iptables-persistent</code></pre>
</div>
</div>
]]></content>
    
    <category term="GeoIP"/>
    <category term="iptables"/>
    <updated>2015-12-20T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>LDAP päringute tegemine</title>
    <summary>Peale Linuxi masina domeeni liitmist saab LDAP p&#228;ringud domeenikontrolleri pihta
teha kasutades arvuti keytabi. Selleks paigalda:</summary>
    <link href="http://lauri.vosandi.com/lan/ldap-utils.html"/>
    <content type="html"><![CDATA[<div class="document" id="ldap-paringute-tegemine">
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags:  ldapsearch, LDAP, GSSAPI, Kerberos -->
<!-- date: 2015-11-15 -->
<div class="section" id="paigaldus">
<h1>Paigaldus</h1>
<p>Peale Linuxi masina domeeni liitmist saab LDAP p&#228;ringud domeenikontrolleri pihta
teha kasutades arvuti keytabi. Selleks paigalda:</p>
<pre class="code bash literal-block"><code>sudo apt-get install ldap-utils dnsutils libsasl2-modules-gssapi-heimdal</code></pre>
<p>Viimane neist on vajalik p&#228;ringute autentimiseks Kerberose abil.</p>
</div>
<div class="section" id="kerberosega-paringu-tegemine">
<h1>Kerberosega p&#228;ringu tegemine</h1>
<p>Esmalt veendu, et domeenikontrolleri IP lahendub tagasi hostinimeks:</p>
<pre class="code bash literal-block"><code>nslookup dc1.example.com
nslookup <span class="m">192</span>.168.?.?</code></pre>
<p>Seej&#228;rel k&#252;si domeenikontrollerist arvutile vastav ticket-granting-ticket:</p>
<pre class="code bash literal-block"><code>sudo -i
kinit -k NETBIOS-NIMI<span class="se">\$</span></code></pre>
<p>V&#245;i lihtsalt:</p>
<pre class="code bash literal-block"><code>kinit -k <span class="k">$(</span>grep <span class="s2">"netbios name"</span> /etc/samba/smb.conf <span class="p">|</span> cut -d <span class="s2">"="</span> -f <span class="m">2</span><span class="k">)</span><span class="se">\$</span></code></pre>
<p>Seej&#228;rel proovi kas saad p&#228;ringut sooritada:</p>
<pre class="code bash literal-block"><code>ldapsearch -Y GSSAPI -H ldap://dc1.example.com -b <span class="nv">dc</span><span class="o">=</span>example,dc<span class="o">=</span>com</code></pre>
<p>P&#228;ring peaks tagastama k&#245;ik domeenikontrolleris olevad objektid &#252;htegi parooli tippimata.</p>
</div>
<div class="section" id="konfiguratsioonifailid">
<h1>Konfiguratsioonifailid</h1>
<p>Tr&#252;kkimisvaeva v&#228;hendamiseks v&#245;ib k&#245;ik selle lisada faili <span class="docutils literal">/etc/ldap/ldap.conf</span> j&#228;rgnevalt:</p>
<pre class="code bash literal-block"><code>URI ldap://dc1.example.com
BASE <span class="nv">dc</span><span class="o">=</span>example,dc<span class="o">=</span>com</code></pre>
<p>Edaspidi piisab lihtsalt j&#228;rgnevast, et kuvada k&#245;ik domeenikontrolleris olevad objektid:</p>
<pre class="code bash literal-block"><code>ldapsearch</code></pre>
<p>Kasutajate saamiseks lisa otsingufilter:</p>
<pre class="code bash literal-block"><code>ldapsearch <span class="s1">'(&amp;(objectClass=user)(objectCategory=person))'</span></code></pre>
</div>
<div class="section" id="kasulikud-paringud">
<h1>Kasulikud p&#228;ringud</h1>
<p>Parajasti sisse logitud kasutaja leidmine:</p>
<pre class="code bash literal-block"><code>ldapsearch <span class="nv">samaccountname</span><span class="o">=</span><span class="nv">$USER</span></code></pre>
<p>Kasutaja konkreetseete attribuutide leidimine:</p>
<pre class="code bash literal-block"><code>ldapsearch -LLL <span class="nv">samaccountname</span><span class="o">=</span><span class="nv">$USER</span> cn</code></pre>
<p>T&#228;pit&#228;htedega nime puhul peab veidi rohkem v&#245;imlema:</p>
<pre class="code bash literal-block"><code>ldapsearch -LLL <span class="nv">samaccountname</span><span class="o">=</span><span class="nv">$USER</span> cn <span class="p">|</span> grep cn <span class="p">|</span> cut -d <span class="s1">' '</span> -f <span class="m">2</span> <span class="p">|</span> base64 -d</code></pre>
</div>
<div class="section" id="vorguketta-jarjehoidja-lisamine">
<h1>V&#245;rguketta j&#228;rjehoidja lisamine</h1>
<p>Nii saame n&#228;iteks automatiseerida v&#245;rguketta j&#228;rjehoidja lisamise
<span class="docutils literal"><span class="pre">/etc/X11/Xsession.d/95generate-gtk-bookmarks</span></span> skriptis:</p>
<pre class="code bash literal-block"><code><span class="nv">URL</span><span class="o">=</span><span class="k">$(</span>ldapsearch -LLL <span class="nv">samaccountname</span><span class="o">=</span><span class="nv">$USER</span> homeDirectory <span class="p">|</span>  sed -e <span class="s1">'s/^\\\\/smb:\/\//'</span> <span class="p">|</span> sed -e <span class="s1">'s/\\/\//g'</span><span class="k">)</span>
<span class="nb">echo</span> <span class="s2">"</span><span class="nv">$URL</span><span class="s2"> V&#245;rguketas"</span> &gt; ~/.gtk-bookmarks</code></pre>
</div>
</div>
]]></content>
    
    <category term="ldapsearch"/>
    <category term="LDAP"/>
    <category term="Kerberos"/>
    <category term="GSSAPI"/>
    <updated>2015-11-15T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Setting homepage with Puppet</title>
    <summary>You can use following Puppet snippet to set the URL opened by default.
Mozilla Firefox and Chromium were rather undocumented and the examples
on the Internet were outdated:</summary>
    <link href="http://lauri.vosandi.com/2015/09/set-homepage-with-puppet.html"/>
    <content type="html"><![CDATA[<div class="document" id="setting-homepage-with-puppet">
<!-- tags: Puppet, Firefox, Chromium -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- date: 2015-09-16 -->
<p>You can use following Puppet snippet to set the URL opened by default.
Mozilla Firefox and Chromium were rather undocumented and the examples
on the Internet were outdated:</p>
<pre class="code ruby literal-block"><code><span class="c1"># Set Mozilla Firefox homepage</span>
<span class="n">file_line</span> <span class="p">{</span> <span class="s2">"firefox-homepage"</span><span class="p">:</span>
    <span class="n">path</span> <span class="o">=&gt;</span> <span class="s2">"/etc/firefox/syspref.js"</span><span class="p">,</span>
    <span class="k">ensure</span> <span class="o">=&gt;</span> <span class="n">present</span><span class="p">,</span>
    <span class="n">match</span> <span class="o">=&gt;</span> <span class="s1">'^user_pref\("browser\.startup\.homepage",'</span><span class="p">,</span>
    <span class="n">line</span> <span class="o">=&gt;</span> <span class="s1">'user_pref("browser.startup.homepage", "https://www.koodur.com");'</span>
<span class="p">}</span>

<span class="c1"># Set Chromium homepage</span>
<span class="n">file</span> <span class="p">{</span> <span class="s2">"/etc/chromium-browser/policies/recommended/homepage.json"</span><span class="p">:</span>
  <span class="k">ensure</span> <span class="o">=&gt;</span> <span class="n">file</span><span class="p">,</span>
  <span class="n">mode</span> <span class="o">=&gt;</span> <span class="mi">644</span><span class="p">,</span>
  <span class="n">owner</span> <span class="o">=&gt;</span> <span class="n">root</span><span class="p">,</span>
  <span class="n">group</span> <span class="o">=&gt;</span> <span class="n">root</span><span class="p">,</span>
  <span class="n">content</span> <span class="o">=&gt;</span> <span class="s2">"{</span><span class="se">\n</span><span class="s2">  </span><span class="se">\"</span><span class="s2">RestoreOnStartup</span><span class="se">\"</span><span class="s2">:4, </span><span class="se">\"</span><span class="s2">RestoreOnStartupURLs</span><span class="se">\"</span><span class="s2">:[</span><span class="se">\"</span><span class="s2">https://www.koodur.com</span><span class="se">\"</span><span class="s2">]</span><span class="se">\n</span><span class="s2">}</span><span class="se">\n</span><span class="s2">"</span>
<span class="p">}</span></code></pre>
<p>Note that on your Puppetmaster you might have to install additional module:</p>
<pre class="code bash literal-block"><code>puppet module install puppetlabs-stdlib</code></pre>
</div>
]]></content>
    
    <category term="Puppet"/>
    <category term="Firefox"/>
    <category term="Chromium"/>
    <updated>2015-09-16T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>OpenSSH võtmetega autentmine</title>
    <summary>OpenSSH kasutab vaikimisi kasutaja autentimiseks parooli.
Tihtipeale see pole just k&#245;ige turvalisem viis kasutajat autentida,
kuna parooli tippimine v&#245;ib k&#245;rvalt vaatajale n&#228;ha olla ning
l&#252;hikese parooli puhul on realistlik ka sisse murdmine toore j&#245;uga.
Selle vastu aitab v&#245;tmepaari genereermine ning avaliku v&#245;tme serverisse
kopeerimine.</summary>
    <link href="http://lauri.vosandi.com/lan/ssh-copy-id.html"/>
    <content type="html"><![CDATA[<div class="document" id="openssh-votmetega-autentmine">
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- license: cc-by-3 -->
<!-- tags: OpenSSH, ssh-copy-id -->
<!-- date: 2015-06-16 -->
<div class="section" id="sissejuhatus">
<h1>Sissejuhatus</h1>
<p>OpenSSH kasutab vaikimisi kasutaja autentimiseks parooli.
Tihtipeale see pole just k&#245;ige turvalisem viis kasutajat autentida,
kuna parooli tippimine v&#245;ib k&#245;rvalt vaatajale n&#228;ha olla ning
l&#252;hikese parooli puhul on realistlik ka sisse murdmine toore j&#245;uga.
Selle vastu aitab v&#245;tmepaari genereermine ning avaliku v&#245;tme serverisse
kopeerimine.</p>
</div>
<div class="section" id="votmepaari-loomine">
<h1>V&#245;tmepaari loomine</h1>
<p>Vaikimisi <em>ssh-keygen</em> loob RSA v&#245;tmed, mis on 2048-bit ja suurema v&#245;tmepikkuse
puhul piisavalt tugevad, aga
j&#228;rgnevas n&#228;ites kasutame ECDSA (<em>elliptic-curve digital signature algorithm</em>),
kuna see on &#252;ks k&#245;ige modernsemaid as&#252;mmeetrilise v&#245;tme algoritme:</p>
<pre class="code bash literal-block"><code>ssh-keygen -t ecdsa -P <span class="s1">''</span></code></pre>
<p>Programm k&#252;sib sisendiks kuhu salvestada v&#245;tmed, seal v&#245;ib vajutada
<em>Enter</em>, et kasutada vaikimisi kataloogi .ssh kodukataloogis kuhu
kirjutatakse privaatne v&#245;ti failinimiega <em>id_ecdsa</em> ning
avalik v&#245;ti failinimega <em>id_ecdsa.pub</em>.
V&#228;ljund peaks v&#228;lja n&#228;gema umbkaudu j&#228;rgnev:</p>
<pre class="code literal-block"><code>Generating public/private ecdsa key pair.
Enter file in which to save the key (/home/kasutaja/.ssh/id_ecdsa):
Your identification has been saved in /home/kasutaja/.ssh/id_ecdsa.
Your public key has been saved in /home/lauri/.ssh/id_ecdsa.pub.
The key fingerprint is:
2e:36:33:9b:3e:ec:23:62:4f:be:82:b5:8a:de:72:2b kasutaja@localhost
The key's randomart image is:
+--[ECDSA  256]---+
|                 |
|                 |
|                 |
|                 |
|        S        |
|  .    .         |
| o ...* .        |
|oE*+..+B         |
|+++*===o         |
+-----------------+</code></pre>
<p>Loodud v&#245;tmepaar vastab konkreetse arvuti parajasti sisse logitud kasutajale
ning avalik v&#245;ti sobib selle kasutaja autentimiseks teistes arvutites.</p>
</div>
<div class="section" id="avaliku-votme-kopeerimine">
<h1>Avaliku v&#245;tme kopeerimine</h1>
<p>Enne kui j&#228;tkad veendu et sihtmasinas oleks OpenSSH server paigaldatud,
vastasel korral v&#245;id serverist vastuseks saada <em>Connection refused</em>:</p>
<pre class="code bash literal-block"><code>sudo apt-get install openssh-server</code></pre>
<p>&#220;lal loodud <em>id_ecdsa.pub</em> alusel saab kasutajat autentida ning
selleks, et v&#245;imaldada sihtarvuti paroolita ligip&#228;&#228;s avaliku v&#245;tme alusel
v&#245;ib kasutada <em>ssh-copy-id</em> k&#228;sku:</p>
<pre class="code bash literal-block"><code>ssh-copy-id kasutaja@sihtmasin</code></pre>
<p>See k&#228;sk logib sihtmasinasse sisse parooliga, vajadusel loob .ssh kataloogi
sihtmasinas ning lisab sinna <em>authorized_keys</em> faili l&#245;ppu avaliku v&#245;tme.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="278 -150 565 431" preserveAspectRatio="xMidYMid meet" style=""><rect x="280" y="40" width="560" height="240" fill="none" fill-opacity="0" stroke-width="2" stroke-dasharray="4" stroke="#000000"/><g><rect x="580" y="220" width="240" height="43.1667" fill="#ffffff"/><rect x="580" y="220" width="240" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9333" x="700" y="246.75" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="700" y="246.75">~/.ssh/id_ecdsa</tspan></text></g><g><rect x="580" y="140" width="240" height="43.1667" fill="#ffffff"/><rect x="580" y="140" width="240" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9333" x="700" y="166.75" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="700" y="166.75">~/.ssh/id_ecdsa.pub</tspan></text></g><g><rect x="580" y="-100" width="240" height="43.1667" fill="#ffffff"/><rect x="580" y="-100" width="240" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9333" x="700" y="-73.25" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="700" y="-73.25">~/.ssh/authorized_keys</tspan></text></g><g><line x1="700" y1="139.107" x2="700" y2="112.903" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="700,105.403 705,115.403 700,112.903 695,115.403 " fill="#000000"/><polygon points="700,105.403 705,115.403 700,112.903 695,115.403 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><text font-size="16.9333" x="300" y="25.875" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="300" y="25.875">Local machine</tspan></text><rect x="280" y="-120" width="560" height="80" fill="none" fill-opacity="0" stroke-width="2" stroke-dasharray="4" stroke="#000000"/><text font-size="16.9333" x="300" y="-134.125" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="300" y="-134.125">Remote machine</tspan></text><g><rect x="300" y="180" width="240" height="43.1667" fill="#ffffff"/><rect x="300" y="180" width="240" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9333" x="420" y="206.75" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="420" y="206.75">ssh-keygen -t ecdsa</tspan></text></g><g><line x1="700" y1="60" x2="700" y2="-46.0983" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="700,-53.5983 705,-43.5983 700,-46.0983 695,-43.5983 " fill="#000000"/><polygon points="700,-53.5983 705,-43.5983 700,-46.0983 695,-43.5983 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><line x1="541.005" y1="184.297" x2="569.357" y2="180.247" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="576.782,179.186 567.589,185.55 569.357,180.247 566.175,175.65 " fill="#000000"/><polygon points="576.782,179.186 567.589,185.55 569.357,180.247 566.175,175.65 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><line x1="541.005" y1="218.87" x2="569.357" y2="222.92" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="576.782,223.981 566.175,227.516 569.357,222.92 567.589,217.617 " fill="#000000"/><polygon points="576.782,223.981 566.175,227.516 569.357,222.92 567.589,217.617 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><text font-size="16.9333" x="720" y="0" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="720" y="0">Password</tspan><tspan x="720" y="21.1667">authentication</tspan></text><g><rect x="460" y="60" width="360" height="43.1667" fill="#ffffff"/><rect x="460" y="60" width="360" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9333" x="640" y="86.75" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="640" y="86.75">ssh-copy-id remote-user@remote-host</tspan></text></g></svg><p class="caption"><em>ssh-copy-id</em> abil <em>ssh-keygen</em> loodud v&#245;tmepaarist avaliku v&#245;tme kaugmasinasse lisamine</p>
</div>
</div>
<div class="section" id="votmega-sisse-logimine">
<h1>V&#245;tmega sisse logimine</h1>
<p>Kui v&#245;tmed on olemas ning avalik v&#245;ti lisatud sihtmasinasse,
peaks autentmine toimima ilma paroolita.
Kui v&#245;tmepaar on olemas pakub klient seda autentmismeetodit serverile,
kui serverile sobib kliendi pakutav v&#245;ti lastakse kasutaja sisse.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-2 10 612 431" preserveAspectRatio="xMidYMid meet" style=""><rect x="0" y="40" width="560" height="160" fill="none" fill-opacity="0" stroke-width="2" stroke-dasharray="4" stroke="#000000"/><g><line x1="389.219" y1="379.107" x2="347.863" y2="348.908" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="341.806,344.485 352.831,346.345 347.863,348.908 346.933,354.421 " fill="#000000"/><polygon points="341.806,344.485 352.831,346.345 347.863,348.908 346.933,354.421 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><rect x="300" y="380" width="240" height="43.1667" fill="#ffffff"/><rect x="300" y="380" width="240" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9331" x="420" y="406.75" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="420" y="406.75">~/.ssh/id_ecdsa</tspan></text></g><g><rect x="20" y="380" width="240" height="43.1667" fill="#ffffff"/><rect x="20" y="380" width="240" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9331" x="140" y="406.75" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="140" y="406.75">~/.ssh/id_ecdsa.pub</tspan></text></g><g><rect x="160" y="140" width="240" height="43.1667" fill="#ffffff"/><rect x="160" y="140" width="240" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9331" x="280" y="166.75" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="280" y="166.75">sshd</tspan></text></g><g><line x1="170.781" y1="379.107" x2="212.137" y2="348.908" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="218.194,344.485 213.067,354.421 212.137,348.908 207.169,346.345 " fill="#000000"/><polygon points="218.194,344.485 213.067,354.421 212.137,348.908 207.169,346.345 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><text font-size="16.9331" x="20" y="265.875" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="20" y="265.875">Local machine</tspan></text><rect x="0" y="280" width="560" height="160" fill="none" fill-opacity="0" stroke-width="2" stroke-dasharray="4" stroke="#000000"/><text font-size="16.9331" x="20" y="25.875" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="20" y="25.875">Remote machine</tspan></text><g><rect x="160" y="300" width="240" height="43.1667" fill="#ffffff"/><rect x="160" y="300" width="240" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9331" x="280" y="326.75" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="280" y="326.75">ssh user@host</tspan></text></g><g><line x1="280" y1="300" x2="280" y2="192.903" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="280,185.403 285,195.403 280,192.903 275,195.403 " fill="#000000"/><polygon points="280,185.403 285,195.403 280,192.903 275,195.403 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><g><rect x="160" y="60" width="240" height="43.1667" fill="#ffffff"/><rect x="160" y="60" width="240" height="43.1667" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="16.9331" x="280" y="86.75" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="280" y="86.75">~/.ssh/authorized_keys</tspan></text></g><g><line x1="280" y1="104.171" x2="280" y2="129.259" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><polygon points="280,136.759 275,126.759 280,129.259 285,126.759 " fill="#000000"/><polygon points="280,136.759 275,126.759 280,129.259 285,126.759 " fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/></g><text font-size="16.9331" x="300" y="240" fill="#000000" text-anchor="start" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="300" y="240">Offer public key</tspan><tspan x="300" y="261.167">Fall back to password authentication</tspan></text></svg><p class="caption">Kliendi autentmine v&#245;tmega</p>
</div>
</div>
<div class="section" id="parooliga-sisselogimise-keelamine">
<h1>Parooliga sisselogimise keelamine</h1>
<p>Kui v&#245;tmega autentmine toimib ning parooli pole vaja m&#245;neks muuks otstarbeks (nt <em>sudo</em>),
v&#245;ib eemaldada ja keelata kasutaja parooli sihtmasinas:</p>
<pre class="code bash literal-block"><code><span class="c1"># Parooli eemaldada ja keelata saab vaid root
</span>passwd -d -l kasutajanimi</code></pre>
<p>Kui parooliga sisselogimist on siiski tarvis aga &#252;le SSH ligip&#228;&#228;s v&#245;iks olla
lubatud vaid avaliku v&#245;tmega, v&#245;ib SSH serveri konfiguratsioonis
v&#228;lja l&#252;litada parooliga autentmise kasutades <em>PasswordAuthentication no</em> rida:</p>
<pre class="code bash literal-block"><code>sed -r -e <span class="s1">'s/^.?PasswordAuthentication .*/PasswordAuthentication no/'</span> -i /etc/ssh/sshd_config
service ssh reload</code></pre>
</div>
</div>
]]></content>
    
    <category term="ssh-copy-id"/>
    <category term="OpenSSH"/>
    <updated>2015-06-16T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
  <entry>
    <title>Linux konteinerid</title>
    <summary>Linux konteinerid (Linux Containers) v&#245;i l&#252;hidalt LXC on tehnoloogia,
mis kasutab Linux tuuma <em>control groups</em> funktsionaalsust
v&#245;imaldades &#252;he Linux tuuma all k&#228;itada mitut isoleeritud
Linux-p&#245;hist operatsioonis&#252;steemi ehk teiste s&#245;nadega
partitsioneerida Linux-p&#245;hise masina ressursse.
Tegu on operatsioonis&#252;steemi tasemel virtualiseerimisega
nagu BSD Jails <a class="footnote-reference brackets" href="#bsd-jails" id="id1">1</a> v&#245;i OpenVZ <a class="footnote-reference brackets" href="#openvz" id="id2">2</a>,
kus samamoodi mitu operatsioonis&#252;steemi instantsi jagavad &#252;hte tuuma.
K&#228;esolev juhend eeldab Debian 8 <em>jessie</em>, Ubuntu 15.04 v&#245;i
hilisemate v&#228;ljalasete paigaldust.</summary>
    <link href="http://lauri.vosandi.com/cfgmgmt/linux-containers.html"/>
    <content type="html"><![CDATA[<div class="document" id="linux-konteinerid">
<!-- date: 2015-05-24 -->
<!-- author: Lauri V&#245;sandi <lauri.vosandi@gmail.com> -->
<!-- tags: Ubuntu, Debian, -->
<div class="section" id="sissejuhatus">
<h1>Sissejuhatus</h1>
<p>Linux konteinerid (Linux Containers) v&#245;i l&#252;hidalt LXC on tehnoloogia,
mis kasutab Linux tuuma <em>control groups</em> funktsionaalsust
v&#245;imaldades &#252;he Linux tuuma all k&#228;itada mitut isoleeritud
Linux-p&#245;hist operatsioonis&#252;steemi ehk teiste s&#245;nadega
partitsioneerida Linux-p&#245;hise masina ressursse.
Tegu on operatsioonis&#252;steemi tasemel virtualiseerimisega
nagu BSD Jails <a class="footnote-reference brackets" href="#bsd-jails" id="id1">1</a> v&#245;i OpenVZ <a class="footnote-reference brackets" href="#openvz" id="id2">2</a>,
kus samamoodi mitu operatsioonis&#252;steemi instantsi jagavad &#252;hte tuuma.
K&#228;esolev juhend eeldab Debian 8 <em>jessie</em>, Ubuntu 15.04 v&#245;i
hilisemate v&#228;ljalasete paigaldust.</p>
<dl class="footnote brackets">
<dt class="label" id="bsd-jails"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
<dd><p><a class="reference external" href="https://www.freebsd.org/doc/en/books/handbook/jails.html">https://www.freebsd.org/doc/en/books/handbook/jails.html</a></p>
</dd>
<dt class="label" id="openvz"><span class="brackets"><a class="fn-backref" href="#id2">2</a></span></dt>
<dd><p><a class="reference external" href="https://openvz.org/">https://openvz.org/</a></p>
</dd>
</dl>
</div>
<div class="section" id="taustast">
<h1>Taustast</h1>
<p>Konteinerite puhul on juurfailis&#252;steemid, st kataloogid mis sisaldavad
operatsioonis&#252;steemi faile eraldatud, aga Linuxi tuum mida konteinerid
kasutavad on sama ning jagatud.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 702 422" preserveAspectRatio="xMidYMid meet" style=""><g><rect x="0" y="140" width="700" height="40" fill="#ffffff"/><rect x="0" y="140" width="700" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="163.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="163.9">Linux tuum</tspan></text></g><g><rect x="180" y="0" width="160" height="60" fill="#ffffff"/><rect x="180" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="25.9">Debian</tspan><tspan x="260" y="41.9">juurfailis&#252;steem</tspan></text></g><g><rect x="360" y="0" width="160" height="60" fill="#ffffff"/><rect x="360" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="25.9">Ubuntu</tspan><tspan x="440" y="41.9">juurfailis&#252;steem</tspan></text></g><g><rect x="540" y="0" width="160" height="60" fill="#ffffff"/><rect x="540" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="25.9">Fedora</tspan><tspan x="620" y="41.9">juurfailis&#252;steem</tspan></text></g><g><rect x="0" y="0" width="160" height="60" fill="#ffffff"/><rect x="0" y="0" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="80" y="25.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="25.9">Host</tspan><tspan x="80" y="41.9">juurfailis&#252;steem</tspan></text></g><line x1="260" y1="60" x2="260" y2="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="440" y1="60" x2="440" y2="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="620" y1="60" x2="620" y2="80" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="620" y1="120" x2="620" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="440" y1="120" x2="440" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="260" y1="120" x2="260" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="80" y1="60" x2="80" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="350" y1="180" x2="350" y2="380" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="590" y1="180" x2="590" y2="380" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="240" y="200" width="220" height="40" fill="#ffffff"/><rect x="240" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="223.9">Virtuaalm&#228;lu</tspan></text></g><line x1="110" y1="380" x2="110" y2="180" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="240" y="380" width="220" height="40" fill="#ffffff"/><rect x="240" y="380" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="403.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="403.9">F&#252;&#252;siline m&#228;lu</tspan></text></g><g><rect x="180" y="80" width="160" height="40" fill="#ffffff"/><rect x="180" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="103.9">Konteiner #1</tspan></text></g><g><rect x="360" y="80" width="160" height="40" fill="#ffffff"/><rect x="360" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="103.9">Konteiner #2</tspan></text></g><g><rect x="540" y="80" width="160" height="40" fill="#ffffff"/><rect x="540" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="103.9">Konteiner #3</tspan></text></g><g><rect x="480" y="380" width="220" height="40" fill="#ffffff"/><rect x="480" y="380" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="590" y="403.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="590" y="403.9">Protsessor</tspan></text></g><g><rect x="0" y="200" width="220" height="40" fill="#ffffff"/><rect x="0" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="223.9">Virtuaalfailis&#252;steem</tspan></text></g><g><rect x="0" y="260" width="220" height="40" fill="#ffffff"/><rect x="0" y="260" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="283.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="283.9">Btrfs/ZFS/ext4 t&#252;&#252;rel</tspan></text></g><g><rect x="0" y="320" width="220" height="40" fill="#ffffff"/><rect x="0" y="320" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="343.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="343.9">Kettakontrolleri t&#252;&#252;rel</tspan></text></g><g><rect x="0" y="380" width="220" height="40" fill="#ffffff"/><rect x="0" y="380" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="403.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="403.9">Ketas ja SSD</tspan></text></g></svg><p class="caption">Tuum on jagatud, juurfailis&#252;steemid eraldi.</p>
</div>
<p>Kontrollgruppidega (control groups), saab isoleerida ka
v&#245;rguliidesed ja protsessid ning piirata protsessori ja m&#228;lu kastutust.</p>
<p>Protsessipuu s&#228;&#228;rase s&#252;steemi k&#228;ivitamisel n&#228;eks v&#228;lja umbkaudu j&#228;rgnev:</p>
<pre class="code literal-block"><code>systemd
  &#9500;&#9472;acpid
  &#9500;&#9472;agetty --noclear tty1 linux
  &#9500;&#9472;atd -f
  &#9500;&#9472;cron -f
  &#9500;&#9472;dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  &#9500;&#9472;dhclient -v -pf /run/dhclient.lxcbr0.pid -lf /var/lib/dhcp/dhclient.lxcbr0.leases lxcbr0
  &#9500;&#9472;lxc-start -d -n ubuntu-trusty-test
  &#9474;   &#9492;&#9472;init
  &#9474;       &#9500;&#9472;dbus-daemon --system --fork
  &#9474;       &#9500;&#9472;dhclient -1 -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
  &#9474;       &#9500;&#9472;getty -8 38400 console
  &#9474;       &#9500;&#9472;cron
  &#9474;       &#9500;&#9472;sshd -D
  &#9474;       &#9500;&#9472;systemd-logind
  &#9474;       &#9500;&#9472;systemd-udevd --daemon
  &#9474;       &#9500;&#9472;upstart-file-br --daemon
  &#9474;       &#9500;&#9472;upstart-socket- --daemon
  &#9474;       &#9492;&#9472;upstart-udev-br --daemon
  &#9500;&#9472;lxc-start -g debian-wheezy-test
  &#9474;   &#9492;&#9472;systemd
  &#9474;       &#9500;&#9472;dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  &#9474;       &#9500;&#9472;dhclient -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
  &#9474;       &#9500;&#9472;agetty --noclear -s console 115200 38400 9600
  &#9474;       &#9500;&#9472;cron
  &#9474;       &#9500;&#9472;sshd -D
  &#9474;       &#9500;&#9472;systemd-journal
  &#9474;       &#9500;&#9472;systemd-logind
  &#9474;       &#9492;&#9472;systemd-udevd
  &#9500;&#9472;lxc-start -d -n debian-jessie-test
  &#9474;   &#9492;&#9472;systemd
  &#9474;       &#9500;&#9472;dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
  &#9474;       &#9500;&#9472;dhclient -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
  &#9474;       &#9500;&#9472;sshd -D
  &#9474;       &#9500;&#9472;systemd-journal
  &#9474;       &#9492;&#9472;systemd-logind
  &#9500;&#9472;sshd -D
  &#9500;&#9472;systemd-journal
  &#9500;&#9472;systemd-logind
  &#9492;&#9472;systemd-udevd</code></pre>
<p>Siit on n&#228;ha, et iga konteineri jaoks on oma virtuaalne v&#245;rguliides <em>eth0</em> ning
DHCP klientrakendus on k&#228;ivitatud iga konteineri jaoks.
Kuna iga konteiner paistab eraldi IP-ga v&#245;rgus on igas konteineris jooksmas
ka OpenSSH server.</p>
</div>
<div class="section" id="paigaldus">
<h1>Paigaldus</h1>
<p>Paigalda LXC ja mallide skriptid:</p>
<pre class="code bash literal-block"><code>apt-get install lxc lxc-templates bridge-utils</code></pre>
</div>
<div class="section" id="konteineri-loomine">
<h1>Konteineri loomine</h1>
<p>Loo Debian 8 konteiner:</p>
<pre class="code bash literal-block"><code>lxc-create -n test1 -t debian -- -r jessie</code></pre>
<p>LXC konteinereid saab paigutada ka failis&#252;steemi jaotistesse
a'la Btrfs v&#245;i ZFS subvolume:</p>
<pre class="code bash literal-block"><code>lxc-create -n test2 -t debian -B btrfs -- -r jessie</code></pre>
<p>Niiviisi paigutatakse konteineri juurfailis&#252;steem
/var/lib/lxc/test2/rootfs
Btrfs subvolume sisse,
mida saab h&#245;lpsalt varundada.</p>
<p>Ubuntu 14.04 i386 konteineri saab luua j&#228;rnevalt:</p>
<pre class="code bash literal-block"><code>lxc-create -n katse -B btrfs -t ubuntu -- -r trusty -a i386</code></pre>
<p>Paigaldada saab ka eel-valmistatud juurfailis&#252;steemi, see on pisut kiirem kui &#252;lemine:</p>
<pre class="code bash literal-block"><code>lxc-create -n katse -B btrfs -t download -- -d ubuntu -r trusty -a i386</code></pre>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>Ubuntu 15.04 ning Debian 8 v&#245;tsid kasutusele <em>systemd</em>, mis t&#228;hendab et vanemal peremeesoperatsioonis&#252;steemil nende v&#245;i hilisemate k&#252;lalisopeartsioonis&#252;steemide k&#228;itamine on veel problemaatiline.</p>
</div>
</div>
<div class="section" id="voora-arhitektuuriga-konteinerid">
<h1>V&#245;&#245;ra arhitektuuriga konteinerid</h1>
<p>64-bitise x86 protsessori peal saab otse k&#228;itada ka 32-bitist
konteinerit, kui konteineri loomisel kasutada <em>-a i386</em> v&#245;tit:</p>
<pre class="code bash literal-block"><code>lxc-create -n test2 -t debian -B btrfs -- -r jessie -a i386</code></pre>
<p>V&#245;&#245;ra arhitektuuriga (ARM, MIPS, PowerPC jms) konteinerite k&#228;itamiseks tuleb paigaldada
QEMU emulatsioonikiht:</p>
<pre class="code bash literal-block"><code>apt-get install qemu-user-static</code></pre>
<p>Nii saab luua n&#228;iteks ARMv7 arhitektuuriga konteineri:</p>
<pre class="code bash literal-block"><code>lxc-create -n test3 -t download -B btrfs -- -d debian -r wheezy -a armhf</code></pre>
<p>Enne k&#228;ivitamist peaks paigaldama QEMU binaarid ka konteineri sisse:</p>
<pre class="code bash literal-block"><code>cp /usr/bin/qemu-*-static /var/lib/lxc/test3/rootfs/usr/bin/</code></pre>
<p>Emuleeritud arhitetuurid on muidugi aeglased, aga see v&#245;imaldab
n&#228;iteks <em>x86-64</em> riistvara peal teha tarkvaraarendust <em>armhf</em> platvormile.</p>
<div class="figure">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -61 702 302" preserveAspectRatio="xMidYMid meet" style=""><line x1="260" y1="0" x2="260" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="440" y1="0" x2="440" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="620" y1="0" x2="620" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="350" y1="180.977" x2="350" y2="200" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="590" y1="180" x2="590" y2="200" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="0" y="140" width="700" height="40" fill="#ffffff"/><rect x="0" y="140" width="700" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="163.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="163.9">Linux tuum</tspan></text></g><g><rect x="180" y="80" width="160" height="40" fill="#ffffff"/><rect x="180" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="103.9">Konteiner #1</tspan></text></g><g><rect x="360" y="80" width="160" height="40" fill="#ffffff"/><rect x="360" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="103.9">Konteiner #2</tspan></text></g><g><rect x="540" y="80" width="160" height="40" fill="#ffffff"/><rect x="540" y="80" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="103.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="103.9">Konteiner #3</tspan></text></g><g><rect x="180" y="-60" width="160" height="60" fill="#ffffff"/><rect x="180" y="-60" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="260" y="-34.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="260" y="-34.1">Debian x86</tspan><tspan x="260" y="-18.1">juurfailis&#252;steem</tspan></text></g><g><rect x="360" y="-60" width="160" height="60" fill="#ffffff"/><rect x="360" y="-60" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="440" y="-34.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="440" y="-34.1">Ubuntu x86-64</tspan><tspan x="440" y="-18.1">juurfailis&#252;steem</tspan></text></g><g><rect x="540" y="-60" width="160" height="60" fill="#ffffff"/><rect x="540" y="-60" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="-34.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="-34.1">Fedora armhf</tspan><tspan x="620" y="-18.1">juurfailis&#252;steem</tspan></text></g><g><rect x="0" y="-60" width="160" height="60" fill="#ffffff"/><rect x="0" y="-60" width="160" height="60" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="80" y="-34.1" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="80" y="-34.1">Host</tspan><tspan x="80" y="-18.1">root</tspan></text></g><line x1="110" y1="200" x2="110" y2="180" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><line x1="80" y1="0" x2="80" y2="140" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><g><rect x="540" y="20" width="160" height="40" fill="#ffffff"/><rect x="540" y="20" width="160" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="620" y="43.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="620" y="43.9">qemu-arm-static</tspan></text></g><g><rect x="240" y="200" width="220" height="40" fill="#ffffff"/><rect x="240" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="350" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="350" y="223.9">M&#228;lu</tspan></text></g><g><rect x="480" y="200" width="220" height="40" fill="#ffffff"/><rect x="480" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="590" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="590" y="223.9">x86-64 protsessor</tspan></text></g><g><rect x="0" y="200" width="220" height="40" fill="#ffffff"/><rect x="0" y="200" width="220" height="40" fill="none" fill-opacity="0" stroke-width="2" stroke="#000000"/><text font-size="12.8" x="110" y="223.9" fill="#000000" text-anchor="middle" font-family="Cabin Condensed" font-style="normal" font-weight="normal"><tspan x="110" y="223.9">Storage</tspan></text></g></svg><p class="caption">binfmt-support abil teab tuum kuidas &#252;hele v&#245;i teisele arhitektuurile m&#245;eldud binaari k&#228;itada.</p>
</div>
</div>
<div class="section" id="konteinerite-haldus">
<h1>Konteinerite haldus</h1>
<p>K&#228;ivita konteiner:</p>
<pre class="code bash literal-block"><code>lxc-start -n katse -d</code></pre>
<p>Haagi konteineri k&#228;sureale:</p>
<pre class="code bash literal-block"><code>lxc-attach -n katse</code></pre>
<p>Konteineri seest saab konteineri kinni panna ja taask&#228;ivitada
tavap&#228;raste <em>halt</em> ja <em>reboot</em> k&#228;skudega.</p>
<p>Peremeesmasinast saab konteineri viisakalt kinni panna j&#228;rgnevalt:</p>
<pre class="code bash literal-block"><code>lxc-stop -n katse</code></pre>
<p>Konteinerite nimekiri:</p>
<pre class="code bash literal-block"><code>lxc-ls -f</code></pre>
<p>Konteineri automaatseks k&#228;ivitamiseks alglaadimisel lisa
j&#228;rgnev rida faili /var/lib/lxc/katse/config:</p>
<pre class="code ini literal-block"><code><span class="na">lxc.start.auto</span> <span class="o">=</span> <span class="s">1</span></code></pre>
</div>
<div class="section" id="vorgu-seadistamine">
<h1>V&#245;rgu seadistamine</h1>
<p>Vaikimisi kointeinerid kas ei saa v&#245;rku &#252;ldse (Debian 8, Ubuntu 14.04) v&#245;i
nad liidetakse lxcbr0 silla koosseisu (Ubuntu 15.04+), kus neile k&#252;ll pakutakse IP aadress
aga selle kaudu internetti veel ei p&#228;&#228;se. K&#245;ige pealt
tee kindlaks et on paigaldatud sildade seadistamiseks ette n&#228;htud t&#246;&#246;riistad:</p>
<pre class="code bash literal-block"><code>apt-get install bridge-utils</code></pre>
<p>Peata v&#245;rguliides <em>eth0</em>, vastasel korral j&#228;&#228;b talle IP aadress k&#252;lge ja
tekivad anomaaliad kui sillal ja v&#245;rguliidesel m&#245;lemal sama IP aadress on.</p>
<pre class="code bash literal-block"><code>ifdown eth0</code></pre>
<p>Selleks, et m&#245;lemas keskkonnas f&#252;&#252;silisse v&#245;rku ligip&#228;&#228;s anda ning
mitte konflikti minna eelseadistatud v&#245;rguliidestega nagu lxcbr0 v&#245;ime
&#252;mber seadistada peremeesmasina v&#245;rgu failis /etc/network/interfaces:</p>
<pre class="code bash literal-block"><code>auto lo
iface lo inet loopback

auto br0
iface br0 inet dhcp
    <span class="c1"># Lisa f&#252;&#252;siline eth0 silla koosseisu
</span>    bridge_ports eth0

<span class="c1"># Eemalda v&#245;rguliidese definitsioon f&#252;&#252;silise v&#245;rguliidese jaoks:
</span>
<span class="c1">#auto eth0
#iface eth0 inet ...</span></code></pre>
<p>K&#228;ivita sild:</p>
<pre class="code bash literal-block"><code>ifup br0</code></pre>
<p>Veendu, et <em>br0</em> saab legitiimse IP-aadressi ning et <em>eth0</em> ning teistel
silla koosseisu kuuluvatel v&#245;rguliidestel poleks IP-aadressi m&#228;&#228;ratud.
Kui j&#228;i eelnevalt <em>eth0</em> kinni panemata saab v&#245;rguliidese l&#252;litada
nn <em>promiscuous</em> re&#382;iimi j&#228;rgnevalt:</p>
<pre class="code bash literal-block"><code>ifconfig eth0 <span class="m">0</span>.0.0.0 promisc up</code></pre>
<p>Seadista k&#252;lalismasina v&#245;rk &#252;mber failis /var/lib/lxc/katse/config:</p>
<pre class="code ini literal-block"><code><span class="c1"># Kasuta virtuaalset ethernet v&#245;rguliidest</span>
<span class="na">lxc.network.type</span> <span class="o">=</span> <span class="s">veth</span>

<span class="c1"># V&#245;rguliides k&#228;ivitatakse konteineri k&#228;ivitamisel</span>
<span class="na">lxc.network.flags</span> <span class="o">=</span> <span class="s">up</span>

 <span class="c1"># V&#245;rguliides lisatakse selle silla koosseisu</span>
<span class="na">lxc.network.link</span> <span class="o">=</span> <span class="s">br0</span></code></pre>
<p>Silla olekut saad kontrollida brctl ja ifconfig abil:</p>
<pre class="code bash literal-block"><code>ifconfig br0        <span class="c1"># Liidesel peaks olema f&#252;&#252;silise v&#245;rgu aadress
</span>ifconfig eth0       <span class="c1"># Liidesel ei tohiks olla IP aadressi
</span>brctl show br0      <span class="c1"># Interfaces all peaks olema eth0 ja vethXXXX (per-konteiner) liidesed</span></code></pre>
</div>
</div>
]]></content>
    
    <category term="Ubuntu"/>
    <category term=""/>
    <category term="Debian"/>
    <updated>2015-05-24T00:00:00Z</updated>
    
    <author>
      <name>Lauri Võsandi</name>
      <email>lauri.vosandi@gmail.com</email>
    </author>
    
  </entry>
  
</feed>