This commit is contained in:
2025-12-24 22:18:05 +05:00
parent 5346aad6fb
commit 39a45a2151
5 changed files with 317 additions and 101 deletions

View File

@@ -1,132 +1,127 @@
{ {
// CGRateS Configuration file // CGRateS Configuration for PPPoE RADIUS Authentication - PAP
// // Single processor approach - fetches password from AttributeS, strips nulls, compares
// Bypasses *radauth null-padding bug by using filter-based comparison
"general": { "general": {
"log_level": 7, "log_level": 7,
"node_id": "pppoe_auth_server",
"default_tenant": "cgrates.org"
}, },
"listen": { "listen": {
"rpc_json": ":2012", // RPC JSON listening address "rpc_json": "127.0.0.1:2012",
"rpc_gob": ":2013", // RPC GOB listening address "rpc_gob": "127.0.0.1:2013",
"http": ":2080", // HTTP listening address "http": "127.0.0.1:2080"
}, },
"data_db": { "data_db": {
"db_type": "redis", "db_type": "*internal"
"db_port": 6379,
"db_name": "10",
}, },
"stor_db": { // database used to store offline tariff plans and CDRs "stor_db": {
"db_password": "CGRateS.org", // password to use when connecting to stordb "db_type": "*internal"
},
"filters": {
"apiers_conns": ["*localhost"],
}, },
"rals": { "caches":{
"enabled": true, "partitions": {
"*attribute_profiles": {"limit": -1, "ttl": "1h"},
"*attribute_filter_indexes": {"limit": -1, "ttl": "1h"}
}
}, },
"schedulers": { "filters": {
"enabled": true, "apiers_conns": ["*localhost"]
},
"cdrs": {
"enabled": true,
"rals_conns": ["*internal"],
},
"resources": {
"enabled": true,
}, },
"attributes": { "attributes": {
"enabled": true, "enabled": true,
}, "apiers_conns": ["*localhost"],
"indexed_selects": true,
"routes": { "prefix_indexed_fields": ["*req.Account"]
"enabled": true,
}, },
"chargers": { "chargers": {
"enabled": true, "enabled": true
}, },
"sessions": { "sessions": {
"enabled": true, "enabled": true,
"attributes_conns": ["*localhost"], "attributes_conns": ["*localhost"],
"cdrs_conns": ["*localhost"], "chargers_conns": ["*internal"],
"rals_conns": ["*localhost"], "debit_interval": "0"
"resources_conns": ["*localhost"],
"chargers_conns": ["*internal"],
"debit_interval": "10s",
}, },
"radius_agent": { "radius_agent": {
"enabled": true, "enabled": true,
"sessions_conns": ["*localhost"], "sessions_conns": ["*localhost"],
"listeners":[ "attributes_conns": ["*localhost"],
{ "listeners":[
"network": "udp", {
"auth_address": "0.0.0.0:1812", "network": "udp",
"acct_address": "0.0.0.0:1813" "auth_address": "0.0.0.0:1812",
} "acct_address": "0.0.0.0:1813"
], }
"client_secrets": { ],
"*default": "CGRateS.org" "client_secrets": {
}, "*default": "testing123"
"client_dictionaries": { },
"*default": ["/usr/share/cgrates/radius/dict/"] "client_dictionaries": {
}, "*default": ["/usr/share/cgrates/radius/dict/"]
"request_processors": [ },
{ "request_processors": [
"id": "CGRPAPAuth", // ============================================================
"filters": ["*string:~*vars.*radReqType:*radAuth"], // Single processor for PAP authentication
"flags": ["*authorize", "*attributes", "*accounts", "*continue", "*log"], // Fetches password from AttributeS, strips nulls, compares
"request_fields": [ // ============================================================
{"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"}, {
{"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*prepaid", "mandatory": true}, "id": "PPPoE_PAP_Auth",
{"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*composed", "value": "~*req.Acct-Session-Id", "mandatory": true}, "filters": [
{"tag": "Account", "path": "*cgreq.Account", "type": "*composed", "value": "~*req.User-Name", "mandatory": true}, "*string:~*vars.*radReqType:*radAuth"
{"tag": "Subject", "path": "*cgreq.Subject", "type": "*composed", "value": "~*req.User-Name", "mandatory": true}, ],
{"tag": "Destination", "path": "*cgreq.Destination", "type": "*constant", "value": "*any", "mandatory": true}, "flags": [
{"tag": "SetupTime", "path": "*cgreq.SetupTime", "type": "*composed", "value": "~*req.Event-Timestamp;*now", "mandatory": true}, "*authorize",
{"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*composed", "value": "~*req.Event-Timestamp;*now", "mandatory": true}, "*attributes",
{"tag": "PasswordFromAttributes", "path": "*cgreq.PasswordFromAttributes", "type": "*constant", "value": "*attributes"} "*log"
], ],
"reply_fields": [] "request_fields": [
}, {"tag": "ToR", "path": "*cgreq.ToR", "type": "*constant", "value": "*data"},
{ {"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "pppoe"},
"id": "RadiusPAPAuthProcessor", {"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*none", "mandatory": true},
"filters": ["*string:~*vars.*radReqType:*radAuth"], {"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*composed", "value": "~*req.User-Name"},
"flags": ["*radauth", "*pap", "*log"], {"tag": "Account", "path": "*cgreq.Account", "type": "*composed", "value": "~*req.User-Name", "mandatory": true},
"request_fields": [ {"tag": "Subject", "path": "*cgreq.Subject", "type": "*composed", "value": "~*req.User-Name"},
{"tag": "UserPassword", "path": "*vars.UserPassword", "type": "*variable", // Marker to fetch password from AttributeS
"value": "~*cgrep.Attributes.PasswordFromAttributes"} {"tag": "Password", "path": "*cgreq.Password", "type": "*constant", "value": "*attributes"},
], // Strip null padding from received password
"reply_fields": [ {"tag": "ReceivedPassword", "path": "*vars.ReceivedPassword", "type": "*variable",
{"tag": "RemoveAddedFields", "filters": ["*notempty:~*cgrep.Error:"], "type": "*removeall", "path": "*rep"}, "value": "~*req.User-Password{*strip:*suffix:*nil}"}
{"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"], ],
"type": "*constant", "value": "AccessReject"}, "reply_fields": [
{"tag": "ReplyMessage", "path": "*rep.Reply-Message", "filters": ["*notempty:~*cgrep.Error:"], // Get expected password from attributes reply
"type": "*variable", "value": "~*cgrep.Error"}, {"tag": "ExpectedPassword", "path": "*vars.ExpectedPassword", "type": "*variable",
{"tag": "SessionTimeout", "path": "*rep.Session-Timeout", "filters": ["*empty:~*cgrep.Error:"], "value": "~*cgrep.Attributes.Password"},
"type": "*constant", "value": "3600"}, // SUCCESS: Passwords match - set standard PPP attributes
{"tag": "AcctInterimInterval", "path": "*rep.Acct-Interim-Interval", "filters": ["*empty:~*cgrep.Error:"], {"tag": "FramedProtocol", "path": "*rep.Framed-Protocol",
"type": "*constant", "value": "30"} "filters": ["*string:~*vars.ReceivedPassword:~*vars.ExpectedPassword"],
] "type": "*constant", "value": "1"},
} {"tag": "ServiceType", "path": "*rep.Service-Type",
] "filters": ["*string:~*vars.ReceivedPassword:~*vars.ExpectedPassword"],
"type": "*constant", "value": "2"},
// FAILURE: Passwords don't match or not found - reject
{"tag": "RejectCode", "path": "*rep.*radReplyCode",
"filters": ["*notstring:~*vars.ReceivedPassword:~*vars.ExpectedPassword"],
"type": "*constant", "value": "AccessReject"},
{"tag": "RejectMessage", "path": "*rep.Reply-Message",
"filters": ["*notstring:~*vars.ReceivedPassword:~*vars.ExpectedPassword"],
"type": "*constant", "value": "Invalid username or password"}
]
}
]
}, },
"apiers": { "apiers": {
"enabled": true, "enabled": true
"scheduler_conns": ["*internal"],
},
} }
}

132
cgrates.json.orig Normal file
View File

@@ -0,0 +1,132 @@
{
// CGRateS Configuration file
//
"general": {
"log_level": 7,
},
"listen": {
"rpc_json": ":2012", // RPC JSON listening address
"rpc_gob": ":2013", // RPC GOB listening address
"http": ":2080", // HTTP listening address
},
"data_db": {
"db_type": "redis",
"db_port": 6379,
"db_name": "10",
},
"stor_db": { // database used to store offline tariff plans and CDRs
"db_password": "CGRateS.org", // password to use when connecting to stordb
},
"filters": {
"apiers_conns": ["*localhost"],
},
"rals": {
"enabled": true,
},
"schedulers": {
"enabled": true,
},
"cdrs": {
"enabled": true,
"rals_conns": ["*internal"],
},
"resources": {
"enabled": true,
},
"attributes": {
"enabled": true,
},
"routes": {
"enabled": true,
},
"chargers": {
"enabled": true,
},
"sessions": {
"enabled": true,
"attributes_conns": ["*localhost"],
"cdrs_conns": ["*localhost"],
"rals_conns": ["*localhost"],
"resources_conns": ["*localhost"],
"chargers_conns": ["*internal"],
"debit_interval": "10s",
},
"radius_agent": {
"enabled": true,
"sessions_conns": ["*localhost"],
"listeners":[
{
"network": "udp",
"auth_address": "0.0.0.0:1812",
"acct_address": "0.0.0.0:1813"
}
],
"client_secrets": {
"*default": "CGRateS.org"
},
"client_dictionaries": {
"*default": ["/usr/share/cgrates/radius/dict/"]
},
"request_processors": [
{
"id": "CGRPAPAuth",
"filters": ["*string:~*vars.*radReqType:*radAuth"],
"flags": ["*authorize", "*attributes", "*accounts", "*continue", "*log"],
"request_fields": [
{"tag": "Category", "path": "*cgreq.Category", "type": "*constant", "value": "call"},
{"tag": "RequestType", "path": "*cgreq.RequestType", "type": "*constant", "value": "*prepaid", "mandatory": true},
{"tag": "OriginID", "path": "*cgreq.OriginID", "type": "*composed", "value": "~*req.Acct-Session-Id", "mandatory": true},
{"tag": "Account", "path": "*cgreq.Account", "type": "*composed", "value": "~*req.User-Name", "mandatory": true},
{"tag": "Subject", "path": "*cgreq.Subject", "type": "*composed", "value": "~*req.User-Name", "mandatory": true},
{"tag": "Destination", "path": "*cgreq.Destination", "type": "*constant", "value": "*any", "mandatory": true},
{"tag": "SetupTime", "path": "*cgreq.SetupTime", "type": "*composed", "value": "~*req.Event-Timestamp;*now", "mandatory": true},
{"tag": "AnswerTime", "path": "*cgreq.AnswerTime", "type": "*composed", "value": "~*req.Event-Timestamp;*now", "mandatory": true},
{"tag": "PasswordFromAttributes", "path": "*cgreq.PasswordFromAttributes", "type": "*constant", "value": "*attributes"}
],
"reply_fields": []
},
{
"id": "RadiusPAPAuthProcessor",
"filters": ["*string:~*vars.*radReqType:*radAuth"],
"flags": ["*radauth", "*pap", "*log"],
"request_fields": [
{"tag": "UserPassword", "path": "*vars.UserPassword", "type": "*variable",
"value": "~*cgrep.Attributes.PasswordFromAttributes"}
],
"reply_fields": [
{"tag": "RemoveAddedFields", "filters": ["*notempty:~*cgrep.Error:"], "type": "*removeall", "path": "*rep"},
{"tag": "Code", "path": "*rep.*radReplyCode", "filters": ["*notempty:~*cgrep.Error:"],
"type": "*constant", "value": "AccessReject"},
{"tag": "ReplyMessage", "path": "*rep.Reply-Message", "filters": ["*notempty:~*cgrep.Error:"],
"type": "*variable", "value": "~*cgrep.Error"},
{"tag": "SessionTimeout", "path": "*rep.Session-Timeout", "filters": ["*empty:~*cgrep.Error:"],
"type": "*constant", "value": "3600"},
{"tag": "AcctInterimInterval", "path": "*rep.Acct-Interim-Interval", "filters": ["*empty:~*cgrep.Error:"],
"type": "*constant", "value": "30"}
]
}
]
},
"apiers": {
"enabled": true,
"scheduler_conns": ["*internal"],
},
}

5
load-tariff.sh Normal file
View File

@@ -0,0 +1,5 @@
curl -X POST http://127.0.0.1:2080/jsonrpc -H "Content-Type: application/json" -d '{
"method": "APIerSv2.LoadTariffPlanFromFolder",
"params": [{"FolderPath": "/etc/cgrates/tariffplans/new"}],
"id": 1
}'

View File

@@ -0,0 +1,42 @@
#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight
# PPPoE User Credentials for RADIUS PAP Authentication
#
# Format: Each user needs an attribute profile that:
# 1. Matches on Account (username)
# 2. Returns PasswordFromAttributes for PAP verification
# 3. Optionally returns session parameters (IP, rate limits, timeout)
#
# The PasswordFromAttributes field will be retrieved by the RADIUS agent
# and compared against the PAP-encoded password in the AccessRequest
# ============================================================
# User: pppoe_user1 - Basic user with password only
# ============================================================
cgrates.org,ATTR_PPPOE_USER1,*sessions,*string:~*req.Account:pppoe_user1,,,*req.PasswordFromAttributes,*constant,SecurePass123,false,10
# ============================================================
# User: pppoe_user2 - User with static IP assignment
# ============================================================
cgrates.org,ATTR_PPPOE_USER2,*sessions,*string:~*req.Account:pppoe_user2,,,*req.PasswordFromAttributes,*constant,MyPassword456,false,10
cgrates.org,ATTR_PPPOE_USER2,,,,,*req.FramedIP,*constant,10.0.0.100,,
# ============================================================
# User: pppoe_user3 - User with rate limiting (Mikrotik example)
# ============================================================
cgrates.org,ATTR_PPPOE_USER3,*sessions,*string:~*req.Account:pppoe_user3,,,*req.PasswordFromAttributes,*constant,FastUser789,false,10
cgrates.org,ATTR_PPPOE_USER3,,,,,*req.FramedIP,*constant,10.0.0.101,,
cgrates.org,ATTR_PPPOE_USER3,,,,,*req.RateLimit,*constant,10M/20M,,
cgrates.org,ATTR_PPPOE_USER3,,,,,*req.SessionTimeout,*constant,86400,,
# ============================================================
# User: pppoe_user4 - Premium user with higher limits
# ============================================================
cgrates.org,ATTR_PPPOE_USER4,*sessions,*string:~*req.Account:pppoe_user4,,,*req.PasswordFromAttributes,*constant,PremiumPass!@#,false,10
cgrates.org,ATTR_PPPOE_USER4,,,,,*req.FramedIP,*constant,10.0.0.102,,
cgrates.org,ATTR_PPPOE_USER4,,,,,*req.RateLimit,*constant,100M/100M,,
cgrates.org,ATTR_PPPOE_USER4,,,,,*req.SessionTimeout,*constant,0,,
# ============================================================
# User: test - Simple test user for quick verification
# ============================================================
cgrates.org,ATTR_PPPOE_TEST,*sessions,*string:~*req.Account:test,,,*req.Password,*constant,test123,false,10
1 #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight
2 # PPPoE User Credentials for RADIUS PAP Authentication
3 #
4 # Format: Each user needs an attribute profile that:
5 # 1. Matches on Account (username)
6 # 2. Returns PasswordFromAttributes for PAP verification
7 # 3. Optionally returns session parameters (IP, rate limits, timeout)
8 #
9 # The PasswordFromAttributes field will be retrieved by the RADIUS agent
10 # and compared against the PAP-encoded password in the AccessRequest
11 # ============================================================
12 # User: pppoe_user1 - Basic user with password only
13 # ============================================================
14 cgrates.org,ATTR_PPPOE_USER1,*sessions,*string:~*req.Account:pppoe_user1,,,*req.PasswordFromAttributes,*constant,SecurePass123,false,10
15 # ============================================================
16 # User: pppoe_user2 - User with static IP assignment
17 # ============================================================
18 cgrates.org,ATTR_PPPOE_USER2,*sessions,*string:~*req.Account:pppoe_user2,,,*req.PasswordFromAttributes,*constant,MyPassword456,false,10
19 cgrates.org,ATTR_PPPOE_USER2,,,,,*req.FramedIP,*constant,10.0.0.100,,
20 # ============================================================
21 # User: pppoe_user3 - User with rate limiting (Mikrotik example)
22 # ============================================================
23 cgrates.org,ATTR_PPPOE_USER3,*sessions,*string:~*req.Account:pppoe_user3,,,*req.PasswordFromAttributes,*constant,FastUser789,false,10
24 cgrates.org,ATTR_PPPOE_USER3,,,,,*req.FramedIP,*constant,10.0.0.101,,
25 cgrates.org,ATTR_PPPOE_USER3,,,,,*req.RateLimit,*constant,10M/20M,,
26 cgrates.org,ATTR_PPPOE_USER3,,,,,*req.SessionTimeout,*constant,86400,,
27 # ============================================================
28 # User: pppoe_user4 - Premium user with higher limits
29 # ============================================================
30 cgrates.org,ATTR_PPPOE_USER4,*sessions,*string:~*req.Account:pppoe_user4,,,*req.PasswordFromAttributes,*constant,PremiumPass!@#,false,10
31 cgrates.org,ATTR_PPPOE_USER4,,,,,*req.FramedIP,*constant,10.0.0.102,,
32 cgrates.org,ATTR_PPPOE_USER4,,,,,*req.RateLimit,*constant,100M/100M,,
33 cgrates.org,ATTR_PPPOE_USER4,,,,,*req.SessionTimeout,*constant,0,,
34 # ============================================================
35 # User: test - Simple test user for quick verification
36 # ============================================================
37 cgrates.org,ATTR_PPPOE_TEST,*sessions,*string:~*req.Account:test,,,*req.Password,*constant,test123,false,10

View File

@@ -0,0 +1,42 @@
#Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight
# PPPoE User Credentials for RADIUS PAP Authentication
#
# Format: Each user needs an attribute profile that:
# 1. Matches on Account (username)
# 2. Returns PasswordFromAttributes for PAP verification
# 3. Optionally returns session parameters (IP, rate limits, timeout)
#
# The PasswordFromAttributes field will be retrieved by the RADIUS agent
# and compared against the PAP-encoded password in the AccessRequest
# ============================================================
# User: pppoe_user1 - Basic user with password only
# ============================================================
cgrates.org,ATTR_PPPOE_USER1,*sessions,*string:~*req.Account:pppoe_user1,,,*req.PasswordFromAttributes,*constant,SecurePass123,false,10
# ============================================================
# User: pppoe_user2 - User with static IP assignment
# ============================================================
cgrates.org,ATTR_PPPOE_USER2,*sessions,*string:~*req.Account:pppoe_user2,,,*req.PasswordFromAttributes,*constant,MyPassword456,false,10
cgrates.org,ATTR_PPPOE_USER2,,,,,*req.FramedIP,*constant,10.0.0.100,,
# ============================================================
# User: pppoe_user3 - User with rate limiting (Mikrotik example)
# ============================================================
cgrates.org,ATTR_PPPOE_USER3,*sessions,*string:~*req.Account:pppoe_user3,,,*req.PasswordFromAttributes,*constant,FastUser789,false,10
cgrates.org,ATTR_PPPOE_USER3,,,,,*req.FramedIP,*constant,10.0.0.101,,
cgrates.org,ATTR_PPPOE_USER3,,,,,*req.RateLimit,*constant,10M/20M,,
cgrates.org,ATTR_PPPOE_USER3,,,,,*req.SessionTimeout,*constant,86400,,
# ============================================================
# User: pppoe_user4 - Premium user with higher limits
# ============================================================
cgrates.org,ATTR_PPPOE_USER4,*sessions,*string:~*req.Account:pppoe_user4,,,*req.PasswordFromAttributes,*constant,PremiumPass!@#,false,10
cgrates.org,ATTR_PPPOE_USER4,,,,,*req.FramedIP,*constant,10.0.0.102,,
cgrates.org,ATTR_PPPOE_USER4,,,,,*req.RateLimit,*constant,100M/100M,,
cgrates.org,ATTR_PPPOE_USER4,,,,,*req.SessionTimeout,*constant,0,,
# ============================================================
# User: test - Simple test user for quick verification
# ============================================================
cgrates.org,ATTR_PPPOE_TEST,*sessions,*string:~*req.Account:test,,,*req.PasswordFromAttributes,*constant,test123,false,10