New app: luci-app-sshtunnel for SSH tunnels (#6424)
* luci-app-sshtunnel: SSH tunnels The app helps to configure SSH tunnels. You can also generate an SSH key and see known hosts. Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
This commit is contained in:
parent
9d746c75f4
commit
7d14746ae8
9 changed files with 1173 additions and 0 deletions
15
applications/luci-app-sshtunnel/Makefile
Normal file
15
applications/luci-app-sshtunnel/Makefile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||||
|
#
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
LUCI_TITLE:=LuCI support for SSH Tunnels (sshtunnel package)
|
||||||
|
|
||||||
|
PKG_MAINTAINER:=Sergey Ponomarev <stokito@gmail.com>
|
||||||
|
LUCI_DEPENDS:=+luci-base +sshtunnel
|
||||||
|
PKG_VERSION:=1.0.0
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
|
include ../../luci.mk
|
||||||
|
|
||||||
|
# call BuildPackage - OpenWrt buildroot signature
|
|
@ -0,0 +1,64 @@
|
||||||
|
'use strict';
|
||||||
|
'require form';
|
||||||
|
'require fs';
|
||||||
|
'require ui';
|
||||||
|
'require view';
|
||||||
|
|
||||||
|
|
||||||
|
return view.extend({
|
||||||
|
load: function () {
|
||||||
|
return Promise.all([
|
||||||
|
fs.lines('/root/.ssh/known_hosts'),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function (data) {
|
||||||
|
var knownHosts = data[0];
|
||||||
|
|
||||||
|
var m, s, o;
|
||||||
|
|
||||||
|
m = new form.Map('sshtunnel', _('SSH Tunnels'),
|
||||||
|
_('This configures <a %s>SSH Tunnels</a>')
|
||||||
|
.format('href="https://openwrt.org/docs/guide-user/services/ssh/sshtunnel"')
|
||||||
|
);
|
||||||
|
|
||||||
|
s = m.section(form.GridSection, '_known_hosts');
|
||||||
|
s.render = L.bind(_renderKnownHosts, this, knownHosts);
|
||||||
|
|
||||||
|
return m.render();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function _renderKnownHosts(knownHosts) {
|
||||||
|
var table = E('table', {'class': 'table cbi-section-table', 'id': 'known_hosts'}, [
|
||||||
|
E('tr', {'class': 'tr table-titles'}, [
|
||||||
|
E('th', {'class': 'th'}, _('Hostname')),
|
||||||
|
E('th', {'class': 'th'}, _('Public Key')),
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
|
||||||
|
var rows = _splitKnownHosts(knownHosts);
|
||||||
|
cbi_update_table(table, rows);
|
||||||
|
|
||||||
|
return E('div', {'class': 'cbi-section cbi-tblsection'}, [
|
||||||
|
E('h3', _('Known hosts ')),
|
||||||
|
E('div', {'class': 'cbi-section-descr'},
|
||||||
|
_('Keys of SSH servers found in %s.').format('<code>/root/.ssh/known_hosts</code>')
|
||||||
|
),
|
||||||
|
table
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _splitKnownHosts(knownHosts) {
|
||||||
|
var knownHostsMap = [];
|
||||||
|
for (var i = 0; i < knownHosts.length; i++) {
|
||||||
|
var sp = knownHosts[i].indexOf(' ');
|
||||||
|
if (sp < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var hostname = knownHosts[i].substring(0, sp);
|
||||||
|
var pub = knownHosts[i].substring(sp + 1);
|
||||||
|
knownHostsMap.push([hostname, '<small><code>' + pub + '</code></small>']);
|
||||||
|
}
|
||||||
|
return knownHostsMap;
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
'use strict';
|
||||||
|
'require form';
|
||||||
|
'require fs';
|
||||||
|
'require ui';
|
||||||
|
'require view';
|
||||||
|
|
||||||
|
var allSshKeys = {};
|
||||||
|
var hasSshKeygen = false;
|
||||||
|
|
||||||
|
return view.extend({
|
||||||
|
load: function () {
|
||||||
|
return L.resolveDefault(fs.list('/root/.ssh/'), []).then(function (entries) {
|
||||||
|
var tasks = [
|
||||||
|
L.resolveDefault(fs.stat('/usr/bin/ssh-keygen'), {}),
|
||||||
|
];
|
||||||
|
// read pub keys
|
||||||
|
for (var i = 0; i < entries.length; i++) {
|
||||||
|
if (entries[i].type === 'file' && entries[i].name.match(/\.pub$/)) {
|
||||||
|
tasks.push(Promise.resolve(entries[i].name));
|
||||||
|
tasks.push(fs.lines('/root/.ssh/' + entries[i].name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.all(tasks);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function (data) {
|
||||||
|
hasSshKeygen = data[0].type === 'file';
|
||||||
|
var sshKeys = _splitSshKeys(data.splice(1));
|
||||||
|
|
||||||
|
var m, s, o;
|
||||||
|
|
||||||
|
m = new form.Map('sshtunnel', _('SSH Tunnels'),
|
||||||
|
_('This configures <a %s>SSH Tunnels</a>')
|
||||||
|
.format('href="https://openwrt.org/docs/guide-user/services/ssh/sshtunnel"')
|
||||||
|
);
|
||||||
|
|
||||||
|
s = m.section(form.GridSection, '_keys');
|
||||||
|
s.render = L.bind(_renderSshKeys, this, sshKeys);
|
||||||
|
|
||||||
|
return m.render();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function _splitSshKeys(sshFiles) {
|
||||||
|
var sshKeys = {};
|
||||||
|
for (var i = 0; i < sshFiles.length; i++) {
|
||||||
|
var sshPubKeyName = sshFiles[i];
|
||||||
|
var sshKeyName = sshPubKeyName.substring(0, sshPubKeyName.length - 4);
|
||||||
|
i++;
|
||||||
|
var sshPub = sshFiles[i];
|
||||||
|
sshKeys[sshKeyName] = '<small><code>' + sshPub + '</code></small>';
|
||||||
|
}
|
||||||
|
allSshKeys = sshKeys;
|
||||||
|
return sshKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _renderSshKeys(sshKeys) {
|
||||||
|
var table = E('table', {'class': 'table cbi-section-table', 'id': 'keys_table'}, [
|
||||||
|
E('tr', {'class': 'tr table-titles'}, [
|
||||||
|
E('th', {'class': 'th'}, _('Name')),
|
||||||
|
E('th', {'class': 'th'}, _('Public Key')),
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
|
||||||
|
var rows = Object.entries(sshKeys);
|
||||||
|
cbi_update_table(table, rows, null);
|
||||||
|
|
||||||
|
var keyGenBtn = E('div', {}, [
|
||||||
|
E('form', {
|
||||||
|
'submit': _handleKeyGenSubmit,
|
||||||
|
}, [
|
||||||
|
E('label', {}, _('Generate a new key') + ': '),
|
||||||
|
E('span', {'class': 'control-group'}, [
|
||||||
|
E('input', {
|
||||||
|
'type': 'text',
|
||||||
|
'name': 'keyName',
|
||||||
|
'value': 'id_ed25519',
|
||||||
|
'pattern': '^[a-zA-Z][a-zA-Z0-9_\.]+',
|
||||||
|
'required': 'required',
|
||||||
|
'maxsize': '35',
|
||||||
|
'autocomplete': 'off',
|
||||||
|
}),
|
||||||
|
E('button', {
|
||||||
|
'id': 'btnGenerateKey',
|
||||||
|
'type': 'submit',
|
||||||
|
'class': 'btn cbi-button cbi-button-action',
|
||||||
|
}, [_('Generate')])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
return E('div', {'class': 'cbi-section cbi-tblsection'}, [
|
||||||
|
E('h3', _('SSH Keys')),
|
||||||
|
E('div', {'class': 'cbi-section-descr'},
|
||||||
|
_('Add the pub key to %s or %s.')
|
||||||
|
.format('<code>/root/.ssh/authorized_keys</code>', '<code>/etc/dropbear/authorized_keys</code>') + ' ' +
|
||||||
|
_('In LuCI you can do that with <a %s>System / Administration / SSH-Keys</a>')
|
||||||
|
.format('href="/cgi-bin/luci/admin/system/admin/sshkeys"')
|
||||||
|
),
|
||||||
|
keyGenBtn, table
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _handleKeyGenSubmit(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var keyName = document.querySelector('input[name="keyName"]').value;
|
||||||
|
if (allSshKeys[keyName]) {
|
||||||
|
document.body.scrollTop = document.documentElement.scrollTop = 0;
|
||||||
|
ui.addNotification(null, E('p', _('A key with that name already exists.'), 'error'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let command = '/usr/bin/ssh-keygen';
|
||||||
|
let commandArgs = ['-t', 'ed25519', '-q', '-N', '', '-f', '/root/.ssh/' + keyName];
|
||||||
|
if (!hasSshKeygen) {
|
||||||
|
command = '/usr/bin/dropbearkey';
|
||||||
|
commandArgs = ['-t', 'ed25519', '-f', '/root/.ssh/' + keyName];
|
||||||
|
}
|
||||||
|
fs.exec(command, commandArgs).then(function (res) {
|
||||||
|
if (res.code === 0) {
|
||||||
|
// refresh the page to see the new key
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
throw new Error(res.stdout + ' ' + res.stderr);
|
||||||
|
}
|
||||||
|
}).catch(function (e) {
|
||||||
|
document.body.scrollTop = document.documentElement.scrollTop = 0;
|
||||||
|
ui.addNotification(null, E('p', _('Unable to generate a key: %s').format(e.message)), 'error');
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
'use strict';
|
||||||
|
'require form';
|
||||||
|
'require fs';
|
||||||
|
'require uci';
|
||||||
|
'require ui';
|
||||||
|
'require view';
|
||||||
|
|
||||||
|
var allSshKeys = {};
|
||||||
|
|
||||||
|
return view.extend({
|
||||||
|
load: function () {
|
||||||
|
return L.resolveDefault(fs.list('/root/.ssh/'), []).then(function (entries) {
|
||||||
|
var tasks = [];
|
||||||
|
for (var i = 0; i < entries.length; i++) {
|
||||||
|
if (entries[i].type === 'file' && entries[i].name.match(/\.pub$/)) {
|
||||||
|
tasks.push(Promise.resolve(entries[i].name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.all(tasks);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function (data) {
|
||||||
|
var sshKeys = _splitSshKeys(data);
|
||||||
|
if (sshKeys.length === 0) {
|
||||||
|
ui.addNotification(null, E('p', _('No SSH keys found, <a %s>generate a new one</a>').format('href="./ssh_keys"')), 'warning');
|
||||||
|
}
|
||||||
|
|
||||||
|
var m, s, o;
|
||||||
|
|
||||||
|
m = new form.Map('sshtunnel', _('SSH Tunnels'),
|
||||||
|
_('This configures <a %s>SSH Tunnels</a>')
|
||||||
|
.format('href="https://openwrt.org/docs/guide-user/services/ssh/sshtunnel"')
|
||||||
|
);
|
||||||
|
|
||||||
|
s = m.section(form.GridSection, 'server', _('Servers'));
|
||||||
|
s.anonymous = false;
|
||||||
|
s.addremove = true;
|
||||||
|
s.nodescriptions = true;
|
||||||
|
|
||||||
|
o = s.tab('general', _('General Settings'));
|
||||||
|
o = s.tab('advanced', _('Advanced Settings'));
|
||||||
|
|
||||||
|
o = s.taboption('general', form.Value, 'hostname', _('Hostname'));
|
||||||
|
o.placeholder = 'example.com';
|
||||||
|
o.datatype = 'host';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.taboption('general', form.Value, 'port', _('Port'));
|
||||||
|
o.placeholder = '22';
|
||||||
|
o.datatype = 'port';
|
||||||
|
|
||||||
|
o = s.taboption('general', form.Value, 'user', _('User'));
|
||||||
|
o.default = 'root';
|
||||||
|
|
||||||
|
o = s.taboption('general', form.ListValue, 'IdentityFile', _('Key file'),
|
||||||
|
_('Private key file with authentication identity. ' +
|
||||||
|
'See <em>ssh_config IdentityFile</em>')
|
||||||
|
);
|
||||||
|
o.value('');
|
||||||
|
Object.keys(sshKeys).forEach(function (keyName) {
|
||||||
|
o.value('/root/.ssh/' + keyName, keyName);
|
||||||
|
});
|
||||||
|
o.optional = true;
|
||||||
|
|
||||||
|
|
||||||
|
o = s.taboption('advanced', form.ListValue, 'LogLevel', _('Log level'), 'See <em>ssh_config LogLevel</em>');
|
||||||
|
o.value('QUIET', 'QUIET');
|
||||||
|
o.value('FATAL', 'FATAL');
|
||||||
|
o.value('ERROR', 'ERROR');
|
||||||
|
o.value('INFO', 'INFO');
|
||||||
|
o.value('VERBOSE', 'VERBOSE');
|
||||||
|
o.value('DEBUG', 'DEBUG');
|
||||||
|
o.value('DEBUG2', 'DEBUG2');
|
||||||
|
o.value('DEBUG3', 'DEBUG3');
|
||||||
|
o.default = 'INFO';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
o = s.taboption('advanced', form.ListValue, 'Compression', _('Use compression'),
|
||||||
|
_('Compression may be useful on slow connections. ' +
|
||||||
|
'See <em>ssh_config Compression</em>')
|
||||||
|
);
|
||||||
|
o.value('yes', _('Yes'));
|
||||||
|
o.value('no', _('No'));
|
||||||
|
o.default = 'no';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
o = s.taboption('advanced', form.Value, 'retrydelay', _('Retry delay'),
|
||||||
|
_('Delay after a connection failure before trying to reconnect.')
|
||||||
|
);
|
||||||
|
o.placeholder = '10';
|
||||||
|
o.default = '10';
|
||||||
|
o.datatype = 'uinteger';
|
||||||
|
o.optional = true;
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
o = s.taboption('advanced', form.Value, 'ServerAliveCountMax', _('Server alive count max'),
|
||||||
|
_('The number of server alive messages which may be sent before SSH disconnects from the server. ' +
|
||||||
|
'See <em>ssh_config ServerAliveCountMax</em>')
|
||||||
|
);
|
||||||
|
o.placeholder = '3';
|
||||||
|
o.datatype = 'uinteger';
|
||||||
|
o.optional = true;
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
o = s.taboption('advanced', form.Value, 'ServerAliveInterval', _('Server alive interval'),
|
||||||
|
_('Keep-alive interval (seconds). ' +
|
||||||
|
'See <em>ssh_config ServerAliveInterval</em>')
|
||||||
|
);
|
||||||
|
o.optional = true;
|
||||||
|
o.default = '60';
|
||||||
|
o.datatype = 'uinteger';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
o = s.taboption('advanced', form.ListValue, 'CheckHostIP', _('Check host IP'),
|
||||||
|
_('Check the host IP address in the <code>known_hosts</code> file. ' +
|
||||||
|
'This allows ssh to detect whether a host key changed due to DNS spoofing. ' +
|
||||||
|
'See <em>ssh_config CheckHostIP</em>')
|
||||||
|
);
|
||||||
|
o.value('yes', _('Yes'));
|
||||||
|
o.value('no', _('No'));
|
||||||
|
o.default = 'no';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
o = s.taboption('advanced', form.ListValue, 'StrictHostKeyChecking', _('Strict host key checking'),
|
||||||
|
_('Refuse to connect to hosts whose host key has changed. ' +
|
||||||
|
'See <em>ssh_config StrictHostKeyChecking</em>'));
|
||||||
|
o.value('accept-new', _('Accept new and check if not changed'));
|
||||||
|
o.value('yes', _('Yes'));
|
||||||
|
o.value('no', _('No'));
|
||||||
|
o.default = 'accept-new';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
return m.render();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function _splitSshKeys(sshFiles) {
|
||||||
|
var sshKeys = {};
|
||||||
|
for (var i = 0; i < sshFiles.length; i++) {
|
||||||
|
var sshPubKeyName = sshFiles[i];
|
||||||
|
var sshKeyName = sshPubKeyName.substring(0, sshPubKeyName.length - 4);
|
||||||
|
sshKeys[sshKeyName] = '';
|
||||||
|
}
|
||||||
|
allSshKeys = sshKeys;
|
||||||
|
return sshKeys;
|
||||||
|
}
|
|
@ -0,0 +1,164 @@
|
||||||
|
'use strict';
|
||||||
|
'require form';
|
||||||
|
'require fs';
|
||||||
|
'require uci';
|
||||||
|
'require ui';
|
||||||
|
'require view';
|
||||||
|
|
||||||
|
return view.extend({
|
||||||
|
load: function () {
|
||||||
|
return Promise.all([
|
||||||
|
uci.load('sshtunnel'),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function (data) {
|
||||||
|
var m, s, o;
|
||||||
|
|
||||||
|
m = new form.Map('sshtunnel', _('SSH Tunnels'),
|
||||||
|
_('This configures <a %s>SSH Tunnels</a>')
|
||||||
|
.format('href="https://openwrt.org/docs/guide-user/services/ssh/sshtunnel"')
|
||||||
|
);
|
||||||
|
|
||||||
|
s = m.section(form.GridSection, 'tunnelR', _('Remote Tunnels'),
|
||||||
|
_('Forward a port on the remote host to a service on the local host.')
|
||||||
|
);
|
||||||
|
s.anonymous = true;
|
||||||
|
s.addremove = true;
|
||||||
|
s.nodescriptions = true;
|
||||||
|
|
||||||
|
o = s.option(form.Flag, 'enabled', _('Enabled'));
|
||||||
|
o.default = '1';
|
||||||
|
|
||||||
|
o = _addServerOption(s);
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'remoteaddress', _('Remote address'),
|
||||||
|
_('Bind IP address e.g. <code>192.168.1.1</code> or hostname e.g. <code>localhost</code>.') + '<br/>' +
|
||||||
|
_('<code>*</code> means to listen all interfaces <b>including public</b>.')
|
||||||
|
);
|
||||||
|
o.datatype = 'or(host, "*")';
|
||||||
|
o.default = '*';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'remoteport', _('Remote port'));
|
||||||
|
o.placeholder = '80';
|
||||||
|
o.datatype = 'port';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'localaddress', _('Local address'),
|
||||||
|
_('Bind IP address e.g. <code>192.168.1.1</code> or hostname e.g. <code>localhost</code>.')
|
||||||
|
);
|
||||||
|
o.datatype = 'host';
|
||||||
|
o.default = 'localhost';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'localport', _('Local port'));
|
||||||
|
o.datatype = 'port';
|
||||||
|
o.placeholder = '80';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
|
||||||
|
s = m.section(form.GridSection, 'tunnelL', _('Local Tunnels'),
|
||||||
|
_('Forward a port on the local host to a service on the remote host.')
|
||||||
|
);
|
||||||
|
s.anonymous = true;
|
||||||
|
s.addremove = true;
|
||||||
|
s.nodescriptions = true;
|
||||||
|
|
||||||
|
o = s.option(form.Flag, 'enabled', _('Enabled'));
|
||||||
|
o.default = '1';
|
||||||
|
|
||||||
|
o = _addServerOption(s);
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'localaddress', _('Local address'),
|
||||||
|
_('Bind IP address e.g. <code>192.168.1.1</code> or hostname e.g. <code>localhost</code>.') + '<br/>' +
|
||||||
|
_('<code>*</code> means to listen all interfaces <b>including public</b>.')
|
||||||
|
);
|
||||||
|
o.datatype = 'or(host, "*")';
|
||||||
|
o.placeholder = '192.168.1.1'; // not the default * public iface because a user must explicitly configure it
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'localport', _('Local port'));
|
||||||
|
o.datatype = 'port';
|
||||||
|
o.placeholder = '80';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'remoteaddress', _('Remote address'),
|
||||||
|
_('Bind IP address e.g. <code>192.168.1.1</code> or hostname e.g. <code>localhost</code>.')
|
||||||
|
);
|
||||||
|
o.datatype = 'host';
|
||||||
|
o.default = 'localhost';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'remoteport', _('Remote port'));
|
||||||
|
o.datatype = 'port';
|
||||||
|
o.default = '80';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
|
||||||
|
s = m.section(form.GridSection, 'tunnelD', _('Dynamic Tunnels'),
|
||||||
|
_('SOCKS proxy via remote host.')
|
||||||
|
);
|
||||||
|
s.anonymous = true;
|
||||||
|
s.addremove = true;
|
||||||
|
s.nodescriptions = true;
|
||||||
|
|
||||||
|
o = s.option(form.Flag, 'enabled', _('Enabled'));
|
||||||
|
o.default = '1';
|
||||||
|
|
||||||
|
o = _addServerOption(s);
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'localaddress', _('Local address'),
|
||||||
|
_('Bind IP address e.g. <code>192.168.1.1</code> or hostname e.g. <code>localhost</code>.') + '<br/>' +
|
||||||
|
_('<code>*</code> means to listen all interfaces <b>including public</b>.')
|
||||||
|
);
|
||||||
|
o.datatype = 'or(host, "*")';
|
||||||
|
o.placeholder = '192.168.1.1'; // not the default * public iface because a user must explicitly configure it
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'localport', _('Local port'));
|
||||||
|
o.datatype = 'port';
|
||||||
|
o.default = '1080';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
|
||||||
|
s = m.section(form.GridSection, 'tunnelW', _('VPN Tunnels'),
|
||||||
|
_('Configure TUN/TAP devices for VPN tunnels.')
|
||||||
|
);
|
||||||
|
s.anonymous = true;
|
||||||
|
s.addremove = true;
|
||||||
|
s.nodescriptions = true;
|
||||||
|
|
||||||
|
o = s.option(form.Flag, 'enabled', _('Enabled'));
|
||||||
|
o.default = '1';
|
||||||
|
|
||||||
|
o = _addServerOption(s);
|
||||||
|
|
||||||
|
o = s.option(form.ListValue, 'vpntype', _('VPN type'));
|
||||||
|
o.value('point-to-point', 'TUN (point-to-point)');
|
||||||
|
o.value('ethernet', 'TAP (ethernet)');
|
||||||
|
o.default = 'point-to-point';
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'localdev', _('Local dev'));
|
||||||
|
o.default = 'any';
|
||||||
|
o.datatype = 'or("any", min(0))';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'remotedev', _('Remote dev'));
|
||||||
|
o.default = 'any';
|
||||||
|
o.datatype = 'or("any", min(0))';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
return m.render();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function _addServerOption(s) {
|
||||||
|
var o = s.option(form.ListValue, 'server', _('Server'));
|
||||||
|
o.datatype = 'uciname';
|
||||||
|
o.rmempty = false;
|
||||||
|
uci.sections('sshtunnel', 'server', function (s, sectionName) {
|
||||||
|
o.value(sectionName, s.hostname ? '%s (%s)'.format(sectionName, s.hostname) : sectionName);
|
||||||
|
});
|
||||||
|
return o;
|
||||||
|
}
|
303
applications/luci-app-sshtunnel/po/ru/sshtunnel.po
Normal file
303
applications/luci-app-sshtunnel/po/ru/sshtunnel.po
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
msgid ""
|
||||||
|
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:37
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:75
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:113
|
||||||
|
msgid "<code>*</code> means to listen all interfaces <b>including public</b>."
|
||||||
|
msgstr ""
|
||||||
|
"<code>*</code> значит принимать соединения на всех интерфейсах <b>включая "
|
||||||
|
"публичные</b>"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:109
|
||||||
|
msgid "A key with that name already exists."
|
||||||
|
msgstr "Ключ с таким именем уже существует."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:128
|
||||||
|
msgid "Accept new and check if not changed"
|
||||||
|
msgstr "Принимать новый и проверять что не изменился"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:95
|
||||||
|
msgid "Add the pub key to %s or %s."
|
||||||
|
msgstr "Добавьте этот публичный ключ в %s или в %s."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:42
|
||||||
|
msgid "Advanced Settings"
|
||||||
|
msgstr "Расширенные настройки"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:36
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:49
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:74
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:87
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:112
|
||||||
|
msgid ""
|
||||||
|
"Bind IP address e.g. <code>192.168.1.1</code> or hostname e.g. "
|
||||||
|
"<code>localhost</code>."
|
||||||
|
msgstr ""
|
||||||
|
"Принимающий соединения IP адрес н.п. <code>192.168.1.1</code> или имя хоста "
|
||||||
|
"н.п. <code>localhost</code>"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:115
|
||||||
|
msgid "Check host IP"
|
||||||
|
msgstr "Проверять IP хоста"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:116
|
||||||
|
msgid ""
|
||||||
|
"Check the host IP address in the <code>known_hosts</code> file. This allows "
|
||||||
|
"ssh to detect whether a host key changed due to DNS spoofing. See "
|
||||||
|
"<em>ssh_config CheckHostIP</em>"
|
||||||
|
msgstr ""
|
||||||
|
"Проверять IP-адрес хоста в файле <code>known_hosts</code>. Это позволяет ssh "
|
||||||
|
"определить, изменился ли ключ хоста из-за спуфинга DNS."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:80
|
||||||
|
msgid ""
|
||||||
|
"Compression may be useful on slow connections. See <em>ssh_config "
|
||||||
|
"Compression</em>"
|
||||||
|
msgstr ""
|
||||||
|
"Сжатие может быть полезным на медленном соединении. См. <em>ssh_config "
|
||||||
|
"Compression</em>"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:126
|
||||||
|
msgid "Configure TUN/TAP devices for VPN tunnels."
|
||||||
|
msgstr "Конифгурация устройств TUN/TAP VPN-туннелей."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:89
|
||||||
|
msgid "Delay after a connection failure before trying to reconnect."
|
||||||
|
msgstr "Задержка перед переподключением"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:99
|
||||||
|
msgid "Dynamic Tunnels"
|
||||||
|
msgstr "Динамические туннели"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:30
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:68
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:106
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:132
|
||||||
|
msgid "Enabled"
|
||||||
|
msgstr "Включен"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:62
|
||||||
|
msgid "Forward a port on the local host to a service on the remote host."
|
||||||
|
msgstr "Перенаправить порт с локального хоста на сервис на удалённом хосте."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:24
|
||||||
|
msgid "Forward a port on the remote host to a service on the local host."
|
||||||
|
msgstr "Перенаправить порт с удалённого хоста на сервис на локальном хосте."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:41
|
||||||
|
msgid "General Settings"
|
||||||
|
msgstr "Общие настройки"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:88
|
||||||
|
msgid "Generate"
|
||||||
|
msgstr "Сгенерировать"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:73
|
||||||
|
msgid "Generate a new key"
|
||||||
|
msgstr "Сгенерировать новый ключ"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/rpcd/acl.d/luci-app-sshtunnel.json:3
|
||||||
|
msgid "Grant UCI access for luci-app-sshtunnel"
|
||||||
|
msgstr "Предоставить UCI доступ для luci-app-sshtunnel"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:35
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:44
|
||||||
|
msgid "Hostname"
|
||||||
|
msgstr "Имя хоста"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:97
|
||||||
|
msgid ""
|
||||||
|
"In LuCI you can do that with <a %s>System / Administration / SSH-Keys</a>"
|
||||||
|
msgstr ""
|
||||||
|
"В LuCI вы можете это сделать через <a %s>Система / Администрирование / SSH "
|
||||||
|
"ключи</a>"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:107
|
||||||
|
msgid ""
|
||||||
|
"Keep-alive interval (seconds). See <em>ssh_config ServerAliveInterval</em>"
|
||||||
|
msgstr ""
|
||||||
|
"Интервал проверки подключения (секунды). См. See <em>ssh_config "
|
||||||
|
"ServerAliveInterval</em>"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:56
|
||||||
|
msgid "Key file"
|
||||||
|
msgstr "Файл ключа"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:46
|
||||||
|
msgid "Keys of SSH servers found in %s."
|
||||||
|
msgstr "Ключи SSH уже известных серверов из %s."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:38
|
||||||
|
msgid "Known Hosts"
|
||||||
|
msgstr "Знакомые хосты"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:44
|
||||||
|
msgid "Known hosts"
|
||||||
|
msgstr "Знакомые хосты"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:61
|
||||||
|
msgid "Local Tunnels"
|
||||||
|
msgstr "Локальные туннели"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:48
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:73
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:111
|
||||||
|
msgid "Local address"
|
||||||
|
msgstr "Локальный адрес"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:142
|
||||||
|
msgid "Local dev"
|
||||||
|
msgstr "Локальное устройство dev"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:55
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:81
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:119
|
||||||
|
msgid "Local port"
|
||||||
|
msgstr "Локальный порт"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:67
|
||||||
|
msgid "Log level"
|
||||||
|
msgstr "Уровень логирования"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:61
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Название"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:84
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:121
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:130
|
||||||
|
msgid "No"
|
||||||
|
msgstr "Нет"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:26
|
||||||
|
msgid "No SSH keys found, <a %s>generate a new one</a>"
|
||||||
|
msgstr ""
|
||||||
|
"Нет ни одного ключа, пожалуйста <a href=\"./ssh_keys\">сгенерируйте новый</"
|
||||||
|
"a>."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:49
|
||||||
|
msgid "Port"
|
||||||
|
msgstr "Порт"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:57
|
||||||
|
msgid ""
|
||||||
|
"Private key file with authentication identity. See <em>ssh_config "
|
||||||
|
"IdentityFile</em>"
|
||||||
|
msgstr ""
|
||||||
|
"Файл приватного ключа для авторизации. См. <em>ssh_config IdentityFile</em>"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:36
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:62
|
||||||
|
msgid "Public Key"
|
||||||
|
msgstr "Публичный ключ"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:126
|
||||||
|
msgid ""
|
||||||
|
"Refuse to connect to hosts whose host key has changed. See <em>ssh_config "
|
||||||
|
"StrictHostKeyChecking</em>"
|
||||||
|
msgstr ""
|
||||||
|
"Отказывать в подключении к хосту если его ключ поменялся. См. <em>ssh_config "
|
||||||
|
"StrictHostKeyChecking</em>"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:23
|
||||||
|
msgid "Remote Tunnels"
|
||||||
|
msgstr "Удалённые туннели"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:35
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:86
|
||||||
|
msgid "Remote address"
|
||||||
|
msgstr "Удалённый адресс"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:147
|
||||||
|
msgid "Remote dev"
|
||||||
|
msgstr "Удалённое устройство dev"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:43
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:93
|
||||||
|
msgid "Remote port"
|
||||||
|
msgstr "Удалённый порт"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:88
|
||||||
|
msgid "Retry delay"
|
||||||
|
msgstr "Задержка попытки"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:100
|
||||||
|
msgid "SOCKS proxy via remote host."
|
||||||
|
msgstr "SOCKS прокси через удалённый хост."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:93
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:14
|
||||||
|
msgid "SSH Keys"
|
||||||
|
msgstr "SSH Ключи"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:20
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:33
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:31
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:18
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:3
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:30
|
||||||
|
msgid "SSH Tunnels"
|
||||||
|
msgstr "SSH туннели"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:157
|
||||||
|
msgid "Server"
|
||||||
|
msgstr "Сервер"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:97
|
||||||
|
msgid "Server alive count max"
|
||||||
|
msgstr "Попыток проверки соединения"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:106
|
||||||
|
msgid "Server alive interval"
|
||||||
|
msgstr "Интервал проверки соединения"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:36
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:22
|
||||||
|
msgid "Servers"
|
||||||
|
msgstr "Серверы"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:125
|
||||||
|
msgid "Strict host key checking"
|
||||||
|
msgstr "Строгая проверка ключа хоста"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:98
|
||||||
|
msgid ""
|
||||||
|
"The number of server alive messages which may be sent before SSH disconnects "
|
||||||
|
"from the server. See <em>ssh_config ServerAliveCountMax</em>"
|
||||||
|
msgstr ""
|
||||||
|
"Сколько проверочных сообщений на сервер отправить прежде чем отключиться.См. "
|
||||||
|
"See <em>ssh_config ServerAliveCountMax</em>"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:21
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:34
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:32
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:19
|
||||||
|
msgid "This configures <a %s>SSH Tunnels</a>"
|
||||||
|
msgstr "Настройка <a %s>SSH туннелей</a>."
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:128
|
||||||
|
msgid "Unable to generate a key: %s"
|
||||||
|
msgstr "Ошибка при генерации ключа: %s"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:79
|
||||||
|
msgid "Use compression"
|
||||||
|
msgstr "Использовать сжатие"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:53
|
||||||
|
msgid "User"
|
||||||
|
msgstr "Пользователь"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:125
|
||||||
|
msgid "VPN Tunnels"
|
||||||
|
msgstr "VPN туннели"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:137
|
||||||
|
msgid "VPN type"
|
||||||
|
msgstr "Тип VPN"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:83
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:120
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:129
|
||||||
|
msgid "Yes"
|
||||||
|
msgstr "Да"
|
284
applications/luci-app-sshtunnel/po/templates/sshtunnel.pot
Normal file
284
applications/luci-app-sshtunnel/po/templates/sshtunnel.pot
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
msgid ""
|
||||||
|
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:37
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:75
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:113
|
||||||
|
msgid "<code>*</code> means to listen all interfaces <b>including public</b>."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:109
|
||||||
|
msgid "A key with that name already exists."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:128
|
||||||
|
msgid "Accept new and check if not changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:95
|
||||||
|
msgid "Add the pub key to %s or %s."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:42
|
||||||
|
msgid "Advanced Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:36
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:49
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:74
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:87
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:112
|
||||||
|
msgid ""
|
||||||
|
"Bind IP address e.g. <code>192.168.1.1</code> or hostname e.g. "
|
||||||
|
"<code>localhost</code>."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:115
|
||||||
|
msgid "Check host IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:116
|
||||||
|
msgid ""
|
||||||
|
"Check the host IP address in the <code>known_hosts</code> file. This allows "
|
||||||
|
"ssh to detect whether a host key changed due to DNS spoofing. See "
|
||||||
|
"<em>ssh_config CheckHostIP</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:80
|
||||||
|
msgid ""
|
||||||
|
"Compression may be useful on slow connections. See <em>ssh_config "
|
||||||
|
"Compression</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:126
|
||||||
|
msgid "Configure TUN/TAP devices for VPN tunnels."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:89
|
||||||
|
msgid "Delay after a connection failure before trying to reconnect."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:99
|
||||||
|
msgid "Dynamic Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:30
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:68
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:106
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:132
|
||||||
|
msgid "Enabled"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:62
|
||||||
|
msgid "Forward a port on the local host to a service on the remote host."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:24
|
||||||
|
msgid "Forward a port on the remote host to a service on the local host."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:41
|
||||||
|
msgid "General Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:88
|
||||||
|
msgid "Generate"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:73
|
||||||
|
msgid "Generate a new key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/rpcd/acl.d/luci-app-sshtunnel.json:3
|
||||||
|
msgid "Grant UCI access for luci-app-sshtunnel"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:35
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:44
|
||||||
|
msgid "Hostname"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:97
|
||||||
|
msgid ""
|
||||||
|
"In LuCI you can do that with <a %s>System / Administration / SSH-Keys</a>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:107
|
||||||
|
msgid ""
|
||||||
|
"Keep-alive interval (seconds). See <em>ssh_config ServerAliveInterval</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:56
|
||||||
|
msgid "Key file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:46
|
||||||
|
msgid "Keys of SSH servers found in %s."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:38
|
||||||
|
msgid "Known Hosts"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:44
|
||||||
|
msgid "Known hosts"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:61
|
||||||
|
msgid "Local Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:48
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:73
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:111
|
||||||
|
msgid "Local address"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:142
|
||||||
|
msgid "Local dev"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:55
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:81
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:119
|
||||||
|
msgid "Local port"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:67
|
||||||
|
msgid "Log level"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:61
|
||||||
|
msgid "Name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:84
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:121
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:130
|
||||||
|
msgid "No"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:26
|
||||||
|
msgid "No SSH keys found, <a %s>generate a new one</a>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:49
|
||||||
|
msgid "Port"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:57
|
||||||
|
msgid ""
|
||||||
|
"Private key file with authentication identity. See <em>ssh_config "
|
||||||
|
"IdentityFile</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:36
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:62
|
||||||
|
msgid "Public Key"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:126
|
||||||
|
msgid ""
|
||||||
|
"Refuse to connect to hosts whose host key has changed. See <em>ssh_config "
|
||||||
|
"StrictHostKeyChecking</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:23
|
||||||
|
msgid "Remote Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:35
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:86
|
||||||
|
msgid "Remote address"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:147
|
||||||
|
msgid "Remote dev"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:43
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:93
|
||||||
|
msgid "Remote port"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:88
|
||||||
|
msgid "Retry delay"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:100
|
||||||
|
msgid "SOCKS proxy via remote host."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:93
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:14
|
||||||
|
msgid "SSH Keys"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:20
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:33
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:31
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:18
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:3
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:30
|
||||||
|
msgid "SSH Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:157
|
||||||
|
msgid "Server"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:97
|
||||||
|
msgid "Server alive count max"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:106
|
||||||
|
msgid "Server alive interval"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:36
|
||||||
|
#: applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json:22
|
||||||
|
msgid "Servers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:125
|
||||||
|
msgid "Strict host key checking"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:98
|
||||||
|
msgid ""
|
||||||
|
"The number of server alive messages which may be sent before SSH disconnects "
|
||||||
|
"from the server. See <em>ssh_config ServerAliveCountMax</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js:21
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:34
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:32
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:19
|
||||||
|
msgid "This configures <a %s>SSH Tunnels</a>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js:128
|
||||||
|
msgid "Unable to generate a key: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:79
|
||||||
|
msgid "Use compression"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:53
|
||||||
|
msgid "User"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:125
|
||||||
|
msgid "VPN Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js:137
|
||||||
|
msgid "VPN type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:83
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:120
|
||||||
|
#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:129
|
||||||
|
msgid "Yes"
|
||||||
|
msgstr ""
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"admin/services/sshtunnel": {
|
||||||
|
"title": "SSH Tunnels",
|
||||||
|
"order": 50,
|
||||||
|
"action": {
|
||||||
|
"type": "alias",
|
||||||
|
"path": "admin/services/sshtunnel/ssh_tunnels"
|
||||||
|
},
|
||||||
|
"depends": {
|
||||||
|
"acl": [ "luci-app-sshtunnel" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"admin/services/sshtunnel/ssh_keys": {
|
||||||
|
"title": "SSH Keys",
|
||||||
|
"order": 10,
|
||||||
|
"action": {
|
||||||
|
"type": "view",
|
||||||
|
"path": "sshtunnel/ssh_keys"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"admin/services/sshtunnel/ssh_servers": {
|
||||||
|
"title": "Servers",
|
||||||
|
"order": 20,
|
||||||
|
"action": {
|
||||||
|
"type": "view",
|
||||||
|
"path": "sshtunnel/ssh_servers"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"admin/services/sshtunnel/ssh_tunnels": {
|
||||||
|
"title": "SSH Tunnels",
|
||||||
|
"order": 30,
|
||||||
|
"action": {
|
||||||
|
"type": "view",
|
||||||
|
"path": "sshtunnel/ssh_tunnels"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"admin/services/sshtunnel/ssh_hosts": {
|
||||||
|
"title": "Known Hosts",
|
||||||
|
"order": 40,
|
||||||
|
"action": {
|
||||||
|
"type": "view",
|
||||||
|
"path": "sshtunnel/ssh_hosts"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"luci-app-sshtunnel": {
|
||||||
|
"description": "Grant UCI access for luci-app-sshtunnel",
|
||||||
|
"read": {
|
||||||
|
"file": {
|
||||||
|
"/root/.ssh/": [ "list" ],
|
||||||
|
"/root/.ssh/*.pub": [ "read" ],
|
||||||
|
"/root/.ssh/known_hosts": [ "read" ],
|
||||||
|
"/usr/bin/ssh-keygen": [ "list" ],
|
||||||
|
"/usr/bin/ssh-keygen *": [ "exec" ],
|
||||||
|
"/usr/bin/dropbearkey": [ "list" ],
|
||||||
|
"/usr/bin/dropbearkey *": [ "exec" ]
|
||||||
|
},
|
||||||
|
"uci": [ "sshtunnel" ]
|
||||||
|
},
|
||||||
|
"write": {
|
||||||
|
"uci": [ "sshtunnel" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue