Merge pull request #265 from bergware/6.4-wip

Include TELNET, SSH and GUI management access
This commit is contained in:
tom mortensen
2018-02-23 06:35:58 -08:00
committed by GitHub
8 changed files with 100 additions and 41 deletions

View File

@@ -314,7 +314,7 @@ $dhcpDisabled = $range ? '':'disabled';
<?if ($protocol[$network] != 'ipv6'):?>
IPv4 custom network on interface <?=$network?> (optional):
: <input type="checkbox" id="DOCKER_CUSTOM_<?=$port?>_edit" onchange="changeCustom(this.id,4)"<?=$subnet?'checked':''?>>
: <input type="checkbox" id="DOCKER_CUSTOM_<?=$port?>_edit" onchange="changeCustom(this.id,4)"<?=$subnet?'checked':''?>><span id="DOCKER_CUSTOM_<?=$port?>_line" class="<?=$subnet?'':'disabled'?>">
<span class="<?=$ip4class?>">**Subnet:** <input type="text" id="DOCKER_CUSTOM_<?=$port?>_net" name="DOCKER_SUBNET_<?=$port?>" class="ip4" value="<?=$subnet?>" title="IPv4 address A.B.C.D"<?=$disabled?>>/
<select id="DOCKER_CUSTOM_<?=$port?>_mask" name="DOCKER_MASK_<?=$port?>" class="mask"<?=$disabled?>>
<?for ($m=16; $m<=30; $m++) echo mk_option($mask?:24,$m,$m)?></select>
@@ -324,7 +324,7 @@ IPv4 custom network on interface <?=$network?> (optional):
**DHCP pool:** <input type="text" id="DOCKER_CUSTOM_<?=$port?>_pool" name="DOCKER_RANGE_<?=$port?>" class="ip4" value="<?=$range?>" title="IPv4 address A.B.C.D"<?=$disabled?>>/
<select id="DOCKER_CUSTOM_<?=$port?>_size" name="DOCKER_SIZE_<?=$port?>" class="mask" onchange="changeHosts(this.id,this.value)"<?=$disabled?>>
<?for ($m=16; $m<=30; $m++) echo mk_option($size?:25,$m,$m)?></select>
<span id="DOCKER_CUSTOM_<?=$port?>_hosts" style="<?=$subnet?'':'display:none'?>">(<?=pow(2,32-($size?:25))?> hosts)</span>
<span id="DOCKER_CUSTOM_<?=$port?>_hosts" style="<?=$subnet?'':'display:none'?>">(<?=pow(2,32-($size?:25))?> hosts)</span></span>
<?endif;?>
<?endforeach;?>
@@ -333,6 +333,9 @@ IPv4 custom network on interface <?=$network?> (optional):
>
> Enter the pool range within each allocated subnet which is used for DHCPv4 assignments by Docker. E.g. 192.168.1.128/25
<?endif;?>
<?if ($include6):?>
<hr>
<?endif;?>
<?foreach ($include6 as $network => $route):?>
<?
@@ -383,7 +386,7 @@ $dhcpDisabled = $range6 ? '':'disabled';
<?if ($protocol[$network] != 'ipv4'):?>
IPv6 custom network on interface <?=$network?> (optional):
: <input type="checkbox" id="DOCKER_CUSTOM6_<?=$port?>_edit" onchange="changeCustom(this.id,6)"<?=$subnet6?'checked':''?>>
: <input type="checkbox" id="DOCKER_CUSTOM6_<?=$port?>_edit" onchange="changeCustom(this.id,6)"<?=$subnet6?'checked':''?>><span id="DOCKER_CUSTOM6_<?=$port?>_line" class="<?=$subnet6?'':'disabled'?>">
<span class="ip6">**Subnet:**<input type="text" id="DOCKER_CUSTOM6_<?=$port?>_net" name="DOCKER_SUBNET6_<?=$port?>" class="ip6" value="<?=$subnet6?>" title="IPv6 address nnnn:xxxx::yyyy"<?=$disabled?>>/
<select id="DOCKER_CUSTOM6_<?=$port?>_mask" name="DOCKER_MASK6_<?=$port?>" class="mask"<?=$disabled?>>
<?for ($m=64; $m<=120; $m+=8) echo mk_option($mask6?:64,$m,$m)?></select></span>
@@ -391,7 +394,7 @@ IPv6 custom network on interface <?=$network?> (optional):
<input type="checkbox" id="DOCKER_CUSTOM6_<?=$port?>_dhcp" onchange="customDHCP(this.id,6)"<?=$subnet6?'checked':''?><?=$dhcpDisabled?>>
**DHCP pool:**<input type="text" id="DOCKER_CUSTOM6_<?=$port?>_pool" name="DOCKER_RANGE6_<?=$port?>" class="ip6" value="<?=$range6?>" title="IPv6 address nnnn:xxxx::yyyy"<?=$disabled?>>/
<select id="DOCKER_CUSTOM6_<?=$port?>_size" name="DOCKER_SIZE6_<?=$port?>" class="mask"<?=$disabled?>>
<?for ($m=64; $m<=120; $m+=8) echo mk_option($size6?:72,$m,$m)?></select>
<?for ($m=64; $m<=120; $m+=8) echo mk_option($size6?:72,$m,$m)?></select></span>
<?endif;?>
<?endforeach;?>
@@ -714,7 +717,13 @@ function changeCustom(id,ip) {
$(id+'dhcp').prop('disabled',!checked);
$(id+'pool').prop('disabled',!checked);
$(id+'size').prop('disabled',!checked);
checked ? $(id+'hosts').show() : $(id+'hosts').hide();
if (checked) {
$(id+'hosts').show();
$(id+'line').removeClass('disabled');
} else {
$(id+'hosts').hide();
$(id+'line').addClass('disabled','disabled');
}
}
function changeMask(id,val) {
var mask = Math.pow(2,32-val);

View File

@@ -27,6 +27,9 @@ $disabled_provision = $keyfile===false || ($isLEcert && $retval_expired===0) ||
$disabled_updatedns = $keyfile!==false && $isLEcert ? '' : 'disabled';
$internalip = $eth0['IPADDR:0'];
?>
<?if (strstr('azure,gray',$display['theme'])):?>
<style>input.trim{width:65px}</style>
<?endif;?>
<script>
function provisionSSL(button) {
var oldlabel = $.trim($(button).text());
@@ -49,11 +52,11 @@ function provisionSSL(button) {
$.get("//"+data.internal_dns+":<?=$var['PORT']?>/dnscheck",function() {
success_rebind_check(data);
}).fail(function(){
failure({"status": 403, "responseJSON": {"error": "Your router or DNS server has DNS rebinding protection enabled, preventing "+data.internal_dns+" <?=$internalip?> resolution. See Help for more details and workarounds"}});
failure({"status":403, "responseJSON":{"error": "Your router or DNS server has DNS rebinding protection enabled, preventing "+data.internal_dns+" <?=$internalip?> resolution. See Help for more details and workarounds"}});
});
}
} else {
failure({"status": 403, "responseJSON": {"error": "Server was unable to provision SSL certificate"}});
failure({"status":403, "responseJSON":{"error": "Server was unable to provision SSL certificate"}});
}
};
var success_rebind_check = function(data) {
@@ -79,43 +82,81 @@ function updateDNS(button) {
$.post("/webGui/include/UpdateDNS.php",success).fail(failure);
}
function checkPorts(form) {
if (!form.PORT.value) form.PORT.value = 80;
if (!form.PORTSSL.value) form.PORTSSL.value = 443;
if (!form.PORTSSH.value) form.PORTSSL.value = 22;
var port = [];
if (form.PORT.value < 1024 && form.PORT.value != 80) port.push('HTTP');
if (form.PORTSSL.value < 1024 && form.PORTSSL.value != 443) port.push('HTTPS');
if (form.PORTSSH.value < 1024 && form.PORTSSH.value != 22) port.push('SSH');
if (port) {
swal({title:'Non-recommended port',text:port.join(',')+' may conflict with well known services',type:'warning',showCancelButton:true},function(){form.submit();});
var check = [{'key':'PORTTELNET','port':'23','text':'TELNET'},{'key':'PORTSSH','port':'22','text':'SSH'},{'key':'PORT','port':'80','text':'HTTP'},{'key':'PORTSSL','port':'443','text':'HTTPS'}];
var list = [];
for (var i=0; i < check.length; i++) {
var key = check[i]['key'];
var port = check[i]['port'];
var text = check[i]['text'];
var item = $(form).find('input[name="'+key+'"]');
if (!item.val()) item.val(port);
if (item.val() < 1024 && item.val() != port && item.prop('disabled')==false) list.push(text+' ('+item.val()+')');
item.prop('disabled',false);
}
if (list.length > 0) {
swal({title:'Non-recommended port'+(list.length>1?'s':''),text:list.join(', ')+'<br>may conflict with well-known services',html:true,type:'warning',showCancelButton:true},function(){form.submit();});
} else {
form.submit();
}
}
function updateTELNET(form) {
form.PORTTELNET.disabled = form.USE_TELNET.value=='no';
}
function updateSSH(form) {
form.PORTSSH.disabled = form.USE_SSH.value=='no';
}
function updateSSL(form) {
form.PORTSSL.disabled = form.USE_SSL.value=='no';
}
$(function(){
var form = document.SSLSettings;
updateTELNET(form);
updateSSH(form);
updateSSL(form);
});
</script>
<form markdown="1" name="SSLSettings" method="POST" action="/update.htm" target="progressFrame">
<input type="hidden" name="changePorts" value="apply">
Restricted management access:
Restrict management access:
: <select name="BIND_MGT" size="1" class="narrow">
<?=mk_option($var['BIND_MGT'], "no", "No")?>
<?=mk_option($var['BIND_MGT'], "yes", "Yes")?>
</select>
> By default webGUI and SSH access are available on any active interface of the system.
> By default GUI, SSH and TELNET access are available on all active interfaces of the system.
>
> Restricted management access limits webGUI and SSH access to the management interface only (eth0).
> *Restrict management access* limits GUI, SSH and TELNET access to the management interface only (eth0).
Use TELNET:
: <select name="USE_TELNET" size="1" class="narrow">
: <select name="USE_TELNET" size="1" class="narrow" onchange="updateTELNET(this.form)">
<?=mk_option($var['USE_TELNET'], "no", "No")?>
<?=mk_option($var['USE_TELNET'], "yes", "Yes")?>
</select>
> By default TELNET access is enabled. TELNET is an insecure type of access however,
> By default TELNET access is enabled. TELNET is an insecure type of CLI access however,
> and it is highly recommended to use SSH access instead and disable TELNET access.
TELNET port:
: <input type="number" name="PORTTELNET" class="trim" min="1" max="65535" value="<?=htmlspecialchars($var['PORTTELNET']??23)?>">
> Enter the TELNET port, default port is 23.
Use SSH:
: <select name="USE_SSH" size="1" class="narrow" onchange="updateSSH(this.form)">
<?=mk_option($var['USE_SSH'], "no", "No")?>
<?=mk_option($var['USE_SSH'], "yes", "Yes")?>
</select>
> SSH is enabled by default and offers a secure way of CLI access. Upon system startup SSH keys are automatically generated
> if not yet existing, and stored on the flash device in the folder */config/ssh*.
SSH port:
: <input type="number" name="PORTSSH" class="trim" min="1" max="65535" value="<?=htmlspecialchars($var['PORTSSH']??22)?>">
> Enter the SSH port, default port is 22.
Use SSL/TLS:
: <select name="USE_SSL" size="1" class="narrow">
: <select name="USE_SSL" size="1" class="narrow" onchange="updateSSL(this.form)">
<?=mk_option($var['USE_SSL'], "auto", "Auto")?>
<?=mk_option($var['USE_SSL'], "no", "No")?>
<?=mk_option($var['USE_SSL'], "yes", "Yes")?>
@@ -173,11 +214,6 @@ HTTPS port:
> Enter the HTTPS port, default port is 443.
SSH port:
: <input type="number" name="PORTSSH" class="trim" min="1" max="65535" value="<?=htmlspecialchars($var['PORTSSH']??22)?>">
> Enter the SSH port, default port is 22.
Local TLD:
: <input type="text" name="LOCAL_TLD" value="<?=htmlspecialchars($var['LOCAL_TLD'])?>" class="narrow">
@@ -187,8 +223,7 @@ Local TLD:
: <input type="button" value="Apply" onclick="checkPorts(this.form)"><input type="button" value="Done" onclick="done()">
</form>
<br><br>
<div style="height:24px"></div>
<form markdown="1" name="Provision" method="POST" action="/update.htm" target="progressFrame">
<input type="hidden" name="changePorts" value="apply">
Certificate issuer:

View File

@@ -264,7 +264,7 @@ $(function() {
if ($.cookie('help')=='help') {$('.inline_help').show(); $('#nav-item.HelpButton').addClass('active');}
$('#'+tab).attr('checked', true);
updateTime();
$.jGrowl.defaults.closeTemplate = '<i class="fa fa-share"></i>';
$.jGrowl.defaults.closeTemplate = '<i class="fa fa-close"></i>';
$.jGrowl.defaults.closerTemplate = '<?=$notify['position'][0]=='b' ? '<div>':'<div class="top">'?>[ close all notifications ]</div>';
$.jGrowl.defaults.sticky = true;
$.jGrowl.defaults.check = 100;

View File

@@ -2,6 +2,7 @@
CONF=/etc/ssh/sshd_config
INET=/etc/inetd.conf
SERV=/etc/services
# read settings
if [[ -a /boot/config/ident.cfg ]]; then
@@ -10,8 +11,10 @@ if [[ -a /boot/config/ident.cfg ]]; then
fi
# preset default values
[[ -z $BIND_MGT ]] && BIND_MGT=yes
[[ -z $BIND_MGT ]] && BIND_MGT=no
[[ -z $USE_TELNET ]] && USE_TELNET=yes
[[ -z $PORTTELNET ]] && PORTTELNET=23
[[ -z $USE_SSH ]] && USE_SSH=yes
[[ -z $PORTSSH ]] && PORTSSH=22
# get management IP addresses
@@ -28,26 +31,38 @@ fi
if [[ $PORTSSH == 22 ]]; then
sed -ri 's/^#?Port [0-9]+$/#Port 22/' $CONF
else
sed -ri "s/^#?Port [0-9]+\$/Port $PORTSSH/" $CONF
sed -ri "s/^#?Port [0-9]+\$/Port ${PORTSSH}/" $CONF
fi
# bind/unbind SSH service
if [[ -n $IPV4 ]]; then
sed -ri "s/^#?(ListenAddress) 0.0.0.0\$/\1 $IPV4/" $CONF
sed -ri "s/^#?(ListenAddress) 0.0.0.0\$/\1 ${IPV4}/" $CONF
else
sed -ri 's/^#?(ListenAddress) [0-9]{1,3}\..+$/#\1 0.0.0.0/' $CONF
fi
if [[ -n $IPV6 ]]; then
sed -ri "s/^#?(ListenAddress) ::\$/\1 $IPV6/" $CONF
sed -ri "s/^#?(ListenAddress) ::\$/\1 ${IPV6}/" $CONF
else
sed -ri 's/^#?(ListenAddress) [A-Fa-f0-9]{1,4}:.+$/#\1 ::/' $CONF
fi
/etc/rc.d/rc.sshd restart >/dev/null
# enable/disable SSH service
/etc/rc.d/rc.sshd stop >/dev/null
if [[ $USE_SSH == yes ]]; then
/etc/rc.d/rc.sshd start >/dev/null
fi
# update TELNET listening port
sed -ri "s/^(telnet\s+)[0-9]+\/(tcp|udp)\$/\1${PORTTELNET}\/\2/" $SERV
# bind/unbind TELNET service
if [[ -n $IPV4 ]]; then
BIND="$IPV4:"
fi
# enable/disable TELNET service
if [[ $USE_TELNET == yes ]]; then
sed -ri 's/^#?(telnet\s.*telnetd$)/\1/' $INET
sed -ri "s/^#?(.+:)?(telnet\s.+telnetd\$)/${BIND}\2/" $INET
else
sed -ri 's/^#?(telnet\s.*telnetd$)/#\1/' $INET
sed -ri 's/^#?(.+:)?(telnet\s.+telnetd$)/#\2/' $INET
fi
/etc/rc.d/rc.inetd restart >/dev/null

View File

@@ -20,7 +20,7 @@ i.title{display:none}
pre ul{margin:0;padding-top:0;padding-bottom:0;padding-left:28px}
pre li{margin:0;padding-top:0;padding-bottom:0;padding-left:18px}
big{font-size:15px;font-weight:bold;text-transform:uppercase}
hr{border-color:#F3F0F4}
hr{border:none;height:1px;color:#606E7F;background-color:#606E7F}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],input[type=file],textarea,.textarea{font-family:arimo;font-size:13px;background:transparent;border:1px solid #606E7F;padding:5px 10px;min-height:20px;line-height:20px;outline:none;width:304px;margin:0 20px 0 0;box-shadow:none;color:#606E7F}
input[type=button],input[type=reset],input[type=submit],button,a.button{font-family:arimo;font-size:13px;border:1px solid #9F9180;border-radius:5px;margin:10px 20px 10px 0;padding:8px 12px;cursor:pointer;outline:none;color:#9F9180;background:#EDEAEF}
input[type=checkbox]{vertical-align:middle;margin-right:6px}

View File

@@ -17,7 +17,7 @@ a.nohand{cursor:default}
i.spacing{margin-left:-6px}
i.icon{margin-right:4px}
i.title{margin-right:8px}
hr{border-color:rgba(255,255,255,0.25)}
hr{border:none;height:1px;color:#282828;background-color:#282828}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],input[type=file],textarea,.textarea{font-family:arimo;font-size:12px;color:#808080;background-color:#000000;border:1px solid #404040;border-radius:4px;padding:2px 8px;min-height:20px;line-height:20px;outline:none;width:301px;margin:0 10px 0 0;box-shadow:inset 1px 1px 5px #404040}
input[type=button],input[type=reset],input[type=submit],button,a.button{font-family:arimo;font-size:12px;border:1px solid #303030;border-radius:6px;margin:12px 14px 0 0;padding:5px 12px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;color:#808080;background:-webkit-radial-gradient(#505050,#181818);background:linear-gradient(#505050,#181818)}
input[type=checkbox]{vertical-align:middle;margin-right:6px}

View File

@@ -20,7 +20,7 @@ i.title{display:none}
pre ul{margin:0;padding-top:0;padding-bottom:0;padding-left:28px}
pre li{margin:0;padding-top:0;padding-bottom:0;padding-left:18px}
big{font-size:15px;font-weight:bold;text-transform:uppercase}
hr{border-color:#0C0F0B}
hr{border:none;height:1px;color:#606E7F;background-color:#606E7F}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],input[type=file],textarea,.textarea{font-family:arimo;font-size:13px;background:transparent;border:1px solid #606E7F;padding:5px 10px;min-height:20px;line-height:20px;outline:none;width:304px;margin:0 20px 0 0;box-shadow:none;color:#606E7F}
input[type=button],input[type=reset],input[type=submit],button,a.button{font-family:arimo;font-size:13px;border:1px solid #606E7F;border-radius:5px;margin:10px 20px 10px 0;padding:8px 12px;cursor:pointer;outline:none;color:#606E7F;background:#121510}
input[type=checkbox]{vertical-align:middle;margin-right:6px}

View File

@@ -17,7 +17,7 @@ a.nohand{cursor:default}
i.spacing{margin-left:-6px}
i.icon{margin-right:4px}
i.title{margin-right:8px}
hr{border-color:rgba(255,255,255,0.25)}
hr{border:none;height:1px;color:#E8E8E8;background-color:#E8E8E8}
input[type=text],input[type=password],input[type=number],input[type=url],input[type=email],input[type=date],input[type=file],textarea,.textarea{font-family:arimo;font-size:12px;color:#303030;background-color:#FFFFFF;border:1px solid #E0E0E0;border-radius:4px;padding:2px 8px;min-height:20px;line-height:20px;outline:none;width:301px;margin:0 10px 0 0;box-shadow:inset 1px 1px 5px #F0F0F0}
input[type=button],input[type=reset],input[type=submit],button,a.button{font-family:arimo;font-size:12px;border:1px solid #E8E8E8;border-radius:6px;margin:12px 14px 0 0;padding:5px 12px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;color:#303030;background:-webkit-radial-gradient(#F0F0F0,#C8C8C8);background:linear-gradient(#F0F0F0,#C8C8C8)}
input[type=checkbox]{vertical-align:middle;margin-right:6px}