From 7d14746ae88a83163a7e34daae70b264285bbe56 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Mon, 4 Dec 2023 20:27:53 +0200 Subject: [PATCH] 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 --- applications/luci-app-sshtunnel/Makefile | 15 + .../resources/view/sshtunnel/ssh_hosts.js | 64 ++++ .../resources/view/sshtunnel/ssh_keys.js | 131 ++++++++ .../resources/view/sshtunnel/ssh_servers.js | 147 +++++++++ .../resources/view/sshtunnel/ssh_tunnels.js | 164 ++++++++++ .../luci-app-sshtunnel/po/ru/sshtunnel.po | 303 ++++++++++++++++++ .../po/templates/sshtunnel.pot | 284 ++++++++++++++++ .../share/luci/menu.d/luci-app-sshtunnel.json | 45 +++ .../share/rpcd/acl.d/luci-app-sshtunnel.json | 20 ++ 9 files changed, 1173 insertions(+) create mode 100644 applications/luci-app-sshtunnel/Makefile create mode 100644 applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js create mode 100644 applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js create mode 100644 applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js create mode 100644 applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js create mode 100644 applications/luci-app-sshtunnel/po/ru/sshtunnel.po create mode 100644 applications/luci-app-sshtunnel/po/templates/sshtunnel.pot create mode 100644 applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json create mode 100644 applications/luci-app-sshtunnel/root/usr/share/rpcd/acl.d/luci-app-sshtunnel.json diff --git a/applications/luci-app-sshtunnel/Makefile b/applications/luci-app-sshtunnel/Makefile new file mode 100644 index 0000000000..4298b6107f --- /dev/null +++ b/applications/luci-app-sshtunnel/Makefile @@ -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 +LUCI_DEPENDS:=+luci-base +sshtunnel +PKG_VERSION:=1.0.0 +PKG_RELEASE:=1 + +include ../../luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js b/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js new file mode 100644 index 0000000000..b82eae2617 --- /dev/null +++ b/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_hosts.js @@ -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 SSH Tunnels') + .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('/root/.ssh/known_hosts') + ), + 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, '' + pub + '']); + } + return knownHostsMap; +} diff --git a/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js b/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js new file mode 100644 index 0000000000..6c83454b0d --- /dev/null +++ b/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_keys.js @@ -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 SSH Tunnels') + .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] = '' + sshPub + ''; + } + 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('/root/.ssh/authorized_keys', '/etc/dropbear/authorized_keys') + ' ' + + _('In LuCI you can do that with System / Administration / SSH-Keys') + .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; +} diff --git a/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js b/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js new file mode 100644 index 0000000000..5aa33e6df8 --- /dev/null +++ b/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js @@ -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, generate a new one').format('href="./ssh_keys"')), 'warning'); + } + + var m, s, o; + + m = new form.Map('sshtunnel', _('SSH Tunnels'), + _('This configures SSH Tunnels') + .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 ssh_config IdentityFile') + ); + 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 ssh_config LogLevel'); + 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 ssh_config Compression') + ); + 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 ssh_config ServerAliveCountMax') + ); + 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 ssh_config ServerAliveInterval') + ); + 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 known_hosts file. ' + + 'This allows ssh to detect whether a host key changed due to DNS spoofing. ' + + 'See ssh_config CheckHostIP') + ); + 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 ssh_config StrictHostKeyChecking')); + 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; +} diff --git a/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js b/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js new file mode 100644 index 0000000000..34fceab2f0 --- /dev/null +++ b/applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_tunnels.js @@ -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 SSH Tunnels') + .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. 192.168.1.1 or hostname e.g. localhost.') + '
' + + _('* means to listen all interfaces including public.') + ); + 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. 192.168.1.1 or hostname e.g. localhost.') + ); + 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. 192.168.1.1 or hostname e.g. localhost.') + '
' + + _('* means to listen all interfaces including public.') + ); + 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. 192.168.1.1 or hostname e.g. localhost.') + ); + 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. 192.168.1.1 or hostname e.g. localhost.') + '
' + + _('* means to listen all interfaces including public.') + ); + 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; +} diff --git a/applications/luci-app-sshtunnel/po/ru/sshtunnel.po b/applications/luci-app-sshtunnel/po/ru/sshtunnel.po new file mode 100644 index 0000000000..71f7cff442 --- /dev/null +++ b/applications/luci-app-sshtunnel/po/ru/sshtunnel.po @@ -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 "* means to listen all interfaces including public." +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 "Добавьте этот публичный ключ в %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. 192.168.1.1 or hostname e.g. " +"localhost." +msgstr "" +"Принимающий соединения IP адрес н.п. 192.168.1.1 или имя хоста " +"н.п. localhost" + +#: 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 known_hosts file. This allows " +"ssh to detect whether a host key changed due to DNS spoofing. See " +"ssh_config CheckHostIP" +msgstr "" +"Проверять IP-адрес хоста в файле known_hosts. Это позволяет 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 ssh_config " +"Compression" +msgstr "" +"Сжатие может быть полезным на медленном соединении. См. ssh_config " +"Compression" + +#: 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 System / Administration / SSH-Keys" +msgstr "" +"В LuCI вы можете это сделать через Система / Администрирование / SSH " +"ключи" + +#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:107 +msgid "" +"Keep-alive interval (seconds). See ssh_config ServerAliveInterval" +msgstr "" +"Интервал проверки подключения (секунды). См. See ssh_config " +"ServerAliveInterval" + +#: 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, generate a new one" +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 ssh_config " +"IdentityFile" +msgstr "" +"Файл приватного ключа для авторизации. См. ssh_config IdentityFile" + +#: 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 ssh_config " +"StrictHostKeyChecking" +msgstr "" +"Отказывать в подключении к хосту если его ключ поменялся. См. ssh_config " +"StrictHostKeyChecking" + +#: 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 ssh_config ServerAliveCountMax" +msgstr "" +"Сколько проверочных сообщений на сервер отправить прежде чем отключиться.См. " +"See ssh_config ServerAliveCountMax" + +#: 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 SSH Tunnels" +msgstr "Настройка SSH туннелей." + +#: 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 "Да" diff --git a/applications/luci-app-sshtunnel/po/templates/sshtunnel.pot b/applications/luci-app-sshtunnel/po/templates/sshtunnel.pot new file mode 100644 index 0000000000..9da1f07a7f --- /dev/null +++ b/applications/luci-app-sshtunnel/po/templates/sshtunnel.pot @@ -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 "* means to listen all interfaces including public." +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. 192.168.1.1 or hostname e.g. " +"localhost." +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 known_hosts file. This allows " +"ssh to detect whether a host key changed due to DNS spoofing. See " +"ssh_config CheckHostIP" +msgstr "" + +#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:80 +msgid "" +"Compression may be useful on slow connections. See ssh_config " +"Compression" +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 System / Administration / SSH-Keys" +msgstr "" + +#: applications/luci-app-sshtunnel/htdocs/luci-static/resources/view/sshtunnel/ssh_servers.js:107 +msgid "" +"Keep-alive interval (seconds). See ssh_config ServerAliveInterval" +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, generate a new one" +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 ssh_config " +"IdentityFile" +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 ssh_config " +"StrictHostKeyChecking" +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 ssh_config ServerAliveCountMax" +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 SSH Tunnels" +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 "" diff --git a/applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json b/applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json new file mode 100644 index 0000000000..b32c53ad49 --- /dev/null +++ b/applications/luci-app-sshtunnel/root/usr/share/luci/menu.d/luci-app-sshtunnel.json @@ -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" + } + } +} diff --git a/applications/luci-app-sshtunnel/root/usr/share/rpcd/acl.d/luci-app-sshtunnel.json b/applications/luci-app-sshtunnel/root/usr/share/rpcd/acl.d/luci-app-sshtunnel.json new file mode 100644 index 0000000000..5dfb1405c7 --- /dev/null +++ b/applications/luci-app-sshtunnel/root/usr/share/rpcd/acl.d/luci-app-sshtunnel.json @@ -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" ] + } + } +} -- 2.30.2