itari's little syno
the incredible NAS
# Besucher
Donate a cup of coffee for Itari

Direkter Zugriff auf die File-Station

2008-10-06

Und es geht doch!!!

Allerdings muss man ein wenig basteln. Eine neue Datei im Verzeichnis /usr/syno/synoman/webman/modules/index1.html mit folgendem Inhalt anlegen (Eigentümer: root - Gruppe: root):

<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
<script src="/scripts/ajax.js" type="text/javascript" language="javascript"></script>
<script language="JavaScript">
function LoginHandler(req) {
if(req.readyState == 4) {
 if(req.status == 200 || !req.status){
  if (!req || !req.responseText) return;
  var login = eval('(' + req.responseText + ')');
  if (!login) return;
  if ("error" == login.result) {
    switch (login.reason) {
    case 'error_guest': alert('Anmeldung beim Gästekonto fehlgeschlagen, '
                        +'bitte verwenden Sie ein anderes.'); break;
    case 'error_cantlogin': alert('Das Konto oder Kennwort ist ungültig. '
                            +'Bitte versuchen Sie es noch einmal.'); break;
    case 'error_nologin_nopasswd': alert('error_nologin_nopasswd'); break;
    case 'error_expired': alert('Ihr Konto wurde deaktiviert. Wenden Sie sich bitte '
                          +'an den Administrator.'); break;
    case 'error_noprivilege': alert('Sie dürfen diesen Dienst nicht verwenden.'); break;
    case 'error_systemfull': alert('Sie können sich nicht an das System anmelden, da '
                             +'der Speicherplatz derzeit voll ist. Führen Sie bitte '
                             +'einen Neustart des Systems aus und versuchen Sie es '
                             +'noch einmal.'); break;
    }
  return;
  }
 window.location = '/webfm/cgi/index.cgi';
 } 
}
}
function SendLogin() {
var login_type = document.login_form.login_type;
var username = document.login_form.username.value;
var passwd = document.login_form.password.value;
var service_type = 2;
var params = "username="+encodeURIComponent(username)+"&passwd="
           +encodeURIComponent(passwd)+"&service_type="+service_type;
AjaxSendRequest("/webman/modules/login.cgi", params, LoginHandler);
return false;
} 
</script></head><body>
<form name="login_form" method="post" action="" onsubmit="return SendLogin();">
<span class="login_message_title">Benutzername:</span>
<input name="username" type="text" value="" size="16">
<span class="login_message_title">Kennwort eingeben:</span>
<input name="password" type="password" size="20">
<input type="submit" value="Anmelden" class="login_button">
</form></body></html>

Der Aufruf erfolgt mit https://Name_der_DS:5001/webman/modules/index1.html. Bei richtiger Eingabe des Benutzernamens und des Kennwortes wird direkt der File Manager aufgerufen. Den Pfad kann man sicherlich noch ein wenig anpassen, indem man (wie bei der index.cgi) symbolische Links einbaut. Auch der Dateiname kann anders lauten. Allerdings muss man den sys-Apache verwenden, weil nur der die Authentifizierungs-Module aufrufen kann. Eventuell mal mit http und Port 5000 probieren.

e2fsck für alle Laufwerke

2008-10-06

sooo ... nun hab ich es ein paar Stunden getestet und es scheint gut zu laufen: der Plattentest beim Booten.

Achtung wichtiger Hinweis: Dieser Hack ist nicht ganz ungefährlich, daher Datensicherung vorher und Mut sammeln; es kann sein, dass man neu installieren muss, wenn wirklich gravierende Fehler erkannt und beseitigt werden!!! Alles geschieht wieder auf eigene Kappe!!!!

Hintergrundgedanken für den Hack: In der Start-Phase ist noch nicht viel los auf der DS, relativ wenig Prozesse, keine Server usw. In dieser Phase ist das /volume1 ... noch nicht gemountet und man kann das /(root)-Volume auf read-only setzen. read-only ist eine hinreichende Bedingung für den fsck-Lauf. Die Meldungen werden ins /tmp-Verzeichnis (steht im als RAM-Disk zur Verfügung) geschrieben.

Die folgenden Zeilen muss man in die /etc/rc aufnehmen (bei mir nach der Zeile 49: mount -t tmpfs /tmp /tmp).


mount -o remount,ro /
date >/tmp/boot.log
echo -e "e2fsck -pf /dev/md0 c" >>/tmp/boot.log
/sbin/e2fsck -pf /dev/md0 2>&1 >>/tmp/boot.log
echo -e "e2fsck -nv /dev/md0 c" >>/tmp/boot.log
/sbin/e2fsck -nv /dev/md0 2>&1 >>/tmp/boot.log
echo -e "e2fsck -p /dev/md2 c" >>/tmp/boot.log
/sbin/e2fsck -p /dev/md2 2>&1 >>/tmp/boot.log
echo -e "e2fsck -nv /dev/md2 c" >>/tmp/boot.log
/sbin/e2fsck -nv /dev/md2 2>&1 >>/tmp/boot.log
#
mount -o remount,rw /

md1 wird nicht untersucht, weil swap-device. md0 wird immer gecheckt. md2 wird nur gecheckt, wenn ein Fehler vorlag. Allerdings dauert es dann schon eine Weile (bei mir so ca. 30 Minuten für 500GB-Raid), bis der Check durch ist und das System weiter macht. Man kann ja am Anfang diese Checks mit #-zeichen auskommentieren und sie erstmal übergehen, um zu sehen, wie es überhaupt geht.

Nachdem das System fertig ist, kann man die Protokoll-Datei /tmp/boot.log anschauen und sehen, was alles so gemacht wurde.

Die Ergebnisse in dieser Datei sind der Wirklichkeit am nächsten. Spätere Live-e2fsck -nv Prüfungen zeigen meist Fehler an, die nicht unbegdingt welche sein müssen, weil das ext3-Protokoll nicht mit in die Prüfung einbezogen wird. Sind also sozusagen unvollendete Transaktionen.

Falls Plattenfehler vorlagen, die mit Dateirekonstruktionen nur bedingt gerade gebogen werden konnten, findet man Restfragmente in den entsprechenden lost+found-Verzeichnissen.

3rdparty apps / Zugriff absichern

2008-10-06

Ja gibt es. Leider nicht ganz einfach, weil sich der vorinstallierte Apache mit seinem PHP ein wenig blöd anstellt. Aber wie dem auch sei. Du brauchst zwei Skripte:

auth.cgi:

#!/bin/ash
USR=$(/usr/syno/synoman/webman/modules/authenticate.cgi)
#[ "$USR" != "admin" ] && exit 1
echo "Content-type: text/html"
echo ""
echo $USR

Achte darauf, dass es bei den Zeilenenden keine ^M steht (mit dem vi gucken), sonst läuft das Skript nicht (also kein Windows-Zeilenende, sondern ein Linux-Zeilenende). Dieses Skripte wäre auch zugleich die Lösung für Shell.cgi-Skripte, wenn man die Zeile 2 entkommentiert.

Das zweite Skript (als PHP-Skript getarnt , könnte auch .html oder sonstwas sein - muss nur den AJAX-JavaSkript-Call können), liest nun den User-Namen via XMLHTTPRequest() ein:

test_auth.php:

<input type="text" id="user" name="user" value=""/>
<script> 
var myXMLHTTPRequest = (window.XMLHttpRequest)?
                        XMLHttpRequest():
                        ActiveXObject("Microsoft.XMLHTTP");
function LoadHTML(htmlfile){
  myXMLHTTPRequest.open("GET", htmlfile, false); myXMLHTTPRequest.send(null);
  return myXMLHTTPRequest.responseText;
}
ret=LoadHTML('https://syno:5001/phpsrc/systeminfo/auth.cgi'); 
alert(ret); 
document.getElementById('user').value=ret; 
</script> 
<?php echo "php-Skript" ?>

Ich hab mal 2 Möglichkeiten gezeigt, mit dem Usernamen umzugehen. Kannst dir nun eine passende Möglichkeit überlegen, wie du das Skript bei falschen Usern beendest.

Anmerkung: Die Lösungen mit dem Request auf autheniticate.cgi (so wie ihn Synology vorschlägt) haben einen Nachteil. Sie basieren darauf, dass das Session-Cookie noch nicht verfallen ist. Also es kann sein, dass man sich immer neu anmelden muss, wenn man es abfragt, weil man wiedermal zu lange vor der Screen gesessen hat.

Wohin mit dem mount --bind?

2008-10-06

User-Mounten geht, in dem du es beim Starten automatisch vernehmen lässt, z. B. in der Datei /etc/rc.local:

Synology> cd /etc
Synology> cat rc.local
#!/bin/sh

# Optware setup
mkdir -p /opt
[ -e /volume1/opt ] && mount -o bind /volume1/opt /opt
[ -x /opt/etc/rc.optware ] && /opt/etc/rc.optware
[ -e /bin/killall ] || ln -s /bin/busybox /bin/killall
[ -e /volume1/web/mp3 ] && mount -o bind /volume1/music /volume1/web/mp3
# remount with noatime
mount -o remount,noatime /
mount -o remount,noatime /volume1
# user mounts
mount --bind / /root

Da kannst dich austoben mit den --bind bzw. -o bind (was dasselbe ist)

3rd-party-apps-Fenster

2008-10-06

Wenn man eine 3rd-party-Integration in den Disk Station Manager vorgenommen hat und in der Konfiguration "type=embedde" festgelegt hat, dann wird die 3rs-party-Application im Disk Station Manger im rechten (eigentlich mittleren wegen der Hilfe) Fenster in einem iframe angezeigt.

An anderer Stelle hatte wir schon mal diskutiert, dass man dessen Größen verändern kann, und zwar in dieser Datei: /usr/syno/synoman/webman/modules/appebd.html:

<div  class="module-root">
<div  class="centering" style="width:98%;">
    <div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>
    <div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc">
        <div class="subtitle">LAN</div>
        <iframe class="otherapp-iframe" frameBorder="0" 
                style="width: 100%; height: 550px;"></iframe>
    </div></div></div>
    <div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>
</div>
</div>

An den roten Stellen kann man das Erscheinungsbild modifizieren. Ich hab mal meine Änderungen eingebaut. Bitte vorher eine Kopie der Datei machen und dran denken, dass diese Datei nach einem Firmware-Update wieder überschrieben wird.

One-click removal USB-drive

2008-10-05

I've made a solution to umount the usb-disk by pressing the usb-copy-button. Are you interested? Did you installed the toolchain? You need to compile a very small C-program to get the status of the usb-copy-button

C-program named getusbbutton.c:

#include 
int main (int argc, char *argv[]) {
FILE *fp;
int c;
if ((fp = fopen("/dev/ttyS1", "r")) == NULL) {
  printf("strings: can't open /dev/ttyS1n");
  return 1;
  } else {
  while ((c = getc(fp)) != '`');
  fclose(fp);
  return 0;
  }
}

The C-program read the status of the /dev/ttyS1 and compares it with the value '`' and returns 0. This means: I've found the button pressed.

Compile it and copy it as getusbbutton to your DS (/usr/bin).

Now you can write a shell-script like this one:

while getusbbutton; do
  echo A >/dev/ttyS1
  sync
  /usr/syno/bin/synousbdisk -umount sdk1 >/dev/null
  >/tmp/usbtab
  sleep 3
  echo B >/dev/ttyS1
done

Name the script S11usb_umount.sh. The script behave like a server, so you can startup it by copying it to /usr/syno/etc/rc.d-directory as a run-command-file. Once you start it, it can only removed by kill -9 pid or with a shutdown. It's a very short solution and if you like, build your own features.

Short interpretion of the script:

It loops with a while and waits of the button-pressure. Once the pressure-state is detected it makes the usb-copy-LED flashing. Now it male a sync to flush the disc-buffers. Then the umount of the usb-disk with the special-command synousbdisk. Be sure that your device is the '/dev/sdk1'. If not, change it or make a pattern match to the return of the mount-command (maybe some people in the forum will help us). Now it removes all tracks of it and shortens the file /tmp/usbtab. This means, the entry disappears in the Syno Disk Manager. After that it waits 3 seconds and gives the command to stop the flashing of the usb-copy-led.

Attention: after starting the script, you can't use the usb-copy-button in the normal manner, but it is in fact your one-click-solution you asked for.

And .... it works, but I've tested it only 5 minutes ... maybe there are side-effects, I could not see and maybe there are error in it. It's a modding, so it is to your responsibility to use it.

[an error occurred while processing this directive]
PHP: -0.982833 sek. | #