Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the simple-lightbox domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /www/htdocs/w010b2f5/page_m/wp-includes/functions.php on line 6121

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the advanced-responsive-video-embedder domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /www/htdocs/w010b2f5/page_m/wp-includes/functions.php on line 6121

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501

Deprecated: Use of "parent" in callables is deprecated in /www/htdocs/w010b2f5/page_m/wp-content/plugins/simple-lightbox/includes/class.options.php on line 501
Linux – mkleine.de https://mkleine.de Alles rund um Softwareentwicklung Sat, 12 May 2018 07:35:51 +0000 de hourly 1 Docker-Container per DNS auflösen https://mkleine.de/blog/2017/12/27/docker-container-per-dns-aufloesen/ Wed, 27 Dec 2017 19:52:54 +0000 http://mkleine.de/?p=1915 Ich habe auf meinem Root-Server alle in Docker-Containern laufen. Also WordPress für mehrere Webseiten. Alles PHP-FPM. Jetzt starte ich meine Docker-Container alle mit einem entsprechenden Hostnamen. Also meistens so wie die Domain heißt plus „.docker“. Also zum Beispiel „klein0r-de.docker“. Dieses Ziel gebe ich dann in meinem Apache für ProxyPathMath an.

ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://kleine-photo-com.docker:9000/usr/src/myapp/$1

Soweit, so gut. Apache läuft bei mir übrigens nicht in einem Container. Warum eigentlich nicht? Könnte ich mir auch noch überlegen.

Jedenfalls habe ich dann das Problem, dass mein Host diese Domain nicht auflösen kann! Also habe ich anfangs die einzelnen Seiten in die etc/hosts eingetragen. Blöd ist dabei nur, dass die IPs natürlich rotieren können, sobald der Server mal neugestartet wird. Also habe ich plötzlich andere Inhalte hinter den Domains – extrem nervig. Das ist mir jetzt 2x passiert und nun habe ich mich mit einer Lösung beschäftigt. Am einfachsten war dabei für mich der Weg über einen weiteren Docker-Container für DNS.

docker run -itd --restart=always --hostname dns.docker --name dns-proxy-server -p 5380:5380 -v /var/run/docker.sock:/var/run/docker.sock -v /etc/resolv.conf:/etc/resolv.conf defreitas/dns-proxy-server

Nun werden alle DNS-Anfragen in den Container gejagt. Außerdem werden nun die Hostnamen der Docker-Container richtig aufgelöst und alles funktioniert wunderbar wie ich mir das vorgestellt habe. Sobald man den Container stoppt ist übrigens wieder alles wie vorher. Also kein Risiko. Danke restart=always wird der Container also nun auch immer brav mitgestartet und alles überlebt ebenfalls einen Neustart des Servers. Puh, das war einfacher als ich dachte!

Nun bin ich kein Sysadmin, sondern Softwareentwickler. Daher lese ich mir solche Themen immer an und bin froh, dass es so einfache Lösungen wie diese gibt. Wenn Du eine bessere oder einfachere Idee hast: Immer her damit!

]]>
fail2ban und mysql 5.7 – Filter funktioniert nicht direkt https://mkleine.de/blog/2017/08/11/fail2ban-und-mysql-5-7-filter-funktioniert-nicht-direkt/ Fri, 11 Aug 2017 21:34:30 +0000 http://mkleine.de/?p=1852 Normalerweise legt man einfach eine neue Datei nach /etc/fail2ban/jail.d/mysql.conf, aktiviert das richtige Jail und schon funktioniert alles. Leider nicht so im Falle von mysql 5.7 – scheinbar hat sich da der Logeintrag etwas geändert. Meine Datei sieht jetzt so aus:

[mysqld-auth]
enabled = true
logpath = /var/log/mysql/error.log

Und den Filter musste ich wie folgt anpassen:

failregex = ^%(__prefix_line)s(\d{6} \s?\d{1,2}:\d{2}:\d{2} )?\[Warning\] Access denied for user '\w+'@'<HOST>' (to database '[^']*'|\(using password: (YES|NO)\))*\s*$
            ^%(__prefix_line)s(?:\d+ |\d{6} \s?\d{1,2}:\d{2}:\d{2} )?\[\w+\] Access denied for user '[^']+'@'<HOST>'

Die erste Zeile habe ich dabei nicht angefasst, sondern nur die zweite hinzugefügt. Statt einer Warning erscheint bei mySQL 5.7 nur noch „Note“. Der reguläre Ausdruck ist natürlich relativ allgemein, aber funktioniert für mich wunderbar. Endlich werden die ganzen Login-Versuche auf root entsprechend geblockt.

Testen kann man das ganze wie folgt:

fail2ban-regex /var/log/mysql/error.log /etc/fail2ban/filter.d/mysqld-auth.conf

Bei mir sieht die Ausgabe nun so aus:

Lines: 492 lines, 0 ignored, 54 matched, 438 missed [processed in 0.07 sec] 
Missed line(s): too many to print.  Use --print-all-missed to print all 438 lines

Sieht also sehr gut aus!

]]>
Fail2Ban und Zugriff auf Docker-Container https://mkleine.de/blog/2017/06/15/fail2ban-und-zugriff-auf-docker-container/ Thu, 15 Jun 2017 12:49:37 +0000 http://mkleine.de/?p=1821 Ich hatte heute das Problem, dass Fail2Ban (läuft auf dem Host) zwar munter Regeln in den iptables angelegt hat, aber die Regel keine Wirkung auf alle weitergeleiteten Ports der Docker-Container hatte.

Die Lösung dafür ist relativ einfach – man darf die Regeln nur nicht als INPUT definieren, sondern muss diese für Forward definieren. Damit Ihr ein etwas leichteres Leben habt, habe ich eine neue Action geschrieben, welche ganz einfach angewendet werden kann:

[INCLUDES]

before = iptables-common.conf

[Definition]

actionstart = <iptables> -N f2bd-<name>
              <iptables> -A f2bd-<name> -j <returntype>
              <iptables> -I FORWARD -p <protocol> -m multiport --dports <port> -j f2bd-<name>

actionstop = <iptables> -D FORWARD -p <protocol> -m multiport --dports <port> -j f2bd-<name>
             <iptables> -F f2bd-<name>
             <iptables> -X f2bd-<name>

actioncheck = <iptables> -n -L FORWARD | grep -q 'f2bd-<name>[ \t]'

actionban = <iptables> -I f2bd-<name> 1 -s <ip> -j <blocktype>

actionunban = <iptables> -D f2bd-<name> -s <ip> -j <blocktype>

[Init]

blocktype = DROP
chain = FORWARD

Für alle Jails, welche für Docker-Container gelten, verwende ich als „banaction“ nur eben diese. Funktioniert bisher einwandfrei!

]]>
ipkg unter DS5 auf einer Synology DS214+ installieren https://mkleine.de/blog/2016/01/07/ipkg-unter-ds5-auf-einer-synology-ds214-installieren/ Thu, 07 Jan 2016 20:16:48 +0000 http://mkleine.de/?p=1631 Ich habe nun hunderte Beiträge im Netz gelesen, ständig für andere Versionen. Dann habe ich dieses gist gefunden und konnte ipkg erfolgreich auf meiner DS214+ zum Laufen bekommen. Was ein Krampf! In der vorigen Version war das wohl alles leichter. Ich möchte hier noch einmal alle Schritte erläutern, damit auch andere in den Genuss von ipkg auf Ihrer DiscStation kommen.

Erstmal müssen wir mit root per ssh auf die DiscStation.

ssh root@xxx.xxx.xxx.xxx

Danach legen wir auf volume1 ein Public-Verzeichnis an (falls es dieses noch nicht gibt).

mkdir /volume1/public

Nun geht es mit vi weiter:

cd /volume1/public
vi install.sh

Dort kommt der folgende Inhalt rein:

feed=http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/unstable
ipk_name=`wget -qO- $feed/Packages | awk '/^Filename: ipkg-opt/ {print $2}'`
wget $feed/$ipk_name
tar -xOvzf $ipk_name ./data.tar.gz | tar -C / -xzvf -
mkdir -p /opt/etc/ipkg
echo "src cross $feed" > /opt/etc/ipkg/feeds.conf

hier kopieren, i (wie insert) drücken, einfügen (Strg + v), ESC drücken, „:wq“ schreiben und Enter drücken

Dann das folgende Verzeichnis anlegen und mounten:

mkdir /volume1/@optware
mkdir /opt
mount -o bind /volume1/@optware /opt

Dann die neue Datei ausführen:

sh install.sh

Nun müssen wir noch die PATH-Variable erweitern:

vi /root/.profile

Dort packen wir ganz ans Ende der Zeile folgenden Inhalt :/opt/bin:/opt/sbin (Bitte unbedingt auf die Doppelpunkte achten, diese trennen die verschiedenen Verzeichnisse voneinander). Bei mir sieht die komplette Zeile wie folgt aus:

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/syno/sbin:/usr/syno/bin:/usr/local/sbin:/usr/local/bin:/opt/bin:/opt/sbin

Nun starten wir die DiscStation neu!

Wieder per SSH einloggen und folgendes nacheinander ausführen:

/etc/rc.optware start
ipkg update

Nun kann man zum Beispiel bash installieren:

ipkg install bash

Zur Info: Bei mir wurde die ipkg version 0.99.163 installiert.

Viel Spaß damit!

ACHTUNG: Ich habe mehrfach gelesen, dass der ssh-login durch diesen Prozess kaputt gehen könnte. Auch anderen Schäden an der DiscStation oder den darauf gespeicherten Dateien sind natürlich nie ganz ausgeschlossen. Ich habe hier nur dokumentiert, wie ich es am Ende dann doch geschafft habe. Geht sehr vorsichtig vor! Ihr seid selbst dafür verantwortlich was ihr aus dem Netz kopiert und ausführt …

Dennoch hat es bei mir reibungslos funktioniert und ich habe vorher schon ganz viel kram ausprobiert.

]]>
Synology: sendmail per shell aktivieren https://mkleine.de/blog/2016/01/07/synology-sendmail-per-shell-aktivieren/ Thu, 07 Jan 2016 17:08:01 +0000 http://mkleine.de/?p=1627 Um auf einer Synology DiscStation über Bash-Scripts per sendmail Mails verschicken zu können (oder auch über php-Scripts), muss zuerst das Paket „Mail Server“ installiert werden. Erst dann steht einem auf der Shell der Befehlt „sendmail“ zur Verfügung.

Danach geht man in die Einstellungen unter der neuen Anwendung „Mail Server“ und dort auf SMTP (schließlich wird dieses Protokoll zum versenden von Mails genutzt). Da ich die Mails nicht direkt vom NAS verschicken möchte, sondern über meinen Webserver, richte ich dort ein weiteres Postfach ein, und gebe die entsprechenden Daten unter „SMTP-Relay“ ein.

Synology-SMTP-Server

Dort auf den Button SMTP-Relais klicken:

SMTP-Relay-Konfiguration

Die genaue Konfiguration ist natürlich vom jeweiligen Provider abhängig. Genauso ist es aber denkbar, als SMTP-Relay einen GMX, T-Online oder einen anderen bestehenden Server einzutragen. Ein eigener Webserver ist also nicht zwingend erforderlich.

Danach kann man auch schon Mails verschicken:

sendmail -F nas@domain.de -t empfaenger@domain.de < inhalt.txt

Hierbei ist nas@domain.de der Absender und empfaenger@domain.de der Empfänger der Mail. Natürlich sollte man nur eine Domain anhängen, welche auch entsprechend registriert ist. Ansonsten werden die ausgehenden Mails schnell als Spam eingestuft!

]]>
Komplettes Webserver-Backup auf eine Synology DiscStation https://mkleine.de/blog/2016/01/07/komplettes-webserver-backup-auf-eine-synology-discstation/ Thu, 07 Jan 2016 16:39:22 +0000 http://mkleine.de/?p=1621 Wie schon berichtet, steht bei mir zu Hause eine Synology DS214+. Nun läuft diese Seite (und auch meine anderen Seiten) alls bei all-inkl. Dort habe ich ein Premium-Paket mit SSH-Zugang. Das Ganze bietet sich natürlich an, um regelmäßig ein Backup des kompletten Servers zu machen und auf der Synology zu speichern. Dabei ist der Plan, täglich die kompletten Daten und auch die mysql-Datenbanken zu sichern.

Was braucht man dafür?

  • SSH-Zugang
  • Einen Benutzer auf der Synology, welcher mit Key-Authentication auf den Webserver darf (dazu muss für den neuen Benutzer ein Key erstellt werden, welcher auf dem Webserver hinterlegt wird). Wie genau das geht, erklären hunderte von Beiträgen im Netz.
  • Etwas Platz auf der DiscStation

Ich habe mir dazu einen neuen Benutzer namens „backup“ (kreativ, oder?) auf der Synology angelegt, welcher als einziger Zugriff auf einen neuen gemeinsamen Ordner Namens „backup“ bekommt. Alle anderen Benutzer dürfen dort nicht schreiben – außer die Administratoren.

Synology_Backup_Verzeichnis

Soweit, so gut. Danach habe ich die Datei „backup_webserver.sh“ im Home-Verzeichnis des Backup-Users erstellt und einen neuen Cronjob eingerichtet, welches dieser Datei jeden Tag um 23 Uhr ausführt.

Synology_Backup_Cron_Web

Natürlich ist hinter „sh“ ein Leerzeichen und kein Zeichenumbruch. Die Textbox ist etwas klein geraten!

Der Inhalt der Datei ist dabei relativ simpel:

#!/bin/bash

current_date=$(date +"%Y-%m-%d")

USER="ssh-w0123456"
SERVER="domain.de.w0123456.kasserver.com"
PORT="22"
SOURCE="/www/htdocs/w0123456/"
TARGET="/volume1/backup/$current_date/data/"
LOG="/volume1/backup/$current_date/backup_data.log"

mkdir /volume1/backup/$current_date

rsync -avz --progress -e "ssh -p $PORT" $USER@$SERVER:$SOURCE $TARGET >> $LOG 2>&1

Unter /volume1/backup/ wird nun also jeden Tag ein neues Verzeichnis erstellt, welches den kompletten Inhalt per rsync herunterlädt. Soweit, so gut. Aufräumen muss man noch selbst! Nach mehreren Monaten wird sich hier also ordentlich was ansammeln.

Fehlt noch die Datenbank. Damit wir das Kommando „mysqldump“ nutzen können, muss das Paket „MariaDB“ über die Paketverwaltung installieren. Ich habe den Dienst nach der Installation direkt wieder gestoppt, um Rechenleistung zu sparen. Die entsprechenden Binaries findet man dann unter „/usr/syno/mysql/bin/mysqldump“.

Für alle Datenbanken habe ich eine CSV-Dateie erstellt, welche nach folgendem Schema aufgebaut ist:

benutzer;passwort
benutzer;passwort
benutzer;passwort
benutzer;passwort

Bei all-inkl ist der Benutzername auch immer gleich der Datenbankname – ansonsten bräuchte man noch eine Spalte.

Das Script sieht dann wie folgt aus:

#!/bin/bash
current_date=$(date +"%Y-%m-%d")
BACKUPDIR="/volume1/backup"
MYSQLTARGET="$BACKUPDIR/$current_date/mysql"

HOST="domain.de.w0123456.kasserver.com"

mkdir ${MYSQLTARGET}

OLDIFS=$IFS
IFS=";"
while read user password
do
    echo "Backing up ${user}"   
    /usr/syno/mysql/bin/mysqldump --opt -h ${HOST} -u${user} -p${password} --databases ${user} | gzip -c -9 > ${MYSQLTARGET}/${user}.gz
done < $1
IFS=$OLDIFS

Fertig! Nun dafür auch noch einen Cron einrichten.

Synology_Backup_Cron_MySql

Und schon laufen jede Nacht die entsprechenden Jobs!

Aufräumen nicht vergessen!

[asa]B00G6AX604[/asa] [asa]B00X17ZWB6[/asa] [asa]B00GK48610[/asa]

Bitte habt Verständnis dafür, dass ich für die genannten Scripte natürlich keine Garantie gebe. Es können sich natürlich immer Fehler einschleichen, welche zu Datenverlust führen. Ich bitte Dich daher, die hier gezeigten Scripte nur einzusetzen, wenn Du genau weißt was Du machst.

]]>
GPIO: Erste Schritte mit dem Raspberry Pi https://mkleine.de/blog/2016/01/05/gpio-erste-schritte-mit-dem-raspberry-pi/ Tue, 05 Jan 2016 21:38:11 +0000 http://mkleine.de/?p=1617 Vor einiger Zeit habe ich eine Artikelserie über das Thema Hausautomatisierung geschrieben. Mittlerweile steht das ganze Zeug leider relativ ungenutzt in der Gegend rum. Das soll sich nun ändern. Und zwar möchte ich nun etwas mit GPIO rumspielen – also den Pins auf dem Raspberry. Ich habe sowohl das Model der ersten generation, als auch der zweiten Generation hier. Da die Pins vom neueren Modell vom Touch-Display belegt sind, nutze ich das ältere Modell. Aber es sollte alles auch mit der neusten Generation funktionieren.

Also habe ich mir ein Start-Kit bestellt, damit ich nicht alles einzeln zusammensuchen muss. Sicher etwas teurer, dafür hat man jede Menge Kram zum spielen dabei. Alles verpackt in einer kleinen praktischen Plastikbox.

Als erstes habe ich wiringPi installiert. Der Build dauert eine ganze Weile – also ruhig einen Kaffee holen in der Zeit.

Ob alles geklappt hat, kann man folgendermaßen testen:

pi@raspberry:~$ gpio -v
gpio version: 2.31
Copyright (c) 2012-2015 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Model B, Revision: 03, Memory: 512MB, Maker: Sony 
  * Root or sudo required for GPIO access.

Fein. Und was nun?

Also eine runde Programmieren. Wahlweise mit C, Python oder eben per Shell. Für mich auch endlich mal eine Chance, etwas in Python einzusteigen. Das hatte ich schon viel zu lange vor. Aber soll ja nicht allzu schwer sein, wenn man schon Erfahrung in C, Java, PHP o.ä. hat.

Dank dem mitgelieferten Manual, hatte ich das erste C-Programm schnell (ab)geschrieben:

#include <wiringPi.h>
#include <stdio.h>

#define LedPin 0
#define SecondPin 3

int main(void)
{
    if (wiringPiSetup() == -1) {
        printf("Das war nix");
        return 1;
    }

    pinMode(LedPin, OUTPUT);

    while(1) {
        digitalWrite(LedPin, LOW);
        digitalWrite(SecondPin, HIGH);
        printf("led on!\n");
        delay(500);

        digitalWrite(LedPin, HIGH);
        digitalWrite(SecondPin, LOW);
        printf("led off!\n");
        delay(500);
    }
}

Schnell kompiliert und ausgeführt:

gcc test.c -o led -lwiringPi
sudo ./led

Dann noch alles ein wenig verkabeln, und schon steht die erste kleine Anwendung: Eine blinkende LED! Der Wahnsinn, oder?

GPIO erste Schritte

Schon jetzt könnte ich meine erste kleine Anwendung schreiben: Status-LEDs für unsere Continous Integration-Umgebung. Heißt: Geht ein Build kaputt, leuchtet eine rote LED auf. Ist alles wieder heile, wird die LED grün. Cool, oder?

Wenn man keine Lust hat alles in C zu schreiben, könnte man die C-Programme natürlich auch mit anderen Sprachen (wie PHP) aufrufen und die LEDs so steuern.

Alternativ kann man die LED in diesem Beispiel natürlich auch per Shell an- und ausschalten:

/usr/local/bin/gpio -g write 17 1
/usr/local/bin/gpio -g write 17 0
[asa]B00T2U7R7I[/asa] [asa]B00HU0Z4C2[/asa] ]]>