FreeRadius filter_username - freeradius

I need to adjust the filter to a radius in order to allow a connection only with the username which contains the word "test".
Set up the block:
filter_private {
if (User-Name =~ /^(?!test).*$/) {
update reply {
Reply-Message += "Rejected: Username rejected, because not test"
}
reject
}
}
But it allows absolutely any username.

Based on the documentation, I think you need to negate the logic:
if (User-Name !~ /^(?!test).*$/) {
# etc.
}
Also, the regex above probably (depending on your local regex engine) allows usernames starting with test (due to ^) not any username containing test. For the latter, you would need to change the logic to be:
if (User-Name !~ /.*test.*/) {
# etc.
}

Related

FreeRadius - Group NAS Clients

Have spent many hours searching and no luck so far,
I am looking for a clean way to group devices in freeradius for policy reference.
I tried creating a custom dictionary attribute (Device-Group) and applying it under the client definition
client cisco_device {
ipaddr = 1.2.3.4
Device-Group = Cisco_ISRs
}
and then in the authorization section:
if (&Device-Group == 'Cisco_ISRs') {
&cisco-avpair := 'priv-lvl 15'
}
But looking at the debug, custom dictionary attributes dont apply with clients.
The only alternative I have so far relies on naming conventions. i.e.
client cisco_site1 {
#blah blah
}
authorize {
if (&Client-Shortname =~ '/^cisco_./') {
#blah blah
}
}
but it would be nicer to have it in defined groups.
Any insight or ideas would be greatly appreciated.

Firestore role based rule

I have the following rules which should allow me to read a document, but I get insufficient permission error. Any advice?
The current user has a document under a collection named users with a field named role that has the value admin
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId}/tickets/{ticketId} {
allow update, delete, create: if false
allow read: if get(/users/$(request.auth.uid)).data.role == "admin"
}
match /users/{userId} {
allow delete:
if false
allow read, write:
if request.auth != null && request.auth.uid == userId
allow update:
if resource.data.points == request.resource.data.points && request.auth != null && request.auth.uid == userId
}
iOS code fetching data
func fetchTickets(contestId: String) -> SignalProducer<[Ticket], FetchError> {
Firestore.firestore()
.collection("users/*/tickets")
.whereField("contest.id", isEqualTo: contestId)
.getDocuments()
}
users collection
{
"role": "admin"
}
users.{userId}.tickets collection
{
"contest": {
"id": ""asdasd
}
}
First of all, wildcards are not supported in Firestore queries. You will need to either identify a single user's tickets and query only that one subcollection. Or, you will need to perform a collection group query on tickets to query all subcollections named tickets. If you use a collection group query, you will need completely different rules to support that.
Second of all, security rules are not filters. Be sure to read that documentation carefully. You can't have a rule filter out some documents based on the get() of another document. This simply does not scale the way that Firestore requires. The client must be able to formulate the filter in the query, and that requires that the data to filter with must be in the documents in the collection being queried (they can't be in other documents).

Policy in freeradius isnt running

Im building a freeradius server for authenticate.
I have a problem with policy.conf:
The policy.conf was loaded in radius.conf as $INCLUDE policy.conf but the content of this file didn't work.
I tested by login with 'test' user but it didn't reject. Can someone help me about this, thanks very much.
policy {
#
# Forbid all EAP types.
#
if (User-Name == 'test'){
reject
}
forbid_eap {
if (EAP-Message) {
reject
}
}
#
# Forbid all non-EAP types outside of an EAP tunnel.
#
permit_only_eap {
if (!EAP-Message) {
# We MAY be inside of a TTLS tunnel.
# PEAP and EAP-FAST require EAP inside of
# the tunnel, so this check is OK.
# If so, then there MUST be an outer EAP message.
if (!"%{outer.request:EAP-Message}") {
reject
}
}
}
#
# Forbid all attempts to login via realms.
#
deny_realms {
if (User-Name =~ /#|\\/) {
reject
}
}
}
First you need to give your policy a name (like the other policies in the policy section).
policy {
reject_test {
if (User-Name == 'test'){
reject
}
}
}
You then need to list the policy in one of the sections (authorize, authenticate, post-auth etc...) of one of the virtual servers.
See the concepts page in the FreeRADIUS wiki for some basic details about which sections get run and where.
If you're using a stock configuration you'll likely need to edit raddb/sites-available/default.
In this case you probably want to add your policy to the authorize section.
authorize {
reject_test
...
}
You don't actually need to define policies in order to run use the policy language, you could insert your condition directly into the authorize section.
authorize {
if (User-Name == 'test'){
reject
}
}

How to write a security rule to allow read without using auth variable

I am trying to write Security rules, but I am bit confused on writing it. For my case I am not authenticating the users using Firebase, but I have node in database which has child named by usernames. I am trying to achieve logic like this: for any child of this node if value is true then he can move on further or else not. Here is my sample node
"Customers":{
"John":"true",
"Jack":"false"
}
"Messages":{
"Message1":{
....
},
},
And here is my rules node where I am confused.I have tried using "$" wild card variable but getting error that variable is unknown.
"rules":{
"Messages":{
".read":"root.child('Customers').child($name).val()===true",
".write":"root.child('Customers').child($name).val()===true"
}
}
I think the "$" variable can't be used this way. So how should I do this?
How do you decide which user to check for value? You must have a value for comparison. If you want a logic like users can see their own messages, you should add an Username field under messages node. Like;
"Messages":{
"Message1":{
"John": {
},
....
},
}
And with this field you can do this;
"rules":{
"Messages":{
"$userId" : {
".read":"root.child('Customers').child($userId).val()===true",
".write":"root.child('Customers').child($userId).val()===true"
}
}
}

Print out only headers in Rails request

I know how to access a header in Rails
request.headers["HEADER_NAME"]
However, I want to get all headers passed by a browser. I see that I can enumerate it
request.headers.each { |header| ... }
However, this will spit out both headers and other environment variables. Is there a way to get only headers?
Update 1
My problem isn't interation. My problem is distinguising between environment variables and headers. Both of them will be reported while interation using each or keys.
Solution
By convention, headers do not usually contain dots. Nginx even rejected requests with dots in headers by default. So I think it's quite a safe assumption to go with.
On contrary, all rails environment garbage is namespaced e.g. action_dispatch.show_exceptions, rack.input etc.
These two facts conveniently suggest a way to distinguish external headers from internal variables:
request.headers.env.reject { |key| key.to_s.include?('.') }
Works neat.
Benchmarking a bit
Note, that include?('.') implementation works about 4 times faster than matching =~ /\./
Benchmark.measure { 500000.times { hsh.reject { |key| key.to_s =~ /\./ } } }
=> real=2.09
Benchmark.measure { 500000.times { hsh.reject { |key| key.to_s.include?('.') } } }
=> real=0.58
Hope that helps.
By using
request.headers.each { |key, value| }
This is iterating your requested header with (key+value), but if you want specific values you have to use key name like, HTTP_KEYNAME because whenever HTTP request come it will append HTTP to keys and be sure about uppercase because it is case sensitive.
for example:
if we have passed auth_token as header request parameter and want to access, we can use this.
request.headers["HTTP_AUTH_TOKEN"]
You can try this to get only headers list from request
request.headers.first(50).to_h.keys
It will convert request.headers object into array and then to hash to get list of all keys in request to be used as
request.headers["keyname"]
It might be not much efficient but I think it can do the job.
Hope this helps.
not sure if this is any helpful but I ended up using this brute force approach
request.env.select {|k,v|
k.match("^HTTP.*|^CONTENT.*|^REMOTE.*|^REQUEST.*|^AUTHORIZATION.*|^SCRIPT.*|^SERVER.*")
}
You might be probably looking for :
request.env
This will basically create a Ruby Hash of the whole request object.
For more details, check this question:
How do I see the whole HTTP request in Rails
If you just want headers:
request.headers.to_h.select { |k,v|
['HTTP','CONTENT','AUTHORIZATION'].any? { |s| k.to_s.starts_with? s }
}
If you want everything that's not an env var:
request.headers.to_h.select { |k,v|
['HTTP','CONTENT','REMOTE','REQUEST','AUTHORIZATION','SCRIPT','SERVER'].any? { |s|
k.to_s.starts_with? s
}
}
You should be able to do
request.headers.each { |key, value| }
In general when iterating over a hash ruby looks at the arity of your block and gives you either a pair (key + value) or separate variables. (The hash in this case is an object internal to the headers object)

Resources