Menu="parentname:nnn"
Title="Tunnel wgX"
Tag="icon-vpn"
---
<?PHP
/* Copyright 2005-2025, Lime Technology
 * Copyright 2012-2025, 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,
 * as published by the Free Software Foundation.
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 */
?>
<?
$check_wgX = in_array('wgX',$active) ? 'true' : 'false';
$start_wgX = in_array('wgX',$autostart);
$peer_wgX  = $wgX = [];

$netpool['wgX']  = long2ip(ip2long($netpool['wg0'])+XXX*256);
$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');
?>
<script>
netbase['wgX']  =  <?=_var($netbase,'wgX')?>;
netpool['wgX']  = "<?=_var($netpool,'wgX')?>";
netport['wgX']  = "<?=_var($netport,'wgX')?>";
netbase6['wgX'] = "<?=_var($netbase6,'wgX')?>";
netpool6['wgX'] = "<?=_var($netpool6,'wgX')?>";
tstate['wgX']   = "<?=$check_wgX ? 'active' : 'passive'?>";

$(function(){
  var ctrl = "<span class='js-wg-ctrl inline-flex flex-row items-center gap-3'>";
  ctrl += "<span class='inline-flex flex-row items-center gap-2'><span class='label'>_(Autostart)_</span><span class=''><input type='checkbox' id='start-wgX' style='display:none'<?=$start_wgX?' checked':''?>></span></span>";
  ctrl += "<span class='inline-flex flex-row items-center gap-2'><span class=''><input type='checkbox' id='view-wgX' style='display:none'></span></span>";
  ctrl += "<span class='inline-flex flex-row items-center gap-2'><span class=''><input type='checkbox' id='toggle-wgX' style='display:none'></span></span>";
  ctrl += "<span class='inline-flex flex-row items-center gap-2'><i id='block-wgX' class='fa fa-fw fa-chevron-up' style='cursor:pointer' onclick='blockToggle(&quot;wgX&quot;)'></i></span>";
  ctrl += "</span>";
  var form = $(document.wgX);
  getPublicIP($('#endpoint-wgX').val(),'wgX',$('#protocol-wgX').val());
  $('div.title').each(function(){if ($(this).html().indexOf('js-wg-ctrl')==-1) {$(this).find('span.right').append(ctrl);return false;}});
  $('#start-wgX').switchButton({labels_placement:'left',off_label:"_(Off)_",on_label:"_(On)_"});
  $('#start-wgX').change(function(){
    var start = $('#start-wgX').is(':checked') ? 'on' : 'off';
    $.post('/webGui/include/update.wireguard.php',{'#cmd':'autostart','#start':start,'#vtun':'wgX'});
  });
  $('#toggle-wgX').switchButton({labels_placement:'left',off_label:"_(Inactive)_",on_label:"_(Active)_",checked:<?=$check_wgX?>});
  $('#toggle-wgX').change(function(e){
<?if ($this_wgX):?>
    e.preventDefault();
    e.stopPropagation();
    var wg = $('#toggle-wgX').is(':checked') ? 'start' : 'stop';
    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==0) tstate['wgX']='active'; else $('#toggle-wgX').switchButton({checked:false});
      } else {
        if (ok==0) tstate['wgX']=''; else $('#toggle-wgX').switchButton({checked:true});
      }
<?if (empty($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);});
<?endif;?>
    });
<?else:?>
    $('#toggle-wgX').prop('checked',false).trigger('change');
<?endif;?>
  });
  if ($.cookie('view-wgX')=='advanced') {
    $('.advanced.wgX').show();
    form.find('i.fa-chevron-down').removeClass('fa-chevron-down').addClass('fa-chevron-up');
    form.find('input[class*="zone"]').show();
    form.find('i[class*="zone"]').each(function(i){if (!form.find('input[name="PublicKey:'+i+'"]').val()) {
      $('div.wgX.key'+i).show();
      $(this).removeClass('key-off').addClass('key-off');
    }});
  }
  $('#view-wgX').switchButton({labels_placement:'left',off_label:"_(Basic)_",on_label:"_(Advanced)_",checked:$.cookie('view-wgX')=='advanced'});
  $('#view-wgX').change(function(){
    if ($.cookie('view-wgX')==null) {
      // advanced view
      $.cookie('view-wgX','advanced',{expires:3650});
      $('.advanced.wgX').show('slow');
      form.find('input[class*="zone"]').show('slow');
      form.find('i.fa-chevron-down').removeClass('fa-chevron-down').addClass('fa-chevron-up');
      form.find('i[class*="zone"]').each(function(i){if (!form.find('input[name="PublicKey:'+i+'"]').val()) {
        $('div.wgX.key'+i).show('slow');
        $(this).removeClass('key-off').addClass('key-off');
      }});
    } else {
      // basic view
      $.removeCookie('view-wgX');
      $('.advanced.wgX').hide('slow');
      form.find('i.fa-chevron-up').removeClass('fa-chevron-up').addClass('fa-chevron-down');
      form.find('i[class*="zone"]').each(function(i){if (form.find('input[name="PublicKey:'+i+'"]').val()) {
        form.find('input[class$="zone'+i+'"]').hide('slow');
        $('div.wgX.key'+i).hide('slow');
        $(this).removeClass('key-off');
      }});
    }
  });
  showRemark(form);
  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()=='');});
  });
  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()=='');});
  });
  form.find('input[name^="gui:Endpoint:"]').each(function(){
    var i = $(this).attr('name').split(':')[2];
    $(this).on('input change',function(){
      form.find('#ping-button2-'+i).prop('disabled',$(this).val()=='');
    });
  });
  if (!$.cookie('block-wgX')) $('div#block-wgX').show(); else $('i#block-wgX').removeClass('fa-chevron-up').addClass('fa-chevron-down');
  if (xml) {
    $('div.upnp.wgX').show();
<?if (empty($wgX['UPNP:0'])):?>
    $.post('/webGui/include/update.wireguard.php',{'#cmd':'upnpc','#xml':xml,'#vtun':'wgX','#link':'<?=$link?>','#ip':'<?=$server?>','#wg':$.cookie('my-wgX')||''},function(data){$('span.upnp.wgX').text(data);});
<?endif;?>
  } else {
    form.find('select[name="UPNP:0"]').val('no');
  }
  var vpn = 0, lan = false
  form.find('select[name^="TYPE:"]').each(function(){
    var i = $(this).attr('name').split(':')[1];
    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)_)");
    showAccess(form,i,$(this).val());
  });
  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();
});
</script>
<div markdown="1" id="block-wgX" style="display:none">
<form markdown="1" name="wgX" autocomplete="off" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareSettings($(this),'wgX')">
<input type="hidden" name="#include" value="/webGui/include/update.wireguard.php">
<input type="hidden" name="#file" value="<?=$conf_wgX?>">
<input type="hidden" name="#cfg" value="<?=$cfg_wgX?>">
<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="">
<input type="hidden" name="#subnets2" value="">
<input type="hidden" name="#shared1" value="">
<input type="hidden" name="#shared2" value="">
<input type="hidden" name="#deleted" value="">
<input type="hidden" name="#locale" value="<?=$locale?>">
<input type="hidden" name="#pooooopooooo" value="pooooopooooo">

_(Local name)_:
: <span class="flex flex-row items-center gap-2">
    <input type="text" name="Name:0" class="wide" maxlength="99" value="<?=_var($wgX,"Name:0")?>" pattern="<?=$validname?>" title="_(Use only letters A-Z, digits or space,dash,underscore)_" placeholder="(_(optional)_)">
    <span class="flex flex-row items-center gap-2">
      <i class="fa fa-fw fa-eye eye0<?=$this_wgX?'':' key-off'?>" style="cursor:pointer" onclick="WGconfig(this,'wgX','')" title="_(View Local Config)_"></i>
      <i class="fa fa-fw fa-key zone0<?=isset($wgX['PublicKey:0'])?'':' key-off'?>" style="cursor:pointer" onclick="openClose($(document.wgX),null,'div.key0')" title="_(Toggle keys)_"></i>
      <i id="chevron-wgX-0" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="openClose($(document.wgX),this,'div.zone0')" title="_(Toggle view)_"></i>
    </span>
  </span>

:wg_local_name_help:

<div markdown="1" class="keys wgX key0" style="<?= isset($wgX['PublicKey:0']) ? 'display:none' : '' ?>">
_(Local private key)_:
: <input type="text" name="PrivateKey:0" class="wide private-0" maxlength="64" value="<?=_var($wgX,'PrivateKey:0')?>" onchange="highlight($(document.wgX),this,0)" placeholder="(_(mandatory)_)" required>
  <span class="inline-block">
    <input type="button" class="form" value="_(Generate Keypair)_" onclick="keypair($(document.wgX),'0')">
  </span>

:wg_generate_keypair_help:

_(Local public key)_:
: <input type="text" name="PublicKey:0" class="wide public-0" maxlength="64" value="<?=_var($wgX,'PublicKey:0')?>" onchange="highlight($(document.wgX),this,0)" placeholder="(_(mandatory)_)" required>

:wg_generate_keypair_help:

</div>
<div markdown="1" class="advanced wgX zone0" style="display:none">
_(Network protocol)_:
: <select id="protocol-wgX" name="PROT:0" onchange="setProtocol($(document.wgX),'wgX',true)">
  <?=mk_option(_var($wgX,'PROT:0'), "", _("IPv4 only"))?>
  <?=mk_option(_var($wgX,'PROT:0'), "6", _("IPv6 only"))?>
  <?=mk_option(_var($wgX,'PROT:0'), "46", _("IPv4 + IPv6"))?>
  </select>

<div markdown="1" class="ipv4 wgX" style="display:none">
_(Local tunnel network pool)_:
: <input type="hidden" name="Network:0" value="">
  <span class="flex flex-row items-center gap-2">
    <input type="text" name="gui:Network:0" maxlength="15" value="<?=explode('/',_var($wgX,'Network:0'))[0]?>" onchange="setPool($(document.wgX),'wgX')" pattern="<?=$validIP4?>" title="_(IPv4 network)_" placeholder="<?=_var($netpool,'wgX')?>">
    <span>/</span>
    <input type="number" name="gui:Mask:0" class="mask" min="1" max="32" value="<?=my_explode('/',_var($wgX,'Network:0'))[1]?>" onchange="if(quickValidate(this)) {setPool($(document.wgX),'wgX')}" placeholder="24">
  </span>

</div>
<div markdown="1" class="ipv6 wgX" style="display:none">
_(Local tunnel network pool IPv6)_:
: <input type="hidden" name="Network6:0" value="">
  <span class="flex flex-row items-center gap-2">
    <input type="text" name="gui:Network6:0" maxlength="40" value="<?=explode('/',_var($wgX,'Network6:0'))[0]?>" onchange="setPool6($(document.wgX),'wgX')" pattern="<?=$validIP6?>" title="_(IPv6 network)_" placeholder="<?=_var($netpool6,'wgX')?>">
    <span>/</span>
    <input type="number" name="gui:Mask6:0" class="mask" min="1" max="128" value="<?=my_explode('/',_var($wgX,'Network6:0'))[1]?>" onchange="if(quickValidate(this)) {setPool6($(document.wgX),'wgX')}" placeholder="64">
  </span>

</div>
:wg_local_tunnel_network_pool_X_help:

<div markdown="1" class="ipv4 wgX" style="display:none">
_(Local tunnel address)_:
: <input type="text" name="Address:0" maxlength="15" value="<?=_var($wgX,'Address:0')?:long2ip(_var($netbase,'wgX')+1)?>" onchange="verifyInSubnet(this);" pattern="<?=$validIP4?>" title="_(IPv4 address)_">

:wg_local_tunnel_address_help:

</div>
<div markdown="1" class="ipv6 wgX" style="display:none">
_(Local tunnel address IPv6)_:
: <input type="text" name="Address6:0" maxlength="40" value="<?=_var($wgX,'Address6:0')?:(_var($netbase6,'wgX').'1')?>" onchange="verifyInSubnet6(this);" pattern="<?=$validIP6?>" title="_(IPv6 address)_">

:wg_local_tunnel_address_help:

</div>
</div>
_(Local endpoint)_:
: <span class="flex flex-row items-center gap-2">
    <input type="text" class="width:10%;" id="endpoint-wgX" name="Endpoint:0" value="<?=$vpn_wgX?'':_var($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>:</span>
    <input type="number" name="gui:ListenPort:0" class="port" min="1" max="65535" value="<?=$vpn_wgX?'':_var($wgX,'ListenPort:0')?>" onchange="if(quickValidate(this)) {portRemark($(document.wgX),'wgX',this.value)}"  placeholder="<?=$vpn_wgX?'':_var($netport,'wgX')?>">
  </span>
  <span class="remark inline-block" style="display:none">_(Remark)_: _(configure your router with port forwarding of port)_ **<span id="my-port-wgX"><?=_var($wgX,'ListenPort:0')?:_var($netport,'wgX')?></span>/_(UDP)_** _(to)_ **<?=$server?>:<?=_var($wgX,'ListenPort:0')?:_var($netport,'wgX')?>**</span><span class="upnp wgX inline-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>

:wg_local_endpoint_X_help:

<div markdown="1" class="advanced wgX zone0" style="display:none">
_(Local server uses NAT)_:
: <select name="NAT:0" onchange="showRoute($(document.wgX),'wgX',0)">
  <?=mk_option(_var($wgX,'NAT:0'), "", _("Yes"))?>
  <?=mk_option(_var($wgX,'NAT:0'), "no", _("No"))?>
  </select>
  <span id="my-static1-wgX" class="inline-block" style="display:none">_(Remark)_: _(configure your router with a static route of)_ **<?=_var($wgX,'Network:0')?>** _(to)_ **<?=$server?>**</span><span id="my-static2-wgX" class="inline-block" style="display:none">_(Remark)_: _(docker containers on custom networks need static routing)_ **<?=_var($wgX,'Network:0')?>** _(to)_ **<?=$server?>**</span>

:wg_local_server_uses_nat_help:

<div markdown="1" class="upnp wg0" style="display:none">
_(Local gateway uses UPnP)_:
: <select name="UPNP:0" onchange="showRemark($(document.wgX))">
  <?=mk_option(_var($wgX,'UPNP:0'), "", _("Yes"))?>
  <?=mk_option(_var($wgX,'UPNP:0'), "no", _("No"))?>
  </select>

:wg_local_gateway_uses_upnp_help:

</div>
_(Local tunnel firewall)_:
: <span class="flex flex-row items-center gap-2">
    <input type="text" name="DROP:0" class="wide" value="<?=_var($wgX,'DROP:0')?>" onchange="quickValidate(this);" pattern="<?=$validList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_, _(CIDR optional)_" placeholder="(_(optional)_)">
    <span class="flex flex-row items-center gap-2">
      <span>_(Rule)_: </span>
      <select name="RULE:0" class="auto">
      <?=mk_option(_var($wgX,'RULE:0'), "", _("Deny"))?>
      <?=mk_option(_var($wgX,'RULE:0'), "1", _("Allow"))?>
      </select>
    </span>
  </span>

:wg_local_tunnel_firewall_help:

_(MTU size)_:
: <span class="flex flex-row items-center gap-2">
    <input type="number" name="MTU:0" class="trim" min="68" max="9198" value="<?=_var($wgX,'MTU:0')?>" onchange="quickValidate(this);" placeholder="(_(auto)_)">
    <span>_(bytes)_</span>
  </span>

:wg_mtu_size_help:

<!--
_(DNS servers)_:
: <span class="input"><input type="text" name="DNS:0" class="wide" value="" placeholder="(_(optional)_)"></span>

> Not used at the moment. It gives errors when used together with Unraid.
-->
</div>
<input type="hidden" name="PostUp:0:0" value="<?=$postUp0?>">
<input type="hidden" name="PostUp:0:1" value="<?=$postUp1?>">
<input type="hidden" name="PostUp:0:2" value="">
<input type="hidden" name="PostDown:0:0" value="<?=$postDown0?>">
<input type="hidden" name="PostDown:0:1" value="<?=$postDown1?>">
<input type="hidden" name="PostDown:0:2" value="">

:wg_peer_configuration_help:

<div id="peers-list-wgX" style="display:none"></div>
<?foreach ($peer_wgX as $i):?>
<div markdown="1" id="index-wgX-<?=$i?>" class="shade">
_(Peer name)_:
: <span class="flex flex-row items-center gap-2">
    <input type="text" name="Name:<?=$i?>" class="wide" maxlength="99" value="<?=_var($wgX,"Name:$i")?>" onchange="quickValidate(this);" pattern="<?=$validname?>" title="_(Use only letters A-Z, digits or space,dash,underscore)_" placeholder="(_(optional)_)">
    <span class="flex flex-row items-center gap-2">
      <i class="fa fa-fw fa-eye eye<?=$i?><?=(file_exists("$etc/peers/peer-$tower-wgX-$i.conf")&&isset($wgX["TYPE:$i"])&&$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?><?=isset($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>
  </span>
  <span class="inline-block">
    <input type="button" class="form" value="_(Delete Peer)_" onclick="delPeer($(document.wgX),'#index-wgX-<?=$i?>')">
  </span>

:wg_peer_name_help:

_(Peer type of access)_:
: <select name="TYPE:<?=$i?>" class="auto" onchange="updatePeer($(document.wgX),<?=$i?>,this.value,'wgX')">
  <?=mk_option(_var($wgX,"TYPE:$i"), "0", _("Remote access to server"))?>
  <?=mk_option(_var($wgX,"TYPE:$i"), "1", _("Remote access to LAN"))?>
  <?=mk_option(_var($wgX,"TYPE:$i"), "2", _("Server to server access"))?>
  <?=mk_option(_var($wgX,"TYPE:$i"), "3", _("LAN to LAN access"))?>
  <?=mk_option(_var($wgX,"TYPE:$i"), "4", _("Server hub & spoke access"))?>
  <?=mk_option(_var($wgX,"TYPE:$i"), "5", _("LAN hub & spoke access"))?>
  <?=mk_option(_var($wgX,"TYPE:$i"), "6", _("Remote tunneled access"))?>
  <?=mk_option(_var($wgX,"TYPE:$i"), "7", _("VPN tunneled access for system"),count($peer_wgX)==1?'':'disabled')?>
  <?=mk_option(_var($wgX,"TYPE:$i"), "8", _("VPN tunneled access for docker"))?>
  </select>
  <span id="access-type-<?=$i?>"></span>

<?if ($i==1):?>
> ![](<?=autov('/webGui/images/wireguard-help.png')?>)
<?endif;?>

<div markdown="1" class="keys wgX key<?=$i?>"<?=isset($wgX["PublicKey:$i"])?' style="display:none">':'>'?>
_(Peer private key)_:
: <input type="text" name="PrivateKey:<?=$i?>" class="wide private-<?=$i?>" maxlength="64" value="<?=_var($wgX,"PrivateKey:$i")?>" onchange="highlight($(document.wgX),this,<?=$i?>)" placeholder="(_(optional)_)">
  <span class="inline-block">
    <input type="button" class="form" value="_(Generate Keypair)_" onclick="keypair($(document.wgX),'<?=$i?>')">
  </span>

:wg_generate_keypair_help:

_(Peer public key)_:
: <input type="text" name="PublicKey:<?=$i?>" class="wide public-<?=$i?>" maxlength="64" value="<?=_var($wgX,"PublicKey:$i")?>" onchange="highlight($(document.wgX),this,<?=$i?>)" placeholder="(_(mandatory)_)" required>

:wg_generate_keypair_help:

_(Peer preshared key)_:
: <input type="text" name="PresharedKey:<?=$i?>" class="wide preshared-<?=$i?>" maxlength="64" value="<?=_var($wgX,"PresharedKey:$i")?>" onchange="highlight($(document.wgX),this,<?=$i?>)" placeholder="(_(optional)_)">
  <span class="inline-block">
    <input type="button" class="form" value="_(Generate Key)_" onclick="presharedkey($(document.wgX),'<?=$i?>')">
  </span>

:wg_peer_preshared_key_help:

</div>
<div markdown="1" class="advanced wgX zone<?=$i?>" style="display:none">
<div markdown="1" class="ipv4 wgX" style="display:none">
_(Peer tunnel address)_:
: <input type="text" name="Address:<?=$i?>" maxlength="15" value="<?=_var($wgX,"Address:$i")?>" onchange="if(verifyInSubnet(this)){setAllow($(document.wgX),this.value,<?=$i?>)}" pattern="<?=$validIP4?>" title="_(IPv4 address)_">
  <span class="inline-block">
    <input type="button" class="form ping-button1-<?=$i?>" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name=&quot;Address:<?=$i?>&quot;]')"<?=isset($wgX["Address:$i"])?'':' disabled'?>>
  </span>

</div>
<div markdown="1" class="ipv6 wgX" style="display:none">
_(Peer tunnel address IPv6)_:
: <input type="text" name="Address6:<?=$i?>" maxlength="40" value="<?=_var($wgX,"Address6:$i")?>" onchange="if(verifyInSubnet6(this)){setAllow6($(document.wgX),this.value,<?=$i?>)}" pattern="<?=$validIP6?>" title="_(IPv6 address)_">
  <span class="inline-block">
    <input type="button" class="form ping-button6-<?=$i?>" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name=&quot;Address6:<?=$i?>&quot;]')"<?=isset($wgX["Address6:$i"])?'':' disabled'?>>
  </span>

</div>
:wg_peer_tunnel_address_help:

_(Peer endpoint)_:
: <input type="hidden" name="Endpoint:<?=$i?>" value="">
  <span class="flex flex-row items-center gap-2">
    <input type="text" name="gui:Endpoint:<?=$i?>" value="<?=_var($wgX,"Endpoint:$i")?>" pattern="<?=$validText?>" title="_(IP address or FQDN)_" onchange="toLC(this);quickValidate(this);" <?=($vpn_wgX||(int)_var($wgX,"TYPE:$i",0)==2||(int)_var($wgX,"TYPE:$i",0)==3)?'placeholder="(_(mandatory)_)" required':'placeholder="(_(not used)_)"'?>>:
    <span>:</span>
    <input type="number" name="gui:ListenPort:<?=$i?>" class="port" min="1" max="65535" value="<?=_var($wgX,"ListenPort:$i")?>" onchange="quickValidate(this);"<?=isset($wgX["Endpoint:$i"])?" placeholder=\"".(_var($wgX,'ListenPort:0')?:_var($netport,'wgX'))."\"":""?>>
  </span>
  <span class="inline-block">
    <input type="button" class="form ping-button2-<?=$i?>" value="Ping" onclick="ping($(document.wgX),this,'input[name=&quot;gui:Endpoint:<?=$i?>&quot;]')"<?=isset($wgX["Endpoint:$i"])?'':' disabled'?>>
  </span>

:wg_peer_endpoint_help:

_(Peer allowed IPs)_:
: <input type="text" name="AllowedIPs:<?=$i?>" class="wide" value="<?=_var($wgX,"AllowedIPs:$i")?>" onchange="quickValidate(this);" pattern="<?=$validList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_, _(CIDR optional)_" placeholder="(_(mandatory)_)" required>

:wg_peer_allowed_ips_help:

_(Peer DNS server)_:
: <input type="text" name="DNS:<?=$i?>" maxlength="60" value="<?=_var($wgX,"DNS:$i")?>" onchange="quickValidate(this);" pattern="<?=$validDNSServerList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_"<?=(int)_var($wgX,"TYPE:$i",0)!=6?'placeholder="(_(optional)_)"':'placeholder="(_(mandatory)_)" required'?>>

:wg_peer_dns_server_help:

_(Persistent keepalive)_:
: <span class="flex flex-row items-center gap-2">
    <input type="number" name="PersistentKeepalive:<?=$i?>" class="trim" min="0" max="600" value="<?=_var($wgX,"PersistentKeepalive:$i")?>" onchange="quickValidate(this);" placeholder="(_(disabled)_)">
    <span>_(seconds)_</span>
  </span>

:wg_persistent_keepalive_help:

</div>

_(Data received)_:
: <span class="rx-wgX-<?=$i?>">0 B</span>

_(Data sent)_:
: <span class="tx-wgX-<?=$i?>">0 B</span>

_(Last handshake)_:
: <span class="hs-wgX-<?=$i?>">_(unknown)_</span>
</div>
<?endforeach;?>

&nbsp;
: <span class="inline-block">
    <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="display:none" onclick="delTunnel('wgX')">
  </span>
</form>

<script markdown="1" type="text/html" id="peer-template-wgX">
<div markdown="1" id="index-wgX-INDEX" class="shade">
_(Peer name)_:
: <span class="flex flex-row items-center gap-2">
    <input type="text" name="Name:INDEX" class="wide" maxlength="99" value="" onchange="quickValidate(this);" pattern="<?=$validname?>" title="_(Use only letters A-Z, digits or space,dash,underscore)_" placeholder="(_(optional)_)">
    <span class="flex flex-row items-center gap-2">
      <i class="fa fa-fw fa-eye eyeINDEX key-off" title="_(Show Peer Config)_"></i>
      <i class="fa fa-fw fa-key zoneINDEX key-off" title="_(Toggle keys)_"></i>
      <i id="chevron-wgX-INDEX" class="fa fa-fw fa-chevron-down" style="cursor:pointer" onclick="openClose($(document.wgX),this,'div.zoneINDEX')" title="_(Toggle view)_"></i>
    </span>
  </span>

:wg_peer_name_help:

_(Peer type of access)_:
: <select name="TYPE:INDEX" class="auto" onchange="updatePeer($(document.wgX),INDEX,this.value,'wgX')">
  <?=mk_option(0, "0", _("Remote access to server"))?>
  <?=mk_option(0, "1", _("Remote access to LAN"))?>
  <?=mk_option(0, "2", _("Server to server access"))?>
  <?=mk_option(0, "3", _("LAN to LAN 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 for system"),'disabled')?>
  <?=mk_option(0, "8", _("VPN tunneled access for docker"))?>
  </select>
  <span id="access-type-INDEX" class="access-type"></span>

> ![](<?=autov('/webGui/images/wireguard-help.png')?>)

<div markdown="1" class="keys wgX keyINDEX">
_(Peer private key)_:
: <input type="text" name="PrivateKey:INDEX" class="wide private-INDEX" maxlength="64" value="" onchange="highlight($(document.wgX),this,0)" placeholder="(_(optional)_)">
  <span class="inline-block">
    <input type="button" class="form" value="_(Generate Keypair)_" onclick="keypair($(document.wgX),'INDEX')">
  </span>

:wg_generate_keypair_help:

_(Peer public key)_:
: <input type="text" name="PublicKey:INDEX" class="wide public-INDEX" maxlength="64" onchange="highlight($(document.wgX),this,0)" placeholder="(_(mandatory)_)" value="" required>

:wg_generate_keypair_help:

_(Peer preshared key)_:
: <input type="text" name="PresharedKey:INDEX" class="wide preshared-INDEX" maxlength="64" value="" onchange="highlight($(document.wgX),this,0)" placeholder="(_(optional)_)">
  <span class="inline-block">
    <input type="button" class="form" value="_(Generate Key)_" onclick="presharedkey($(document.wgX),'INDEX')">
  </span>

:wg_peer_preshared_key_help:

</div>
<div markdown="1" class="advanced wgX zoneINDEX" style="display:none">
<div markdown="1" class="ipv4 wgX" style="display:none">
_(Peer tunnel address)_:
: <input type="text" name="Address:INDEX" maxlength="15" value="" onchange="if(verifyInSubnet(this)){setAllow($(document.wgX),this.value,INDEX)}" pattern="<?=$validIP4?>" title="_(IPv4 address)_">
  <span class="inline-block">
    <input type="button" class="form ping-button1-INDEX" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name=&quot;Address:INDEX&quot;]')" disabled>
  </span>

</div>
<div markdown="1" class="ipv6 wgX" style="display:none">
_(Peer tunnel address IPv6)_:
: <input type="text" name="Address6:INDEX" maxlength="40" value="" onchange="if(verifyInSubnet6(this)){setAllow6($(document.wgX),this.value,INDEX)}" pattern="<?=$validIP6?>" title="_(IPv6 address)_">
  <span class="inline-block">
    <input type="button" class="form ping-button6-INDEX" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name=&quot;Address6:INDEX&quot;]')" disabled>
  </span>

</div>
:wg_peer_tunnel_address_help:

_(Peer endpoint)_:
: <input type="hidden" name="Endpoint:INDEX" value="">
  <span class="flex flex-row items-center gap-2">
    <input type="text" name="gui:Endpoint:INDEX" value="" pattern="<?=$validText?>" title="_(IP address or FQDN)_" onchange="toLC(this);quickValidate(this);" placeholder="(_(not used)_)">
    <span>:</span>
    <input type="number" name="gui:ListenPort:INDEX" class="port" min="1" max="65535" value="" onchange="quickValidate(this);">
  </span>
  <span class="inline-block">
    <input type="button" class="form ping-button2-INDEX" value="_(Ping)_" onclick="ping($(document.wgX),this,'input[name=&quot;gui:Endpoint:INDEX&quot;]')" disabled>
  </span>

:wg_peer_endpoint_help:

_(Peer allowed IPs)_:
: <input type="text" name="AllowedIPs:INDEX" class="wide" value="" onchange="quickValidate(this);" pattern="<?=$validList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_, _(CIDR optional)_" placeholder="(_(mandatory)_)" required>

:wg_peer_allowed_ips_help:

_(Peer DNS server)_:
: <input type="text" name="DNS:INDEX" maxlength="60" value="" onchange="quickValidate(this);" pattern="<?=$validDNSServerList?>" title="_(Comma separated list of IPv4 and IPv6 IP addresses)_" placeholder="(_(optional)_)">

:wg_peer_dns_server_help:

_(Persistent keepalive)_:
: <span class="flex flex-row items-center gap-2">
    <input type="number" name="PersistentKeepalive:INDEX" class="trim" min="0" max="600" value="" onchange="quickValidate(this);" placeholder="(_(disabled)_)">
    <span>_(seconds)_</span>
  </span>

:wg_persistent_keepalive_help:

</div>
</div>
</script>
</div>
