I have been building an complete Invoice / Cashier system for Cafés in my spare time for quite some time. It consists of an server, running the web app, an laptop to use as the real cashier system, multiple Android Phones as a way for the waiters to enter their orders and two Raspberry Pis with Brother QL-570s as Invoice Printers. One of those is set at the counter, printing the "normal invoice", the second one is located at the kitchen and got some special routing logic, so that it only recieves the items actually produced in the kitchen. However, as I was using these special kind of printers, I was bound to use the printer-ptouch drivers... and yeah, they are *kind of* buggy. Buggy in that way, that, after installing them with cups and hacking your paper media in there - they will just stop working from time to time. Without further warning. They will stop printing just somewhere in the middle of the job. I really tried all options available to me now - and was now keen on finding *other* kinds of solutions. And after two days of searching, I stumpled upon this master piece: https://github.com/pklaus/brother_ql. Mr. Philipp Klaus did actually dump the whole cups and printer server stuff and directly converted png files into the needed binary code for the printer. And not only the QL-570, but other types as well. I really recommend checking out his code and trying his way on printing - its a huge timesaver, especially on embedded devices like the Raspberry Pi :)!
Category: Computer
Computer Stuff
[Talk] Docker Grundlagen
My Docker 101 presentation @ Containerschifffahrt SB - Docker-Meetup 2016 (14.10.2016, https://www.meetup.com/de-DE/Containerschifffahrt-SB-Docker-Meetup/events/234248360/)
Docker_Meetup2016.pdf (0,42 MB, PDF).
Sourcecode / Example can be found on https://github.com/nmaas87/docker-demo
[Freifunk] Virtual Freifunk Router on VMWare ESXi 4.1
This post was planed a LONG TIME, however - due to the fact that I could not get it working back in 2015 (See: https://github.com/freifunk-gluon/gluon/issues/496) it had been delayed. However, as I have the need to get Freifunk working as VM on a central ESXi Server - I tried it again - and it worked! Basic instruction to get it working can be found here in german: https://www.it-kl.eu/2015/08/gluon-x86-unter-vmware/
I got following equipment: ESXi 4.1 Server with multiple NICs.
Start up with getting the right image from your Freifunk Team. I got the gluon-fftr-0.8.4-x86-vmware.vmdk from the Firmware Store of my trusted guys from FFTR (https://github.com/freifunktrier/firmware_store/tree/master/firmware/stable/factory [ Trier 0.8.4 is gluon 2016.1.6-3-g9300421, it's just 2016.1.6 + ee597c6 + Webinterface-color-patches ] )
After that, create a new VM on your VMWare ESXi Server. Choose an user definied configuration, "Other" OS and "Other (32-Bit)" Version. I gave the VM a 1 vCPU and 512 MB of RAM - but you can chose as you like. After that, you need to create two Network Devices / NICs. I chose two E1000 ones, and gave the first Interface the Freifunk LAN and added the second Interface to my common WAN (IMPORTANT!). After that, you're not going to create an HDD.
After the creation of the VM, upload your vmdk file to the folder, edit the VM and chose the downloaded VMDK as Harddrive.
On your ESXi Server, go to Configuration, Network and edit your vSwitch. Allow Promiscuous Mode, MAC Change and Fake Transmissions.
After that, go to Configuration, Software, Advanced Settings - to the "Net" section and change Net.ReversePathFwdCheckPromisc to 1 (thanks to FFS-Roland for helping out! :))
After that, you can start up your VM. You should get DHCP on your FFLAN Port - something like an 192.168.1.x address. Go to 192.168.1.1 via browser, give your Router a name, enable Mesh VPN (important!) and maybe change the bandwidth settings. Save and mail your VPN Key to your Freifunk Team. In some hours, you should be good to go (the Key added to their system - and after a quick reboot of your VM, you should be live :))
Thanks a lot to Draco and Ranlvor from Freifunk Trier for their tremendous help :)!
[Sonarqube] Use Sonarqube in IntelliJ / PhpStorm / etc.
Sonarqube is cool, as the generated results can not only be viewed via the web interface, but also via an plugin in IntelliJ or other Jetbrains IDEs. The installation is quite simple, you just need to download the latest plugin on this website: https://plugins.jetbrains.com/plugin/7238 and install it in the way described here: https://github.com/sonar-intellij-plugin/sonar-intellij-plugin. After that, you can easily hunt down and eliminate those errors :)!
[Docker] Sonarqube with Gogs/Drone to check software quality
Sonarqube is an really useful tool to check for different kind of errors in all kinds of programming languages. If you want to check out Sonarqube in a livedemo, just go over to https://sonarqube.com/. In the last two parts of my Docker series we created an gogs Git Repo as docker container and then went over to integrating gogs with drone (Version 0.4), an CI Build Server - also as Docker container. Today, we want to install Sonarqube as a tool to check upon our software quality, so that - as soon as we push an update to our gogs project, drone will execute an analysis using Sonarqube - which will give us information about different kind of errors and code quality.
# We will start by creating the needed folders:
sudo mkdir /var/sonarqube
sudo mkdir /var/sonarqube/data
sudo mkdir /var/sonarqube/extensions
sudo chown -R yourusername:yourusername /var/sonarqube
# Then we change our drone docker-compose.yml, so that drone and sonarqube will be started at the same time
sonarqube:
restart: unless-stopped
image: sonarqube:lts-alpine
volumes:
- /var/sonarqube/data:/opt/sonarqube/data
- /var/sonarqube/extensions:/opt/sonarqube/extensions
environment:
- SONARQUBE_HOME=/opt/sonarqube
- SONARQUBE_JDBC_USERNAME=sonar
- SONARQUBE_JDBC_PASSWORD=sonar
- SONARQUBE_JDBC_URL=
ports:
- "9000:9000"
- "9092:9092"
drone:
restart: unless-stopped
image: drone/drone:0.4.2
volumes:
- /var/drone:/var/lib/drone
- /var/run/docker.sock:/var/run/docker.sock
env_file:
- ./dronerc
ports:
- "8000:8000"
links:
- sonarqube
After that, we can start the service with docker-compose up -d and see Sonarqube on http://IPADDRESS:9000 (needs some time to load...).
To do an check of i.e. an Java Project, we need to write an new pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.appexample</groupId>
<artifactId>appexample</artifactId>
<version>1.0</version>
<name>phpTest</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sonar.language>java</sonar.language>
<sonar.sources>src</sonar.sources>
<sonar.exclusions>src/test/test.php, src/test/test/*</sonar.exclusions>
</properties>
</project>
and we need a new .drone.yml
cache:
mount:
- /drone/.m2
build:
main:
image: maven:3-jdk-8-onbuild
commands:
- mvn sonar:sonar -Dsonar.host.url=http://IPOFTHESONARQUBESERVER:9000 -Dmaven.repo.local=/drone/.m2
- echo "Sonarqube has been completed."
- mvn clean install -Pcoverage -Dmaven.repo.local=/drone/.m2
- mvn package -Dmaven.repo.local=/drone/.m2
- mvn test -Dmaven.repo.local=/drone/.m2
- echo "Build has been completed."
debug: true
And thats it :). Login into drone, activate your repo as valid CI repo and after that - with every push to that gogs repo, a new sonarqube analysis should be performed.
[Ubuntu] Use Molly-Guard to stop shooting your own leg
If you're working on some dozens of linux servers (or even more than 100,.. as in my case), you end up doing administration via SSH - which is the way to go. And chances are, that you'll get dozens of SSH connections open in dozens of tabs and you did some updates on some of those servers and want to restart this thing with a quick sudo reboot now...
I won't lie if I say, it happend more than once that I accidentally rebooted the wrong server - at least that was the case more than a year ago.
For the last year, since I have been using Molly-Guard - that did not happen once. Why? Because Molly-Guard does stop the reboot command if it detects that you're issuing it from an SSH console - and asks for the server name. If you're entering it correctly - it will reboot. If you're in a frenzy, doing your "sudo reboot now" and enter name serverB while you're on serverA - yep, Molly-Guard will stop you from shooting yourself in the leg. Neat, ain't it?
Oh - and the best part? Ease of use: sudo apt-get install molly-guard
Thats it, you're set, bye.
Nope. Really. No configuration needed. Just install that baby and be safe :)!
[Docker] CI with Drone and Gogs
Now that we have a running Gogs installation for our source code (see here) - we can use Drone to build working software from those repos. Drone is an Continious Integration System, that comes in two flavors: Drone.io - which is the hosted service you could use - or Drone - as self-hosted service. We want to use the later one. To install drone in our existing Docker setup (with gogs already installed) we need to complete following steps:
# Create docker-compose.yml in ~/drone/
cd ~
mkdir drone
cd drone
vi docker-compose.yml
# Copy this content into your docker-compose.yml file
drone:
restart: unless-stopped
image: drone/drone:0.4.2
volumes:
- /var/drone:/var/lib/drone
- /var/run/docker.sock:/var/run/docker.sock
env_file:
- ./dronerc
ports:
- "8000:8000"
# Create the dronerc file
vi dronerc
# Copy this content into your dronerc file
# replace yourserverip with the ip or dns name of your server, i.e. example.com
# replace the gogsport with the port of the http port of the gogs installation, i.e. was 3000 in our example
REMOTE_DRIVER=gogs REMOTE_CONFIG=https://yourserverip:gogsport?open=false DEBUG=true
# Create the needed folders
sudo mkdir /var/drone
sudo chown -R yourusername:yourusername /var/drone/
After that, an docker-compose up will start the service, you can end it via STRG + C and really start it in deattached mode with docker-compose up -d
You can then go to http://yourserverip:8000 and log in into drone with your gogs login and allow access.
The current readme for drone can be found on http://readme.drone.io/usage/overview/ and you'll need to include a .drone.yml in your repos to really build something.
In my example, I used this .drone.yml
cache:
mount:
- /drone/.m2
build:
main:
image: maven:3-jdk-8-onbuild
commands:
- mvn clean install -Pcoverage -Dmaven.repo.local=/drone/.m2
- mvn package -Dmaven.repo.local=/drone/.m2
- mvn test -Dmaven.repo.local=/drone/.m2
- echo "Build has been completed."
debug: true
and this pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>WhereIsMyPi</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>Where is my Pi</name>
<url>http://www.nico-maas.de</url>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>WMP</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
to build my "WhereIsMyPi" project :).
Happy building!
[Ubuntu] Secure your Apache 2 Reverse Proxy
We got an Apache 2, working as Reverse Proxy to some Docker instances (we won't talk about the nginx vs Apache stuff here for the same reasons we won't talk about vi vs emacs vs xyz ;)) - and somehow we realized that our apps are a little bit too sensitive to allow them from any ip.
First, we want to activate the needed modules. Normally that should not be necessary, but for sake of completeness:
sudo a2enmod mod_authz_core
sudo a2enmod mod_authz_host
Secondly, we want to allow them only from trusted ips. We do redirect them to the docker instances via ProxyPass - but need to create an Location / "catcher" - otherwise we could not use the mod_authz to deny other ips :).
<VirtualHost *:80> ServerAdmin johndoe@example.com ServerName hex.example.com ServerAlias hex RedirectMatch ^/$ https://example.com <Location / > <RequireAll> Require ip 192.168.1.0/24 192.168.2.0/24 192.168.3.0/24 </RequireAll> </Location> ProxyPass "/" "http://127.0.0.1:8020/" ProxyPassReverse "/" "http://127.0.0.1:8020/" </VirtualHost> <VirtualHost *:443> ServerAdmin johndoe@example.com ServerName hex.example.com ServerAlias hex <Location / > <RequireAll> Require ip 192.168.1.0/24 192.168.2.0/24 192.168.3.0/24 </RequireAll> </Location> ProxyPass "/" "http://127.0.0.1:8020/" ProxyPassReverse "/" "http://127.0.0.1:8020/" # Alias /static /srv/example_sw/sw/public_html/ SSLEngine on SSLCertificateFile /etc/ssl/certs/hex.example.com.pem SSLCertificateKeyFile /etc/ssl/private/hex.example.com.key SSLCertificateChainFile /etc/ssl/chains/example-ca-chain.pem </VirtualHost>
That way, hosts from other subnets than 192.168.1.0, 2.0 and 3.0 won't be able to access the proxy and therefore our app :)!
Cisco Prime Infrastructure 3.1 Cheat Sheet
A little cheat sheet for myself. All commands can be used via SSH or Shell:
Show Config: show run
Show Inventory: show inventory (Does show i.e. how many CPUs and RAM is installed. This does match normally to the Version of Cisco Prime. i.E. 8 vCPUs and 16 GB RAM -> Express Plus Type)
Show status of prime: ncs status
Backup OS and Application: backup PI311 repository defaultRepo
Backup Application only: backup PI311appOnly repository defaultRepo application NCS
Activate OS Shell: shell
Locations of different files
defaultRepo: /localdisk/defaultRepo
Config: /storedconfig
License Files: /opt/CSCOlumos/licenses
To transfer the backup files to a safe place, just use scp :).
[Ubuntu] Radsecproy for secure Radius over WAN
Chances are you going to need an radius Auth over WAN - because your Radius and Identity Mngmnt is hosted in the security of the local datacenter of your corp... but the client (i.e. an network switch) is somewhere over the rainbow WAN. You *could* just pipe the radius traffic over the internet - but there be dragons: radius communication is unencrypted. So... just no.
Enter radsecproxy: Radsecproxy is - as the name implies, an radius proxy - which needs to be installed on both servers (the local one in your company, now called SERVER, and the remote one with the switch attached, now called CLIENT) - and does encrypt the communication between both server parts (over WAN i.e.) via TLS.
1.) Install radsecproxy on Server ( sudo apt-get install radsecproxy )
2.) Create CA with generate-CA.sh (in /etc/radsecproxy/) [ https://github.com/owntracks/tools/blob/master/TLS/generate-CA.sh - please change keybits to 4096 bits, thanks! ]
3.) Create Certs (Server, Client) with generate-client.sh (in /etc/radsecproxy/) [ at the end of this post, http://rockingdlabs.dunmire.org/exercises-experiments/ssl-client-certs-to-secure-mqtt - please change keybits to 4096 bits as well! 🙂 ]
4.) Configure /etc/radsecproxy.conf [UPPERLETTERS are constants which you need to change]
# Master config file for radsecproxy
sourceTLS IPADDR_OF_SERVER
listenTLS IPADDR_OF_SERVER:2083
LogLevel 3
LogDestination file:///var/log/radsecproxy/radsecproxy.log
LoopPrevention on
tls default {
CACertificateFile /etc/radsecproxy/ca.crt
CertificateFile /etc/radsecproxy/SERVER_NAME_FQDN.crt
CertificateKeyFile /etc/radsecproxy/SERVER_NAME_FAQN.key
}
client CLIENT_NAME {
host IPADDR_OF_CLIENT
type tls
certificatenamecheck off
secret PW_OF_CLIENT_RADSEC
}
server SERVER_NAME_auth {
host IPADDR_OF_SERVER:1812
type udp
StatusServer on
secret PW_OF_SERVER_FOR_RADIUS
}
server SERVER_NAME_acct {
host IPADDR_OF_SERVER:1813
type udp
StatusServer on
secret PW_OF_SERVER_FOR_RADIUS
}
realm * {
server SERVER_NAME_auth
accountingserver SERVER_NAME_acct
}
# example config for localhost, rejecting all users
client 127.0.0.1 {
type udp
secret TEST_SECRET
}
realm * {
replymessage "User unknown"
}
5.) sudo service radsecproxy restart
6.) Install radsecproxy on Client ( sudo apt-get install radsecproxy )
7.) Copy client cert and ca.crt to Client /etc/radsecproxy
8.) Configure /etc/radsecproxy.conf [UPPERLETTERS are constants which you need to change]
#sourceUDP 127.0.0.1
sourceUDP IPADDR_OF_CLIENT
listenUDP *:1812
listenUDP *:1813
LogLevel 3
LogDestination file:///var/log/radsecproxy/radsecproxy.log
LoopPrevention on
tls default {
CACertificateFile /etc/radsecproxy/ca.crt
CertificateFile /etc/radsecproxy/CLIENT_NAME_FQDN.crt
CertificateKeyFile /etc/radsecproxy/CLIENT_NAME_FQDN.key
}
client CLIENT_NAME {
#host 127.0.0.1
host IPADDR_OF_CLIENT
type udp
secret CLIENT_RADIUS_SECRET
}
client SWITCH_NAME {
host SWITCH_IP
type udp
secret SWITCH_RADIUS_SECRET
}
server SERVER_NAME {
certificatenamecheck off
host IPADDR_OF_SERVER
type tls
StatusServer on
secret PW_OF_CLIENT_RADSEC
}
realm * {
server SERVER_NAME
accountingserver SERVER_NAME
}
# example config for localhost, rejecting all users
client 127.0.0.1 {
type udp
secret TEST_SECRET
}
realm * {
replymessage "User unknown"
}
9.) sudo service radsecproxy restart
10.) If you now point your switches to the CLIENT_IP with the correct credential, it should go via the radsecproxy to your main radius server and get the connection working. Please pay attention that on your CLIENT site no radiusd daemon is allowed to run, as it would block the ports needed for radsecproxy / radius. Make use of the radsecproxy log files to see, wheter the two radsecproxy servers do connect and talk to each other :).