mirror of https://github.com/h44z/wg-portal.git
				
				
				
			support different interface types: client and server mode
This commit is contained in:
		
							parent
							
								
									39903922dd
								
							
						
					
					
						commit
						94ca177884
					
				|  | @ -80,4 +80,12 @@ pre{background:#f7f7f9}iframe{overflow:hidden;border:none}@media (min-width: 768 | ||||||
| .form-group.required label:after { | .form-group.required label:after { | ||||||
|     content:"*"; |     content:"*"; | ||||||
|     color:red; |     color:red; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | a.advanced-settings:before { | ||||||
|  |     content: "Hide"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | a.advanced-settings.collapsed:before { | ||||||
|  |     content: "Show"; | ||||||
| } | } | ||||||
|  | @ -91,11 +91,11 @@ | ||||||
|             </div> |             </div> | ||||||
|             <div class="form-row"> |             <div class="form-row"> | ||||||
|                 <div class="form-group col-md-6"> |                 <div class="form-group col-md-6"> | ||||||
|                     <label for="server_PersistentKeepalive">Persistent Keepalive</label> |                     <label for="server_PersistentKeepalive">Persistent Keepalive (0 = off)</label> | ||||||
|                     <input type="number" name="keepalive" class="form-control" id="server_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}"> |                     <input type="number" name="keepalive" class="form-control" id="server_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}"> | ||||||
|                 </div> |                 </div> | ||||||
|                 <div class="form-group col-md-6"> |                 <div class="form-group col-md-6"> | ||||||
|                     <label for="server_MTU">Client MTU</label> |                     <label for="server_MTU">Client MTU (0 = default)</label> | ||||||
|                     <input type="number" name="mtu" class="form-control" id="server_MTU" placeholder="" value="{{.Peer.Mtu}}"> |                     <input type="number" name="mtu" class="form-control" id="server_MTU" placeholder="" value="{{.Peer.Mtu}}"> | ||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
|  | @ -192,7 +192,7 @@ | ||||||
|             </div> |             </div> | ||||||
|             <div class="form-row"> |             <div class="form-row"> | ||||||
|                 <div class="form-group col-md-12"> |                 <div class="form-group col-md-12"> | ||||||
|                     <label for="client_PersistentKeepalive">Persistent Keepalive</label> |                     <label for="client_PersistentKeepalive">Persistent Keepalive (0 = off)</label> | ||||||
|                     <input type="number" name="keepalive" class="form-control" id="client_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}"> |                     <input type="number" name="keepalive" class="form-control" id="client_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}"> | ||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
|  | @ -209,124 +209,6 @@ | ||||||
|             </div> |             </div> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|             <button type="submit" class="btn btn-primary">Save</button> |  | ||||||
|             <a href="/admin" class="btn btn-secondary">Cancel</a> |  | ||||||
|         </form> |  | ||||||
|         {{end}} |  | ||||||
| 
 |  | ||||||
|         <!-- custom mode --> |  | ||||||
|         {{if eq .Device.Type "custom"}} |  | ||||||
|         {{if .Peer.IsNew}} |  | ||||||
|         <h1>Create a new peer</h1> |  | ||||||
|         {{else}} |  | ||||||
|         <h1>Edit peer: <strong>{{.Peer.Identifier}}</strong></h1> |  | ||||||
|         {{end}} |  | ||||||
| 
 |  | ||||||
|         <form method="post" enctype="multipart/form-data"> |  | ||||||
|             <input type="hidden" name="_csrf" value="{{.Csrf}}"> |  | ||||||
|             <input type="hidden" name="uid" value="{{.Peer.UID}}"> |  | ||||||
|             <input type="hidden" name="devicetype" value="{{.Device.Type}}"> |  | ||||||
|             <input type="hidden" name="device" value="{{.Device.DeviceName}}"> |  | ||||||
|             {{if .EditableKeys}} |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_PrivateKey">Private Key</label> |  | ||||||
|                     <input type="text" name="privkey" class="form-control" id="custom_PrivateKey" value="{{.Peer.PrivateKey}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group required col-md-12"> |  | ||||||
|                     <label for="custom_PublicKey">Public Key</label> |  | ||||||
|                     <input type="text" name="pubkey" class="form-control" id="custom_PublicKey" value="{{.Peer.PublicKey}}" required> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_PresharedKey">Preshared Key</label> |  | ||||||
|                     <input type="text" name="presharedkey" class="form-control" id="custom_PresharedKey" value="{{.Peer.PresharedKey}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             {{else}} |  | ||||||
|             <input type="hidden" name="privkey" value="{{.Peer.PrivateKey}}"> |  | ||||||
|             <input type="hidden" name="presharedkey" value="{{.Peer.PresharedKey}}"> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_ro_PublicKey">Public Key</label> |  | ||||||
|                     <input type="text" name="pubkey" readonly class="form-control" id="custom_ro_PublicKey" value="{{.Peer.PublicKey}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             {{end}} |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group required col-md-12"> |  | ||||||
|                     <label for="custom_Identifier">Peer Friendly Name</label> |  | ||||||
|                     <input type="text" name="identifier" class="form-control" id="custom_Identifier" value="{{.Peer.Identifier}}" required> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group required col-md-12"> |  | ||||||
|                     <label for="custom_Email">Peer Email Address</label> |  | ||||||
|                     <input type="email" name="mail" class="form-control" id="custom_Email" value="{{.Peer.Email}}" required> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_Endpoint">Endpoint Address</label> |  | ||||||
|                     <input type="text" name="endpoint" class="form-control" id="custom_Endpoint" value="{{.Peer.Endpoint}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group required col-md-12"> |  | ||||||
|                     <label for="custom_EndpointPublicKey">Endpoint Public Key</label> |  | ||||||
|                     <input type="text" name="endpointpubkey" class="form-control" id="custom_EndpointPublicKey" value="{{.Peer.EndpointPublicKey}}" required> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_IP">Peer IP Address</label> |  | ||||||
|                     <input type="text" name="ip" class="form-control" id="custom_IP" value="{{.Peer.IPsStr}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_AllowedIP">Allowed IPs</label> |  | ||||||
|                     <input type="text" name="allowedip" class="form-control" id="custom_AllowedIP" value="{{.Peer.AllowedIPsStr}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_DNS">Peer DNS Servers</label> |  | ||||||
|                     <input type="text" name="dns" class="form-control" id="custom_DNS" value="{{.Peer.DNSStr}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_PersistentKeepalive">Persistent Keepalive</label> |  | ||||||
|                     <input type="number" name="keepalive" class="form-control" id="custom_PersistentKeepalive" placeholder="16" value="{{.Peer.PersistentKeepalive}}"> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_MTU">Client MTU</label> |  | ||||||
|                     <input type="number" name="mtu" class="form-control" id="custom_MTU" placeholder="" value="{{.Peer.Mtu}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
| 
 |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <div class="custom-control custom-switch"> |  | ||||||
|                         <input class="custom-control-input" name="isdisabled" type="checkbox" value="true" id="custom_Disabled" {{if .Peer.DeactivatedAt}}checked{{end}}> |  | ||||||
|                         <label class="custom-control-label" for="custom_Disabled"> |  | ||||||
|                             Disabled |  | ||||||
|                         </label> |  | ||||||
|                     </div> |  | ||||||
|                     <div class="custom-control custom-switch"> |  | ||||||
|                         <input class="custom-control-input" name="ignoreglobalsettings" type="checkbox" value="true" id="custom_IgnoreGlobalSettings" {{if .Peer.IgnoreGlobalSettings}}checked{{end}}> |  | ||||||
|                         <label class="custom-control-label" for="custom_IgnoreGlobalSettings"> |  | ||||||
|                             Ignore global settings |  | ||||||
|                         </label> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|             <button type="submit" class="btn btn-primary">Save</button> |             <button type="submit" class="btn btn-primary">Save</button> | ||||||
|             <a href="/admin" class="btn btn-secondary">Cancel</a> |             <a href="/admin" class="btn btn-secondary">Cancel</a> | ||||||
|         </form> |         </form> | ||||||
|  |  | ||||||
|  | @ -23,338 +23,231 @@ | ||||||
|             <li class="nav-item"> |             <li class="nav-item"> | ||||||
|                 <a class="nav-link {{if eq .Device.Type "client"}}active{{end}}" data-toggle="tab" href="#client">Client Mode</a> |                 <a class="nav-link {{if eq .Device.Type "client"}}active{{end}}" data-toggle="tab" href="#client">Client Mode</a> | ||||||
|             </li> |             </li> | ||||||
|             <li class="nav-item"> |  | ||||||
|                 <a class="nav-link {{if eq .Device.Type "custom"}}active{{end}}" data-toggle="tab" href="#custom">Custom Mode (Experimental)</a> |  | ||||||
|             </li> |  | ||||||
|         </ul> |         </ul> | ||||||
| 
 | 
 | ||||||
|         <div id="configContent" class="tab-content"> |         <div id="configContent" class="tab-content"> | ||||||
|             <!-- server mode --> |             <!-- server mode --> | ||||||
|             <div class="tab-pane fade {{if eq .Device.Type "server"}}active show{{end}}" id="server"> |             <div class="tab-pane fade {{if eq .Device.Type "server"}}active show{{end}}" id="server"> | ||||||
|                 <form method="post" enctype="multipart/form-data"> |                 <form method="post" enctype="multipart/form-data"> | ||||||
|                 <input type="hidden" name="_csrf" value="{{.Csrf}}"> |                     <input type="hidden" name="_csrf" value="{{.Csrf}}"> | ||||||
|                 <input type="hidden" name="device" value="{{.Device.DeviceName}}"> |                     <input type="hidden" name="device" value="{{.Device.DeviceName}}"> | ||||||
|                 <input type="hidden" name="devicetype" value="server"> |                     <input type="hidden" name="devicetype" value="server"> | ||||||
|                 <h3>Server's interface configuration</h3> |                     <h3>Server's interface configuration</h3> | ||||||
|                 <div class="form-row"> |                     <div class="form-row"> | ||||||
|                     <div class="form-group col-md-12"> |                         <div class="form-group col-md-12"> | ||||||
|                         <label for="server_DisplayName">Display Name</label> |                             <label for="server_DisplayName">Display Name</label> | ||||||
|                         <input type="text" name="displayname" class="form-control" id="server_DisplayName" value="{{.Device.DisplayName}}"> |                             <input type="text" name="displayname" class="form-control" id="server_DisplayName" value="{{.Device.DisplayName}}"> | ||||||
|  |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                     {{if .EditableKeys}} | ||||||
|                 {{if .EditableKeys}} |                     <div class="form-row"> | ||||||
|                 <div class="form-row"> |                         <div class="form-group required col-md-12"> | ||||||
|                     <div class="form-group required col-md-12"> |                             <label for="server_PrivateKey">Private Key</label> | ||||||
|                         <label for="server_PrivateKey">Private Key</label> |                             <input type="text" name="privkey" class="form-control" id="server_PrivateKey" value="{{.Device.PrivateKey}}" required> | ||||||
|                         <input type="text" name="privkey" class="form-control" id="server_PrivateKey" value="{{.Device.PrivateKey}}" required> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                     <div class="form-row"> | ||||||
|                 <div class="form-row"> |                         <div class="form-group required col-md-12"> | ||||||
|                     <div class="form-group required col-md-12"> |                             <label for="server_PublicKey">Public Key</label> | ||||||
|                         <label for="server_PublicKey">Public Key</label> |                             <input type="text" name="pubkey" class="form-control" id="server_PublicKey" value="{{.Device.PublicKey}}" required> | ||||||
|                         <input type="text" name="pubkey" class="form-control" id="server_PublicKey" value="{{.Device.PublicKey}}" required> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                     {{else}} | ||||||
|                 {{else}} |                     <input type="hidden" name="privkey" value="{{.Device.PrivateKey}}"> | ||||||
|                 <input type="hidden" name="privkey" value="{{.Device.PrivateKey}}"> |                     <div class="form-row"> | ||||||
|                 <div class="form-row"> |                         <div class="form-group col-md-12"> | ||||||
|                     <div class="form-group col-md-12"> |                             <label for="server_ro_PublicKey">Public Key</label> | ||||||
|                         <label for="server_ro_PublicKey">Public Key</label> |                             <input type="text" name="pubkey" readonly class="form-control" id="server_ro_PublicKey" value="{{.Device.PublicKey}}"> | ||||||
|                         <input type="text" name="pubkey" readonly class="form-control" id="server_ro_PublicKey" value="{{.Device.PublicKey}}"> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                     {{end}} | ||||||
|                 {{end}} |                     <div class="form-row"> | ||||||
|                 <div class="form-row"> |                         <div class="form-group required col-md-6"> | ||||||
|                     <div class="form-group required col-md-6"> |                             <label for="server_ListenPort">Listen port</label> | ||||||
|                         <label for="server_ListenPort">Listen port</label> |                             <input type="number" name="port" class="form-control" id="server_ListenPort" placeholder="51820" value="{{.Device.ListenPort}}" required> | ||||||
|                         <input type="number" name="port" class="form-control" id="server_ListenPort" placeholder="51820" value="{{.Device.ListenPort}}" required> |                         </div> | ||||||
|  |                         <div class="form-group required col-md-6"> | ||||||
|  |                             <label for="server_IPs">Server IP address</label> | ||||||
|  |                             <input type="text" name="ip" class="form-control" id="server_IPs" placeholder="10.6.6.1/24" value="{{.Device.IPsStr}}" required> | ||||||
|  |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div class="form-group required col-md-6"> |                     <h3>Client's global configuration</h3> | ||||||
|                         <label for="server_IPs">Server IP address</label> |                     <div class="form-row"> | ||||||
|                         <input type="text" name="ip" class="form-control" id="server_IPs" placeholder="10.6.6.1/24" value="{{.Device.IPsStr}}" required> |                         <div class="form-group required col-md-12"> | ||||||
|  |                             <label for="server_PublicEndpoint">Public Endpoint for Clients</label> | ||||||
|  |                             <input type="text" name="endpoint" class="form-control" id="server_PublicEndpoint" placeholder="vpn.company.com:51820" value="{{.Device.DefaultEndpoint}}" required> | ||||||
|  |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                     <div class="form-row"> | ||||||
|                 <div class="form-row"> |                         <div class="form-group col-md-6"> | ||||||
|                     <div class="form-group col-md-6"> |                             <label for="server_DNS">DNS Servers</label> | ||||||
|                         <label for="server_FirewallMark">Firewall Mark</label> |                             <input type="text" name="dns" class="form-control" id="server_DNS" placeholder="1.1.1.1" value="{{.Device.DNSStr}}"> | ||||||
|                         <input type="number" name="firewallmark" class="form-control" id="server_FirewallMark" placeholder="0" value="{{.Device.FirewallMark}}"> |                         </div> | ||||||
|  |                         <div class="form-group col-md-6"> | ||||||
|  |                             <label for="server_AllowedIP">Default allowed IPs</label> | ||||||
|  |                             <input type="text" name="allowedip" class="form-control" id="server_AllowedIP" placeholder="10.6.6.0/24" value="{{.Device.DefaultAllowedIPsStr}}"> | ||||||
|  |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div class="form-group col-md-6"> |                     <div class="form-row"> | ||||||
|                         <label for="server_RoutingTable">Routing Table</label> |                         <div class="form-group col-md-6"> | ||||||
|                         <input type="text" name="routingtable" class="form-control" id="server_RoutingTable" placeholder="auto" value="{{.Device.RoutingTable}}"> |                             <label for="server_MTU">MTU (also used for the server interface, 0 = default)</label> | ||||||
|  |                             <input type="number" name="mtu" class="form-control" id="server_MTU" placeholder="" value="{{.Device.Mtu}}"> | ||||||
|  |                         </div> | ||||||
|  |                         <div class="form-group col-md-6"> | ||||||
|  |                             <label for="server_PersistentKeepalive">Persistent Keepalive (0 = off)</label> | ||||||
|  |                             <input type="number" name="keepalive" class="form-control" id="server_PersistentKeepalive" placeholder="16" value="{{.Device.DefaultPersistentKeepalive}}"> | ||||||
|  |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                     <h3>Interface configuration hooks</h3> | ||||||
|                 <h3>Client's global configuration</h3> |                     <div class="form-row"> | ||||||
|                 <div class="form-row"> |                         <div class="form-group col-md-12"> | ||||||
|                     <div class="form-group required col-md-12"> |                             <label for="server_PreUp">Pre Up</label> | ||||||
|                         <label for="server_PublicEndpoint">Public Endpoint for Clients</label> |                             <input type="text" name="preup" class="form-control" id="server_PreUp" value="{{.Device.PreUp}}"> | ||||||
|                         <input type="text" name="endpoint" class="form-control" id="server_PublicEndpoint" placeholder="vpn.company.com:51820" value="{{.Device.DefaultEndpoint}}" required> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                     <div class="form-row"> | ||||||
|                 <div class="form-row"> |                         <div class="form-group col-md-12"> | ||||||
|                     <div class="form-group col-md-6"> |                             <label for="server_PostUp">Post Up</label> | ||||||
|                         <label for="server_DNS">DNS Servers</label> |                             <input type="text" name="postup" class="form-control" id="server_PostUp" value="{{.Device.PostUp}}"> | ||||||
|                         <input type="text" name="dns" class="form-control" id="server_DNS" placeholder="1.1.1.1" value="{{.Device.DNSStr}}"> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div class="form-group col-md-6"> |                     <div class="form-row"> | ||||||
|                         <label for="server_AllowedIP">Default allowed IPs</label> |                         <div class="form-group col-md-12"> | ||||||
|                         <input type="text" name="allowedip" class="form-control" id="server_AllowedIP" placeholder="10.6.6.0/24" value="{{.Device.DefaultAllowedIPsStr}}"> |                             <label for="server_PreDown">Pre Down</label> | ||||||
|  |                             <input type="text" name="predown" class="form-control" id="server_PreDown" value="{{.Device.PreDown}}"> | ||||||
|  |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                     <div class="form-row"> | ||||||
|                 <div class="form-row"> |                         <div class="form-group col-md-12"> | ||||||
|                     <div class="form-group col-md-6"> |                             <label for="server_PostDown">Post Down</label> | ||||||
|                         <label for="server_MTU">Global MTU</label> |                             <input type="text" name="postdown" class="form-control" id="server_PostDown" value="{{.Device.PostDown}}"> | ||||||
|                         <input type="number" name="mtu" class="form-control" id="server_MTU" placeholder="" value="{{.Device.Mtu}}"> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div class="form-group col-md-6"> |  | ||||||
|                         <label for="server_PersistentKeepalive">Persistent Keepalive</label> |  | ||||||
|                         <input type="number" name="keepalive" class="form-control" id="server_PersistentKeepalive" placeholder="16" value="{{.Device.DefaultPersistentKeepalive}}"> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|                 <h3>Interface configuration hooks</h3> |  | ||||||
|                 <div class="form-row"> |  | ||||||
|                     <div class="form-group col-md-12"> |  | ||||||
|                         <label for="server_PreUp">Pre Up</label> |  | ||||||
|                         <input type="text" name="preup" class="form-control" id="server_PreUp" value="{{.Device.PreUp}}"> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="form-row"> |  | ||||||
|                     <div class="form-group col-md-12"> |  | ||||||
|                         <label for="server_PostUp">Post Up</label> |  | ||||||
|                         <input type="text" name="postup" class="form-control" id="server_PostUp" value="{{.Device.PostUp}}"> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="form-row"> |  | ||||||
|                     <div class="form-group col-md-12"> |  | ||||||
|                         <label for="server_PreDown">Pre Down</label> |  | ||||||
|                         <input type="text" name="predown" class="form-control" id="server_PreDown" value="{{.Device.PreDown}}"> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="form-row"> |  | ||||||
|                     <div class="form-group col-md-12"> |  | ||||||
|                         <label for="server_PostDown">Post Down</label> |  | ||||||
|                         <input type="text" name="postdown" class="form-control" id="server_PostDown" value="{{.Device.PostDown}}"> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
| 
 | 
 | ||||||
|                 <button type="submit" class="btn btn-primary">Save</button> |                     <div class="form-row"> | ||||||
|                 <a href="/admin" class="btn btn-secondary">Cancel</a> |                         <div class="d-flex align-items-center"> | ||||||
|                 <a href="/admin/device/applyglobals" class="btn btn-dark float-right">Apply Global Settings to peers</a> |                             <a href="#" class="advanced-settings btn btn-link collapsed" data-toggle="collapse" data-target="#collapseAdvancedServer" aria-expanded="false" aria-controls="collapseAdvancedServer"> | ||||||
|             </form> |                                 Advanced Settings | ||||||
|  |                             </a> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                     <div id="collapseAdvancedServer" class="collapse" aria-labelledby="collapseAdvancedServer"> | ||||||
|  |                         <div class="form-row"> | ||||||
|  |                             <div class="form-group col-md-6"> | ||||||
|  |                                 <label for="server_FirewallMark">Firewall Mark (0 = default or off)</label> | ||||||
|  |                                 <input type="number" name="firewallmark" class="form-control" id="server_FirewallMark" placeholder="" value="{{.Device.FirewallMark}}"> | ||||||
|  |                             </div> | ||||||
|  |                             <div class="form-group col-md-6"> | ||||||
|  |                                 <label for="server_RoutingTable">Routing Table (empty = default or auto)</label> | ||||||
|  |                                 <input type="text" name="routingtable" class="form-control" id="server_RoutingTable" placeholder="auto" value="{{.Device.RoutingTable}}"> | ||||||
|  |                             </div> | ||||||
|  |                         </div> | ||||||
|  |                         <div class="form-row"> | ||||||
|  |                             <div class="form-group col-md-12"> | ||||||
|  |                                 <div class="custom-control custom-switch"> | ||||||
|  |                                     <input class="custom-control-input" name="saveconfig" type="checkbox" value="true" id="server_SaveConfig" {{if .Peer.SaveConfig}}checked{{end}}> | ||||||
|  |                                     <label class="custom-control-label" for="server_SaveConfig"> | ||||||
|  |                                         Save Configuration (if interface was edited via WireGuard configuration tool) | ||||||
|  |                                     </label> | ||||||
|  |                                 </div> | ||||||
|  |                             </div> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  | 
 | ||||||
|  |                     <button type="submit" class="btn btn-primary">Save</button> | ||||||
|  |                     <a href="/admin" class="btn btn-secondary">Cancel</a> | ||||||
|  |                     <a href="/admin/device/applyglobals" class="btn btn-dark float-right">Apply Global Settings to clients</a> | ||||||
|  |                 </form> | ||||||
|             </div> |             </div> | ||||||
| 
 | 
 | ||||||
|             <!-- client mode --> |             <!-- client mode --> | ||||||
|             <div class="tab-pane fade {{if eq .Device.Type "client"}}active show{{end}}" id="client"> |             <div class="tab-pane fade {{if eq .Device.Type "client"}}active show{{end}}" id="client"> | ||||||
|                 <form method="post" enctype="multipart/form-data"> |                 <form method="post" enctype="multipart/form-data"> | ||||||
|             <input type="hidden" name="_csrf" value="{{.Csrf}}"> |                     <input type="hidden" name="_csrf" value="{{.Csrf}}"> | ||||||
|             <input type="hidden" name="device" value="{{.Device.DeviceName}}"> |                     <input type="hidden" name="device" value="{{.Device.DeviceName}}"> | ||||||
|             <input type="hidden" name="devicetype" value="client"> |                     <input type="hidden" name="devicetype" value="client"> | ||||||
|             <h3>Client's interface configuration</h3> |                     <h3>Client's interface configuration</h3> | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group col-md-12"> |                         <div class="form-group col-md-12"> | ||||||
|                     <label for="client_DisplayName">Display Name</label> |                             <label for="client_DisplayName">Display Name</label> | ||||||
|                     <input type="text" name="displayname" class="form-control" id="client_DisplayName" value="{{.Device.DisplayName}}"> |                             <input type="text" name="displayname" class="form-control" id="client_DisplayName" value="{{.Device.DisplayName}}"> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |                     </div> | ||||||
|             {{if .EditableKeys}} |                     {{if .EditableKeys}} | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group required col-md-12"> |                         <div class="form-group required col-md-12"> | ||||||
|                     <label for="client_PrivateKey">Private Key</label> |                             <label for="client_PrivateKey">Private Key</label> | ||||||
|                     <input type="text" name="privkey" class="form-control" id="client_PrivateKey" value="{{.Device.PrivateKey}}" required> |                             <input type="text" name="privkey" class="form-control" id="client_PrivateKey" value="{{.Device.PrivateKey}}" required> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |                     </div> | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group required col-md-12"> |                         <div class="form-group required col-md-12"> | ||||||
|                     <label for="client_PublicKey">Public Key</label> |                             <label for="client_PublicKey">Public Key</label> | ||||||
|                     <input type="text" name="pubkey" class="form-control" id="client_PublicKey" value="{{.Device.PublicKey}}" required> |                             <input type="text" name="pubkey" class="form-control" id="client_PublicKey" value="{{.Device.PublicKey}}" required> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |                     </div> | ||||||
|             {{else}} |                     {{else}} | ||||||
|             <input type="hidden" name="privkey" value="{{.Device.PrivateKey}}"> |                     <input type="hidden" name="privkey" value="{{.Device.PrivateKey}}"> | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group col-md-12"> |                         <div class="form-group col-md-12"> | ||||||
|                     <label for="client_ro_PublicKey">Public Key</label> |                             <label for="client_ro_PublicKey">Public Key</label> | ||||||
|                     <input type="text" name="pubkey" readonly class="form-control" id="client_ro_PublicKey" value="{{.Device.PublicKey}}"> |                             <input type="text" name="pubkey" readonly class="form-control" id="client_ro_PublicKey" value="{{.Device.PublicKey}}"> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |                     </div> | ||||||
|             {{end}} |                     {{end}} | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group required col-md-6"> |                         <div class="form-group required col-md-6"> | ||||||
|                     <label for="client_IPs">Client IP address</label> |                             <label for="client_IPs">Client IP address</label> | ||||||
|                     <input type="text" name="ip" class="form-control" id="client_IPs" placeholder="10.6.6.1/24" value="{{.Device.IPsStr}}" required> |                             <input type="text" name="ip" class="form-control" id="client_IPs" placeholder="10.6.6.1/24" value="{{.Device.IPsStr}}" required> | ||||||
|                 </div> |                         </div> | ||||||
|                 <div class="form-group col-md-6"> |                         <div class="form-group col-md-6"> | ||||||
|                     <label for="client_DNS">DNS Servers</label> |                             <label for="client_DNS">DNS Servers</label> | ||||||
|                     <input type="text" name="dns" class="form-control" id="client_DNS" placeholder="1.1.1.1" value="{{.Device.DNSStr}}"> |                             <input type="text" name="dns" class="form-control" id="client_DNS" placeholder="1.1.1.1" value="{{.Device.DNSStr}}"> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |                     </div> | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group col-md-4"> |                         <div class="form-group col-md-4"> | ||||||
|                     <label for="client_MTU">Global MTU</label> |                             <label for="client_MTU">MTU (0 = default)</label> | ||||||
|                     <input type="number" name="mtu" class="form-control" id="client_MTU" placeholder="" value="{{.Device.Mtu}}"> |                             <input type="number" name="mtu" class="form-control" id="client_MTU" placeholder="" value="{{.Device.Mtu}}"> | ||||||
|                 </div> |                         </div> | ||||||
|                 <div class="form-group col-md-4"> |                         <div class="form-group col-md-4"> | ||||||
|                     <label for="client_FirewallMark">Firewall Mark</label> |                             <label for="client_FirewallMark">Firewall Mark (0 = default or off)</label> | ||||||
|                     <input type="number" name="firewallmark" class="form-control" id="client_FirewallMark" placeholder="" value="{{.Device.FirewallMark}}"> |                             <input type="number" name="firewallmark" class="form-control" id="client_FirewallMark" placeholder="" value="{{.Device.FirewallMark}}"> | ||||||
|                 </div> |                         </div> | ||||||
|                 <div class="form-group col-md-4"> |                         <div class="form-group col-md-4"> | ||||||
|                     <label for="client_RoutingTable">Routing Table</label> |                             <label for="client_RoutingTable">Routing Table (empty = default or auto)</label> | ||||||
|                     <input type="text" name="routingtable" class="form-control" id="client_RoutingTable" placeholder="auto" value="{{.Device.RoutingTable}}"> |                             <input type="text" name="routingtable" class="form-control" id="client_RoutingTable" placeholder="auto" value="{{.Device.RoutingTable}}"> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |                     </div> | ||||||
|             <h3>Interface configuration hooks</h3> |                     <h3>Interface configuration hooks</h3> | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group col-md-12"> |                         <div class="form-group col-md-12"> | ||||||
|                     <label for="client_PreUp">Pre Up</label> |                             <label for="client_PreUp">Pre Up</label> | ||||||
|                     <input type="text" name="preup" class="form-control" id="client_PreUp" value="{{.Device.PreUp}}"> |                             <input type="text" name="preup" class="form-control" id="client_PreUp" value="{{.Device.PreUp}}"> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |                     </div> | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group col-md-12"> |                         <div class="form-group col-md-12"> | ||||||
|                     <label for="client_PostUp">Post Up</label> |                             <label for="client_PostUp">Post Up</label> | ||||||
|                     <input type="text" name="postup" class="form-control" id="client_PostUp" value="{{.Device.PostUp}}"> |                             <input type="text" name="postup" class="form-control" id="client_PostUp" value="{{.Device.PostUp}}"> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |                     </div> | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group col-md-12"> |                         <div class="form-group col-md-12"> | ||||||
|                     <label for="client_PreDown">Pre Down</label> |                             <label for="client_PreDown">Pre Down</label> | ||||||
|                     <input type="text" name="predown" class="form-control" id="client_PreDown" value="{{.Device.PreDown}}"> |                             <input type="text" name="predown" class="form-control" id="client_PreDown" value="{{.Device.PreDown}}"> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |                     </div> | ||||||
|             <div class="form-row"> |                     <div class="form-row"> | ||||||
|                 <div class="form-group col-md-12"> |                         <div class="form-group col-md-12"> | ||||||
|                     <label for="client_PostDown">Post Down</label> |                             <label for="client_PostDown">Post Down</label> | ||||||
|                     <input type="text" name="postdown" class="form-control" id="client_PostDown" value="{{.Device.PostDown}}"> |                             <input type="text" name="postdown" class="form-control" id="client_PostDown" value="{{.Device.PostDown}}"> | ||||||
|                 </div> |                         </div> | ||||||
|             </div> |  | ||||||
| 
 |  | ||||||
|             <button type="submit" class="btn btn-primary">Save</button> |  | ||||||
|             <a href="/admin" class="btn btn-secondary">Cancel</a> |  | ||||||
|         </form> |  | ||||||
|             </div> |  | ||||||
| 
 |  | ||||||
|             <!-- custom mode --> |  | ||||||
|             <div class="tab-pane fade {{if eq .Device.Type "custom"}}active show{{end}}" id="custom"> |  | ||||||
|                 <form method="post" enctype="multipart/form-data"> |  | ||||||
|             <input type="hidden" name="_csrf" value="{{.Csrf}}"> |  | ||||||
|             <input type="hidden" name="device" value="{{.Device.DeviceName}}"> |  | ||||||
|             <input type="hidden" name="devicetype" value="custom"> |  | ||||||
|             <h3>Custom interface configuration</h3> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_DisplayName">Display Name</label> |  | ||||||
|                     <input type="text" name="displayname" class="form-control" id="custom_DisplayName" value="{{.Device.DisplayName}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             {{if .EditableKeys}} |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group required col-md-12"> |  | ||||||
|                     <label for="custom_PrivateKey">Private Key</label> |  | ||||||
|                     <input type="text" name="privkey" class="form-control" id="custom_PrivateKey" value="{{.Device.PrivateKey}}" required> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group required col-md-12"> |  | ||||||
|                     <label for="custom_PublicKey">Public Key</label> |  | ||||||
|                     <input type="text" name="pubkey" class="form-control" id="custom_PublicKey" value="{{.Device.PublicKey}}" required> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             {{else}} |  | ||||||
|             <input type="hidden" name="privkey" value="{{.Device.PrivateKey}}"> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_ro_PublicKey">Public Key</label> |  | ||||||
|                     <input type="text" name="pubkey" readonly class="form-control" id="custom_ro_PublicKey" value="{{.Device.PublicKey}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             {{end}} |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_ListenPort">Listen port</label> |  | ||||||
|                     <input type="number" name="port" class="form-control" id="custom_ListenPort" placeholder="51820" value="{{.Device.ListenPort}}"> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="form-group required col-md-6"> |  | ||||||
|                     <label for="custom_IPs">Interface IP address</label> |  | ||||||
|                     <input type="text" name="ip" class="form-control" id="custom_IPs" placeholder="10.6.6.1/24" value="{{.Device.IPsStr}}" required> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_FirewallMark">Firewall Mark</label> |  | ||||||
|                     <input type="number" name="firewallmark" class="form-control" id="custom_FirewallMark" placeholder="" value="{{.Device.FirewallMark}}"> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_RoutingTable">Routing Table</label> |  | ||||||
|                     <input type="text" name="routingtable" class="form-control" id="custom_RoutingTable" placeholder="auto" value="{{.Device.RoutingTable}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <div class="custom-control custom-switch"> |  | ||||||
|                         <input class="custom-control-input" name="saveconfig" type="checkbox" value="true" id="custom_SaveConfig" {{if .Peer.SaveConfig}}checked{{end}}> |  | ||||||
|                         <label class="custom-control-label" for="custom_SaveConfig"> |  | ||||||
|                             Save Configuration (if Interface was edited via WireGuard configuration tool) |  | ||||||
|                         </label> |  | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <h3>Peer's global configuration</h3> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_PublicEndpoint">Public Endpoint for Clients</label> |  | ||||||
|                     <input type="text" name="endpoint" class="form-control" id="custom_PublicEndpoint" placeholder="vpn.company.com:51820" value="{{.Device.DefaultEndpoint}}"> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_PersistentKeepalive">Persistent Keepalive</label> |  | ||||||
|                     <input type="number" name="keepalive" class="form-control" id="custom_PersistentKeepalive" placeholder="16" value="{{.Device.DefaultPersistentKeepalive}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_DNS">DNS Servers</label> |  | ||||||
|                     <input type="text" name="dns" class="form-control" id="custom_DNS" placeholder="1.1.1.1" value="{{.Device.DNSStr}}"> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_AllowedIP">Default allowed IPs</label> |  | ||||||
|                     <input type="text" name="allowedip" class="form-control" id="custom_AllowedIP" placeholder="10.6.6.0/24" value="{{.Device.DefaultAllowedIPsStr}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-6"> |  | ||||||
|                     <label for="custom_MTU">Global MTU</label> |  | ||||||
|                     <input type="number" name="mtu" class="form-control" id="custom_MTU" placeholder="" value="{{.Device.Mtu}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <h3>Interface configuration hooks</h3> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_PreUp">Pre Up</label> |  | ||||||
|                     <input type="text" name="preup" class="form-control" id="custom_PreUp" value="{{.Device.PreUp}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="server_PostUp">Post Up</label> |  | ||||||
|                     <input type="text" name="postup" class="form-control" id="custom_PostUp" value="{{.Device.PostUp}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="custom_PreDown">Pre Down</label> |  | ||||||
|                     <input type="text" name="predown" class="form-control" id="custom_PreDown" value="{{.Device.PreDown}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="form-row"> |  | ||||||
|                 <div class="form-group col-md-12"> |  | ||||||
|                     <label for="server_PostDown">Post Down</label> |  | ||||||
|                     <input type="text" name="postdown" class="form-control" id="custom_PostDown" value="{{.Device.PostDown}}"> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
| 
 | 
 | ||||||
|             <button type="submit" class="btn btn-primary">Save</button> |                     <button type="submit" class="btn btn-primary">Save</button> | ||||||
|             <a href="/admin" class="btn btn-secondary">Cancel</a> |                     <a href="/admin" class="btn btn-secondary">Cancel</a> | ||||||
|             <a href="/admin/device/applyglobals" class="btn btn-dark float-right">Apply Global Settings to clients</a> |                 </form> | ||||||
|         </form> |  | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|  | @ -18,7 +18,9 @@ | ||||||
|         <div class="card"> |         <div class="card"> | ||||||
|             <div class="card-header"> |             <div class="card-header"> | ||||||
|                 <div class="d-flex align-items-center"> |                 <div class="d-flex align-items-center"> | ||||||
|                     <span class="mr-auto">Interface status for <strong>{{.Device.DeviceName}}</strong></span> |                     <span class="mr-auto">Interface status for <strong>{{.Device.DeviceName}}</strong> {{if eq $.Device.Type "server"}}(server mode){{end}}{{if eq $.Device.Type "client"}}(client mode){{end}}</span> | ||||||
|  |                     <a href="/admin/device/write?dev={{.Device.DeviceName}}" title="Write interface configuration"><i class="fas fa-save"></i></a> | ||||||
|  |                         | ||||||
|                     <a href="/admin/device/download?dev={{.Device.DeviceName}}" title="Download interface configuration"><i class="fas fa-download"></i></a> |                     <a href="/admin/device/download?dev={{.Device.DeviceName}}" title="Download interface configuration"><i class="fas fa-download"></i></a> | ||||||
|                         |                         | ||||||
|                     <a href="/admin/device/edit?dev={{.Device.DeviceName}}" title="Edit interface settings"><i class="fas fa-cog"></i></a> |                     <a href="/admin/device/edit?dev={{.Device.DeviceName}}" title="Edit interface settings"><i class="fas fa-cog"></i></a> | ||||||
|  | @ -26,6 +28,7 @@ | ||||||
|             </div> |             </div> | ||||||
|             <div class="card-body"> |             <div class="card-body"> | ||||||
|                 <div class="row"> |                 <div class="row"> | ||||||
|  |                     {{if eq $.Device.Type "server"}} | ||||||
|                     <div class="col-sm-6"> |                     <div class="col-sm-6"> | ||||||
|                         <table class="table table-sm table-borderless device-status-table"> |                         <table class="table table-sm table-borderless device-status-table"> | ||||||
|                             <tbody> |                             <tbody> | ||||||
|  | @ -78,21 +81,60 @@ | ||||||
|                             </tbody> |                             </tbody> | ||||||
|                         </table> |                         </table> | ||||||
|                     </div> |                     </div> | ||||||
|  |                     {{end}} | ||||||
|  |                     {{if eq $.Device.Type "client"}} | ||||||
|  |                     <div class="col-sm-6"> | ||||||
|  |                         <table class="table table-sm table-borderless device-status-table"> | ||||||
|  |                             <tbody> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td>Public Key:</td> | ||||||
|  |                                 <td>{{.Device.PublicKey}}</td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td>Enabled Endpoints:</td> | ||||||
|  |                                 <td>{{len .Device.Interface.Peers}}</td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td>Total Endpoints:</td> | ||||||
|  |                                 <td>{{.TotalPeers}}</td> | ||||||
|  |                             </tr> | ||||||
|  |                             </tbody> | ||||||
|  |                         </table> | ||||||
|  |                     </div> | ||||||
|  |                     <div class="col-sm-6"> | ||||||
|  |                         <table class="table table-sm table-borderless device-status-table"> | ||||||
|  |                             <tbody> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td>IP Address:</td> | ||||||
|  |                                 <td>{{.Device.IPsStr}}</td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td>DNS servers:</td> | ||||||
|  |                                 <td>{{.Device.DNSStr}}</td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td>Default MTU:</td> | ||||||
|  |                                 <td>{{.Device.Mtu}}</td> | ||||||
|  |                             </tr> | ||||||
|  |                             </tbody> | ||||||
|  |                         </table> | ||||||
|  |                     </div> | ||||||
|  |                     {{end}} | ||||||
|                 </div> |                 </div> | ||||||
| 
 | 
 | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|         <div class="mt-4 row"> |         <div class="mt-4 row"> | ||||||
|             <div class="col-sm-10 col-12"> |             <div class="col-sm-10 col-12"> | ||||||
|                 {{with or (eq $.Device.Type "server") (eq $.Device.Type "custom")}} |                 {{if eq $.Device.Type "server"}} | ||||||
|                 <h2 class="mt-2">Current VPN Peers</h2> |                 <h2 class="mt-2">Current VPN Peers</h2> | ||||||
|                 {{end}} |                 {{end}} | ||||||
|                 {{with eq $.Device.Type "client"}} |                 {{if eq $.Device.Type "client"}} | ||||||
|                 <h2 class="mt-2">Current VPN Endpoints</h2> |                 <h2 class="mt-2">Current VPN Endpoints</h2> | ||||||
|                 {{end}} |                 {{end}} | ||||||
|             </div> |             </div> | ||||||
|             <div class="col-sm-2 col-12 text-right"> |             <div class="col-sm-2 col-12 text-right"> | ||||||
|                 {{with eq $.Device.Type "server"}} |                 {{if eq $.Device.Type "server"}} | ||||||
|                 <a href="/admin/peer/createldap" title="Add multiple peers" class="btn btn-primary"><i class="fa fa-fw fa-user-plus"></i></a> |                 <a href="/admin/peer/createldap" title="Add multiple peers" class="btn btn-primary"><i class="fa fa-fw fa-user-plus"></i></a> | ||||||
|                 {{end}} |                 {{end}} | ||||||
|                 <a href="/admin/peer/create" title="Add a peer" class="btn btn-primary"><i class="fa fa-fw fa-plus"></i>M</a> |                 <a href="/admin/peer/create" title="Add a peer" class="btn btn-primary"><i class="fa fa-fw fa-plus"></i>M</a> | ||||||
|  | @ -140,9 +182,11 @@ | ||||||
|                                             <li class="nav-item"> |                                             <li class="nav-item"> | ||||||
|                                                 <a class="nav-link active" data-toggle="tab" href="#t1{{$p.UID}}">Personal</a> |                                                 <a class="nav-link active" data-toggle="tab" href="#t1{{$p.UID}}">Personal</a> | ||||||
|                                             </li> |                                             </li> | ||||||
|  |                                             {{if eq $.Device.Type "server"}} | ||||||
|                                             <li class="nav-item"> |                                             <li class="nav-item"> | ||||||
|                                                 <a class="nav-link" data-toggle="tab" href="#t2{{$p.UID}}">Configuration</a> |                                                 <a class="nav-link" data-toggle="tab" href="#t2{{$p.UID}}">Configuration</a> | ||||||
|                                             </li> |                                             </li> | ||||||
|  |                                             {{end}} | ||||||
|                                             <li class="nav-item"> |                                             <li class="nav-item"> | ||||||
|                                                 <a class="nav-link" data-toggle="tab" href="#t3{{$p.UID}}">Danger Zone</a> |                                                 <a class="nav-link" data-toggle="tab" href="#t3{{$p.UID}}">Danger Zone</a> | ||||||
|                                             </li> |                                             </li> | ||||||
|  | @ -168,22 +212,28 @@ | ||||||
|                                                     <p class="ml-4">{{if $p.DeactivatedAt}}-{{else}}<i class="fas fa-long-arrow-alt-down" title="Download"></i> {{formatBytes $p.Peer.ReceiveBytes}} / <i class="fas fa-long-arrow-alt-up" title="Upload"></i> {{formatBytes $p.Peer.TransmitBytes}}{{end}}</p> |                                                     <p class="ml-4">{{if $p.DeactivatedAt}}-{{else}}<i class="fas fa-long-arrow-alt-down" title="Download"></i> {{formatBytes $p.Peer.ReceiveBytes}} / <i class="fas fa-long-arrow-alt-up" title="Upload"></i> {{formatBytes $p.Peer.TransmitBytes}}{{end}}</p> | ||||||
|                                                 {{end}} |                                                 {{end}} | ||||||
|                                             </div> |                                             </div> | ||||||
|  |                                             {{if eq $.Device.Type "server"}} | ||||||
|                                             <div id="t2{{$p.UID}}" class="tab-pane fade"> |                                             <div id="t2{{$p.UID}}" class="tab-pane fade"> | ||||||
|                                                 <pre>{{$p.Config}}</pre> |                                                 <pre>{{$p.Config}}</pre> | ||||||
|                                             </div> |                                             </div> | ||||||
|  |                                             {{end}} | ||||||
|                                             <div id="t3{{$p.UID}}" class="tab-pane fade"> |                                             <div id="t3{{$p.UID}}" class="tab-pane fade"> | ||||||
|                                                 <a href="/admin/peer/delete?pkey={{$p.PublicKey}}" class="btn btn-danger" title="Delete peer">Delete</a> |                                                 <a href="/admin/peer/delete?pkey={{$p.PublicKey}}" class="btn btn-danger" title="Delete peer">Delete</a> | ||||||
|                                             </div> |                                             </div> | ||||||
|                                         </div> |                                         </div> | ||||||
|                                     </div> |                                     </div> | ||||||
|                                     <div class="col-md-3"> |                                     <div class="col-md-3"> | ||||||
|  |                                         {{if eq $.Device.Type "server"}} | ||||||
|                                         <img class="list-image-large" src="/user/qrcode?pkey={{$p.PublicKey}}"/> |                                         <img class="list-image-large" src="/user/qrcode?pkey={{$p.PublicKey}}"/> | ||||||
|  |                                         {{end}} | ||||||
|                                     </div> |                                     </div> | ||||||
|                                     <div class="col-md-3"> |                                     <div class="col-md-3"> | ||||||
|  |                                         {{if eq $.Device.Type "server"}} | ||||||
|                                         <div class="float-right mt-5"> |                                         <div class="float-right mt-5"> | ||||||
|                                         <a href="/admin/peer/download?pkey={{$p.PublicKey}}" class="btn btn-primary" title="Download configuration">Download</a> |                                         <a href="/admin/peer/download?pkey={{$p.PublicKey}}" class="btn btn-primary" title="Download configuration">Download</a> | ||||||
|                                         <a href="/admin/peer/email?pkey={{$p.PublicKey}}" class="btn btn-primary" title="Send configuration via Email">Email</a> |                                         <a href="/admin/peer/email?pkey={{$p.PublicKey}}" class="btn btn-primary" title="Send configuration via Email">Email</a> | ||||||
|                                         </div> |                                         </div> | ||||||
|  |                                         {{end}} | ||||||
|                                     </div> |                                     </div> | ||||||
|                                 </div> |                                 </div> | ||||||
|                             </div> |                             </div> | ||||||
|  |  | ||||||
|  | @ -160,6 +160,7 @@ func (s *Server) updateFormInSession(c *gin.Context, formData interface{}) error | ||||||
| 
 | 
 | ||||||
| func (s *Server) setNewPeerFormInSession(c *gin.Context) (SessionData, error) { | func (s *Server) setNewPeerFormInSession(c *gin.Context) (SessionData, error) { | ||||||
| 	currentSession := GetSessionData(c) | 	currentSession := GetSessionData(c) | ||||||
|  | 
 | ||||||
| 	// If session does not contain a peer form ignore update
 | 	// If session does not contain a peer form ignore update
 | ||||||
| 	// If url contains a formerr parameter reset the form
 | 	// If url contains a formerr parameter reset the form
 | ||||||
| 	if currentSession.FormData == nil || c.Query("formerr") == "" { | 	if currentSession.FormData == nil || c.Query("formerr") == "" { | ||||||
|  |  | ||||||
|  | @ -58,8 +58,6 @@ func (s *Server) PostAdminEditInterface(c *gin.Context) { | ||||||
| 		formDevice.DefaultPersistentKeepalive = 0 | 		formDevice.DefaultPersistentKeepalive = 0 | ||||||
| 		formDevice.SaveConfig = false | 		formDevice.SaveConfig = false | ||||||
| 	case wireguard.DeviceTypeServer: | 	case wireguard.DeviceTypeServer: | ||||||
| 		formDevice.SaveConfig = false |  | ||||||
| 	case wireguard.DeviceTypeCustom: |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Update WireGuard device
 | 	// Update WireGuard device
 | ||||||
|  | @ -127,6 +125,21 @@ func (s *Server) GetInterfaceConfig(c *gin.Context) { | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (s *Server) GetSaveConfig(c *gin.Context) { | ||||||
|  | 	currentSession := GetSessionData(c) | ||||||
|  | 
 | ||||||
|  | 	err := s.WriteWireGuardConfigFile(currentSession.DeviceName) | ||||||
|  | 	if err != nil { | ||||||
|  | 		SetFlashMessage(c, "Failed to save WireGuard config-file: "+err.Error(), "danger") | ||||||
|  | 		c.Redirect(http.StatusSeeOther, "/admin/") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	SetFlashMessage(c, "Updated WireGuard config-file", "success") | ||||||
|  | 	c.Redirect(http.StatusSeeOther, "/admin/") | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (s *Server) GetApplyGlobalConfig(c *gin.Context) { | func (s *Server) GetApplyGlobalConfig(c *gin.Context) { | ||||||
| 	currentSession := GetSessionData(c) | 	currentSession := GetSessionData(c) | ||||||
| 	device := s.peers.GetDevice(currentSession.DeviceName) | 	device := s.peers.GetDevice(currentSession.DeviceName) | ||||||
|  | @ -149,10 +162,7 @@ func (s *Server) GetApplyGlobalConfig(c *gin.Context) { | ||||||
| 		peer.PersistentKeepalive = device.DefaultPersistentKeepalive | 		peer.PersistentKeepalive = device.DefaultPersistentKeepalive | ||||||
| 		peer.DNSStr = device.DNSStr | 		peer.DNSStr = device.DNSStr | ||||||
| 		peer.Mtu = device.Mtu | 		peer.Mtu = device.Mtu | ||||||
| 
 | 		peer.EndpointPublicKey = device.PublicKey | ||||||
| 		if device.Type == wireguard.DeviceTypeServer { |  | ||||||
| 			peer.EndpointPublicKey = device.PublicKey |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		if err := s.peers.UpdatePeer(peer); err != nil { | 		if err := s.peers.UpdatePeer(peer); err != nil { | ||||||
| 			SetFlashMessage(c, err.Error(), "danger") | 			SetFlashMessage(c, err.Error(), "danger") | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ func SetupRoutes(s *Server) { | ||||||
| 	admin.GET("/device/edit", s.GetAdminEditInterface) | 	admin.GET("/device/edit", s.GetAdminEditInterface) | ||||||
| 	admin.POST("/device/edit", s.PostAdminEditInterface) | 	admin.POST("/device/edit", s.PostAdminEditInterface) | ||||||
| 	admin.GET("/device/download", s.GetInterfaceConfig) | 	admin.GET("/device/download", s.GetInterfaceConfig) | ||||||
|  | 	admin.GET("/device/write", s.GetSaveConfig) | ||||||
| 	admin.GET("/device/applyglobals", s.GetApplyGlobalConfig) | 	admin.GET("/device/applyglobals", s.GetApplyGlobalConfig) | ||||||
| 	admin.GET("/peer/edit", s.GetAdminEditPeer) | 	admin.GET("/peer/edit", s.GetAdminEditPeer) | ||||||
| 	admin.POST("/peer/edit", s.PostAdminEditPeer) | 	admin.POST("/peer/edit", s.PostAdminEditPeer) | ||||||
|  |  | ||||||
|  | @ -46,8 +46,6 @@ func (s *Server) PrepareNewPeer(device string) (wireguard.Peer, error) { | ||||||
| 	peer.UID = fmt.Sprintf("u%x", md5.Sum([]byte(peer.PublicKey))) | 	peer.UID = fmt.Sprintf("u%x", md5.Sum([]byte(peer.PublicKey))) | ||||||
| 
 | 
 | ||||||
| 	switch dev.Type { | 	switch dev.Type { | ||||||
| 	case wireguard.DeviceTypeCustom: |  | ||||||
| 		fallthrough |  | ||||||
| 	case wireguard.DeviceTypeServer: | 	case wireguard.DeviceTypeServer: | ||||||
| 		peer.EndpointPublicKey = dev.PublicKey | 		peer.EndpointPublicKey = dev.PublicKey | ||||||
| 		peer.Endpoint = dev.DefaultEndpoint | 		peer.Endpoint = dev.DefaultEndpoint | ||||||
|  | @ -121,7 +119,7 @@ func (s *Server) CreatePeer(device string, peer wireguard.Peer) error { | ||||||
| 
 | 
 | ||||||
| 	// Create WireGuard interface
 | 	// Create WireGuard interface
 | ||||||
| 	if peer.DeactivatedAt == nil { | 	if peer.DeactivatedAt == nil { | ||||||
| 		if err := s.wg.AddPeer(device, peer.GetConfig()); err != nil { | 		if err := s.wg.AddPeer(device, peer.GetConfig(&dev)); err != nil { | ||||||
| 			return errors.WithMessage(err, "failed to add WireGuard peer") | 			return errors.WithMessage(err, "failed to add WireGuard peer") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -137,6 +135,7 @@ func (s *Server) CreatePeer(device string, peer wireguard.Peer) error { | ||||||
| // UpdatePeer updates the physical WireGuard interface and the database.
 | // UpdatePeer updates the physical WireGuard interface and the database.
 | ||||||
| func (s *Server) UpdatePeer(peer wireguard.Peer, updateTime time.Time) error { | func (s *Server) UpdatePeer(peer wireguard.Peer, updateTime time.Time) error { | ||||||
| 	currentPeer := s.peers.GetPeerByKey(peer.PublicKey) | 	currentPeer := s.peers.GetPeerByKey(peer.PublicKey) | ||||||
|  | 	dev := s.peers.GetDevice(peer.DeviceName) | ||||||
| 
 | 
 | ||||||
| 	// Update WireGuard device
 | 	// Update WireGuard device
 | ||||||
| 	var err error | 	var err error | ||||||
|  | @ -144,9 +143,9 @@ func (s *Server) UpdatePeer(peer wireguard.Peer, updateTime time.Time) error { | ||||||
| 	case peer.DeactivatedAt == &updateTime: | 	case peer.DeactivatedAt == &updateTime: | ||||||
| 		err = s.wg.RemovePeer(peer.DeviceName, peer.PublicKey) | 		err = s.wg.RemovePeer(peer.DeviceName, peer.PublicKey) | ||||||
| 	case peer.DeactivatedAt == nil && currentPeer.Peer != nil: | 	case peer.DeactivatedAt == nil && currentPeer.Peer != nil: | ||||||
| 		err = s.wg.UpdatePeer(peer.DeviceName, peer.GetConfig()) | 		err = s.wg.UpdatePeer(peer.DeviceName, peer.GetConfig(&dev)) | ||||||
| 	case peer.DeactivatedAt == nil && currentPeer.Peer == nil: | 	case peer.DeactivatedAt == nil && currentPeer.Peer == nil: | ||||||
| 		err = s.wg.AddPeer(peer.DeviceName, peer.GetConfig()) | 		err = s.wg.AddPeer(peer.DeviceName, peer.GetConfig(&dev)) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return errors.WithMessage(err, "failed to update WireGuard peer") | 		return errors.WithMessage(err, "failed to update WireGuard peer") | ||||||
|  | @ -178,10 +177,11 @@ func (s *Server) DeletePeer(peer wireguard.Peer) error { | ||||||
| // RestoreWireGuardInterface restores the state of the physical WireGuard interface from the database.
 | // RestoreWireGuardInterface restores the state of the physical WireGuard interface from the database.
 | ||||||
| func (s *Server) RestoreWireGuardInterface(device string) error { | func (s *Server) RestoreWireGuardInterface(device string) error { | ||||||
| 	activePeers := s.peers.GetActivePeers(device) | 	activePeers := s.peers.GetActivePeers(device) | ||||||
|  | 	dev := s.peers.GetDevice(device) | ||||||
| 
 | 
 | ||||||
| 	for i := range activePeers { | 	for i := range activePeers { | ||||||
| 		if activePeers[i].Peer == nil { | 		if activePeers[i].Peer == nil { | ||||||
| 			if err := s.wg.AddPeer(device, activePeers[i].GetConfig()); err != nil { | 			if err := s.wg.AddPeer(device, activePeers[i].GetConfig(&dev)); err != nil { | ||||||
| 				return errors.WithMessage(err, "failed to add WireGuard peer") | 				return errors.WithMessage(err, "failed to add WireGuard peer") | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -126,8 +126,15 @@ func (p Peer) GetAllowedIPs() []string { | ||||||
| 	return common.ParseStringList(p.AllowedIPsStr) | 	return common.ParseStringList(p.AllowedIPsStr) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p Peer) GetConfig() wgtypes.PeerConfig { | func (p Peer) GetConfig(dev *Device) wgtypes.PeerConfig { | ||||||
| 	publicKey, _ := wgtypes.ParseKey(p.PublicKey) | 	var publicKey wgtypes.Key | ||||||
|  | 	switch dev.Type { | ||||||
|  | 	case DeviceTypeServer: | ||||||
|  | 		publicKey, _ = wgtypes.ParseKey(p.PublicKey) | ||||||
|  | 	case DeviceTypeClient: | ||||||
|  | 		publicKey, _ = wgtypes.ParseKey(p.EndpointPublicKey) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	var presharedKey *wgtypes.Key | 	var presharedKey *wgtypes.Key | ||||||
| 	if p.PresharedKey != "" { | 	if p.PresharedKey != "" { | ||||||
| 		presharedKeyTmp, _ := wgtypes.ParseKey(p.PresharedKey) | 		presharedKeyTmp, _ := wgtypes.ParseKey(p.PresharedKey) | ||||||
|  | @ -218,7 +225,6 @@ type DeviceType string | ||||||
| const ( | const ( | ||||||
| 	DeviceTypeServer DeviceType = "server" | 	DeviceTypeServer DeviceType = "server" | ||||||
| 	DeviceTypeClient DeviceType = "client" | 	DeviceTypeClient DeviceType = "client" | ||||||
| 	DeviceTypeCustom DeviceType = "custom" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type Device struct { | type Device struct { | ||||||
|  | @ -272,7 +278,6 @@ func (d Device) IsValid() bool { | ||||||
| 		if len(d.GetIPAddresses()) == 0 { | 		if len(d.GetIPAddresses()) == 0 { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 	case DeviceTypeCustom: |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return true | 	return true | ||||||
|  | @ -360,6 +365,17 @@ func NewPeerManager(db *gorm.DB, wg *Manager) (*PeerManager, error) { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// validate and update existing peers if needed
 | ||||||
|  | 	for _, deviceName := range wg.Cfg.DeviceNames { | ||||||
|  | 		dev := pm.GetDevice(deviceName) | ||||||
|  | 		peers = pm.GetAllPeers(deviceName) | ||||||
|  | 		for i := range peers { | ||||||
|  | 			if err := pm.fixPeerDefaultData(&peers[i], &dev); err != nil { | ||||||
|  | 				return nil, errors.WithMessagef(err, "unable to fix peers for interface %s", deviceName) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return pm, nil | 	return pm, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -406,16 +422,33 @@ func (m *PeerManager) InitFromPhysicalInterface() error { | ||||||
| // assumption: server mode is used
 | // assumption: server mode is used
 | ||||||
| func (m *PeerManager) validateOrCreatePeer(device string, wgPeer wgtypes.Peer) error { | func (m *PeerManager) validateOrCreatePeer(device string, wgPeer wgtypes.Peer) error { | ||||||
| 	peer := Peer{} | 	peer := Peer{} | ||||||
| 	m.db.Where("public_key = ?", wgPeer.PublicKey.String()).FirstOrInit(&peer) | 	m.db.Where("public_key = ? OR endpoint_public_key = ?", wgPeer.PublicKey.String(), wgPeer.PublicKey.String()).FirstOrInit(&peer) | ||||||
|  | 
 | ||||||
|  | 	dev := m.GetDevice(device) | ||||||
| 
 | 
 | ||||||
| 	if peer.PublicKey == "" { // peer not found, create
 | 	if peer.PublicKey == "" { // peer not found, create
 | ||||||
| 		peer.UID = fmt.Sprintf("u%x", md5.Sum([]byte(wgPeer.PublicKey.String()))) | 		peer.UID = fmt.Sprintf("u%x", md5.Sum([]byte(wgPeer.PublicKey.String()))) | ||||||
| 		peer.PublicKey = wgPeer.PublicKey.String() | 		if dev.Type == DeviceTypeServer { | ||||||
|  | 			peer.PublicKey = wgPeer.PublicKey.String() | ||||||
|  | 			peer.Identifier = "Autodetected Client (" + peer.PublicKey[0:8] + ")" | ||||||
|  | 		} else if dev.Type == DeviceTypeClient { | ||||||
|  | 			// create a new key pair, not really needed but otherwise our "client exists" detection does not work...
 | ||||||
|  | 			key, err := wgtypes.GeneratePrivateKey() | ||||||
|  | 			if err != nil { | ||||||
|  | 				return errors.Wrap(err, "failed to generate dummy private key") | ||||||
|  | 			} | ||||||
|  | 			peer.PrivateKey = key.String() | ||||||
|  | 			peer.PublicKey = key.PublicKey().String() | ||||||
|  | 			peer.EndpointPublicKey = wgPeer.PublicKey.String() | ||||||
|  | 			if wgPeer.Endpoint != nil { | ||||||
|  | 				peer.Endpoint = wgPeer.Endpoint.String() | ||||||
|  | 			} | ||||||
|  | 			peer.Identifier = "Autodetected Endpoint (" + peer.EndpointPublicKey[0:8] + ")" | ||||||
|  | 		} | ||||||
| 		if wgPeer.PresharedKey != (wgtypes.Key{}) { | 		if wgPeer.PresharedKey != (wgtypes.Key{}) { | ||||||
| 			peer.PresharedKey = wgPeer.PresharedKey.String() | 			peer.PresharedKey = wgPeer.PresharedKey.String() | ||||||
| 		} | 		} | ||||||
| 		peer.Email = "autodetected@example.com" | 		peer.Email = "autodetected@example.com" | ||||||
| 		peer.Identifier = "Autodetected Client (" + peer.PublicKey[0:8] + ")" |  | ||||||
| 		peer.UpdatedAt = time.Now() | 		peer.UpdatedAt = time.Now() | ||||||
| 		peer.CreatedAt = time.Now() | 		peer.CreatedAt = time.Now() | ||||||
| 		IPs := make([]string, len(wgPeer.AllowedIPs)) // use allowed IP's as the peer IP's
 | 		IPs := make([]string, len(wgPeer.AllowedIPs)) // use allowed IP's as the peer IP's
 | ||||||
|  | @ -424,9 +457,6 @@ func (m *PeerManager) validateOrCreatePeer(device string, wgPeer wgtypes.Peer) e | ||||||
| 		} | 		} | ||||||
| 		peer.SetIPAddresses(IPs...) | 		peer.SetIPAddresses(IPs...) | ||||||
| 		peer.DeviceName = device | 		peer.DeviceName = device | ||||||
| 		if wgPeer.Endpoint != nil { |  | ||||||
| 			peer.Endpoint = wgPeer.Endpoint.String() // TODO: do we need to import this for server mode?
 |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		res := m.db.Create(&peer) | 		res := m.db.Create(&peer) | ||||||
| 		if res.Error != nil { | 		if res.Error != nil { | ||||||
|  | @ -494,6 +524,29 @@ func (m *PeerManager) populatePeerData(peer *Peer) { | ||||||
| 	peer.IsOnline = false | 	peer.IsOnline = false | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // fixPeerDefaultData tries to fill all required fields for the given peer
 | ||||||
|  | func (m *PeerManager) fixPeerDefaultData(peer *Peer, device *Device) error { | ||||||
|  | 	updatePeer := false | ||||||
|  | 
 | ||||||
|  | 	switch device.Type { | ||||||
|  | 	case DeviceTypeServer: | ||||||
|  | 		if peer.Endpoint == "" { | ||||||
|  | 			peer.Endpoint = device.DefaultEndpoint | ||||||
|  | 			updatePeer = true | ||||||
|  | 		} | ||||||
|  | 		if peer.EndpointPublicKey == "" { | ||||||
|  | 			peer.EndpointPublicKey = device.PublicKey | ||||||
|  | 			updatePeer = true | ||||||
|  | 		} | ||||||
|  | 	case DeviceTypeClient: | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if updatePeer { | ||||||
|  | 		return m.UpdatePeer(*peer) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // populateDeviceData enriches the device struct with WireGuard live data like interface information
 | // populateDeviceData enriches the device struct with WireGuard live data like interface information
 | ||||||
| func (m *PeerManager) populateDeviceData(device *Device) { | func (m *PeerManager) populateDeviceData(device *Device) { | ||||||
| 	// set data from WireGuard interface
 | 	// set data from WireGuard interface
 | ||||||
|  |  | ||||||
|  | @ -10,13 +10,16 @@ | ||||||
| PrivateKey = {{ .Interface.PrivateKey }} | PrivateKey = {{ .Interface.PrivateKey }} | ||||||
| Address = {{ .Interface.IPsStr }} | Address = {{ .Interface.IPsStr }} | ||||||
| 
 | 
 | ||||||
| # Misc. settings | # Misc. settings (optional) | ||||||
| {{- if ne .Interface.ListenPort 0}} | {{- if ne .Interface.ListenPort 0}} | ||||||
| ListenPort = {{ .Interface.ListenPort }} | ListenPort = {{ .Interface.ListenPort }} | ||||||
| {{- end}} | {{- end}} | ||||||
| {{- if ne .Interface.Mtu 0}} | {{- if ne .Interface.Mtu 0}} | ||||||
| MTU = {{.Interface.Mtu}} | MTU = {{.Interface.Mtu}} | ||||||
| {{- end}} | {{- end}} | ||||||
|  | {{- if and (ne .Interface.DNSStr "") (eq $.Interface.Type "client")}} | ||||||
|  | DNS = {{ .Interface.DNSStr }} | ||||||
|  | {{- end}} | ||||||
| {{- if ne .Interface.FirewallMark 0}} | {{- if ne .Interface.FirewallMark 0}} | ||||||
| FwMark = {{.Interface.FirewallMark}} | FwMark = {{.Interface.FirewallMark}} | ||||||
| {{- end}} | {{- end}} | ||||||
|  | @ -27,11 +30,19 @@ Table = {{.Interface.RoutingTable}} | ||||||
| SaveConfig = true | SaveConfig = true | ||||||
| {{- end}} | {{- end}} | ||||||
| 
 | 
 | ||||||
| # Interface hooks | # Interface hooks (optional) | ||||||
|  | {{- if .Interface.PreUp}} | ||||||
| PreUp = {{ .Interface.PreUp }} | PreUp = {{ .Interface.PreUp }} | ||||||
|  | {{- end}} | ||||||
|  | {{- if .Interface.PostUp}} | ||||||
| PostUp = {{ .Interface.PostUp }} | PostUp = {{ .Interface.PostUp }} | ||||||
|  | {{- end}} | ||||||
|  | {{- if .Interface.PreDown}} | ||||||
| PreDown = {{ .Interface.PreDown }} | PreDown = {{ .Interface.PreDown }} | ||||||
|  | {{- end}} | ||||||
|  | {{- if .Interface.PostDown}} | ||||||
| PostDown = {{ .Interface.PostDown }} | PostDown = {{ .Interface.PostDown }} | ||||||
|  | {{- end}} | ||||||
| 
 | 
 | ||||||
| # | # | ||||||
| # Peers | # Peers | ||||||
|  | @ -43,12 +54,24 @@ PostDown = {{ .Interface.PostDown }} | ||||||
| # -WGP- Peer email: {{.Email}} | # -WGP- Peer email: {{.Email}} | ||||||
| # -WGP- PrivateKey: {{.PrivateKey}} | # -WGP- PrivateKey: {{.PrivateKey}} | ||||||
| [Peer] | [Peer] | ||||||
|  | {{- if eq $.Interface.Type "server"}} | ||||||
| PublicKey = {{ .PublicKey }} | PublicKey = {{ .PublicKey }} | ||||||
|  | {{- end}} | ||||||
|  | {{- if eq $.Interface.Type "client"}} | ||||||
|  | PublicKey = {{ .EndpointPublicKey }} | ||||||
|  | {{- end}} | ||||||
| {{- if .PresharedKey}} | {{- if .PresharedKey}} | ||||||
| PresharedKey = {{ .PresharedKey }} | PresharedKey = {{ .PresharedKey }} | ||||||
| {{- end}} | {{- end}} | ||||||
|  | {{- if eq $.Interface.Type "server"}} | ||||||
|  | AllowedIPs = {{ .IPsStr }} | ||||||
|  | {{- end}} | ||||||
|  | {{- if eq $.Interface.Type "client"}} | ||||||
|  | {{- if .AllowedIPsStr}} | ||||||
| AllowedIPs = {{ .AllowedIPsStr }} | AllowedIPs = {{ .AllowedIPsStr }} | ||||||
| {{- if and (ne .Endpoint "") (ne $.Interface.Type "server")}} | {{- end}} | ||||||
|  | {{- end}} | ||||||
|  | {{- if and (ne .Endpoint "") (eq $.Interface.Type "client")}} | ||||||
| Endpoint = {{ .Endpoint }} | Endpoint = {{ .Endpoint }} | ||||||
| {{- end}} | {{- end}} | ||||||
| {{- if ne .PersistentKeepalive 0}} | {{- if ne .PersistentKeepalive 0}} | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ | ||||||
| PrivateKey = {{ .Peer.PrivateKey }} | PrivateKey = {{ .Peer.PrivateKey }} | ||||||
| Address = {{ .Peer.IPsStr }} | Address = {{ .Peer.IPsStr }} | ||||||
| 
 | 
 | ||||||
| # Misc. settings | # Misc. settings (optional) | ||||||
| {{- if .Peer.DNSStr}} | {{- if .Peer.DNSStr}} | ||||||
| DNS = {{ .Peer.DNSStr }} | DNS = {{ .Peer.DNSStr }} | ||||||
| {{- end}} | {{- end}} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue