mirror of
https://github.com/unraid/webgui.git
synced 2026-05-05 01:09:25 -05:00
Merge pull request #1067 from bergware/master
Change page switching to better suit Safari on mobile devices
This commit is contained in:
@@ -44,8 +44,6 @@ th.load{width:140px}
|
||||
input.wait{width:24px;margin:0 4px;padding:0 5px;border:none;box-shadow:none;background-color:transparent}
|
||||
table tbody td{line-height:normal}
|
||||
</style>
|
||||
<div id="iframe-popup" style="display:none;-webkit-overflow-scrolling:touch;"></div>
|
||||
<span class="status" style="margin-top:<?=$width?>px"><span><input type="checkbox" class="advancedview"></span></span>
|
||||
<table id="docker_containers" class="tablesorter shift">
|
||||
<thead><tr><th><a href="#" style="cursor:hand;margin-left:12px;display:inline-block;width:32px" onclick="resetSorting()" title="_(Reset sorting)_"><i class="fa fa-th-list"></i></a>_(Application)_</th><th>_(Version)_</th><th>_(Network)_</th><th>_(Port Mappings)_ <small>(_(App to Host)_)</small></th><th>_(Volume Mappings)_ <small>(_(App to Host)_)</small></th><th class="load advanced">_(CPU & Memory load)_</th><th class="nine">_(Autostart)_</th><th class="five">_(Uptime)_</th><th></th></tr></thead>
|
||||
<tbody id="docker_list"><tr><td colspan='9'></td></tr></tbody>
|
||||
@@ -58,6 +56,7 @@ table tbody td{line-height:normal}
|
||||
<input type="button" onclick="checkAll()" value="_(Check for Updates)_" id="checkAll" style="display:none">
|
||||
<input type="button" onclick="updateAll()" value="_(Update All)_" id="updateAll" style="display:none">
|
||||
<input type="button" onclick="sizes()" value="_(Container Size)_" style="display:none">
|
||||
<div id="iframe-popup" style="display:none;-webkit-overflow-scrolling:touch;"></div>
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
||||
<script src="<?autov('/plugins/dynamix.docker.manager/javascript/docker.js')?>"></script>
|
||||
@@ -68,16 +67,14 @@ $('#title').append("<span id='busy' class='red-text strong' style='display:none;
|
||||
$('.tabs').append("<span id='busy' class='red-text strong' style='display:none;position:relative;top:<?=$top?>px;left:40px;font-size:1.4rem;letter-spacing:2px'><?=$busy?></span>");
|
||||
<?endif;?>
|
||||
<?if ($display['resize']):?>
|
||||
function resize(bind) {
|
||||
function resize() {
|
||||
var width = [];
|
||||
var h = $('#docker_list').height();
|
||||
var s = Math.max(window.innerHeight-340,330);
|
||||
if (h>s || bind) {
|
||||
$('#docker_list').height(s);
|
||||
$('#docker_containers tbody tr:first-child td').each(function(){width.push($(this).width());});
|
||||
$('#docker_containers thead tr th').each(function(i){$(this).width(width[i]);});
|
||||
if (!bind) $('#docker_containers thead,#docker_containers tbody').addClass('fixed');
|
||||
}
|
||||
$('#docker_list').height(Math.max(window.innerHeight-340,330));
|
||||
$('#docker_containers thead,#docker_containers tbody').removeClass('fixed');
|
||||
$('#docker_containers tbody tr:first-child td').each(function(){width.push($(this).width());});
|
||||
$('#docker_containers thead tr th').each(function(i){$(this).width(width[i]);});
|
||||
$('#docker_containers tbody tr td').each(function(i){$(this).width(width[i]);});
|
||||
$('#docker_containers thead,#docker_containers tbody').addClass('fixed');
|
||||
}
|
||||
<?endif;?>
|
||||
function resetSorting() {
|
||||
@@ -99,7 +96,7 @@ var sortableHelper = function(e,i){
|
||||
});
|
||||
return i;
|
||||
};
|
||||
function loadlist() {
|
||||
function loadlist(init) {
|
||||
timers.docker = setTimeout(function(){$('div.spinner.fixed').show('slow');},500);
|
||||
$.get('/plugins/dynamix.docker.manager/include/DockerContainers.php',function(d) {
|
||||
clearTimeout(timers.docker);
|
||||
@@ -114,7 +111,7 @@ function loadlist() {
|
||||
$('head').append('<script>'+data[1]+'<\/script>');
|
||||
<?if ($display['resize']):?>
|
||||
resize();
|
||||
$(window).bind('resize',function(){resize(true);});
|
||||
if (init) $(window).bind('resize',function(){resize();});
|
||||
<?endif;?>
|
||||
$('.iconstatus').each(function(){
|
||||
if ($(this).hasClass('stopped')) $('div.'+$(this).prop('id')).hide();
|
||||
@@ -160,6 +157,7 @@ dockerload.on('message', function(msg){
|
||||
}
|
||||
});
|
||||
$(function() {
|
||||
$(".tabs").append('<span class="status"><span><input type="checkbox" class="advancedview"></span></span>');
|
||||
$('.advancedview').switchButton({labels_placement:'left', on_label:"_(Advanced View)_", off_label:"_(Basic View)_", checked:$.cookie('docker_listview_mode')=='advanced'});
|
||||
$('.advancedview').change(function(){
|
||||
$('.advanced').toggle('slow');
|
||||
@@ -167,7 +165,7 @@ $(function() {
|
||||
$.cookie('docker_listview_mode',$('.advancedview').is(':checked')?'advanced':'basic',{expires:3650});
|
||||
listview();
|
||||
});
|
||||
loadlist();
|
||||
loadlist(true);
|
||||
dockerload.start();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -950,21 +950,21 @@ _(Config Type)_:
|
||||
</select>
|
||||
|
||||
_(Name)_:
|
||||
: <input type="text" name="Name">
|
||||
: <input type="text" name="Name" autocomplete="off" spellcheck="false">
|
||||
|
||||
<div markdown="1" id="Target">
|
||||
<span id="dt1">_(Target)_</span>:
|
||||
: <input type="text" name="Target">
|
||||
: <input type="text" name="Target" autocomplete="off" spellcheck="false">
|
||||
</div>
|
||||
|
||||
<div markdown="1" id="Value">
|
||||
<span id="dt2">_(Value)_</span>:
|
||||
: <input type="text" name="Value">
|
||||
: <input type="text" name="Value" autocomplete="off" spellcheck="false">
|
||||
</div>
|
||||
|
||||
<div markdown="1" id="Default">
|
||||
_(Default Value)_:
|
||||
: <input type="text" name="Default">
|
||||
: <input type="text" name="Default" autocomplete="off" spellcheck="false">
|
||||
</div>
|
||||
|
||||
<div id="Mode"></div>
|
||||
|
||||
+64
-46
@@ -54,12 +54,13 @@ function iflink($eth) {
|
||||
function concat($array) {
|
||||
return implode(',',array_map(function($v){return "'$v'";},$array));
|
||||
}
|
||||
function readConf(&$peer_wg,&$wg,$vtun) {
|
||||
function readConf(&$peer_wg, &$wg, $vtun) {
|
||||
global $etc,$netbase,$netpool,$netbase6,$netpool6,$validIP4,$validIP6;
|
||||
$conf = "$etc/$vtun.conf";
|
||||
$cfg = "$etc/$vtun.cfg";
|
||||
$file = $vpn = false;
|
||||
if (file_exists($conf) && filesize($conf)>0) {
|
||||
$file = false;
|
||||
$vpn = 0;
|
||||
if (file_exists($conf) && filesize($conf) > 0) {
|
||||
$entries = array_filter(array_map('trim',preg_split('/\[(Interface|Peer)\]/',file_get_contents($conf))));
|
||||
foreach ($entries as $key => $entry) {
|
||||
$i = $key-1;
|
||||
@@ -121,8 +122,8 @@ function readConf(&$peer_wg,&$wg,$vtun) {
|
||||
$netbase[$vtun] = ip2long($netpool[$vtun]);
|
||||
$netbase6[$vtun] = $netpool6[$vtun];
|
||||
}
|
||||
foreach ($peer_wg as $i) if ((int)$wg["TYPE:$i"]==7) {$vpn = true; break;}
|
||||
return [$conf,$cfg,$file,$vpn];
|
||||
foreach ($peer_wg as $i) if ($wg["TYPE:$i"]>=7) {$vpn = $wg["TYPE:$i"]; break;}
|
||||
return [$conf, $cfg, $file, $vpn];
|
||||
}
|
||||
$public = $nginx['NGINX_WANFQDN'];
|
||||
$active = (array)explode(' ',exec('wg show interfaces'));
|
||||
@@ -280,10 +281,10 @@ if (!HTMLInputElement.prototype.reportValidity || (navigator.userAgent.indexOf("
|
||||
}
|
||||
|
||||
function ipv4(ip) {
|
||||
return ip.indexOf('.')>0;
|
||||
return ip.indexOf('.') > 0;
|
||||
}
|
||||
function ipv6(ip) {
|
||||
return ip.indexOf(':')>0;
|
||||
return ip.indexOf(':') > 0;
|
||||
}
|
||||
function ipset(ip) {
|
||||
return ipv4(ip) ? ip : '['+ip+']';
|
||||
@@ -323,7 +324,7 @@ function prepareSettings(form,vtun) {
|
||||
var mypool = netpool[vtun];
|
||||
var network6 = form.find('input[name="gui:Network6:0"]').val();
|
||||
var mypool6 = netpool6[vtun];
|
||||
var vpn = false;
|
||||
var vpn = 0;
|
||||
form.find('input[name="Network:0"]').val((network||mypool)+'/'+(form.find('input[name="gui:Mask:0"]').val()||24));
|
||||
form.find('input[name="Network6:0"]').val((network6||mypool6)+'/'+(form.find('input[name="gui:Mask6:0"]').val()||64));
|
||||
form.find('input[name^="Address:"]').each(function(){
|
||||
@@ -356,8 +357,8 @@ function prepareSettings(form,vtun) {
|
||||
form.find('input[name="#shared2"]').val(form.find('input[name="Network:0"]').val()+', '+hosts);
|
||||
break;
|
||||
}
|
||||
form.find('select[name^="TYPE:"]').each(function(){if($(this).val()==7){vpn=true;return false};});
|
||||
if (!vpn) form.find('input[name="ListenPort:0"]').val(listen);
|
||||
form.find('select[name^="TYPE:"]').each(function(){if($(this).val()>=7){vpn=$(this).val();return false};});
|
||||
if (vpn==0) form.find('input[name="ListenPort:0"]').val(listen);
|
||||
form.find('input[name^="gui:Endpoint:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[2];
|
||||
var endpoint = form.find('input[name="Endpoint:'+i+'"]');
|
||||
@@ -377,7 +378,7 @@ function prepareSettings(form,vtun) {
|
||||
<?if (!is_executable('/usr/bin/upnpc')):?>
|
||||
upnp.val('no');
|
||||
<?endif;?>
|
||||
if (!xml||vpn||upnp.val()=='no') {
|
||||
if (!xml||vpn > 0||upnp.val()=='no') {
|
||||
postup.prop('disabled',true);
|
||||
postdown.prop('disabled',true);
|
||||
} else {
|
||||
@@ -451,13 +452,13 @@ function prepareSettings(form,vtun) {
|
||||
}
|
||||
switch (protocol) {
|
||||
case '46':
|
||||
if (ip4.length>0) {
|
||||
if (ip4.length > 0) {
|
||||
postup1.push(postup3);
|
||||
postup1.push(ip4);
|
||||
postup1.push(postupZ.patch(source));
|
||||
postdown1.push(postdown3);
|
||||
}
|
||||
if (ip6.length>0) {
|
||||
if (ip6.length > 0) {
|
||||
postup16.push(postup36);
|
||||
postup16.push(ip6);
|
||||
postup16.push(postupZ6.patch(source6));
|
||||
@@ -469,7 +470,7 @@ function prepareSettings(form,vtun) {
|
||||
postdown.val(postdown1.bind(vtun));
|
||||
break;
|
||||
case '6':
|
||||
if (ip6.length>0) {
|
||||
if (ip6.length > 0) {
|
||||
postup16.push(postup36);
|
||||
postup16.push(ip6);
|
||||
postup16.push(postupZ6.patch(source6));
|
||||
@@ -479,7 +480,7 @@ function prepareSettings(form,vtun) {
|
||||
postdown.val(postdown16.bind(vtun));
|
||||
break;
|
||||
default:
|
||||
if (ip4.length>0) {
|
||||
if (ip4.length > 0) {
|
||||
postup1.push(postup3);
|
||||
postup1.push(ip4);
|
||||
postup1.push(postupZ.patch(source));
|
||||
@@ -489,6 +490,10 @@ function prepareSettings(form,vtun) {
|
||||
postdown.val(postdown1.bind(vtun));
|
||||
break;
|
||||
}
|
||||
$('div[id^="index-wg0-"]').each(function(){
|
||||
var temp = $(this).find('select[name^="TYPE:"]').val();
|
||||
if (temp >= 7) form.find('input[name="#type"]').val(temp);
|
||||
});
|
||||
if (!postup.val()) postup.prop('disabled',true);
|
||||
if (!postdown.val()) postdown.prop('disabled',true);
|
||||
}
|
||||
@@ -578,12 +583,12 @@ function addPeer(form,vtun) {
|
||||
$(this).attr('id','helpinfo'+i);
|
||||
var pin = $(this).prev();
|
||||
if (!pin.prop('nodeName')) pin = $(this).parent().prev();
|
||||
while (pin.prop('nodeName') && pin.prop('nodeName').search(/(table|dl)/i)==-1) pin = pin.prev();
|
||||
while (pin.prop('nodeName') && pin.prop('nodeName').search(/(table|dl)/i) == -1) pin = pin.prev();
|
||||
pin.find('tr:first,dt:last').each(function() {
|
||||
var node = $(this);
|
||||
var name = node.prop('nodeName').toLowerCase();
|
||||
if (name=='dt') {
|
||||
while (!node.html() || node.html().search(/(<input|<select|nbsp;)/i)>=0 || name!='dt') {
|
||||
while (!node.html() || node.html().search(/(<input|<select|nbsp;)/i) >= 0 || name!='dt') {
|
||||
if (name=='dt' && node.is(':first-of-type')) break;
|
||||
node = node.prev();
|
||||
name = node.prop('nodeName').toLowerCase();
|
||||
@@ -650,6 +655,7 @@ function updatePeer(form,i,n,vtun) {
|
||||
form.find('input[name="DNS:'+i+'"]').attr('placeholder',"(_(optional)_)").removeAttr('required');
|
||||
break;
|
||||
}
|
||||
form.find('#addpeer-'+vtun).prop('disabled',n>=7);
|
||||
var subnet = form.find('input[name="Address:'+i+'"]').val();
|
||||
var subnet6 = form.find('input[name="Address6:'+i+'"]').val();
|
||||
switch (protocol) {
|
||||
@@ -859,14 +865,14 @@ function setAllow(form,subnet,i) {
|
||||
var input = form.find('input[name="AllowedIPs:'+i+'"]');
|
||||
var type = form.find('select[name="TYPE:'+i+'"]').val();
|
||||
var prot = form.find('select[name="PROT:0"]').val();
|
||||
if (type!='7') {
|
||||
if (type < 7) {
|
||||
var list = input.val().replace(/ +/g,'').split(',');
|
||||
var n = prot=='46' ? 0 : (list.length>1 ? 2 : 1);
|
||||
var n = prot=='46' ? 0 : (list.length > 1 ? 2 : 1);
|
||||
list.splice(0,n);
|
||||
list.unshift(subnet);
|
||||
list = [...new Set(list)];
|
||||
list = list.filter(nodefault);
|
||||
if (n>0) list = list.filter(ipv4);
|
||||
if (n > 0) list = list.filter(ipv4);
|
||||
} else {
|
||||
var list = prot!='46' ? ['0.0.0.0/0'] : ['0.0.0.0/0','::/0'];
|
||||
}
|
||||
@@ -877,14 +883,14 @@ function setAllow6(form,subnet6,i) {
|
||||
var input = form.find('input[name="AllowedIPs:'+i+'"]');
|
||||
var type = form.find('select[name="TYPE:'+i+'"]').val();
|
||||
var prot = form.find('select[name="PROT:0"]').val();
|
||||
if (type!='7') {
|
||||
if (type < 7) {
|
||||
var list = input.val().replace(/ +/g,'').split(',');
|
||||
var n = prot=='46' ? 0 : (list.length>1 ? 2 : 1);
|
||||
var n = prot=='46' ? 0 : (list.length > 1 ? 2 : 1);
|
||||
list.splice(0,n);
|
||||
list.unshift(subnet6);
|
||||
list = [...new Set(list)];
|
||||
list = list.filter(nodefault6);
|
||||
if (n>0) list = list.filter(ipv6);
|
||||
if (n > 0) list = list.filter(ipv6);
|
||||
} else {
|
||||
var list = prot!='46' ? ['::/0'] : ['0.0.0.0/0','::/0'];
|
||||
}
|
||||
@@ -911,19 +917,19 @@ function highlight(form,input,i) {
|
||||
}
|
||||
function showRemark(form) {
|
||||
var upnp = form.find('select[name="UPNP:0"]').val();
|
||||
var vpn = false;
|
||||
form.find('select[name^="TYPE:"]').each(function(){vpn |= $(this).val()=='7';});
|
||||
if (upnp=='' || vpn) form.find('span.remark').hide(); else form.find('span.remark').show();
|
||||
if (upnp=='' && !vpn) form.find('span.upnp').show(); else form.find('span.upnp').hide();
|
||||
var vpn = 0;
|
||||
form.find('select[name^="TYPE:"]').each(function(){if ($(this).val()>=7 && vpn==0) vpn = $(this).val();});
|
||||
if (upnp=='' || vpn > 0) form.find('span.remark').hide(); else form.find('span.remark').show();
|
||||
if (upnp=='' && vpn < 7) form.find('span.upnp').show(); else form.find('span.upnp').hide();
|
||||
}
|
||||
function showRoute(form,vtun,i) {
|
||||
var nat = form.find('select[name="NAT:0"]').val();
|
||||
var vpn = false, lan = false;
|
||||
var vpn = 0, lan = false;
|
||||
form.find('select[name^="TYPE:"]').each(function(){
|
||||
vpn |= $(this).val()=='7';
|
||||
lan |= $(this).val()=='6' || $(this).val() % 2;
|
||||
if ($(this).val()>=7 && vpn==0) vpn = $(this).val();
|
||||
else lan |= $(this).val()=='6' || $(this).val() % 2;
|
||||
});
|
||||
if (nat=='no' && !vpn && lan) {
|
||||
if (nat=='no' && vpn==0 && lan) {
|
||||
$('span#my-static1-'+vtun).show();
|
||||
$('span#my-static2-'+vtun).hide();
|
||||
} else {
|
||||
@@ -934,7 +940,7 @@ function showRoute(form,vtun,i) {
|
||||
}
|
||||
function showAccess(form,i,n) {
|
||||
switch (n) {
|
||||
case '0':
|
||||
case '0':
|
||||
switch (form.find('select[name="PROT:0"]').val()) {
|
||||
case '6' : var peer_addr = form.find('input[name="Address6:0"]').val()+"</b>"; break;
|
||||
case '46': var peer_addr = form.find('input[name="Address:0"]').val()+"</b> _(or)_ <b>"+form.find('input[name="Address6:0"]').val()+"</b>"; break;
|
||||
@@ -956,6 +962,7 @@ function showAccess(form,i,n) {
|
||||
break;
|
||||
case '5': form.find('span#access-type-'+i).html("_(Remark)_: _(ensure the peer networks are different from)_ <b><?=exec("ip -4 route show dev $link scope link|awk '{print \$1;exit}'")?></b>"); break;
|
||||
case '7': form.find('span#access-type-'+i).html("_(Remark)_: _(this must be the only peer in the tunnel and sole active tunnel when in use)_"); break;
|
||||
case '8': form.find('span#access-type-'+i).html("_(Remark)_: _(VPN tunnel for docker containers only)_"); break;
|
||||
}
|
||||
}
|
||||
function portRemark(form,vtun,val) {
|
||||
@@ -1124,11 +1131,16 @@ $(function(){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var wg = $('#toggle-wg0').is(':checked') ? 'start' : 'stop';
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'toggle','#wg':wg,'#vtun':'wg0'},function(ok){
|
||||
var type = 0;
|
||||
$('div[id^="index-wg0-"]').each(function(){
|
||||
var temp = $(this).find('select[name^="TYPE:"]').val();
|
||||
if (temp >= 7 && type==0) type = temp;
|
||||
});
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'toggle','#wg':wg,'#vtun':'wg0','#type':type},function(ok){
|
||||
if (wg=='start') {
|
||||
if (ok) tstate['wg0']='active'; else $('#toggle-wg0').switchButton({checked:false});
|
||||
if (ok==0) tstate['wg0']='active'; else $('#toggle-wg0').switchButton({checked:false});
|
||||
} else {
|
||||
if (ok) tstate['wg0']=''; else $('#toggle-wg0').switchButton({checked:true});
|
||||
if (ok==0) tstate['wg0']=''; else $('#toggle-wg0').switchButton({checked:true});
|
||||
}
|
||||
<?if ($wg0['UPNP:0']===''):?>
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'upnpc','#xml':xml,'#vtun':'wg0','#link':'<?=$link?>','#ip':'<?=$server?>','#wg':tstate['wg0']},function(data){$('span.upnp.wg0').text(data);});
|
||||
@@ -1175,11 +1187,11 @@ $(function(){
|
||||
setProtocol(form,'wg0');
|
||||
form.find('input[name^="Address:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if (i>0) $(this).on('input change',function(){form.find('.ping-button1-'+i).prop('disabled',$(this).val()=='');});
|
||||
if (i > 0) $(this).on('input change',function(){form.find('.ping-button1-'+i).prop('disabled',$(this).val()=='');});
|
||||
});
|
||||
form.find('input[name^="Address6:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if (i>0) $(this).on('input change',function(){form.find('.ping-button6-'+i).prop('disabled',$(this).val()=='');});
|
||||
if (i > 0) $(this).on('input change',function(){form.find('.ping-button6-'+i).prop('disabled',$(this).val()=='');});
|
||||
});
|
||||
form.find('input[name^="gui:Endpoint:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[2];
|
||||
@@ -1196,15 +1208,18 @@ $(function(){
|
||||
} else {
|
||||
form.find('select[name="UPNP:0"]').val('no');
|
||||
}
|
||||
var vpn = false, lan = false
|
||||
var vpn = 0, lan = false
|
||||
form.find('select[name^="TYPE:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
vpn |= $(this).val()=='7';
|
||||
if ($(this).val()>=7 && vpn==0) vpn = $(this).val();
|
||||
lan |= $(this).val()=='6' || $(this).val() % 2;
|
||||
form.find('input[name="DNS:'+i+'"]').attr('placeholder',$(this).val()=='7' ? "(_(not used)_)" : "(_(optional)_)");
|
||||
form.find('input[name="DNS:'+i+'"]').attr('placeholder',$(this).val()>=7 ? "(_(not used)_)" : "(_(optional)_)");
|
||||
showAccess(form,i,$(this).val());
|
||||
});
|
||||
if (vpn) form.find('select[name="NAT:0"]').val('no').prop('disabled',true);
|
||||
if (vpn > 0) {
|
||||
form.find('select[name="NAT:0"]').val('no').prop('disabled',true);
|
||||
form.find('#addpeer-wg0').prop('disabled',true);
|
||||
}
|
||||
else if (form.find('select[name="NAT:0"]').val()=='no' && lan) $('span#my-static1-wg0').show();
|
||||
else if (lan) $('span#my-static2-wg0').show();
|
||||
<?if (file_exists($tmp)):?>
|
||||
@@ -1222,6 +1237,7 @@ $(function(){
|
||||
<input type="hidden" name="#cmd" value="update">
|
||||
<input type="hidden" name="#name" value="<?=$tower?>">
|
||||
<input type="hidden" name="#vtun" value="wg0">
|
||||
<input type="hidden" name="#type" value="0">
|
||||
<input type="hidden" name="#wg" value="">
|
||||
<input type="hidden" name="#internet" value="<?=$public?>">
|
||||
<input type="hidden" name="#subnets1" value="">
|
||||
@@ -1291,7 +1307,7 @@ _(Local tunnel address IPv6)_:
|
||||
</div>
|
||||
</div>
|
||||
_(Local endpoint)_:
|
||||
: <span class="input"><input type="text" id="endpoint-wg0" name="Endpoint:0" class="subnet" value="<?=$vpn_wg0?'':$wg0['Endpoint:0']?>" onchange="toLC(this);quickValidate(this);" pattern="<?=$validText?>" title="_(IP address or FQDN)_" placeholder="<?=$vpn_wg0?'(not used)':preg_replace('/^(.+?\.)[0-9a-zA-Z]+(\.(my)?unraid.net)$/','$1<hash>$2',$public)?>">:
|
||||
: <span class="input"><input type="text" id="endpoint-wg0" name="Endpoint:0" class="subnet" value="<?=$vpn_wg0?'':$wg0['Endpoint:0']?>" onchange="toLC(this);quickValidate(this);" pattern="<?=$validText?>" title="_(IP address or FQDN)_" placeholder="<?=$vpn_wg0?'(_(not used)_)':preg_replace('/^(.+?\.)[0-9a-zA-Z]+(\.(my)?unraid.net)$/','$1<hash>$2',$public)?>">:
|
||||
<input type="number" name="gui:ListenPort:0" class="port" min="1" max="65535" value="<?=$vpn_wg0?'':$wg0['ListenPort:0']?>" onchange="if(quickValidate(this)) {portRemark($(document.wg0),'wg0',this.value)}" placeholder="<?=$vpn_wg0?'':$netport['wg0']?>"></span>
|
||||
<span class="remark block" style="display:none">_(Remark)_: _(configure your router with port forwarding of port)_ **<span id="my-port-wg0"><?=$wg0['ListenPort:0']?:$netport['wg0']?></span>/_(UDP)_** _(to)_ **<?=$server?>:<?=$wg0['ListenPort:0']?:$netport['wg0']?>**</span><span class="upnp wg0 block"></span>
|
||||
<input type="hidden" name="ListenPort:0" value=""><dl id="endpoint4-wg0" style="display:none"></dl><dl id="endpoint6-wg0" style="display:none"></dl>
|
||||
@@ -1354,7 +1370,7 @@ _(DNS servers)_:
|
||||
_(Peer name)_:
|
||||
: <span class="input"><input type="text" name="Name:<?=$i?>" class="wide" maxlength="99" value="<?=$wg0["Name:$i"]??''?>" onchange="quickValidate(this);" pattern="<?=$validname?>" title="_(Use only letters A-Z, digits or space,dash,underscore)_" placeholder="(_(optional)_)"></span>
|
||||
<input type="button" class="form" value="_(Delete Peer)_" onclick="delPeer($(document.wg0),'#index-wg0-<?=$i?>')">
|
||||
<span class="pin"><i class="fa fa-fw fa-eye eye<?=$i?><?=(file_exists("$etc/peers/peer-$tower-wg0-$i.conf")&&(int)$wg0["TYPE:$i"]!=7)?'':' key-off'?>" style="cursor:pointer" onclick="WGconfig(this,'peer-<?=$tower?>-wg0-<?=$i?>','/peers')" title="_(View Peer Config)_"></i>
|
||||
<span class="pin"><i class="fa fa-fw fa-eye eye<?=$i?><?=(file_exists("$etc/peers/peer-$tower-wg0-$i.conf")&&$wg0["TYPE:$i"]<=6)?'':' key-off'?>" style="cursor:pointer" onclick="WGconfig(this,'peer-<?=$tower?>-wg0-<?=$i?>','/peers')" title="_(View Peer Config)_"></i>
|
||||
<i class="fa fa-fw fa-key zone<?=$i?><?=$wg0["PublicKey:$i"]?'':' key-off'?>" style="cursor:pointer" onclick="openClose($(document.wg0),null,'div.key<?=$i?>')" title="_(Toggle keys)_"></i>
|
||||
<i id="chevron-wg0-<?=$i?>" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="openClose($(document.wg0),this,'div.zone<?=$i?>')" title="_(Toggle view)_"></i></span>
|
||||
|
||||
@@ -1369,7 +1385,8 @@ _(Peer type of access)_:
|
||||
<?=mk_option($wg0["TYPE:$i"], "4", _("Server hub & spoke access"))?>
|
||||
<?=mk_option($wg0["TYPE:$i"], "5", _("LAN hub & spoke access"))?>
|
||||
<?=mk_option($wg0["TYPE:$i"], "6", _("Remote tunneled access"))?>
|
||||
<?=mk_option($wg0["TYPE:$i"], "7", _("VPN tunneled access"),count($peer_wg0)==1?'':'disabled')?>
|
||||
<?=mk_option($wg0["TYPE:$i"], "7", _("VPN tunneled access for system"),count($peer_wg0)==1?'':'disabled')?>
|
||||
<?=mk_option($wg0["TYPE:$i"], "8", _("VPN tunneled access for docker"),count($peer_wg0)==1?'':'disabled')?>
|
||||
</select></span>
|
||||
<span id="access-type-<?=$i?>" class="access-type"></span>
|
||||
|
||||
@@ -1440,7 +1457,7 @@ _(Persistent keepalive)_:
|
||||
<?endforeach;?>
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" onclick="return(validateForm($(document.wg0),'wg0'))" disabled><input type="button" value="_(Done)_" onclick="done()"><input type="button" value="_(Add Peer)_" onclick="addPeer($(document.wg0),'wg0')">
|
||||
: <input type="submit" value="_(Apply)_" onclick="return(validateForm($(document.wg0),'wg0'))" disabled><input type="button" value="_(Done)_" onclick="done()"><input type="button" id="addpeer-wg0" value="_(Add Peer)_" onclick="addPeer($(document.wg0),'wg0')">
|
||||
<input type="button" class="advanced wg0" value="_(Delete Tunnel)_" style="float:right;display:none" onclick="delTunnel('wg0')"<?=file_exists($conf_wg0)?'':' disabled'?>>
|
||||
</form>
|
||||
<small style="position:absolute;left:10px;top:30px">"WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfield</small>
|
||||
@@ -1464,7 +1481,8 @@ _(Peer type of access)_:
|
||||
<?=mk_option(0, "4", _("Server hub & spoke access"))?>
|
||||
<?=mk_option(0, "5", _("LAN hub & spoke access"))?>
|
||||
<?=mk_option(0, "6", _("Remote tunneled access"))?>
|
||||
<?=mk_option(0, "7", _("VPN tunneled access"),'disabled')?>
|
||||
<?=mk_option(0, "7", _("VPN tunneled access for system"),'disabled')?>
|
||||
<?=mk_option(0, "8", _("VPN tunneled access for docker"),'disabled')?>
|
||||
</select></span>
|
||||
<span id="access-type-INDEX" class="access-type"></span>
|
||||
|
||||
|
||||
+28
-17
@@ -3,8 +3,8 @@ Title="Tunnel wgX"
|
||||
Tag="icon-vpn"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, Bergware International.
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -24,7 +24,7 @@ $netpool6['wgX'] = str_replace(':0:0:',':XXX:0:',$netpool6['wg0']);
|
||||
$netport['wgX'] = $netport['wg0']+XXX;
|
||||
|
||||
// read current configuration
|
||||
[$conf_wgX,$cfg_wgX,$this_wgX,$vpn_wgX] = readConf($peer_wgX,$wgX,'wgX');
|
||||
[$conf_wgX, $cfg_wgX, $this_wgX, $vpn_wgX] = readConf($peer_wgX, $wgX, 'wgX');
|
||||
?>
|
||||
<script>
|
||||
netbase['wgX'] = <?=$netbase['wgX']?>;
|
||||
@@ -54,11 +54,16 @@ $(function(){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var wg = $('#toggle-wgX').is(':checked') ? 'start' : 'stop';
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'toggle','#wg':wg,'#vtun':'wgX'},function(ok){
|
||||
var type = 0;
|
||||
$('div[id^="index-wgX-"]').each(function(){
|
||||
var temp = $(this).find('select[name^="TYPE:"]').val();
|
||||
if (temp >= 7 && type==0) type = temp;
|
||||
});
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'toggle','#wg':wg,'#vtun':'wgX','#type':type},function(ok){
|
||||
if (wg=='start') {
|
||||
if (ok) tstate['wgX']='active'; else $('#toggle-wgX').switchButton({checked:false});
|
||||
if (ok==0) tstate['wgX']='active'; else $('#toggle-wgX').switchButton({checked:false});
|
||||
} else {
|
||||
if (ok) tstate['wgX']=''; else $('#toggle-wgX').switchButton({checked:true});
|
||||
if (ok==0) tstate['wgX']=''; else $('#toggle-wgX').switchButton({checked:true});
|
||||
}
|
||||
<?if ($wgX['UPNP:0']===''):?>
|
||||
$.post('/webGui/include/update.wireguard.php',{'#cmd':'upnpc','#xml':xml,'#vtun':'wgX','#link':'<?=$link?>','#ip':'<?=$server?>','#wg':tstate['wgX']},function(data){$('span.upnp.wgX').text(data);});
|
||||
@@ -105,11 +110,11 @@ $(function(){
|
||||
setProtocol(form,'wgX');
|
||||
form.find('input[name^="Address:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if (i>0) $(this).on('input change',function(){form.find('#ping-button1-'+i).prop('disabled',$(this).val()=='');});
|
||||
if (i > 0) $(this).on('input change',function(){form.find('#ping-button1-'+i).prop('disabled',$(this).val()=='');});
|
||||
});
|
||||
form.find('input[name^="Address6:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
if (i>0) $(this).on('input change',function(){form.find('.ping-button6-'+i).prop('disabled',$(this).val()=='');});
|
||||
if (i > 0) $(this).on('input change',function(){form.find('.ping-button6-'+i).prop('disabled',$(this).val()=='');});
|
||||
});
|
||||
form.find('input[name^="gui:Endpoint:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[2];
|
||||
@@ -126,15 +131,18 @@ $(function(){
|
||||
} else {
|
||||
form.find('select[name="UPNP:0"]').val('no');
|
||||
}
|
||||
var vpn = false, lan = false
|
||||
var vpn = 0, lan = false
|
||||
form.find('select[name^="TYPE:"]').each(function(){
|
||||
var i = $(this).attr('name').split(':')[1];
|
||||
vpn |= $(this).val()=='7';
|
||||
if ($(this).val()>=7 && vpn==0) vpn = $(this).val();
|
||||
lan |= $(this).val()=='6' || $(this).val() % 2;
|
||||
form.find('input[name="DNS:'+i+'"]').attr('placeholder',$(this).val()=='7' ? "(_(not used)_)" : "(_(optional)_)");
|
||||
form.find('input[name="DNS:'+i+'"]').attr('placeholder',$(this).val()>=7 ? "(_(not used)_)" : "(_(optional)_)");
|
||||
showAccess(form,i,$(this).val());
|
||||
});
|
||||
if (vpn) form.find('select[name="NAT:0"]').val('no').prop('disabled',true);
|
||||
if (vpn > 0) {
|
||||
form.find('select[name="NAT:0"]').val('no').prop('disabled',true);
|
||||
form.find('#addpeer-wgX').prop('disabled',true);
|
||||
}
|
||||
else if (form.find('select[name="NAT:0"]').val()=='no' && lan) $('span#my-static1-wgX').show();
|
||||
else if (lan) $('span#my-static2-wgX').show();
|
||||
});
|
||||
@@ -147,6 +155,7 @@ $(function(){
|
||||
<input type="hidden" name="#cmd" value="update">
|
||||
<input type="hidden" name="#name" value="<?=$tower?>">
|
||||
<input type="hidden" name="#vtun" value="wgX">
|
||||
<input type="hidden" name="#type" value="0">
|
||||
<input type="hidden" name="#wg" value="">
|
||||
<input type="hidden" name="#internet" value="<?=$public?>">
|
||||
<input type="hidden" name="#subnets1" value="">
|
||||
@@ -216,7 +225,7 @@ _(Local tunnel address IPv6)_:
|
||||
</div>
|
||||
</div>
|
||||
_(Local endpoint)_:
|
||||
: <span class="input"><input type="text" id="endpoint-wgX" name="Endpoint:0" class="subnet" value="<?=$vpn_wgX?'':$wgX['Endpoint:0']?>" onchange="toLC(this);quickValidate(this);" pattern="<?=$validText?>" title="_(IP address or FQDN)_" placeholder="<?=$vpn_wgX?'(not used)':preg_replace('/^(www\.).+(\.unraid.net)$/','$1<hash>$2',$public)?>">:
|
||||
: <span class="input"><input type="text" id="endpoint-wgX" name="Endpoint:0" class="subnet" value="<?=$vpn_wgX?'':$wgX['Endpoint:0']?>" onchange="toLC(this);quickValidate(this);" pattern="<?=$validText?>" title="_(IP address or FQDN)_" placeholder="<?=$vpn_wgX?'(_(not used)_)':preg_replace('/^(www\.).+(\.unraid.net)$/','$1<hash>$2',$public)?>">:
|
||||
<input type="number" name="gui:ListenPort:0" class="port" min="1" max="65535" value="<?=$vpn_wgX?'':$wgX['ListenPort:0']?>" onchange="if(quickValidate(this)) {portRemark($(document.wgX),'wgX',this.value)}" placeholder="<?=$vpn_wgX?'':$netport['wgX']?>"></span>
|
||||
<span class="remark block" style="display:none">_(Remark)_: _(configure your router with port forwarding of port)_ **<span id="my-port-wgX"><?=$wgX['ListenPort:0']?:$netport['wgX']?></span>/_(UDP)_** _(to)_ **<?=$server?>:<?=$wgX['ListenPort:0']?:$netport['wgX']?>**</span><span class="upnp wgX block"></span>
|
||||
<input type="hidden" name="ListenPort:0" value=""><dl id="endpoint4-wgX" style="display:none"></dl><dl id="endpoint6-wgX" style="display:none"></dl>
|
||||
@@ -279,7 +288,7 @@ _(DNS servers)_:
|
||||
_(Peer name)_:
|
||||
: <span class="input"><input type="text" name="Name:<?=$i?>" class="wide" maxlength="99" value="<?=$wgX["Name:$i"]??''?>" onchange="quickValidate(this);" pattern="<?=$validname?>" title="_(Use only letters A-Z, digits or space,dash,underscore)_" placeholder="(_(optional)_)"></span>
|
||||
<input type="button" class="form" value="_(Delete Peer)_" onclick="delPeer($(document.wgX),'#index-wgX-<?=$i?>')">
|
||||
<span class="pin"><i class="fa fa-fw fa-eye eye<?=$i?><?=(file_exists("$etc/peers/peer-$tower-wgX-$i.conf")&&(int)$wgX["TYPE:$i"]!=7)?'':' key-off'?>" style="cursor:pointer" onclick="WGconfig(this,'peer-<?=$tower?>-wgX-<?=$i?>','/peers')" title="_(View Peer Config)_"></i>
|
||||
<span class="pin"><i class="fa fa-fw fa-eye eye<?=$i?><?=(file_exists("$etc/peers/peer-$tower-wgX-$i.conf")&&$wgX["TYPE:$i"]<=6)?'':' key-off'?>" style="cursor:pointer" onclick="WGconfig(this,'peer-<?=$tower?>-wgX-<?=$i?>','/peers')" title="_(View Peer Config)_"></i>
|
||||
<i class="fa fa-fw fa-key zone<?=$i?><?=$wgX["PublicKey:$i"]?'':' key-off'?>" style="cursor:pointer" onclick="openClose($(document.wgX),null,'div.key<?=$i?>')" title="_(Toggle keys)_"></i>
|
||||
<i id="chevron-wgX-<?=$i?>" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="openClose($(document.wgX),this,'div.zone<?=$i?>')" title="_(Toggle view)_"></i></span>
|
||||
|
||||
@@ -294,7 +303,8 @@ _(Peer type of access)_:
|
||||
<?=mk_option($wgX["TYPE:$i"], "4", _("Server hub & spoke access"))?>
|
||||
<?=mk_option($wgX["TYPE:$i"], "5", _("LAN hub & spoke access"))?>
|
||||
<?=mk_option($wgX["TYPE:$i"], "6", _("Remote tunneled access"))?>
|
||||
<?=mk_option($wgX["TYPE:$i"], "7", _("VPN tunneled access"),count($peer_wgX)==1?'':'disabled')?>
|
||||
<?=mk_option($wgX["TYPE:$i"], "7", _("VPN tunneled access for system"),count($peer_wgX)==1?'':'disabled')?>
|
||||
<?=mk_option($wgX["TYPE:$i"], "8", _("VPN tunneled access for docker"))?>
|
||||
</select></span>
|
||||
<span id="access-type-<?=$i?>" class="access-type"></span>
|
||||
|
||||
@@ -365,7 +375,7 @@ _(Persistent keepalive)_:
|
||||
<?endforeach;?>
|
||||
|
||||
|
||||
: <input type="submit" value="_(Apply)_" onclick="return(validateForm($(document.wgX),'wgX'))" disabled><input type="button" value="_(Done)_" onclick="done()"><input type="button" value="_(Add Peer)_" onclick="addPeer($(document.wgX),'wgX')"><input type="button" class="advanced wgX" value="_(Delete Tunnel)_" style="float:right;display:none" onclick="delTunnel('wgX')">
|
||||
: <input type="submit" value="_(Apply)_" onclick="return(validateForm($(document.wgX),'wgX'))" disabled><input type="button" value="_(Done)_" onclick="done()"><input type="button" id="addpeer-wgX" value="_(Add Peer)_" onclick="addPeer($(document.wgX),'wgX')"><input type="button" class="advanced wgX" value="_(Delete Tunnel)_" style="float:right;display:none" onclick="delTunnel('wgX')">
|
||||
</form>
|
||||
|
||||
<script markdown="1" type="text/html" id="peer-template-wgX">
|
||||
@@ -387,7 +397,8 @@ _(Peer type of access)_:
|
||||
<?=mk_option(0, "4", _("Server hub & spoke access"))?>
|
||||
<?=mk_option(0, "5", _("LAN hub & spoke access"))?>
|
||||
<?=mk_option(0, "6", _("Remote tunneled access"))?>
|
||||
<?=mk_option(0, "7", _("VPN tunneled access"),'disabled')?>
|
||||
<?=mk_option(0, "7", _("VPN tunneled access for system"),'disabled')?>
|
||||
<?=mk_option(0, "8", _("VPN tunneled access for docker"))?>
|
||||
</select></span>
|
||||
<span id="access-type-INDEX" class="access-type"></span>
|
||||
|
||||
|
||||
@@ -161,9 +161,10 @@ function refresh(top) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
function initab() {
|
||||
function initab(page) {
|
||||
$.removeCookie('one');
|
||||
$.removeCookie('tab');
|
||||
if (page != null) location.replace(page);
|
||||
}
|
||||
function settab(tab) {
|
||||
<?switch ($myPage['name']):?>
|
||||
@@ -421,7 +422,7 @@ foreach ($tasks as $button) {
|
||||
$page = $button['name'];
|
||||
echo "<div id='nav-item'";
|
||||
echo $task==$page ? " class='active'>" : ">";
|
||||
echo "<a href=\"/$page\" onclick='initab();window.location=\"/$page\"'>"._($button['Name'] ?? $page)."</a></div>";
|
||||
echo "<a href=\"/$page\" onclick=\"initab('/$page')\">"._($button['Name'] ?? $page)."</a></div>";
|
||||
// create list of nchan scripts to be started
|
||||
if (isset($button['Nchan'])) nchan_merge($button['root'], $button['Nchan']);
|
||||
}
|
||||
|
||||
@@ -19,37 +19,90 @@ if (!isset($_SESSION['locale'])) $_SESSION['locale'] = $_POST['#locale'];
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
|
||||
$etc = '/etc/wireguard';
|
||||
$validIP4 = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}";
|
||||
$validIP6 = "(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(:|([0-9a-fA-F]{1,4}:)+):(([0-9a-fA-F]{1,4}:)*[0-9a-fA-F]{1,4})?)";
|
||||
$dockerd = is_file('/var/run/dockerd.pid') && is_dir('/proc/'.file_get_contents('/var/run/dockerd.pid'));
|
||||
$etc = '/etc/wireguard';
|
||||
$validIP4 = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}";
|
||||
$validIP6 = "(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(:|([0-9a-fA-F]{1,4}:)+):(([0-9a-fA-F]{1,4}:)*[0-9a-fA-F]{1,4})?)";
|
||||
$normalize = ['address'=>'Address', 'dns'=>'DNS', 'privatekey'=>'PrivateKey', 'publickey'=>'PublicKey', 'allowedips'=>'AllowedIPs', 'endpoint'=>'Endpoint'];
|
||||
$dockernet = "172.31";
|
||||
|
||||
$t1 = '6'; // 6 sec timeout
|
||||
$t2 = '12'; // 12 sec timeout
|
||||
$t1 = '10'; // 10 sec timeout
|
||||
$t2 = '15'; // 15 sec timeout
|
||||
|
||||
function mask2cidr($mask) {
|
||||
$long = ip2long($mask);
|
||||
$base = ip2long('255.255.255.255');
|
||||
return 32-log(($long ^ $base)+1,2);
|
||||
}
|
||||
function ipv4($ip) {
|
||||
return strpos($ip,'.')!==false;
|
||||
return strpos($ip,':')===false;
|
||||
}
|
||||
function ipv6($ip) {
|
||||
return strpos($ip,':')!==false;
|
||||
}
|
||||
function ipset($ip) {
|
||||
return ipv4($ip) ? $ip : "[$ip]";
|
||||
}
|
||||
function ipv6($ip) {
|
||||
function ipsplit($ip) {
|
||||
return ipv4($ip) ? ':' : ']:';
|
||||
}
|
||||
function ipfilter(&$list) {
|
||||
// we only import IPv4 addresses at this moment, strip any IPv6 addresses
|
||||
$list = implode(', ',array_filter(array_map('trim',explode(',',$list)),'ipv4'));
|
||||
}
|
||||
function host($ip) {
|
||||
return strpos($ip,'/')!==false ? $ip : (ipv4($ip) ? "$ip/32" : "$ip/128");
|
||||
}
|
||||
function wgState($vtun, $state, $type=0) {
|
||||
global $t1;
|
||||
$tmp = '/tmp/wg-quick.tmp';
|
||||
exec("timeout $t1 wg-quick $state $vtun 2>$tmp");
|
||||
$table = exec("grep -Pom1 'fwmark \K[\d]+' $tmp");
|
||||
delete_file($tmp);
|
||||
if ($type==8) {
|
||||
// make VPN tunneled access for Docker containers only
|
||||
$route = exec("grep -Pom1 '^Address=\K.+$' /etc/wireguard/$vtun.conf");
|
||||
sleep(3);
|
||||
// remove default route and set local route instead
|
||||
exec("ip -4 route flush table $table");
|
||||
exec("ip -4 route add $route dev $vtun table $table");
|
||||
}
|
||||
}
|
||||
function status($vtun) {
|
||||
return strpos(exec("wg show interfaces|tr '\n' ' '"),"$vtun ")===false;
|
||||
return in_array($vtun,explode(" ",exec("wg show interfaces")));
|
||||
}
|
||||
function vtun() {
|
||||
global $etc;
|
||||
$x = 0; while (file_exists("$etc/wg{$x}.conf")) $x++;
|
||||
return "wg{$x}";
|
||||
}
|
||||
function normalize(&$id) {
|
||||
// ensure correct capitalization of keywords, some VPN providers use the wrong case
|
||||
global $normalize;
|
||||
$id = $normalize[strtolower($id)];
|
||||
}
|
||||
function addDocker($vtun) {
|
||||
global $dockerd, $dockernet;
|
||||
// create a docker network for the WG tunnel, containers can select this network for communication
|
||||
if ($dockerd && !exec("docker network ls --filter name='$vtun' --format='{{.Name}}'")) {
|
||||
$index = substr($vtun,2)+200;
|
||||
$network = "$dockernet.$index.0/24";
|
||||
exec("docker network create $vtun --subnet=$network 2>/dev/null");
|
||||
}
|
||||
}
|
||||
function delDocker($vtun) {
|
||||
global $dockerd, $dockernet;
|
||||
// delete the docker network, containers using this network need to be reconfigured
|
||||
if ($dockerd && exec("docker network ls --filter name='$vtun' --format='{{.Name}}'")) {
|
||||
$index = substr($vtun,2)+200;
|
||||
$network = "$dockernet.$index.0/24";
|
||||
exec("docker network rm $vtun 2>/dev/null");
|
||||
}
|
||||
}
|
||||
function delPeer($vtun, $id='') {
|
||||
global $etc,$name;
|
||||
$dir = "$etc/peers";
|
||||
foreach (glob("$dir/peer-$name-$vtun-$id*",GLOB_NOSORT) as $peer) unlink($peer);
|
||||
foreach (glob("$dir/peer-$name-$vtun-$id*",GLOB_NOSORT) as $peer) delete_file($peer);
|
||||
}
|
||||
function addPeer(&$x) {
|
||||
global $peers,$var;
|
||||
@@ -118,7 +171,7 @@ function createPeerFiles($vtun) {
|
||||
$cfg = "$dir/peer-$name-$vtun-$id.conf";
|
||||
$cfgold = @file_get_contents($cfg) ?: '';
|
||||
$cfgnew = implode("\n",$peer)."\n";
|
||||
if ($cfgnew !== $cfgold && !$vpn) {
|
||||
if ($cfgnew !== $cfgold && $vpn==0) {
|
||||
$list[] = "$vtun: peer $id (".($peer[1][0]=='#' ? substr($peer[1],1) : _('no name')).')';
|
||||
file_put_contents($cfg,$cfgnew);
|
||||
$png = str_replace('.conf','.png',$cfg);
|
||||
@@ -126,17 +179,30 @@ function createPeerFiles($vtun) {
|
||||
}
|
||||
}
|
||||
// store the peer names which are updated
|
||||
if (count($list)) file_put_contents($tmp,implode("<br>",$list)); else @unlink($tmp);
|
||||
if (count($list)) file_put_contents($tmp,implode("<br>",$list)); else delete_file($tmp);
|
||||
}
|
||||
function parseInput(&$input,&$x) {
|
||||
global $conf,$user,$var,$default,$default6,$vpn;
|
||||
function parseInput(&$input,&$x,$vtun) {
|
||||
global $conf,$user,$var,$default,$default6,$vpn,$dockernet;
|
||||
$section = 0; $addPeer = false;
|
||||
foreach ($input as $key => $value) {
|
||||
if ($key[0]=='#') continue;
|
||||
[$id,$i] = my_explode(':',$key);
|
||||
if ($i != $section) {
|
||||
if ($section==0) {
|
||||
// add WG routing for docker containers. Only IPv4 supported
|
||||
extract(parse_ini_file('state/network.ini',true));
|
||||
$index = substr($vtun,2)+200;
|
||||
$network = "$dockernet.$index.0/24";
|
||||
$thisnet = long2ip(ip2long($eth0['IPADDR:0']) & ip2long($eth0['NETMASK:0'])).'/'.mask2cidr($eth0['NETMASK:0']);
|
||||
$gateway = $eth0['GATEWAY:0'];
|
||||
$conf[] = "PostUp=ip -4 rule add from $network table $index";
|
||||
$conf[] = "PostUp=ip -4 route add default via $tunip table $index";
|
||||
$conf[] = "PostUp=ip -4 route add $thisnet via $gateway table $index";
|
||||
$conf[] = "PostDown=ip -4 route flush table $index";
|
||||
$conf[] = "PostDown=ip -4 rule del from $network table $index";
|
||||
}
|
||||
$conf[] = "\n[Peer]";
|
||||
// add peers only for peer sections
|
||||
// add peers, this is only used for peer sections
|
||||
$addPeer ? addPeer($x) : $addPeer = true;
|
||||
$section = $i;
|
||||
}
|
||||
@@ -166,7 +232,7 @@ function parseInput(&$input,&$x) {
|
||||
}
|
||||
break;
|
||||
case 'DNS':
|
||||
if ($i>0 && $value) {
|
||||
if ($i > 0 && $value) {
|
||||
$user[] = "$id:$x=\"$value\"";
|
||||
$var['dns'] = "$id=$value";
|
||||
} else $var['dns'] = false;
|
||||
@@ -185,7 +251,7 @@ function parseInput(&$input,&$x) {
|
||||
$var['allowedIPs'] = implode(', ',array_map('host',array_filter($list)));
|
||||
$var['tunnel'] = ($value==2||$value==3) ? $tunnel : false;
|
||||
$user[] = "$id:$x=\"$value\"";
|
||||
if ($value==7) $vpn = true;
|
||||
if ($value>=7) $vpn = $value;
|
||||
break;
|
||||
case 'Network':
|
||||
case 'Network6':
|
||||
@@ -200,6 +266,7 @@ function parseInput(&$input,&$x) {
|
||||
if ($i==0) {
|
||||
$conf[] = "$id=$value";
|
||||
$tunnel = "$id=$hosts";
|
||||
$tunip = $value;
|
||||
} else {
|
||||
$user[] = "$id:$x=\"$value\"";
|
||||
$var['address'] = "$id=$hosts";
|
||||
@@ -215,8 +282,8 @@ function parseInput(&$input,&$x) {
|
||||
$var['endpoint'] = $value ? "Endpoint=".ipset($value) : false;
|
||||
} else {
|
||||
if ($value) $conf[] = "$id=$value";
|
||||
$var['listenport'] = $value ? "ListenPort=".explode(ipv6($value),$value)[1] : false;
|
||||
if ($var['endpoint'] && strpos($var['endpoint'],ipv6($var['endpoint']))===false) $var['endpoint'] .= ":".explode(ipv6($var['internet']),$var['internet'])[1];
|
||||
$var['listenport'] = $value ? "ListenPort=".explode(ipsplit($value),$value)[1] : false;
|
||||
if ($var['endpoint'] && strpos($var['endpoint'],ipsplit($var['endpoint']))===false) $var['endpoint'] .= ":".explode(ipsplit($var['internet']),$var['internet'])[1];
|
||||
}
|
||||
break;
|
||||
case 'PersistentKeepalive':
|
||||
@@ -263,32 +330,34 @@ case 'update':
|
||||
$var['shared1'] = "AllowedIPs=".implode(', ',(array_unique(explode(', ',$_POST['#shared1']))));
|
||||
$var['shared2'] = "AllowedIPs=".implode(', ',(array_unique(explode(', ',$_POST['#shared2']))));
|
||||
$var['internet'] = "Endpoint=".implode(', ',(array_unique(explode(', ',$_POST['#internet']))));
|
||||
$x = 1; $vpn = false;
|
||||
parseInput($_POST,$x);
|
||||
$x = 1; $vpn = 0;
|
||||
parseInput($_POST,$x,$vtun);
|
||||
addPeer($x);
|
||||
exec("wg-quick down $vtun 2>/dev/null");
|
||||
addDocker($vtun);
|
||||
$upstate = status($vtun);
|
||||
wgState($vtun,'down');
|
||||
file_put_contents($file,implode("\n",$conf)."\n");
|
||||
file_put_contents($cfg,implode("\n",$user)."\n");
|
||||
createPeerFiles($vtun);
|
||||
if ($wg) exec("wg-quick up $vtun >/dev/null");
|
||||
if ($upstate) wgState($vtun,'up',$_POST['#type']);
|
||||
$save = false;
|
||||
break;
|
||||
case 'toggle':
|
||||
$vtun = $_POST['#vtun'];
|
||||
switch ($_POST['#wg']) {
|
||||
case 'stop':
|
||||
exec("timeout $t1 wg-quick down $vtun 2>/dev/null");
|
||||
wgState($vtun,'down');
|
||||
echo status($vtun) ? 1 : 0;
|
||||
break;
|
||||
case 'start':
|
||||
exec("timeout $t1 wg-quick up $vtun 2>/dev/null");
|
||||
wgState($vtun,'up',$_POST['#type']);
|
||||
echo status($vtun) ? 0 : 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'ping':
|
||||
$addr = $_POST['#addr'];
|
||||
echo exec("ping -qc1 -W4 $addr|grep -Po '1 received'");
|
||||
echo exec("ping -qc1 -W4 $addr|grep -Pom1 '1 received'");
|
||||
break;
|
||||
case 'public':
|
||||
$ip = $_POST['#ip'];
|
||||
@@ -305,18 +374,18 @@ case 'addtunnel':
|
||||
$vtun = vtun();
|
||||
$name = $_POST['#name'];
|
||||
touch("$etc/$vtun.conf");
|
||||
exec("wg-quick down $vtun 2>/dev/null");
|
||||
@unlink("$etc/$vtun.cfg");
|
||||
wgState($vtun,'down');
|
||||
delete_file("$etc/$vtun.cfg");
|
||||
delPeer($vtun);
|
||||
autostart('off',$vtun);
|
||||
break;
|
||||
case 'deltunnel':
|
||||
$vtun = $_POST['#vtun'];
|
||||
$name = $_POST['#name'];
|
||||
exec("wg-quick down $vtun 2>/dev/null");
|
||||
@unlink("$etc/$vtun.conf");
|
||||
@unlink("$etc/$vtun.cfg");
|
||||
wgState($vtun,'down');
|
||||
delete_file("$etc/$vtun.conf","$etc/$vtun.cfg");
|
||||
delPeer($vtun);
|
||||
delDocker($vtun);
|
||||
autostart('off',$vtun);
|
||||
break;
|
||||
case 'import':
|
||||
@@ -328,8 +397,9 @@ case 'import':
|
||||
foreach (explode("\n",$entry) as $row) {
|
||||
if (ltrim($row)[0]!='#') {
|
||||
[$id,$data] = array_map('trim',my_explode('=',$row));
|
||||
normalize($id);
|
||||
$import["$id:$i"] = $data;
|
||||
} elseif ($i>=0) {
|
||||
} elseif ($i >= 0) {
|
||||
$import["Name:$i"] = substr(trim($row),1);
|
||||
}
|
||||
}
|
||||
@@ -339,21 +409,23 @@ case 'import':
|
||||
$import['NAT:0'] = 'no';
|
||||
[$subnet,$mask] = my_explode('/',$import['Address:0']);
|
||||
if (ipv4($subnet)) {
|
||||
$mask = ($mask>0 && $mask<32) ? $mask : 24;
|
||||
$mask = ($mask > 0 && $mask < 32) ? $mask : 24;
|
||||
$import['Network:0'] = long2ip(ip2long($subnet) & (0x100000000-2**(32-$mask))).'/'.$mask;
|
||||
$import['Address:0'] = $subnet;
|
||||
$import['PROT:0'] = '';
|
||||
} else {
|
||||
$mask = ($mask>0 && $mask<128) ? $mask : 64;
|
||||
$mask = ($mask > 0 && $mask < 128) ? $mask : 64;
|
||||
$import['Network6:0'] = strstr($subnet,'::',true).'::/'.$mask;
|
||||
$import['Address:0'] = $subnet;
|
||||
$import['PROT:0'] = '6';
|
||||
}
|
||||
$import['Endpoint:0'] = '';
|
||||
for ($n = 1; $n <= $i; $n++) {
|
||||
$vpn = strpos($import["AllowedIPs:$n"],$default)!==false || strpos($import["AllowedIPs:$n"],$default6)!==false;
|
||||
if ($vpn) $import["Address:$n"] = '';
|
||||
$import["TYPE:$n"] = $vpn ? 7 : 0;
|
||||
$vpn = array_map('trim',explode(',',$import["AllowedIPs:$n"]));
|
||||
$vpn = (in_array($default, $vpn) || in_array($default6, $vpn)) ? 8 : 0;;
|
||||
if ($vpn==8) $import["Address:$n"] = '';
|
||||
$import["TYPE:$n"] = $vpn;
|
||||
ipfilter($import["AllowedIPs:$n"]);
|
||||
if ($import["TYPE:$n"]==0) $var['subnets1'] = "AllowedIPs=".$import["AllowedIPs:$n"];
|
||||
}
|
||||
foreach ($import as $key => $val) $sort[] = explode(':',$key)[1];
|
||||
@@ -362,12 +434,13 @@ case 'import':
|
||||
$conf = ['[Interface]'];
|
||||
$var['default'] = $import['PROT:0']=='' ? "AllowedIPs=$default" : "AllowedIPs=$default6";
|
||||
$var['internet'] = "Endpoint=unknown";
|
||||
parseInput($import,$x);
|
||||
addPeer($x);
|
||||
$vtun = vtun();
|
||||
parseInput($import,$x,$vtun);
|
||||
addPeer($x);
|
||||
file_put_contents("$etc/$vtun.conf",implode("\n",$conf)."\n");
|
||||
file_put_contents("$etc/$vtun.cfg",implode("\n",$user)."\n");
|
||||
delPeer($vtun);
|
||||
addDocker($vtun);
|
||||
autostart('off',$vtun);
|
||||
echo $vtun;
|
||||
break;
|
||||
|
||||
@@ -475,6 +475,6 @@ while (true) {
|
||||
|
||||
publish('devices', implode("\0",$echo));
|
||||
publish('arraymonitor', $var['fsState']=='Started' ? 1 : 0);
|
||||
usleep(400000);
|
||||
sleep(1);
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -18,6 +18,7 @@ $varroot = '/var/local/emhttp';
|
||||
$log = '/boot/config/parity-checks.log';
|
||||
$stamps = '/var/tmp/stamps.ini';
|
||||
$resync = '/var/tmp/resync.ini';
|
||||
$timer = time();
|
||||
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/publish.php";
|
||||
@@ -117,9 +118,13 @@ while (true) {
|
||||
else $process = 0;
|
||||
|
||||
publish('parity', implode(';',$data));
|
||||
publish('paritymonitor', $spot>0 ? 1 : 0);
|
||||
publish('fsState', $fsState);
|
||||
publish('mymonitor', $process);
|
||||
if (time()-$timer >= 2) {
|
||||
// update every 2 seconds
|
||||
publish('paritymonitor', $spot>0 ? 1 : 0);
|
||||
publish('fsState', $fsState);
|
||||
publish('mymonitor', $process);
|
||||
$timer = time();
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user