freeradius 3 mac auth user group (for configuration simplicity) - freeradius

I have implemented Radius MAC authentication with Unifi AP and freeradius. I am using Radius primarily to set the vlan that the device should sent to allowing a consolidated SSID to handle multiple vlans. (This is a home network, not an enterprise so I am not concerned with the mac spoofing situation). Any MAC connecting will get a vlan (but non-radius users will go to a guest vlan by default)
The freeradius question is how I can go about assigning a group value to each MAC user definition and then post-auth use that group name to define the specific attributes such as Tunnel-Type, Tunnel-Medium-Type, and Tunnel-Private-Group-Id. I simply want to do this to avoid having to repeat all these tunnel values for each device.
Example (not sure if syntax is right)
authorize file
AABBCCDDEEFFGG Group := "iot", Cleartext-Password := "AABBCCDDEEFFGG"
site-enabled/default (I think it might go here)
if (group == "iot) { #update reply, set Tunnel-* values }
Any guidance someone could provide would be great. All the examples I have found seem to be using the mysql backend and I don't have a need for the additional complexity.

I was able to figure this out using control variables. Here is the solution.
Create a custom attribute in the dictionary file.
ATTRIBUTE VLAN-Group-Name 3000 string
Add users to the authorize file like so
AA-BB-CC-DD-EE-FF Cleartext-Password := "AA-BB-CC-DD-EE-FF", VLAN-Group-Name := "iot"
In your virtual server, in my case it was sites-enabled/default, look for the post-auth section and add code similar to this. You will replace the group-id XXX with your vlan # you want sent back to the AP to be assigned. I placed the code right above the -sql portion.
switch "&control:VLAN-Group-Name" {
case "iot" {
update reply {
Tunnel-Type = 13,
Tunnel-Medium-Type = 6,
Tunnel-Private-Group-Id = XXX
}
}
case "general" {
update reply {
Tunnel-Type = 13,
Tunnel-Medium-Type = 6,
Tunnel-Private-Group-Id = XXX
}
}
}
This allows you to keep the authorize file clean with just users and assign them a group and keep the group values simplified in the post-auth. If you ever needed to change the vlan # of any group just one update and restart.
Cheers!

Related

Is it possible to call an URL passing website parameters?

I am writing code for a custom SAP program regarding some Vendor information. In my program flow, there is a possibility of me trying to use a Vendor VAT Number that belongs to an unknown Vendor. There is a Web site (EU Based - https://ec.europa.eu/taxation_customs/vies/) for such purposes that requires a country key and the specified VAT Number in order for it to provide an answer with the available Company information (only works for company VAT numbers of course). My problem is that I cannot seem to find any way to pass those parameters dynamically to the Web site without needing the user to interfere during this process. Manually, the process would be to select a country key, type in a VAT number and press 'Verify'.
Is there any way for me to call this specific Web site URL and "bypass" this process to only display the result page? For now, I'm using the following Function Module to just call the specified URL, in lack of any better choices.
call function 'CALL_INTERNET_ADRESS'
exporting
pi_adress = 'https://ec.europa.eu/taxation_customs/vies/'
exceptions
no_input_data = 1
others = 2.
You can use CL_HTTP_CLIENT class or HTTP_POST/HTPP_GET FM.
You need to install given web page SSL root certificate to your system with STRUST t-code.
Example usage of CL_HTTP_CLIENT below.
DATA: lv_url TYPE string VALUE 'http://mkysoft.com/ip.php'.
DATA: o_client TYPE REF TO if_http_client.
DATA: lv_http_rc TYPE i.
DATA: lv_reason TYPE string.
DATA: lt_fields TYPE tihttpnvp.
TRY.
cl_http_client=>create_by_url( EXPORTING
url = lv_url
IMPORTING
client = o_client
EXCEPTIONS
OTHERS = 0 ).
o_client->request->get_header_fields( CHANGING fields = lt_fields ).
o_client->request->set_header_field( name = '~request_uri' value = '/ip.php' ).
o_client->request->set_header_field( name = '~host' value = 'mkysoft.com' ).
o_client->request->set_method( if_http_request=>co_request_method_get ).
o_client->send( ).
o_client->receive( ).
o_client->response->get_status( IMPORTING
code = lv_http_rc
reason = lv_reason ).
* Error check
IF lv_http_rc = 200.
DATA(lv_xml) = o_client->response->get_cdata( ).
* Handle error
ELSE.
WRITE: / 'Fehler: ', lv_http_rc.
ENDIF.
o_client->close( ).
CATCH cx_root INTO DATA(e_txt).
WRITE: / e_txt->get_text( ).
ENDTRY.
EU Commission has a SOAP service for vat numbers.
See the info page
https://ec.europa.eu/taxation_customs/vies/technicalInformation.html
and that it even supports http
http://ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl
You have a non screen scrape method, proper interface you should look at.
On the other point of Avoiding SSL.
Make a basic guide for customers to add the European commission cert to their SAP system. If someone is complaining about that, then they are a serious user of the internet. Every sap on premise user, that needs to call the internet adds certs.
Http is dead....

NodeMCU default access point name (AI Thinkerxxx)

NodeMCU shows a default network as "AI-Thinkerxxx" when it's powered up.
How can I change the default access point name (AI thinker xxx to some other name)?
Where should I make changes to achieve it?
You can use the function wifi.ap.config(). The sole parameter is a table of configuration details. An example:
local cfg = { ssid = 'MySSID', pwd = 'MySecurePwd', save = true }
wifi.api.config(cfg)
Full documentation can be found at https://nodemcu.readthedocs.io/en/master/en/modules/wifi/#wifiapconfig

Is there a way in deployd to map a collection to a different endpoint?

I have a collection called customer_devices and I can't change the name. Can I expose it via deployd as /devices ? How?
There are a few ways that I can think of. If you really just want to rename the collection, you can do so from the dashboard, as #thomasb mentioned in his answer.
Alternatively, you can create a "proxy" event resource devices and forward all queries to customer_devices. For example, in devices/get.js you would say
dpd.customer_devices.get(query, function(res, err) {
if (err) cancel(err);
setResult(res);
});
Update
Finally, here is a "hack" to redirect all requests from one resource path to a different path. This is poorly tested so use at your own risk. This requires that you set up your own server as explained here. Once you have that, you can modify the routing behaviour using this snippet:
server.on('listening', function() {
var customer_devices = server.router.resources.filter(function (res) {
return res.path === '/customer_devices';
})[0];
// Make a copy of the Object's prototype
var devices = Object.create(customer_devices);
// Shallow copy the properties
devices = extend(devices, customer_devices);
// Change the routing path
devices.path = "/devices";
// Add back to routing cache
server.router.resources.push(devices);
});
This will take your customer_devices resource, copy it, change the path, and re-insert it into the cached routing table. I tested it and it works, but I won't guarantee that it's safe or a good idea...
Can't you change the name via dashboard?
Mouseover your collection customer_devices
Click the down arrow
Select 'Rename'
Enter the new name and click 'Rename'

Several questions about this Varnish VCL

I'm setting up varnish-devicedetect VCL in Varnish 4.0.2:
https://github.com/varnish/varnish-devicedetect/blob/master/INSTALL.rst
I'm following the directions for method #1: "Send HTTP header to backend"
I've read through this readme and have Googled for quite some time now and still quite a few concepts are escaping me.
Here's my code (excerpts):
default.vcl
include "devicedetect.vcl";
sub vcl_recv {
call devicedetect;
# ... snip ...
}
sub vcl_backend_response {
# device detect
if (bereq.http.X-UA-Device) {
if (!beresp.http.Vary) { # no Vary at all
set beresp.http.Vary = "X-UA-Device";
} elseif (beresp.http.Vary !~ "X-UA-Device") { # add to existing Vary
set beresp.http.Vary = beresp.http.Vary + ", X-UA-Device";
}
}
# ... snip ...
}
sub vcl_deliver {
# device detect
if ((req.http.X-UA-Device) && (resp.http.Vary)) {
set resp.http.Vary = regsub(resp.http.Vary, "X-UA-Device", "User-Agent");
}
# ... snip ...
}
Here's my questions.
When I inspect the response in Chrome Dev Tools, why is the Vary header set to User-Agent. Isn't the whole approach of method #1 NOT to use user agent, and instead use X-UA-Device?
Based on other guides I read... it seems this will hit the origin for EACH type of mobile (if you look in device detect, its split up into... mobile-iphone, mobile-android, mobile-smartphone, etc). Is this true in my code above? I definitely DONT want to hit the origin server more than twice for any given URL (desktop, and mobile ... I don't want all the mobile-* cached separately).
Can someone describe what the 3 code blocks above actually do? In somewhat laymen's terms. About the only one I truly understand is the first code block. call devicedetect just looks at the User-Agent and then sets X-UA-Device header with the appropriate grouping on the request to the backend. I'm a bit confused what the other 2 code blocks do though.
Can I delete the bit with X-UA-Device-force if I don't intend to allow the user to 'use desktop site'?
The guide mentions that I should be setting something in the backend in my app code. Right now this is all I have (rails). I'm not changing headers or changing anything about the response. I'm only changing the way the HTML looks (for the mobile version of the site). Should I be changing a header or something? This is what I have so far:
Rails:
def detect_device
if request.headers['X-UA-Device'] =~ /^mobile/
#device = 'mobile'
prepend_view_path Rails.root + 'app' + 'views_mobile'
else
#device = 'desktop'
end
end
As to point 1, your X-UA-Device is a custom header for internal consumption, ie by default not exposed to the external world. To ensure the external caches/proxies understand you are considering the device/user-agent in the response, you have to update the Vary with a header which reflect this. this is where the user-agent comes in, as thats where you have derived the X-UA-Device from.
note the comment within the link you indicate
to keep any caches in the wild from serving wrong content to client #2 behind them, we need to transform the Vary on the way out.

Get System minimum password length and complexity

In local security policy (PC-Control panel-Administration-local security policy) there is a parameter "Minimum length of the password" and a parameter "Password must meet complexity requirements" (true/false). How can I read them in Delphi (for WinXpSp3-Win2003-Vista-Win7-Win2008(+r2))?
I'm looking for something like:
Function DetectSystemMinPassLength:integer;
begin
//?
end;
Function DetectSystemPassComplexity:boolean;
begin
//?
end;
Additional question:
Does there exist in Delphi (or WinApi) function which can check if a given password conforms to system policies (or set)?
For example:
Function MyCheckPassComplexity (Password:string):boolean;
begin
// ???
end;
use
MyCheckPassComplexity (' 12345 '); //result False
MyCheckPassComplexity (' MyCoolPassword9999 '); //result True
Usually to read a local or group policy setting you must use the Group Policy Settings Reference for Windows and Windows Server which basically is a set of excel files which contains the windows registry keys where is stored such info. unfortunately in this case if you check such reference for these Account policies (Enforce password history,
Maximum password age, Minimum password age, Minimum password length) you will find this message:
Password Policy security settings are not registry keys.
Exist a set of WMI classes in the root\RSOP\Computer namespace like RSOP_SecuritySettingBoolean, RSOP_SecuritySettingNumeric , RSOP_SecuritySettings to access the an account policy but these classes only works (I mean retrieve information) on systems which is are in a domain, but it does not work in a workgroup.
For the moment I think which you best option is export the local policies to a ini file using this command (and then parse the result using a TIniFile class)
secedit.exe /export /cfg C:\Output\Policy.Ini
This command will create a file like this
[Unicode]
Unicode=yes
[System Access]
MinimumPasswordAge = 0
MaximumPasswordAge = 42
MinimumPasswordLength = 0
PasswordComplexity = 0
PasswordHistorySize = 0
About your second question to validate a password you can use the NetValidatePasswordPolicy WinAPI function.

Resources