VPN network Theory (Gargoyle)

Report wireless and/or network connectivity problems in this forum.

Moderator: Moderators

ispyisail
Moderator
Posts: 5194
Joined: Mon Apr 06, 2009 3:15 am
Location: New Zealand

Re: VPN network Theory (Gargoyle)

Post by ispyisail »

The other option is to add an entry box like what they do on the OpenVPN client side.

The advantage is the user can add any custom entry they want.

Whichever is the easiest.....

Image

Lantis
Moderator
Posts: 6903
Joined: Mon Jan 05, 2015 5:33 am
Location: Australia

Re: VPN network Theory (Gargoyle)

Post by Lantis »

I have a prototype of this working locally.
Here's a diff if you want to try it yourself.

There's currently ZERO error checking. You need to enter a proper ip/subnet for it to work
e.g.
192.168.10.0
255.255.255.0

Note the trailing zero on the IP. I will write code that checks and fixes this later and checks for conflicts with any other subnets you have defined.

Code: Select all

diff --git a/package/plugin-gargoyle-i18n-English-EN/files/www/i18n/English-EN/openvpn.js b/package/plugin-gargoyle-i18n-English-EN/files/www/i18n/English-EN/openvpn.js
index 6aaf3ea7..51dc5538 100644
--- a/package/plugin-gargoyle-i18n-English-EN/files/www/i18n/English-EN/openvpn.js
+++ b/package/plugin-gargoyle-i18n-English-EN/files/www/i18n/English-EN/openvpn.js
@@ -27,9 +27,12 @@ ovpnS.CredMC="Credentials Can Be Used By Multiple Clients";
 ovpnS.CUse="Clients Use VPN For";
 ovpnS.ATrff="All Client Traffic";
 ovpnS.HTrff="Only Traffic Destined for Hosts Behind VPN";
+ovpnS.SASnet="Advertised Additional Server Subnets";
+ovpnS.SASnetAdd="Add Additional Server Subnet";
+ovpnS.SASnetHlp="Let clients know about additional subnets for which the server acts as a gateway. Only available when LAN Subnet Access is allowed.";
 ovpnS.OSAC="OpenVPN Server: Allowed Clients";
 ovpnS.CClnt="Currently Configured Clients";
-ovpnS.ZipCred="After generating client configuration, click download to obtain zip file containing necessary credentials, and place in your client‘s OpenVPN configuration folder";
+ovpnS.ZipCred="After generating client configuration, click download to obtain zip (or .ovpn) file containing necessary credentials, and place in your client‘s OpenVPN configuration folder";
 ovpnS.CfgCred="Configure A New Client / Set of Credentials";
 ovpnS.ClntN="Client Name";
 ovpnS.ClntIP="Client Internal IP";
@@ -101,6 +104,9 @@ ovpnS.UpCErr="Could not update client configuration.";
 //openvpn_allowed_client_edit.sh
 ovpnS.EditOCS="Edit OpenVPN Client Settings";
 
+//openvpn_additional_route_template.sh
+ovpnS.EditES="Edit OpenVPN Server Extra Subnets";
+
 //openvpn_upload_client.sh (handled by shell scripts)
 ovpnS.uc_CA_f="Could not find CA file";
 ovpnS.uc_crt_f="Could not find certificate file";
diff --git a/package/plugin-gargoyle-openvpn/files/usr/lib/gargoyle/openvpn.sh b/package/plugin-gargoyle-openvpn/files/usr/lib/gargoyle/openvpn.sh
index 764db546..609ee4ec 100755
--- a/package/plugin-gargoyle-openvpn/files/usr/lib/gargoyle/openvpn.sh
+++ b/package/plugin-gargoyle-openvpn/files/usr/lib/gargoyle/openvpn.sh
@@ -117,6 +117,8 @@ create_server_conf()
 	openvpn_redirect_gateway=$(load_def "${11}" "push \"redirect-gateway def1\"" "true")
 	openvpn_regenerate_cert="${12}"
 
+	openvpn_extra_subnets="${13}"
+
 	if [ -n "$openvpn_pool" ] ; then
 		openvpn_pool="ifconfig-pool $openvpn_pool"
 	fi
@@ -230,6 +232,13 @@ EOF
 		# once all client ccd files are in place on the server
 		echo "$openvpn_server_local_subnet_ip $openvpn_server_local_subnet_mask $openvpn_server_internal_ip" > "$random_dir/route_data_server"
 	fi
+	if [ -n "$openvpn_extra_subnets" ] ; then
+		for openvpn_extra_subnet in $openvpn_extra_subnets ; do
+			esubnet_ip=$(echo "$openvpn_extra_subnet" | cut -d '_' -f 1)
+			esubnet_mask=$(echo "$openvpn_extra_subnet" | cut -d '_' -f 2)
+			echo "$esubnet_ip $esubnet_mask $openvpn_server_internal_ip" >> "$random_dir/route_data_server"
+		done
+	fi
 
 	copy_if_diff "$random_dir/server.conf"        "$OPENVPN_DIR/server.conf"
 	copy_if_diff "$random_dir/route_data_server"  "$OPENVPN_DIR/route_data/server"
@@ -612,7 +621,7 @@ regenerate_server_and_allowed_clients_from_uci()
 	. /lib/functions.sh
 	config_load "openvpn_gargoyle"
 	
-	server_vars="internal_ip internal_mask port proto cipher client_to_client duplicate_cn redirect_gateway subnet_access regenerate_credentials subnet_ip subnet_mask pool"
+	server_vars="internal_ip internal_mask port proto cipher client_to_client duplicate_cn redirect_gateway subnet_access regenerate_credentials subnet_ip subnet_mask pool extra_subnet"
 	for var in $server_vars ; do
 		config_get "$var" "server" "$var"
 	done
@@ -628,7 +637,8 @@ regenerate_server_and_allowed_clients_from_uci()
 				"$duplicate_cn"            \
 				"$pool"                    \
 				"$redirect_gateway"        \
-				"$regenerate_credentials"
+				"$regenerate_credentials"  \
+				"$extra_subnet"
 
 	server_regenerate_credentials="$regenerate_credentials"
 	config_foreach regenerate_allowed_client_from_uci "allowed_client"
diff --git a/package/plugin-gargoyle-openvpn/files/www/js/openvpn.js b/package/plugin-gargoyle-openvpn/files/www/js/openvpn.js
index c36ea15d..6d5eceb5 100644
--- a/package/plugin-gargoyle-openvpn/files/www/js/openvpn.js
+++ b/package/plugin-gargoyle-openvpn/files/www/js/openvpn.js
@@ -129,10 +129,18 @@ function saveChanges()
 			uci.set("openvpn_gargoyle", "server", "subnet_access", getSelectedValue(prefix + "subnet_access"))
 			uci.set("openvpn_gargoyle", "server", "duplicate_cn", getSelectedValue(prefix + "duplicate_cn"))
 			uci.set("openvpn_gargoyle", "server", "redirect_gateway", getSelectedValue(prefix + "redirect_gateway"))
+			uci.remove("openvpn_gargoyle", "server", "extra_subnet")
 			if( getSelectedValue(prefix + "subnet_access") == "true")
 			{
 				uci.set("openvpn_gargoyle", "server", "subnet_ip",   adjustSubnetIp(currentLanIp, currentLanMask) )
 				uci.set("openvpn_gargoyle", "server", "subnet_mask", currentLanMask )
+
+				var extraSubnets = getTableDataArray(byId('openvpn_server_extra_subnets_table'), true, false);
+				if(extraSubnets.length > 0)
+				{
+					var extraSubnetsUci = extraSubnets.map(function(extraSubnet) {return extraSubnet[0] + "_" + extraSubnet[1]});
+					uci.set("openvpn_gargoyle", "server", "extra_subnet", extraSubnetsUci);
+				}
 			}
 			else
 			{
@@ -458,6 +466,28 @@ function resetData()
 	setSelectedValue("openvpn_server_duplicate_cn", getServerVarWithDefault("duplicate_cn", "false"))
 	setSelectedValue("openvpn_server_redirect_gateway", getServerVarWithDefault("redirect_gateway", "true"))
 
+	var extraSNetTableData = [];
+	var extraSNets = uciOriginal.get('openvpn_gargoyle','server','extra_subnet');
+	var esi;
+	for(esi = 0; esi < extraSNets.length; esi++)
+	{
+		var extraSNet = extraSNets[esi];
+		var splitData = extraSNet.split('_');
+		if(splitData.length == 2)
+		{
+			var ip = splitData[0];
+			var mask = splitData[1];
+			extraSNetTableData.push([ip,mask,createButton(UI.Edit, 'btn-edit', editOvpnServerExtraSubnetsModal, false)]);
+		}
+	}
+	var esTable = createTable([ ovpnS.SubIP, ovpnS.SubM, ""], extraSNetTableData, "openvpn_server_extra_subnets_table", true, false)
+	var tableContainer = document.getElementById("openvpn_server_extra_subnets_table_container");
+	while(tableContainer.firstChild != null)
+	{
+		tableContainer.removeChild(tableContainer.firstChild);
+	}
+	tableContainer.appendChild(esTable);
+
 	var acTableData = []
 	var allowedClients = uciOriginal.getAllSectionsOfType("openvpn_gargoyle", "allowed_client")
 	var aci;
@@ -807,10 +837,12 @@ function setOpenvpnVisibility()
 	document.getElementById("openvpn_allowed_client_fieldset").style.display = openvpnMode == "server" ? "block" : "none"
 	document.getElementById("openvpn_client_fieldset").style.display         = openvpnMode == "client" ? "block" : "none"
 	
+	var subnetAccess = getSelectedValue('openvpn_server_subnet_access');
+	document.getElementById('openvpn_server_extra_subnet_container').style.display = subnetAccess == 'true' ? 'block' : 'none';
+
 	var dupeCn = getSelectedValue("openvpn_server_duplicate_cn");
 	dupeCn= dupeCn == "true" || dupeCn == "1"
 
-
 	var allowedTable = document.getElementById("openvpn_allowed_client_table");
 	if(allowedTable != null)
 	{
@@ -1406,4 +1438,85 @@ function togglePass(name)
 	{
 		password_field.type = 'password';
 	}
-}
\ No newline at end of file
+}
+
+function addEs()
+{
+	var errors = [];
+	if(errors.length > 0)
+	{
+		alert(errors.join("\n") + "\n"+ovpnS.AddCErr);
+	}
+	else
+	{
+		var subnetIp = document.getElementById("openvpn_extra_subnet_ip").value;
+		var subnetMask = document.getElementById("openvpn_extra_subnet_mask").value;
+
+		var esTable = document.getElementById("openvpn_server_extra_subnets_table");
+
+		var rowData = [ subnetIp, subnetMask, createButton(UI.Edit, 'btn-edit', editOvpnServerExtraSubnetsModal, false) ]
+		addTableRow(esTable, rowData, true, false);
+	
+		closeModalWindow('openvpn_server_extra_subnet_modal');
+	}
+
+}
+
+function editEs(editRow)
+{
+	// error checking goes here
+	var errors = [];
+	if(errors.length > 0)
+	{
+		alert(errors.join("\n") + "\n"+ovpnS.AddCErr);
+	}
+	else
+	{
+		//update document with new data
+		var newIp = document.getElementById("openvpn_extra_subnet_ip").value;
+		var newMask = document.getElementById("openvpn_extra_subnet_mask").value;
+		editRow.childNodes[0].firstChild.data = newIp;
+		editRow.childNodes[1].firstChild.data = newMask;
+		closeModalWindow('openvpn_server_extra_subnet_modal');
+	}
+}
+
+function editOvpnServerExtraSubnetsModal()
+{
+	editRow=this.parentNode.parentNode;
+
+	modalButtons = [
+		{"title" : UI.CApplyChanges, "classes" : "btn btn-primary", "function" : function(){editEs(editRow);}},
+		"defaultDiscard"
+	];
+
+	var ip = editRow.childNodes[0].firstChild.data;
+	var mask = editRow.childNodes[1].firstChild.data;
+
+	modalElements = [
+		{"id" : "openvpn_extra_subnet_ip", "value" : ip},
+		{"id" : "openvpn_extra_subnet_mask", "value" : mask}
+	];
+
+	modalPrepare('openvpn_server_extra_subnet_modal', ovpnS.EditES, modalElements, modalButtons);
+	openModalWindow('openvpn_server_extra_subnet_modal');
+}
+
+function addOvpnServerExtraSubnetsModal()
+{
+	modalButtons = [
+		{"title" : UI.Add, "classes" : "btn btn-primary", "function" : addEs},
+		"defaultDismiss"
+	];
+
+	var ip = "";
+	var mask = "";
+
+	modalElements = [
+		{"id" : "openvpn_extra_subnet_ip", "value" : ip},
+		{"id" : "openvpn_extra_subnet_mask", "value" : mask}
+	];
+
+	modalPrepare('openvpn_server_extra_subnet_modal', ovpnS.SASnetAdd, modalElements, modalButtons);
+	openModalWindow('openvpn_server_extra_subnet_modal');
+}
diff --git a/package/plugin-gargoyle-openvpn/files/www/openvpn.sh b/package/plugin-gargoyle-openvpn/files/www/openvpn.sh
index 13770039..9e8d6be8 100755
--- a/package/plugin-gargoyle-openvpn/files/www/openvpn.sh
+++ b/package/plugin-gargoyle-openvpn/files/www/openvpn.sh
@@ -163,13 +163,27 @@
 				<div id="openvpn_server_subnet_access_container" class="row form-group">
 					<label class="col-xs-5" for='openvpn_server_subnet_access' id='openvpn_server_subnet_access_label'><%~ LSAc %>:</label>
 					<span class="col-xs-7">
-						<select class="form-control" id='openvpn_server_subnet_access'>
+						<select class="form-control" id='openvpn_server_subnet_access' onchange='setOpenvpnVisibility()'>
 							<option value='true'><%~ CtoH %></option>
 							<option value='false'><%~ CnoL %></option>
 						</select>
 					</span>
 				</div>
 
+				<div id='openvpn_server_extra_subnet_container' class="row form-group">
+					<label class="col-xs-offset-5 col-xs-7" id="openvpn_server_extra_subnet_add_label" style="text-decoration:underline"><p><%~ SASnetAdd %>:</p></label>
+					<div class="row form-group">
+						<div class="col-xs-offset-5 col-xs-7">
+							<button id='openvpn_server_extra_subnet_add' class='btn btn-default btn-add' onclick='addOvpnServerExtraSubnetsModal()'><%~ Add %></button>
+						</div>
+					</div>
+
+					<div class='col-xs-offset-5 col-xs-7'>
+						<div id="openvpn_server_extra_subnets_table_container" class="table table-responsive"></div>
+					</div>
+					<div class='col-xs-offset-5 col-xs-7'><em><%~ SASnetHlp %></em></div>
+				</div>
+
 				<div id="openvpn_server_duplicate_cn_container" class="row form-group">
 					<label class="col-xs-5" for='openvpn_server_duplicate_cn' id='openvpn_server_duplicate_cn_label'><%~ CredR %>:</label>
 					<span class="col-xs-7">
@@ -466,6 +480,22 @@
 	</div>
 </div>
 
+<div class="modal fade" tabindex="-1" role="dialog" id="openvpn_server_extra_subnet_modal" aria-hidden="true" aria-labelledby="openvpn_server_extra_subnet_modal_title">
+	<div class="modal-dialog" role="document">
+		<div class="modal-content">
+			<div class="modal-header">
+				<h3 id="openvpn_server_extra_subnet_modal_title" class="panel-title"><%~ SASnetAdd %></h3>
+			</div>
+			<div class="modal-body">
+				<%in templates/openvpn_additional_route_template %>
+			</div>
+			<div class="modal-footer" id="openvpn_server_extra_subnet_modal_button_container">
+			</div>
+		</div>
+	</div>
+</div>
+
+
 <script>
 	resetData()
 </script>
diff --git a/package/plugin-gargoyle-openvpn/files/www/templates/openvpn_additional_route_template b/package/plugin-gargoyle-openvpn/files/www/templates/openvpn_additional_route_template
new file mode 100644
index 00000000..37d9ec97
--- /dev/null
+++ b/package/plugin-gargoyle-openvpn/files/www/templates/openvpn_additional_route_template
@@ -0,0 +1,8 @@
+				<div class="row form-group">
+					<label class="col-xs-5" id='add_subnet_ip_label' for='add_subnet_ip'><%~ SubIP %></label>
+					<span class="col-xs-7"><input type='text' id='openvpn_extra_subnet_ip' class='form-control' oninput='proofreadIp(this)' maxLength='35' /></span>
+				</div>
+				<div class="row form-group">
+					<label class="col-xs-5" id='add_subnet_mask_label' for='add_subnet_mask'><%~ SubM %></label>
+					<span class="col-xs-7"><input type='text' id='openvpn_extra_subnet_mask' class='form-control' oninput='proofreadMask(this)' maxLength='35' /></span>
+				</div>
\ No newline at end of file
https://lantisproject.com/downloads/gargoylebuilds for the latest releases
Please be respectful when posting. I do this in my free time on a volunteer basis.

Lantis
Moderator
Posts: 6903
Joined: Mon Jan 05, 2015 5:33 am
Location: Australia

Re: VPN network Theory (Gargoyle)

Post by Lantis »

https://lantisproject.com/downloads/gargoylebuilds for the latest releases
Please be respectful when posting. I do this in my free time on a volunteer basis.

ispyisail
Moderator
Posts: 5194
Joined: Mon Apr 06, 2009 3:15 am
Location: New Zealand

Re: VPN network Theory (Gargoyle)

Post by ispyisail »

OK Thanks

pkkrusty
Posts: 49
Joined: Mon Jan 13, 2020 4:41 pm

Re: VPN network Theory (Gargoyle)

Post by pkkrusty »

What's the latest on this effort? I'm running into the problem of connecting to my gargoyle router OpenVPN server, which is successful, but then I can't access LAN devices. My guess is that the routing table isn't correct (even though The dropdown "LAN Subnet Access: Allow Clients to Access Hosts on LAN" is selected) Maybe because this router is not serving DHCP or DNS? I have another host on the LAN doing that.

I'll spend some time looking at ispysail's fix to see if i can wrap my head around it.

I'm running 1.13.0.

pkkrusty
Posts: 49
Joined: Mon Jan 13, 2020 4:41 pm

Re: VPN network Theory (Gargoyle)

Post by pkkrusty »

Some progress. Seems like Gargoyle is acting correctly, in that I have the correct line in the openvpn config file to forward to the LAN, but in my OpenVPN log on my computer I see this:

```
⏎[Jul 18, 2024, 09:43:18] EVENT: ASSIGN_IP ⏎[Jul 18, 2024, 09:43:18] exception parsing IPv4 route: [route] [192.168.1.0] [255.255.255.0] [10.8.0.1] : tun_prop_route_error: route destinations other than vpn_gateway or net_gateway are not supported
```
Probably something with my OpenVPN client on my Mac. (Although my OpenVPN config on my Raspberry Pi on the same LAN does work). I'll do some googling.

Lantis
Moderator
Posts: 6903
Joined: Mon Jan 05, 2015 5:33 am
Location: Australia

Re: VPN network Theory (Gargoyle)

Post by Lantis »

Use the “client prefers vpn_gateway” option should make it happier.
You have to do the same on iOS devices so it’s probably not surprising Mac is the same.
https://lantisproject.com/downloads/gargoylebuilds for the latest releases
Please be respectful when posting. I do this in my free time on a volunteer basis.

Lantis
Moderator
Posts: 6903
Joined: Mon Jan 05, 2015 5:33 am
Location: Australia

Re: VPN network Theory (Gargoyle)

Post by Lantis »

I hope if you googled you saw that it leads you straight back to this forum where I solved it in 2017 :D
https://lantisproject.com/downloads/gargoylebuilds for the latest releases
Please be respectful when posting. I do this in my free time on a volunteer basis.

pkkrusty
Posts: 49
Joined: Mon Jan 13, 2020 4:41 pm

Re: VPN network Theory (Gargoyle)

Post by pkkrusty »

Yes indeed. Haha.

However, it didn't solve the problem for me. I'll have to keep googling.

Lantis
Moderator
Posts: 6903
Joined: Mon Jan 05, 2015 5:33 am
Location: Australia

Re: VPN network Theory (Gargoyle)

Post by Lantis »

I didn’t notice you were back on 1.13. I expect you have a lot of errors showing.
The latest OpenVPN client has changed a lot of the settings expectations.

I would recommend the latest 1.15 beta where I fixed that too.
viewtopic.php?p=66068#p66068
https://lantisproject.com/downloads/gargoylebuilds for the latest releases
Please be respectful when posting. I do this in my free time on a volunteer basis.

Post Reply