mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-25 03:44:52 +00:00
01_FHEMWEB.js: add rescueDialog
git-svn-id: https://svn.fhem.de/fhem/trunk@26494 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
20dd2563b0
commit
a4ba6e8b41
@ -189,16 +189,17 @@ FHEMWEB_Initialize($)
|
||||
menuEntries
|
||||
mainInputLength
|
||||
nameDisplay
|
||||
nrAxis
|
||||
ploteditor:always,onClick,never
|
||||
plotfork:1,0
|
||||
plotmode:gnuplot-scroll,gnuplot-scroll-svg,SVG
|
||||
plotEmbed:2,1,0
|
||||
plotsize
|
||||
plotWeekStartDay:0,1,2,3,4,5,6
|
||||
nrAxis
|
||||
redirectCmds:0,1
|
||||
redirectTo
|
||||
refresh
|
||||
rescueDialog:1,0
|
||||
reverseLogs:0,1
|
||||
roomIcons:textField-long
|
||||
showUsedFiles:0,1
|
||||
@ -1247,7 +1248,7 @@ FW_dataAttr()
|
||||
addParam($FW_wname, "styleData", "").
|
||||
addParam("global", "language", "EN").
|
||||
"data-availableJs='$FW_fhemwebjs' ".
|
||||
"data-webName='$FW_wname '";
|
||||
"data-webName='$FW_wname' ";
|
||||
}
|
||||
|
||||
sub
|
||||
@ -1742,27 +1743,44 @@ FW_roomOverview($)
|
||||
my $sfx = AttrVal("global", "language", "EN");
|
||||
$sfx = ($sfx eq "EN" ? "" : "_$sfx");
|
||||
my @list = (
|
||||
"Everything", "$FW_ME?room=all",
|
||||
"", "",
|
||||
"Commandref", "$FW_ME/docs/commandref${sfx}.html",
|
||||
"Remote doc", "http://fhem.de/fhem.html#Documentation",
|
||||
"Edit files", "$FW_ME?cmd=style%20list",
|
||||
"Select style", "$FW_ME?cmd=style%20select",
|
||||
"Event monitor", "$FW_ME?cmd=style%20eventMonitor",
|
||||
"", "");
|
||||
my $lastname = ","; # Avoid double "".
|
||||
'Everything', "$FW_ME?room=all",
|
||||
'', '',
|
||||
'Commandref', "$FW_ME/docs/commandref${sfx}.html",
|
||||
'Remote doc', 'http://fhem.de/fhem.html#Documentation',
|
||||
'Edit files', "$FW_ME?cmd=style%20list",
|
||||
'Select style', "$FW_ME?cmd=style%20select",
|
||||
'Event monitor', "$FW_ME?cmd=style%20eventMonitor",
|
||||
'', '');
|
||||
|
||||
my $lfn = "Logfile";
|
||||
if($defs{$lfn}) { # Add the current Logfile to the list if defined
|
||||
my @l = FW_fileList($defs{$lfn}{logfile},1);
|
||||
my $fn = pop @l;
|
||||
splice @list, 4,0, ("Logfile",
|
||||
splice @list, 4,0, ('Logfile',
|
||||
"$FW_ME/FileLog_logWrapper?dev=$lfn&type=text&file=$fn");
|
||||
}
|
||||
|
||||
if(AttrVal($FW_wname, 'rescueDialog', undef)) {
|
||||
my $pid = $defs{$FW_wname}{rescuePID};
|
||||
$pid = 0 if(!$pid || !kill(0,$pid));
|
||||
my $key="";
|
||||
|
||||
if(!-r "certs/fhemrescue.pub") {
|
||||
mkdir("certs");
|
||||
`ssh-keygen -N "" -t ed25519 -f certs/fhemrescue`;
|
||||
}
|
||||
if(open(my $fh, "certs/fhemrescue.pub")) {
|
||||
$key = <$fh>;
|
||||
close($fh);
|
||||
}
|
||||
splice @list, @list-2,0, ('Rescue',
|
||||
"javascript:FW_rescueClient(\"$pid\",\"$key\")");
|
||||
}
|
||||
|
||||
my @me = split(",", AttrVal($FW_wname, "menuEntries", ""));
|
||||
push @list, @me, "", "" if(@me);
|
||||
|
||||
my $lastname = ",";
|
||||
for(my $idx = 0; $idx < @list; $idx+= 2) {
|
||||
next if($FW_hiddenroom{$list[$idx]} || $list[$idx] eq $lastname);
|
||||
push @list1, $list[$idx];
|
||||
@ -3445,12 +3463,16 @@ sub
|
||||
FW_Set($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
my %cmd = ("rereadicons" => 1, "clearSvgCache" => 1);
|
||||
my %cmd = ("rereadicons" => ":noArg", "clearSvgCache" => ":noArg");
|
||||
if(AttrVal($hash->{NAME}, "rescueDialog", "")) {
|
||||
$cmd{"rescueStart"} = "";
|
||||
$cmd{"rescueTerminate"} = ":noArg";
|
||||
}
|
||||
|
||||
return "no set value specified" if(@a < 2);
|
||||
return ("Unknown argument $a[1], choose one of ".
|
||||
join(" ", map { "$_:noArg" } sort keys %cmd))
|
||||
if(!$cmd{$a[1]});
|
||||
join(" ", map { "$_$cmd{$_}" } sort keys %cmd))
|
||||
if(!defined($cmd{$a[1]}));
|
||||
|
||||
if($a[1] eq "rereadicons") {
|
||||
my @dirs = keys %FW_icons;
|
||||
@ -3459,6 +3481,7 @@ FW_Set($@)
|
||||
FW_readIcons($d);
|
||||
}
|
||||
}
|
||||
|
||||
if($a[1] eq "clearSvgCache") {
|
||||
my $cDir = "$FW_dir/SVGcache";
|
||||
if(opendir(DH, $cDir)) {
|
||||
@ -3468,6 +3491,31 @@ FW_Set($@)
|
||||
return "Can't open $cDir: $!";
|
||||
}
|
||||
}
|
||||
|
||||
if($a[1] eq "rescueStart") {
|
||||
return "error: rescueStart needs two arguments: host and port"
|
||||
if(!$a[2] || !$a[3] || $a[3] !~ m/[0-9]{1,5}/ || $a[3] > 65536);
|
||||
return "error: rescue process is running with PID $hash->{rescuePID}"
|
||||
if($hash->{rescuePID} && kill(0, $hash->{rescuePID}));
|
||||
return "error: certificate certs/fhemrescue is not available"
|
||||
if(! -r "certs/fhemrescue");
|
||||
$hash->{rescuePID} = fhemFork();
|
||||
return "error: cannot fork rescue pid\n"
|
||||
if($hash->{rescuePID} == -1);
|
||||
return undef if($hash->{rescuePID}); # Parent
|
||||
my $cmd = "exec ssh -N -R0.0.0.0:18083:localhost:$hash->{PORT} ".
|
||||
"-i certs/fhemrescue -p$a[3] fhemrescue\@$a[2]";
|
||||
Log 1, "Starting $cmd";
|
||||
exec($cmd);
|
||||
}
|
||||
|
||||
if($a[1] eq "rescueTerminate") {
|
||||
return "error: nothing to terminate"
|
||||
if(!$hash->{rescuePID});
|
||||
kill(15, $hash->{rescuePID});
|
||||
delete($hash->{rescuePID});
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
@ -4206,6 +4254,48 @@ FW_log($$)
|
||||
seconds).
|
||||
</li><br>
|
||||
|
||||
<a id="FHEMWEB-attr-rescueDialog"></a>
|
||||
<li>rescueDialog<br>
|
||||
If set, show a Rescue link in the menu. The goal is to be able to get
|
||||
help from someone with more knowlege (rescuer), who is then able to
|
||||
remote control this installation.<br>
|
||||
After opening the dialog, a key is shown, which is to be sent to the
|
||||
rescuer. After the rescuer installed the key (see below), the
|
||||
connection can be established, by entering the adress of the
|
||||
rescuers server.<br><br>
|
||||
|
||||
<b>TODO for the rescuer:</b>
|
||||
<ul>
|
||||
<li>Forward a public IP/PORT combination to your SSH server.</li>
|
||||
<li>create a fhemrescue user on this server, and store the key from
|
||||
the client:<br>
|
||||
<ul><code>
|
||||
useradd -d /tmp -s /bin/false fhemrescue<br>
|
||||
echo "KEY_FROM_THE_CLIENT" > /etc/sshd/fhemrescue.auth<br>
|
||||
chown fhemrescue:fhemrescue /etc/sshd/fhemrescue.auth<br>
|
||||
chmod 600 /etc/sshd/fhemrescue.auth
|
||||
</code></ul>
|
||||
</li>
|
||||
<li>Append to /etc/ssh/sshd_config:<br>
|
||||
<ul><code>
|
||||
Match User fhemrescue<br>
|
||||
<ul>
|
||||
AllowTcpForwarding remote<br>
|
||||
PermitTTY no<br>
|
||||
GatewayPorts yes<br>
|
||||
ForceCommand /bin/false<br>
|
||||
AuthorizedKeysFile /etc/ssh/fhemrescue.auth<br>
|
||||
</ul>
|
||||
</code></ul>
|
||||
</li>
|
||||
<li>Restart sshd, e.g. with systemctl restart sshd
|
||||
</li>
|
||||
<li>Tell the client your public IP/PORT.</li>
|
||||
<li>After the client started the connection in the rescue dialog, you
|
||||
can access the clients FHEM via your host, port 18083.</li>
|
||||
</ul>
|
||||
</li><br>
|
||||
|
||||
<a id="FHEMWEB-attr-reverseLogs"></a>
|
||||
<li>reverseLogs<br>
|
||||
Display the lines from the logfile in a reversed order, newest on the
|
||||
@ -4987,6 +5077,53 @@ FW_log($$)
|
||||
Refresh, z.B. nach 5 Sekunden.
|
||||
</li><br>
|
||||
|
||||
<a id="FHEMWEB-attr-rescueDialog"></a>
|
||||
<li>rescueDialog<br>
|
||||
Falls gesetzt, im Menue wird ein Rescue Link angezeigt. Das Ziel ist
|
||||
von jemanden mit mehr Wissen (Retter) Hilfe zu bekommen, indem er die
|
||||
lokale FHEM-Installation fernsteuert.<br>
|
||||
Nach öffnen des Dialogs wird ein Schlüssel angezeigt, was dem
|
||||
Retter zu schicken ist. Nachdem er diesen Schlüssel bei sich
|
||||
installiert hat, muss seine Adresse (Host und Port) im Dialog
|
||||
eingetragen werden. Danach kann er die Verbindung fernsteuern.
|
||||
<br><br>
|
||||
|
||||
<b>TODO für den Retter:</b>
|
||||
<ul>
|
||||
<li>eine öffentliche IP/PORT Kombination zum eigenen SSH Server
|
||||
weiterleiten.</li>
|
||||
|
||||
<li>einen fhemrescue Benutzer auf diesem Server anlegen, und den
|
||||
Schlüssel vom Hilfesuchenden eintragen:<br>
|
||||
<ul><code>
|
||||
useradd -d /tmp -s /bin/false fhemrescue<br>
|
||||
echo "KEY_FROM_THE_CLIENT" > /etc/sshd/fhemrescue.auth<br>
|
||||
chown fhemrescue:fhemrescue /etc/sshd/fhemrescue.auth<br>
|
||||
chmod 600 /etc/sshd/fhemrescue.auth
|
||||
</code></ul>
|
||||
</li>
|
||||
<li>Zu /etc/ssh/sshd_config Folgendes hinzufügen:<br>
|
||||
<ul><code>
|
||||
Match User fhemrescue<br>
|
||||
<ul>
|
||||
AllowTcpForwarding remote<br>
|
||||
PermitTTY no<br>
|
||||
GatewayPorts yes<br>
|
||||
ForceCommand /bin/false<br>
|
||||
AuthorizedKeysFile /etc/ssh/fhemrescue.auth<br>
|
||||
</ul>
|
||||
</code></ul>
|
||||
</li>
|
||||
<li>sshd neu starten, z.Bsp. mit systemctl restart sshd
|
||||
</li>
|
||||
<li>Dem Hilfesuchenden die öffentliche IP/PORT Kombination
|
||||
mitteilen.</li>
|
||||
<li>Nachdem der Hilfesuchende diese Daten eingegeben hat, und die
|
||||
Verbindung gestartet hat, kann die Remote-FHEM-Installation ueber
|
||||
den eigenen SSH-Server, Port 1803 erreicht wedern.</li>
|
||||
</ul>
|
||||
</li><br>
|
||||
|
||||
<a id="FHEMWEB-attr-reverseLogs"></a>
|
||||
<li>reverseLogs<br>
|
||||
Damit wird das Logfile umsortiert, die neuesten Einträge stehen
|
||||
|
@ -2239,6 +2239,56 @@ FW_checkNotifydev(reName)
|
||||
});
|
||||
}
|
||||
|
||||
function
|
||||
FW_rescueClient(pid, key)
|
||||
{
|
||||
let html='<div id="rescueDialog" style="display:none">';
|
||||
if(!pid || pid == "0") {
|
||||
html += '<b>Key (send it to the rescuer):</b><br>'+
|
||||
(key ? '<code>'+key+'</code>' : 'Not found, generate one first');
|
||||
html += '<br><br>';
|
||||
}
|
||||
|
||||
let buttons = [];
|
||||
|
||||
if(key) {
|
||||
if(pid && pid != "0") {
|
||||
html += "<div>There is a connection with pid "+pid+"</div><br>";
|
||||
buttons.push({
|
||||
text:"Terminate connection",
|
||||
click:function(){
|
||||
FW_cmd(FW_root+
|
||||
"?cmd=set "+$("body").attr("data-webname")+
|
||||
" rescueTerminate&XHR=1");
|
||||
setTimeout(function(){ location.reload() }, 1000);
|
||||
}});
|
||||
|
||||
} else {
|
||||
html += "Address (rescuer will tell you host and port)<br>";
|
||||
html += "<input type='text' size='20' placeholder='host port' >";
|
||||
|
||||
buttons.push({
|
||||
text:"Start connection",
|
||||
click:function(){
|
||||
FW_cmd(FW_root+
|
||||
"?cmd=set "+$("body").attr("data-webname")+" rescueStart "+
|
||||
$("#rescueDialog input").val()+"&XHR=1");
|
||||
setTimeout(function(){ location.reload() }, 1000);
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
buttons.push({ text:"Cancel", click:function(){ $(this).dialog('close')} });
|
||||
|
||||
$('body').append(html);
|
||||
|
||||
$('#rescueDialog').dialog({
|
||||
modal:true, closeOnEscape:true, width:"auto",
|
||||
close:function(){ $('#rescueDialog').remove(); },
|
||||
buttons:buttons
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
=pod
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user