Wednesday, June 29, 2016

Deploy Firefox on Windows XP

Firefox is one of Fully futured browser which still are supported on Windows XP. Even version 47. Some company in my country still have 200 XP workstations and they asked me can i write a script for Firefox deployment. Here it is:
@echo off

rem this script will install chech and install firefox on windows xp worksatition

setlocal EnableDelayedExpansion

rem detects Windows XP operating system
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v ProductName | find "Windows XP" > nul 2>&1
if !errorlevel!==0 (

rem check inf any Firefox is installed
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s | find "Mozilla Firefox"
if not !errorlevel!==0 (

echo Installing Mozilla Firefox
for /f "tokens=*" %%a in ('dir /b "%~dp0Firefox*Setup*.exe"') do start /wait "" "%~dp0%%a" /SILENT

) else echo Firefox is already installed

) else echo This is not Windows XP operating system

endlocal

Related files:
https://download-installer.cdn.mozilla.net/pub/firefox/releases/47.0.1/win32/en-US/Firefox Setup 47.0.1.exe

Tuesday, June 28, 2016

Substitute only the first match with sed

I am going to automate this instruction and one thing i challenged myself is to insert some multi line content in the middle of file. For example this is the content i need to insert:
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES
The file i working with looks like:
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#
<-- i need to insert multi line content here
# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines


# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT

# quickly process packets for which we already have a connection
-A ufw-before-input -m state --state RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m state --state RELATED,ESTABLISHED -j ACCEPT

# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m state --state INVALID -j ufw-logging-deny
-A ufw-before-input -m state --state INVALID -j DROP

# ok icmp codes
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type source-quench -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT

# allow dhcp client to work
-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT

#
# ufw-not-local
#
-A ufw-before-input -j ufw-not-local

# if LOCAL, RETURN
-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN

# if MULTICAST, RETURN
-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN

# if BROADCAST, RETURN
-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN

# all other non-local packets are dropped
-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
-A ufw-not-local -j DROP

# allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT

# allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT

# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT
I solved this by searching the first empty line. This is possible with sed. For example this will add another five empty lines to the first empty line:
sed -i "0,/^$/s/^$/\n\n\n\n\n/" /etc/ufw/before.rules
And now the file looks like this:
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#






# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines
...
At the end i used this command:
sed -i "0,/^$/s/^$/\n# START OPENVPN RULES\n# NAT table rules\n*nat\n:POSTROUTING ACCEPT [0:0]\n# Allow traffic from OpenVPN client to eth0\n-A POSTROUTING -s 10\.8\.0\.0\/8 -o eth0 -j MASQUERADE\nCOMMIT\n# END OPENVPN RULES\n/" /etc/ufw/before.rules
and i got what i need:
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines
...
Ok it is kind of silly thing to match first empty line. In this case more safer way is to try look for line:
# Don't delete these required lines, otherwise there will be errors
and then insert content before this line.

In this case i need to use:
sed "0,/^.*Don.*delete these required lines.*otherwise there will be errors$/s/^.*Don.*delete these required lines.*otherwise there will be errors$/# START OPENVPN RULES\n# NAT table rules\n*nat\n:POSTROUTING ACCEPT [0:0]\n# Allow traffic from OpenVPN client to eth0\n-A POSTROUTING -s 10\.8\.0\.0\/8 -o eth0 -j MASQUERADE\nCOMMIT\n# END OPENVPN RULES\n\n# Don\'t delete these required lines, otherwise there will be errors\n/" /etc/ufw/before.rules
Related:
https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-debian-8

Monday, June 27, 2016

Restore Windows Photo Viewer file association, Server 2008 R2

After these weeks windows updates all image file association in my Server 2008 R2 has gone back to Microsoft Photo editor and if the image is bigger than 5248x3936 than it can not handle that:

I notified that i can restore file association But this works only for current user.

i used my Process Monitor to monitor what happens under the hood:
and i found these keys :)

At the end I created group policy to force file association for jpg, png and tiff extension:

Another solution is to run these commands with simple user permissions:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.jpg\UserChoice" /v Progid /t REG_SZ /d "PhotoViewer.FileAssoc.Jpeg" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.png\UserChoice" /v Progid /t REG_SZ /d "PhotoViewer.FileAssoc.Png" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.jpeg\UserChoice" /v Progid /t REG_SZ /d "PhotoViewer.FileAssoc.Jpeg" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.jpe\UserChoice" /v Progid /t REG_SZ /d "PhotoViewer.FileAssoc.Jpeg" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.tiff\UserChoice" /v Progid /t REG_SZ /d "PhotoViewer.FileAssoc.Tiff" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.tif\UserChoice" /v Progid /t REG_SZ /d "PhotoViewer.FileAssoc.Tiff" /f

Saturday, June 25, 2016

re-download latest applications

I am testing windows operating systems every time I create a new iso file which includes a bunch of updates. As a part of real word installation I also need to include basic applications for daily use. I am pretty tired of re-checking and re-downloading latest versions. I know there are brilliant service https://ninite.com/ which I also use but if I want to create 100% offline installation then i need to have a bunch of offline installers and that is why i started this project. So here comes quick idea to do this automatically.

I have these two main programs:
64-bit-re-download.cmd and 32-bit-re-download.cmd.
Each of these files will search for another files witch contains "x64" or "x86" in the name.

For example 64-bit-re-download.cmd includes:
@echo off
if exist "%userprofile%\Desktop\x64" rd "%userprofile%\Desktop\x64" /Q /S
if not exist "%userprofile%\Desktop\x64\FirstRun" md "%userprofile%\Desktop\x64\FirstRun"
echo @echo off > "%userprofile%\Desktop\x64\FirstRun\FirstRun.bat"
for /f "tokens=*" %%a in ('dir /b "*x64*cmd"') do call "%%a" %userprofile%\Desktop\x64\FirstRun
For example this is how to download latest firefox 64-bit version, put in the x64 directory and add silent install command to FirstRun.cmd
@echo off
for /f "tokens=*" %%a in ('wget --no-check-certificate -qO- "https://www.mozilla.org/en-US/firefox/all/" ^| sed "s/\d034/\n/g" ^| grep "^https.*download.mozilla.*win64.*en-US"') do wget --no-check-certificate "%%a" -P %1 
echo for /f "tokens=*" %%%%a in ('dir /b "%%~dp0Firefox*Setup*.exe"') do start /wait "" "%%~dp0%%%%a" /SILENT>> "%1\FirstRun.bat"
I have 10+ applications added to the project. Full list and source code can see:
https://github.com/catonrug/re-download-latest

Download all files together:
https://github.com/catonrug/re-download-latest/archive/master.zip

Tuesday, June 21, 2016

Adobe Reader 11 silent uninstall

This is how to uninstall all Adobe Reader versions without using any source files.

silent-uninstall.cmd:
@echo off
setlocal EnableDelayedExpansion
set U=Microsoft\Windows\CurrentVersion\Uninstall
set v=DisplayVersion
set v110={AC76BA86-7AD7-1033-7B44-AB0000000001}
if "%ProgramFiles(x86)%"=="" (
set SW=HKLM\SOFTWARE
) else (
set SW=HKLM\SOFTWARE\Wow6432Node
)
:uninstall
for %%a in ({AC76BA86-7AD7-1033-7646-A00000000001} ^
{AC76BA86-7AD7-1033-7B44-A70000000000} ^
{AC76BA86-7AD7-1033-7B44-A71000000002} ^
{AC76BA86-7AD7-1033-7B44-A80000000002} ^
{AC76BA86-7AD7-1033-7B44-A81000000003} ^
{AC76BA86-7AD7-1033-7B44-A82000000003} ^
{AC76BA86-7AD7-1033-7B44-A83000000003} ^
{AC76BA86-7AD7-1033-7B44-A90000000001} ^
{AC76BA86-7AD7-1033-7B44-A91000000001} ^
{AC76BA86-7AD7-1033-7B44-A92000000001} ^
{AC76BA86-7AD7-1033-7B44-A93000000001} ^
{AC76BA86-7AD7-1033-7B44-A94000000001} ^
{AC76BA86-7AD7-1033-7B44-A95000000001} ^
{AC76BA86-7AD7-1033-7B44-AA0000000001} ^
{AC76BA86-7AD7-1033-7B44-AA1000000001} ^
{AC76BA86-7AD7-1033-7B44-AB0000000001}) do (
reg query %SW%\%U%\%%a > nul 2>&1
if !errorlevel!==0 (
echo Found version:
reg query %SW%\%U%\%%a /v %v% | find "%v%"
echo Uninstalling..
%systemroot%\system32\msiexec.exe /x%%a /qn /norestart
)
)
endlocal

Sunday, June 19, 2016

Powering 4 raspberries with ACME CH16


It been a quite a while since i use ACME CH12 to power two Raspberry Pi 2. ACME CH12 is 2.1A 5V charger and it can satisfy two raspberry pi 2 at the same time if using no peripherals at all.
Now acme CH16 came out with 4.9A 5V power. Is it better to use one ACME CH16 instead of two CH12 models? I am using my Energy Power Meter EL-EPM02HQ to take some measure about energy eating.

So i turned my 4 pies using two CH12 models and let the pies do what there are supposed to do. CPU gets very warm as always that means that there happens energy eating. After 10 minutes I look at maximum WATS measure and it says 10.4W. I was doing the same with CH16 and the maximum WATS measure says 12.3W.
The CH16 model definitely eats more energy. One thing I am really happy about that I can turn out one raspberry and plug off from usb port then turn it back and the other 3 pies has no reflection to it. If I do the same with CH12 then the brother pi always restart when I try to power on by one.

Related:
http://www.acme.eu/en-us/node/3089/pdf

Wednesday, June 15, 2016

Join Zabbix Server and Zabbix Proxy, 2 MikroTik


I faced this situation that i was not able to check when Zabbix Proxy is alive and when not. This is very important cause there are no errors in zabbix server if zabbix proxy simply goes offline.

In my scenario I have two MikroTik routers. In both routers I have enable VPN connection which will allow to set very static public DNS record.

One DNS name is zabbix server address which is used in zabbix proxy configuration file /usr/local/etc/zabbix_proxy.conf and also in zabbix agent configuration file /usr/local/etc/zabbix_agentd.conf. Second DNS address is used only to configure zabbix proxy/agent host on zabbix server side:
zabbix-proxy-as-host.png

On zabbix agent/proxy side I have to create NAT rule witch will allow zabbix server communicate with zabbix agent through port 10050:
client-side-nat-rule-for-zabbix-agent.png

On zabbix server side i have to create NAT rule witch will allow zabbix agent/proxy server receive configuration and send data back it to server via port 10051:
server-side-nat-rule-for-zabbix-proxy.png

This is how i install zabbix proxy and zabbix agent on raspberry pi model b. All comments are embeded in code:
#!/bin/bash
#this code is tested un fresh 2016-05-27-raspbian-jessie-lite.img Raspberry Pi image
#sudo raspi-config -> extend partition -> reboot
#sudo su
#apt-get update -y && apt-get install git -y
#git clone https://github.com/catonrug/raspberry-pi-zabbix.git && cd raspberry-pi-zabbix && chmod +x proxy-agent-install.sh
#time ./proxy-agent-install.sh

#update system
apt-get update -y && apt-get upgrade -y

#install all prerequsites
apt-get install sqlite3 -y #install sqlite3 database engine
apt-get install libsqlite3-dev -y #configure: error: SQLite3 library not found
apt-get install libsnmp-dev -y #configure: error: Invalid Net-SNMP directory - unable to find net-snmp-config
apt-get install libssh2-1-dev -y #configure: error: SSH2 library not found
apt-get install fping -y #/usr/sbin/fping: [2] No such file or directory

#set up zabbix user and group
groupadd zabbix
useradd -g zabbix zabbix

#extract zabbix source
tar -vzxf zabbix-*.tar.gz -C ~

#create basic database
mkdir -p /var/lib/sqlite
cd ~/zabbix-*/database/sqlite3
sqlite3 /var/lib/sqlite/zabbix.db <schema.sql

cd ~/zabbix-*/
./configure --enable-agent --enable-proxy --with-net-snmp --with-sqlite3 --with-ssh2
make install

echo
echo default zabbix_proxy.conf config file:
grep -v "^#\|^$" /usr/local/etc/zabbix_proxy.conf
echo

sed -i "s/^Server=.*$/Server=xxxxxxxxxxxx\.sn\.mynetname\.net/" /usr/local/etc/zabbix_proxy.conf #write ip address of real zabbix server
sed -i "s/^Hostname=.*$/Hostname=Broceni/" /usr/local/etc/zabbix_proxy.conf #write a name for this proxy server
sed -i "s/^DBName=.*$/DBName=\/var\/lib\/sqlite\/zabbix.db/" /usr/local/etc/zabbix_proxy.conf #set location to database
#set permissions to database
chown -R zabbix:zabbix /var/lib/sqlite/
chmod 774 -R /var/lib/sqlite
chmod 664 /var/lib/sqlite/zabbix.db
sed -i "s/^.*FpingLocation=.*$/FpingLocation=\/usr\/bin\/fping/" /usr/local/etc/zabbix_proxy.conf #/usr/sbin/fping: [2] No such file or directory

echo
echo zabbix_proxy.conf file now are:
grep -v "^#\|^$" /usr/local/etc/zabbix_proxy.conf
echo

#set up startup service
cat > /etc/init.d/zabbix_proxy << EOF
#!/bin/sh
case "\$1" in
start)
/usr/local/sbin/zabbix_proxy -c /usr/local/etc/zabbix_proxy.conf
echo "Zabbix proxy started"
;;
stop)
pkill zabbix_proxy
echo "Zabbix proxy stopped"
;;
restart)
pkill zabbix_proxy
sleep 5
/usr/local/sbin/zabbix_proxy -c /usr/local/etc/zabbix_proxy.conf
echo "Zabbix proxy restarted"
;;
*)
echo "Use start, stop, restart"
exit 1
;;
esac
EOF

#set startup service executable
chmod 755 /etc/init.d/zabbix_proxy

#re-read all startup applicaition
update-rc.d zabbix_proxy defaults

#install zabbix agent service
cp ~/zabbix-*/misc/init.d/debian/zabbix-agent /etc/init.d/

#let zabbix agent service to start up automatically at systems startup
update-rc.d zabbix-agent defaults

echo
echo default zabbix_agentd.conf config file:
grep -v "^#\|^$" /usr/local/etc/zabbix_agentd.conf
echo

#set zabbix agent configuration file
sed -i "s/^Server=.*$/Server=xxxxxxxxxxxx\.sn\.mynetname\.net/" /usr/local/etc/zabbix_agentd.conf #write ip address of real zabbix server
sed -i "s/^Hostname=.*$/Hostname=Broceni/" /usr/local/etc/zabbix_agentd.conf #write a name for this proxy server
sed -i "s/^LogFile=.*$/LogFile=\/tmp\/zabbix_agentd.log/" /usr/local/etc/zabbix_agentd.conf #destination for zabbix agent log file
sed -i "s/^ServerActive=.*$/#ServerActive=127\.0\.0\.1/" /usr/local/etc/zabbix_agentd.conf #turn off ServerActive parameter

echo
echo zabbix_agentd.conf file now are:
grep -v "^#\|^$" /usr/local/etc/zabbix_agentd.conf
echo

#set up reboot at midnight
echo "05 00 * * * root reboot">> /etc/crontab
Project on github:
https://github.com/catonrug/raspberry-pi-zabbix/blob/master/proxy-agent-install.sh

Tuesday, June 14, 2016

Failed to restart postgresql.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files

I have CentOS 7 and I am doing same basic postresql install and configuring. At the end I restart postgresql daemon (systemctl restart postgresql) and I got:
Failed to restart postgresql.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files
Turns out have still logged into the system with user postgres and I need to go back to root to restart service::
exit
systemctl restart postgresql

Monday, June 13, 2016

Friday, June 10, 2016

Measure Raspberry Pi temperature

Make a temperature note:
vcgencmd measure_temp
To create a stress test at first sysbench tools must be installed:
sudo apt-get install sysbench -y
Now the test-heatsink.sh script
#!/bin/bash

clear

for f in {1..10}
do
vcgencmd measure_temp
sysbench --test=cpu --cpu-max-prime=20000 --num-threads=4 run >/dev/null 2>&1
done

vcgencmd measure_temp
To install it globally enter super user mode:
sudo su
Paste this content:
cat > /usr/bin/heatsink-test <<EOF
#!/bin/bash

clear

for f in {1..10}
do
vcgencmd measure_temp
sysbench --test=cpu --cpu-max-prime=20000 --num-threads=4 run >/dev/null 2>&1
done

vcgencmd measure_temp
EOF
chmod 755 /usr/bin/heatsink-test

Thursday, June 9, 2016

Job for smbd.service failed. Raspbian

Agter updating raspbian Jessie lite image i got
Job for smbd.service failed. See 'systemctl status smbd.service' and 'journalctl -xn' for details.
invoke-rc.d: initscript smbd, action "start" failed.
dpkg: error processing package samba (--configure):
 subprocess installed post-installation script returned error exit status 1
Lucky for me i got similar thing on CentOS 7.

Please check if samba configuration is perfectly good:
smbstatus
In my case it reports:
WARNING: Ignoring invalid value 'share' for parameter 'security'
Can't load /etc/samba/smb.conf - run testparm to debug it
To solve this case open /etc/samba/smb.conf and replace
security = share
with
#security = share

Wednesday, June 8, 2016

How did I come to organize my blog as it currently stands?

Why did the rug start?
It all started a few hundred days ago when I had a directory with my name on it on my own computer. This same directory was on my girlfriends computer, my mums computer and my other laptop. Then I thought. If I make all things online then my life will become much easier. No flash drives, no CDs, no external hard disks. I moved all files to Google Drive, to Dropbox. I deleted everything from local computer. I made sure that everything was located in one place only. It was hard to find things for the first half year.
Another reason is that I was pretty much pissed off that a lot of screenshots out there on the internet use jpg instead of png. I thought wtf? Why not make better quality and less size? This is just stupid. I will show the world that png format is much lighter.

Now..

About content:
I am trying to write down every problem I solve. I try to categorize every post in only one category. Sometimes I try force myself to extract what I have learned today. I really believe that it is possible to make huge improvement by knowing just one command or three lines of code to make computing world a better place. It is better to know how exactly to solve one tiny simple problem practically instead of knowing how to solve twenty huge things theoretically.
Sometimes I write an application (script) and post it here even if I have not tested it yet. It is just like a reminder of the idea. Sometimes I post it in a date far away in the past so no one will ever find out about it :) Nowadays I try to force myself to test things more before going with them public. I discipline myself to not move on to the next thing unless I have written down how I solved the first one. This is very funny at the end of weekends when the learning experience can grow faster. If I find or learn something new, of course, then I can go deeper and faster into next situation, BUT I do not let myself do that unless I write down what I have learned two minutes ago. Sometimes these situations end up with me shutting down the computer, laying down on the bed and looking at walls because it is a great way to prevent me to go deeper into this situation. Just a few weeks ago I learned the importance of writing the post from my very own point of view. I try to avoid using the word "you" because it is my experience and the instruction you read right now will not help you but me. It can help others, i can help others, but it is better to write things in the first person of view. Lets prevent recommending things to others. Everyone should choose himself what to use or not.

What I recommend for future bloggers?
You have a problem and you write it into the search engine. If the first result did not satisfy you then you should have a blog. Then you need to look how to solve this case and you need to write about it. Just configure blogger template for post title to appear as heading 1 and then wait half a year and I promise you it will appear in some of the search results.

Usually the world teaches that the complicated things are the best. That is because no one will pay money unless it is complicated. Everything needs to look complicated.

Have I tried to create step by step? Write a movement and hit enter. Do I know how to read step by step? Just read a movement and compare the output. Does it need to be more complicated? No.

Tuesday, June 7, 2016

Overwriting configuration file for multiple RPi devices

I have multiple Raspberry Pies and i want to change some of service content for all devices together.

I ended up using Dropbox public folder.

I have installed one script file which will run every hour, download configuration from public internet then look for some sign to make sure if the download was really successful. If everything was fine then script overwrites existing service content

Here is how the main application looks like:
#!/bin/sh
curl https://dl.dropboxusercontent.com/u/000000000/servicename > /tmp/renewservicecontent
lines=$(grep -c detectcontent /tmp/renewservicecontent)
if [ $lines -lt 10 ]; then
echo "sorry"
else
echo $lines
echo "installing new service"
cat /tmp/renewservicecontent > /etc/init.d/servicename
fi
At the end this is how i install service file via putty:
cat > /usr/bin/renewservicecontent << EOF
#!/bin/sh
curl https://dl.dropboxusercontent.com/u/000000000/servicename > /tmp/renewservicecontent
lines=\$(grep -c detectcontent /tmp/renewservicecontent)
if [ \$lines -lt 10 ]; then
echo "sorry"
else
echo \$lines
echo "installing new service"
cat /tmp/renewservicecontent > /etc/init.d/servicename
fi
EOF
Set the service executable:
chmod 755 /usr/bin/renewservicecontent
Set to launch this code every hour:
echo "56 * * * * root /usr/bin/renewservicecontent">> /etc/crontab

Monday, June 6, 2016

Reset MikroTik router, 951G-2HnD

I have Such a brilliant experience for resetting MikroTik router.
I hope i will remember this forever :)

Turn off the device power.
Hold the reset button and do not release.
Turn on the device power and wait until the USER LED labeled with “ACT” starts flashing.
Now release the button to clear configuration.
Wait for a few minutes for the router to clear and restore the factory settings.
video
If i release the reset button after the LED stops flashing, i have to redo everything again.

I was very happy cause no matter how madly i press reset button the router backup files are always with me. Just select one of the files:

Click restore:

Sunday, June 5, 2016

Zabbix proxy connects to Zabbix server via MikroTik

Following my previous example about zabbix proxy server now i want to merge two networks together using MikroTik router. At first i open zabbix tcp port 10051 so the zabbix server can listen for new information from zabbix proxy. This port also will be used for zabbix proxy to receive new item configuration:

Now i need to know exact vpn address of my mikrotik router. This will let me use the service if the external ip address has been changed:

And finally i put this vpn address into zabbix proxy configuration.
At the end my zabbix proxy configuration looks similar to this:
Server=xxxxxxxxxxxx.sn.mynetname.net
Hostname=Broceni
LogFile=/tmp/zabbix_proxy.log
DBName=/var/lib/sqlite/zabbix.db
DBUser=root
FpingLocation=/usr/bin/fping

Saturday, June 4, 2016

Install Zabbix proxy from source, sqlite3, Raspbian

This example is tested on 2016-05-27-raspbian-jessie-lite.img image together with zabbix-2.4.8.tar.gz source code:

proxy-install.sh:
#!/bin/bash
#this code is tested un fresh 2016-05-27-raspbian-jessie-lite.img Raspberry Pi image
#sudo raspi-config -> extend partition -> reboot
#sudo su
#apt-get update -y && apt-get upgrade -y && apt-get install git -y
#git clone https://github.com/catonrug/raspberry-pi-zabbix.git && cd raspberry-pi-zabbix && chmod +x proxy-install.sh
#./proxy-install.sh

#update system
apt-get update -y && apt-get upgrade -y

#install all prerequsites
apt-get install sqlite3 -y #install sqlite3 database engine
apt-get install libsqlite3-dev -y #configure: error: SQLite3 library not found
apt-get install libsnmp-dev -y #configure: error: Invalid Net-SNMP directory - unable to find net-snmp-config
apt-get install libssh2-1-dev -y #configure: error: SSH2 library not found
apt-get install fping -y #/usr/sbin/fping: [2] No such file or directory

#set up zabbix user and group
groupadd zabbix
useradd -g zabbix zabbix

#extract zabbix source
tar -vzxf zabbix-*.tar.gz -C ~

#create basic database
mkdir -p /var/lib/sqlite
cd ~/zabbix-*/database/sqlite3
sqlite3 /var/lib/sqlite/zabbix.db <schema.sql

cd ~/zabbix-*/
./configure --enable-proxy --with-net-snmp --with-sqlite3 --with-ssh2
make install

echo
echo default config file:
grep -v "^#\|^$" /usr/local/etc/zabbix_proxy.conf
echo


sed -i "s/^Server=.*$/Server=192.168.88.55/" /usr/local/etc/zabbix_proxy.conf #write ip address of real zabbix server
sed -i "s/^Hostname=.*$/Hostname=Broceni/" /usr/local/etc/zabbix_proxy.conf #write a name for this proxy server
sed -i "s/^DBName=.*$/DBName=\/var\/lib\/sqlite\/zabbix.db/" /usr/local/etc/zabbix_proxy.conf #set location to database
#set permissions to database
chown -R zabbix:zabbix /var/lib/sqlite/
chmod 774 -R /var/lib/sqlite
chmod 664 /var/lib/sqlite/zabbix.db
sed -i "s/^.*FpingLocation=.*$/FpingLocation=\/usr\/bin\/fping/" /usr/local/etc/zabbix_proxy.conf #/usr/sbin/fping: [2] No such file or directory

echo
echo config file now:
grep -v "^#\|^$" /usr/local/etc/zabbix_proxy.conf
echo

#set up startup service
cat > /etc/init.d/zabbix_proxy << EOF
#!/bin/sh
case "\$1" in
start)
/usr/local/sbin/zabbix_proxy -c /usr/local/etc/zabbix_proxy.conf
echo "Zabbix proxy started"
;;
stop)
pkill zabbix_proxy
echo "Zabbix proxy stopped"
;;
restart)
pkill zabbix_proxy
sleep 5
/usr/local/sbin/zabbix_proxy -c /usr/local/etc/zabbix_proxy.conf
echo "Zabbix proxy restarted"
;;
*)
echo "Use start, stop, restart"
exit 1
;;
esac
EOF

#set startup service executable
chmod 755 /etc/init.d/zabbix_proxy

#re-read all startup applicaition
update-rc.d zabbix_proxy defaults
Or install with git:
sudo su
apt-get update -y && apt-get upgrade -y && apt-get install git -y
git clone https://github.com/catonrug/raspberry-pi-zabbix.git && cd raspberry-pi-zabbix && chmod +x proxy-install.sh
time ./proxy-install.sh
Now the system needs to be rebooted or i have to start proxy manually with:
/usr/local/sbin/zabbix_proxy -c /usr/local/etc/zabbix_proxy.conf
wait five minutes and the check the log file:
tail -f /tmp/zabbix_proxy.log
It should say something like:
Cannot adopt OID in NET-SNMP-AGENT-MIB: nsNotifyRestart ::= { netSnmpNotifications 3 }
Cannot adopt OID in UCD-SNMP-MIB: laErrMessage ::= { laEntry 101 }
Cannot adopt OID in UCD-SNMP-MIB: laErrorFlag ::= { laEntry 100 }
Cannot adopt OID in UCD-SNMP-MIB: laLoadFloat ::= { laEntry 6 }
Cannot adopt OID in UCD-SNMP-MIB: laLoadInt ::= { laEntry 5 }
Cannot adopt OID in UCD-SNMP-MIB: laConfig ::= { laEntry 4 }
Cannot adopt OID in UCD-SNMP-MIB: laLoad ::= { laEntry 3 }
Cannot adopt OID in UCD-SNMP-MIB: laNames ::= { laEntry 2 }
Cannot adopt OID in UCD-SNMP-MIB: laIndex ::= { laEntry 1 }
   577:20160605:170412.444 Unable to connect to the server [192.168.88.55]:10051 [cannot connect to [[192.168.88.55]:10051]: [101] Network is unreachable]. Will retry every 120 second(s)
   578:20160605:170519.447 sending heartbeat message to server failed: error:"negative response: "failed"", info:"proxy "Broceni" not found"
   578:20160605:170619.458 sending heartbeat message to server failed: error:"negative response: "failed"", info:"proxy "Broceni" not found"
   577:20160605:170620.304 Connection restored.
   577:20160605:170620.308 cannot obtain configuration data from server: proxy "Broceni" not found
   578:20160605:170719.469 sending heartbeat message to server failed: error:"negative response: "failed"", info:"proxy "Broceni" not found"
   578:20160605:170819.480 sending heartbeat message to server failed: error:"negative response: "failed"", info:"proxy "Broceni" not found"
Now i need to add zabbix proxy at the server side.
Click [Administration] -> [Proxies] -> [Create proxy]

Write proxy name and click [Add]:

Wait a few seconds and make sure [Last seen] colon give some data:

Once the [Last seen] column has received some data then /tmp/zabbix_proxy.log stops receiving errors :)

Good to go!

Project on github:
https://github.com/catonrug/raspberry-pi-zabbix/blob/master/proxy-install.sh

Friday, June 3, 2016

Slipstream updates, Windows 7/2008/8.1, install.wim

I wanted to create one slipstream code which is more universal and it can be used to slipstream updates for Windows 7, Windows Server 2008 R2 and Windows 8.1. In usually tend to keep all scripts on github but all windows iso and update files are located on google drive for example in c:\g\w:

In this project i wanted for the code to be as short as possible. One way how to accomplish this goal is to create application which is a lot based on directory names. For example i can look exact name of windows version which i am working on with command:
dism /get-wiminfo /wimfile:c:\iso\sources\install.wim /index:1 | find "Name "
This can output names like:
Name : Windows 7 ULTIMATE
Name : Windows Server 2008 R2 SERVERDATACENTER
Name : Windows 8.1 Pro
Later based on these names i look for directory names like these to take content and automatically work with.

Since Windows 7 x64 needs pretty much the same content as Windows Server 2008 R2 i have to figure out how let these booth operating systems take content from same directory. I solve this problem with Windows version number::
dism /get-wiminfo /wimfile:c:\iso\sources\install.wim /index:1 | find "Version "
This will output content like
6.1.7601
6.3.9600
6.1.7601 is for Windows 7 and Server 2008 R2
6.3.9600 is for Windows 8.1


All files together:

All other non-selected files is just the profiles how i can quickly just choose one of the interested operating systems for example if i want to create Windows 7 Professional x64 edition i run.
call "%~dp0slipstream.cmd" C:\g\w\X17-59186.iso C:\g\w\u6.1.7601x64 3 c:
slipstream.cmd need to get four parameters:
%1 - file location to the iso file
%2 - directory where the updates are having a good time
%3 - index number i want to work with
%4 - output directory for new iso file
none of the parameters supports spaces or quotes!

Here is the main program slipstream.cmd:
@echo off
cls
setlocal EnableDelayedExpansion

if "%1"=="" (
echo Enter full path of iso file:
set /p s=
) else set s=%1

if "%2"=="" (
echo Enter full path of update directory:
set /p u=
) else set u=%2

if "%3"=="" (
echo Enter install.wim index you want to work with:
set /p i=
) else set i=%3

if "%4"=="" (
echo Enter destination path for output:
set /p d=
) else set d=%4

set w=%temp%
echo Working directory is:
echo %w%
echo.

for /f "tokens=*" %%d in ('"%~dp0date.exe" +%%Y-%%m-%%d') do set yyyymmdd=%%d

for /f "tokens=*" %%d in ('dir /b "%u%" ^| find /C "KB"') do echo Total number of updates to slipstream: %%d
echo.

echo Extracting iso..
if exist "%w%\iso" rd "%w%\iso" /Q /S
"%~dp07z.exe" x "%s%" -o"%w%\iso" > nul 2>&1
echo.

%systemdrive%
cd "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\DISM"

for /f "tokens=2 delims=:" %%n in ('dism /get-wiminfo /wimfile:%w%\iso\sources\install.wim /index:%i% ^| find "Name"') do for /f "tokens=* delims= " %%f in ('echo %%n') do (
for /f "tokens=3 delims= " %%a in ('dism /get-wiminfo /wimfile:%w%\iso\sources\install.wim /index:%i% ^| find "Architecture"') do (
for /f "tokens=3 delims= " %%v in ('dism /get-wiminfo /wimfile:%w%\iso\sources\install.wim /index:%i% ^| find "Version"') do (
for /f "tokens=3 delims= " %%e in ('dism /get-wiminfo /wimfile:%w%\iso\sources\install.wim /index:%i% ^| find "Edition"') do (
for /f "tokens=4 delims= " %%w in ('dism /get-wiminfo /wimfile:%w%\iso\sources\install.wim /index:%i% ^| find "Name"') do (

echo Working with %%f %%a
echo.

if exist "%d%\%%f %%a-%yyyymmdd%.log" del "%d%\%%f %%a-%yyyymmdd%.log" /Q /F
echo Existing errors will be writed to:
echo %d%\%%f %%a-%yyyymmdd%.log
echo.

echo mounting install.wim..
if not exist "%w%\mount" md "%w%\mount"
dism /mount-wim /wimfile:"%w%\iso\sources\install.wim" /index:%i% /mountdir:"%w%\mount" > nul 2>&1
echo.

if "%%f"=="Windows Server 2008 R2 SERVERDATACENTER" (
echo integrating .NET 2.0, 3.0 and 3.5 for Windows Server 2008 R2
dism /image:"%w%\mount" /enable-feature /featurename:NetFx3 > nul 2>&1
echo.
)

if "%%f"=="Windows 8.1 Pro" (
echo integrating .NET 2.0, 3.0 and 3.5 for Windows 8.1
dism /image:"%w%\mount" /enable-feature /featurename:NetFx3 /all /limitaccess /source:"%w%\iso\sources\sxs" > nul 2>&1
echo.
)

echo integrating windows updates..
for /f "tokens=*" %%i in ('dir /b "%u%"') do (
echo slipstreaming %%i
dism /image:"%w%\mount" /add-package /packagepath:"%u%\%%i" > nul 2>&1
if not !errorlevel!==0 (
echo %%i not OK
echo %%i not OK >> "%d%\%%f %%a-%yyyymmdd%.log"
)
)

dism /image:"%w%\mount" /Set-Syslocale:lv-LV > nul 2>&1
dism /image:"%w%\mount" /Set-UserLocale:lv-LV > nul 2>&1
dism /image:"%w%\mount" /Set-TimeZone:"FLE Standard Time" > nul 2>&1
dism /image:"%w%\mount" /Get-Intl
dism /unmount-wim /mountdir:"%w%\mount" /commit

if exist "%w%\mount" rd "%w%\mount" /Q /S > nul 2>&1
echo.

if exist "%~dp0%%f" (
echo Adding autounattend.xml..
xcopy "%~dp0%%f" "%w%\iso" /Y /S /F /Q > nul 2>&1
echo.
)

echo Adding FirstRun script..
xcopy "%~dp0w%%v%%a" "%w%\iso" /Y /S /F /Q > nul 2>&1
echo.

echo Exporting only index %i% from install.wim
dism /Export-Image /SourceImageFile:%w%\iso\sources\install.wim /SourceIndex:%i% /DestinationImageFile:"%d%\%%f %%a-%yyyymmdd%.wim" /Compress:max  > nul 2>&1
echo.

echo Overwriting install.wim..
xcopy "%d%\%%f %%a-%yyyymmdd%.wim" "%w%\iso\sources\install.wim" /Y > nul 2>&1
echo.

echo Creating iso file %d%\%%f %%a-%yyyymmdd%.iso
"..\Oscdimg\oscdimg.exe" -b"%w%\iso\boot\etfsboot.com" -h -u2 -m -lwin2k8r2 "%w%\iso" "%d%\%%f %%a-%yyyymmdd%.iso" > nul 2>&1
echo.

if exist "%w%\iso" rd "%w%\iso" /Q /S > nul 2>&1
endlocal
echo.
echo This is it!
time /t
)
)
)
)
)
Whole project can be found under:
https://github.com/catonrug/wus

Thursday, June 2, 2016

httpd does not appear to be running and proxying cobbler

httpd does not appear to be running and proxying cobbler
This only means that SELinux is blocking something. Quick way how to ensure it:
setenforce 0
Turn off SELinux at next boot:
sed -i "s/^SELINUX=.*$/SELINUX=disabled/" /etc/selinux/config

Windows 7 SP1 (KB976932), Published: 2/12/2015?


Windows 7 Serveice Pack 1 Published on 2/12/2015?

Turns out i need to install update kb2533552. This update must be installed in online mode and can not be completely slipstreamed into install.wim.

Here is direct link for 64-bit update:
windows6.1-kb2533552-x64_0ba5ac38d4e1c9588a1e53ad390d23c1e4ecd04d.msu
5e36c18d1b78f2003146dcd9528f8885
0ba5ac38d4e1c9588a1e53ad390d23c1e4ecd04d

Here is direct link for 32-bit update:
windows6.1-kb2533552-x86_f2061d1c40b34f88efbe55adf6803d278aa67064.msu
0fbaea9220e4709854f9f2ee0df0e7c9
f2061d1c40b34f88efbe55adf6803d278aa67064

This is how to install this update for 64-bit and 32-bit system:
if not "%ProgramFiles(x86)%"=="" %systemroot%\system32\wusa.exe "%~dp0windows6.1-kb2533552-x64_0ba5ac38d4e1c9588a1e53ad390d23c1e4ecd04d.msu" /quiet /norestart
if "%ProgramFiles(x86)%"=="" %systemroot%\system32\wusa.exe "%~dp0windows6.1-kb2533552-x86_f2061d1c40b34f88efbe55adf6803d278aa67064.msu" /quiet /norestart
This is how i personally install it together with .NET 4.6.1 and so on:
https://github.com/catonrug/wus/tree/master/w6.1.7601x64/FirstRun

Wednesday, June 1, 2016

VirtualBox must have settings

There are some VirtualBox settings that i have addicted.

First is default location for all machines location.
I love to put it on RAMDisk since it is the fastest drive ever:

Second rule is turn of updater cause VirtualBox releases new version pretty often:

Third must have future is turn off VirtualBox balloon tips:
"%programfiles%\Oracle\VirtualBox\VBoxManage.exe" setextradata global GUI/SuppressMessages "all"
All these settings are located under %userprofile%\.VirtualBox\VirtualBox.xml:
<?xml version="1.0"?>
<!--
** DO NOT EDIT THIS FILE.
** If you make changes to this file while any VirtualBox related application
** is running, your changes will be overwritten later, without taking effect.
** Use VBoxManage or the VirtualBox Manager GUI to make changes.
-->
<VirtualBox xmlns="http://www.innotek.de/VirtualBox-settings" version="1.12-windows">
  <Global>
    <ExtraData>
      <ExtraDataItem name="GUI/DetailsPageBoxes" value="general,system,preview,display,storage,audio,network,usb,sharedFolders,description"/>
      <ExtraDataItem name="GUI/LastWindowPosition" value="575,250,770,550"/>
      <ExtraDataItem name="GUI/SplitterSizes" value="255,510"/>
      <ExtraDataItem name="GUI/SuppressMessages" value="all"/>
      <ExtraDataItem name="GUI/UpdateCheckCount" value="2"/>
      <ExtraDataItem name="GUI/UpdateDate" value="never"/>
    </ExtraData>
    <MachineRegistry/>
    <MediaRegistry>
      <HardDisks/>
      <DVDImages/>
      <FloppyImages/>
    </MediaRegistry>
    <NetserviceRegistry>
      <DHCPServers>
        <DHCPServer networkName="HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter" IPAddress="192.168.56.100" networkMask="255.255.255.0" lowerIP="192.168.56.101" upperIP="192.168.56.254" enabled="1"/>
      </DHCPServers>
    </NetserviceRegistry>
    <SystemProperties defaultMachineFolder="R:\" defaultHardDiskFormat="VDI" VRDEAuthLibrary="VBoxAuth" webServiceAuthLibrary="VBoxAuth" LogHistoryCount="3" exclusiveHwVirt="false"/>
    <USBDeviceFilters/>
  </Global>
</VirtualBox>