I need help configuring freeradius with WPA2 Enterprise via LDAP.
LDAP normally works for other services, however, it does not work for WPA2E.
We have also managed WPA2E to work with hard coded username/password fine. So we know all the components on their own work, but do not work together.
We have the freeradius server configured fine to work with the LDAP service.
Any help is appreciated
Here is my ldap setting for free radius modules/ldap file (mostly irrelevant for this issue)
ldap {
server = "ldapmaster.domain.com,ldapslave.domain.com"
identity = "uid=binder,ou=services,dc=security,dc=domain,dc=com"
password = asdfasdfasdf
basedn = "ou=internal,ou=users,dc=security,dc=domain,dc=com"
filter = "(mail=%{%{Stripped-User-Name}:-%{User-Name}})"
ldap_connections_number = 5
max_uses = 0
timeout = 4
timelimit = 3
net_timeout = 1
tls {
start_tls = yes
require_cert = "never"
}
dictionary_mapping = ${confdir}/ldap.attrmap
password_attribute = userPassword
edir_account_policy_check = no
keepalive {
idle = 60
probes = 3
interval = 3
}}
Also have the following setup for eap.conf
eap {
default_eap_type = peap
timer_expire = 60
ignore_unknown_eap_types = no
cisco_accounting_username_bug = no
max_sessions = 4096
md5 {
}
leap {
}
gtc {
auth_type = PAP
}
tls {
certdir = ${confdir}/certs
cadir = ${confdir}/certs
private_key_password = whatever
private_key_file = ${certdir}/server.key
certificate_file = ${certdir}/server.pem
CA_file = ${cadir}/ca.pem
dh_file = ${certdir}/dh
random_file = /dev/urandom
CA_path = ${cadir}
cipher_list = "DEFAULT"
make_cert_command = "${certdir}/bootstrap"
cache {
enable = no
max_entries = 255
}
verify {
}
}
ttls {
default_eap_type = md5
copy_request_to_tunnel = no
use_tunneled_reply = no
virtual_server = "inner-tunnel"
}
peap {
default_eap_type = mschapv2
copy_request_to_tunnel = no
use_tunneled_reply = no
virtual_server = "inner-tunnel"
}
mschapv2 {
}}
Also have two sites enabled, default and inner-tunnel:
default
authorize {
preprocess
suffix
eap {
ok = return
}
expiration
logintime
ldap
}
authenticate {
eap
ldap
}
inner-tunnel
authorize {
mschap
update control {
Proxy-To-Realm := LOCAL
}
eap {
ok = return
}
expiration
ldap
logintime
}
authenticate {
Auth-Type MS-CHAP {
mschap
}
eap
ldap
}
Here is a sample log I am seeing in the debug logs:
https://gist.github.com/anonymous/10483144
You appear to of removed the symlink between sites-available/inner-tunnel and sites-enabled/inner-tunnel
If you look in the log it's complaining it can't find the inner-tunnel server, which it requires to perform MSCHAPv2 auth in the TLS tunnel of the PEAP authentication.
server {
PEAP: Setting User-Name to emre#domain.com
Sending tunneled request
EAP-Message = 0x0205001a01656d72654071756269746469676974616c2e636f6d
FreeRADIUS-Proxied-To = 127.0.0.1
User-Name = "emre#domain.com"
server inner-tunnel {
No such virtual server "inner-tunnel"
} # server inner-tunnel
You add the symlink back, and list the ldap module at the top of the authorize section in the inner-tunnel server. You will also need to map the attribute holding the user's Cleartext-Password to the User-Password attribute, using the ldap attrmap file.
If you do not have the user's Cleartext-Password in the directory (for example if it's hashed), then you should use EAP-TTLS-PAP, and list the LDAP module in the authenticate section of the inner-tunnel server, then add:
if (User-Password) {
update control {
Auth-Type := LDAP
}
}
To the authorize section of the inner-tunnel server.
Related
Hell, I am trying to deploy rke k8s with terraform, but I am not able to connect to the desired host via ssh:
time="2022-02-28T11:17:38+01:00" level=warning msg="Failed to set up SSH tunneling for host [poc-k8s.my-domain.com]: Can't retrieve Docker Info: error during connect: Get \"http://%2Fvar%2Frun%2Fdocker.sock/v1.24/info\": Unable to access node with address [poc-k8s.my-domain.com:22] using SSH. Please check if you are able to SSH to the node using the specified SSH Private Key and if you have configured the correct SSH username. Error: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain"
and this is the .tf file I am using:
terraform {
required_providers {
rke = {
source = "rancher/rke"
version = "1.3.0"
}
}
}
provider "rke" {
log_file = "rke_debug.log"
}
resource "rke_cluster" "cluster" {
nodes {
address = "poc-k8s.my-domain.com"
user = "root"
role = ["controlplane", "worker", "etcd"]
ssh_key = file("~/.ssh/root_key")
}
nodes {
address = "poc-k8s.my-domain.com"
user = "root"
role = ["worker", "etcd"]
ssh_key = file("~/.ssh/root_key")
}
addons_include = [
"https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml",
"https://gist.githubusercontent.com/superseb/499f2caa2637c404af41cfb7e5f4a938/raw/930841ac00653fdff8beca61dab9a20bb8983782/k8s-dashboard-user.yml",
]
}
resource "local_file" "kube_cluster_yaml" {
filename = "~/.kube/kube_config_cluster.yml"
sensitive_content = "rke_cluster.cluster.kube_config_yaml"
}
The key if of course correct and I am able to connect to the desired host:
ssh -i ~/.ssh/root_key root#poc-k8s.my-domain.com
what am I missing here?
[Update]
Cluster resource has delay_on_creation property that can be used
resource "rke_cluster" "cluster" {
delay_on_creation = 180
(...)
}
I'm facing a similar issue. On the second run of terrafor apply it works correctly. In my case the issue is that docker is not up fast enough for RKE provider.
I've found following workaround from citynetwork /
citycloud-examples:
resource "rke_cluster" "cluster" {
(...)
depends_on = [null_resource.wait-for-docker]
}
resource "null_resource" "wait-for-docker" {
provisioner "local-exec" {
command = "sleep 180"
}
depends_on = [
# list of servers docker being installed on
(...)
]
}
It waits for 180s which is not ideal, though.
What I did?
Created a terraform module with provider as cloudflare
provider "cloudflare" {
}
Provided token to the shell environment using variable CLOUDFLARE_API_TOKEN
Token have access to the zone say: example.com
Creating a CNAME record which is targeting to my S3 bucket using:
resource "cloudflare_record" "cname-bucket" {
zone_id = var.domain
name = var.bucket_name
value = "${var.bucket_name}.s3-website.${var.region}.amazonaws.com"
proxied = true
type = "CNAME"
}
After applying this module, getting error:
Error: failed to create DNS record: error from makeRequest: HTTP status 400: content "{\"success\":false,\"errors\":[{\"code\":7003,\"message\":\"Could not route to \\/zones\\/example.com\\/dns_records, perhaps your object identifier is invalid?\"},{\"code\":7000,\"message\":\"No route for that URI\"}],\"messages\":[],\"result\":null}"
When I tried creating the same using cloudflare with browser, everything works fine but when trying same with terraform, getting the above error.
Access my token have: example.com - DNS:Edit
What I need?
What I am doing wrong here?
How to create this CNAME record using terraform module?
It looks like the problem is zone_id = var.domain line in your cloudflare_record resource. You are using example.com as the zone_id , but instead you should be using your Cloudflare Zone ID.
You can find you Zone ID in your Cloudflare Dashboard for your domain: check in Overview , on the right column in the API section.
locals {
domain = "example.com"
hostname = "example.com" # TODO: Varies by environment
}
variable "CLOUDFLARE_ACCOUNT_ID" {}
variable "CLOUDFLARE_API_TOKEN" { sensitive = true }
provider "cloudflare" {
api_token = var.CLOUDFLARE_API_TOKEN
account_id = var.CLOUDFLARE_ACCOUNT_ID
}
resource "cloudflare_zone" "default" {
zone = local.domain
plan = "free"
}
resource "cloudflare_record" "a" {
zone_id = cloudflare_zone.default.id
name = local.hostname
value = "192.0.2.1"
type = "A"
ttl = 1
proxied = true
}
Source https://github.com/kriasoft/terraform-starter-kit
As an alternative to the other answers. You can use this module. In this case, your code will look like this:
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
}
}
}
variable "cloudflare_api_token" {
type = string
sensitive = true
description = "The Cloudflare API token."
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
module "bucket" {
source = "registry.terraform.io/alex-feel/zone/cloudflare"
version = "1.8.0"
zone = var.domain # For instance, it may be example.com
records = [
{
record_name = "bucket_cname"
type = "CNAME"
name = var.bucket_name # A subdomain of the example.com domain
value = "${var.bucket_name}.s3-website.${var.region}.amazonaws.com" # Where the subdomain should point to
proxied = true
}
]
}
To use the module with this configuration, your token must have at least the following privileges for the desired zone: DNS:Edit, Zone:Edit, Zone Settings:Edit. And to use all the features of the module, you need an additional privilege: Page Rules:Edit.
P.S. You do not need the zone_id for this configuration.
I have a lot of sites on an CloudFlare account, sometimes when servers are migrate, i need to change every domain DNS in CF manually. How can I use some tool or script, that helps me to download all domains info, and than easy change it?
Maybe some Terraform example? I didnt use Terraform yet, so just thinking about ways how to automate this proccess.
Tnx.
Yes, you can use Terraform for this. There are an official Cloudflare Provider, the documentation for which you can find here.
When using the provider "directly", your Terraform configuration will look like this:
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = ">= 3.12.1"
}
}
}
variable "cloudflare_api_token" {
type = string
sensitive = true
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
resource "cloudflare_zone" "acme_com" {
zone = "acme.com"
}
You may be interested in the following Cloudflare resources to use them in your configuration:
cloudflare_zone
cloudflare_zone_settings_override
cloudflare_record
Also, you can use this module. Then your configuration may look like this:
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = ">= 3.12.1"
}
}
}
variable "cloudflare_api_token" {
type = string
sensitive = true
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
module "acme_com" {
source = "registry.terraform.io/alex-feel/zone/cloudflare"
version = "1.7.0"
zone = "acme.com"
}
There are examples to help you get started with the module.
And here is a concrete, ready-to-use example that you can use in your specific case when using the module:
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = ">= 3.12.1"
}
}
}
variable "cloudflare_api_token" {
type = string
sensitive = true
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
locals {
# All your zones go here
zones = ["acme.com", "example.com"]
# Your IP for A records for all the zones goes here
ip = "192.0.2.1"
}
module "all_domains" {
source = "registry.terraform.io/alex-feel/zone/cloudflare"
version = "1.7.0"
for_each = toset(local.zones)
zone = each.value
records = [
{
record_name = "a_main"
type = "A"
value = local.ip
}
]
}
In this case, it will be enough for you to list all your domains in the zones variable and specify the desired IP in the ip variable. As a result, an A record with the specified IP will be created for each of your domains.
To get all your zones you can use Cloudflare API List Zones method. So your request will look like this:
curl --request GET \
--url https://api.cloudflare.com/client/v4/zones \
--header 'Authorization: Bearer YOUR_TOKEN'
I follow this Plain MAC-Auth setup guide to configure the freeradius (version 2.2.5), in order to carry out MAC Authentication. However, MAC authentication is failed with the following log message
rad_recv: Access-Request packet from host 192.168.0.7 port 59966, id=9, length=79
NAS-IP-Address = 192.168.0.7
User-Name = "34:76:C5:57:0F:A3"
User-Password = "34:76:C5:57:0F:A3"
# Executing section authorize from file /etc/freeradius/sites-enabled/default
+group authorize {
++[preprocess] = ok
++policy rewrite.calling_station_id {
+++? if ((Calling-Station-Id) && "%{Calling-Station-Id}" =~ /^%{config:policy.mac-addr}$/i)
?? Evaluating (Calling-Station-Id) -> FALSE
? Skipping ("%{Calling-Station-Id}" =~ /^%{config:policy.mac-addr}$/i)
+++? if ((Calling-Station-Id) && "%{Calling-Station-Id}" =~ /^%{config:policy.mac-addr}$/i) -> FALSE
+++else else {
++++[noop] = noop
+++} # else else = noop
++} # policy rewrite.calling_station_id = noop
[authorized_macs] expand: %{Calling-Station-Id} ->
++[authorized_macs] = noop
++? if (!ok)
? Evaluating !(ok) -> TRUE
++? if (!ok) -> TRUE
++if (!ok) {
+++[reject] = reject
++} # if (!ok) = reject
+} # group authorize = reject
Using Post-Auth-Type REJECT
WARNING: Unknown value specified for Post-Auth-Type. Cannot perform requested action.
Delaying reject of request 0 for 1 seconds
Going to the next request
Waking up in 0.9 seconds.
Sending delayed reject for request 0
Sending Access-Reject of id 9 to 192.168.0.7 port 59966
Waking up in 4.9 seconds.
Cleaning up request 0 ID 9 with timestamp +30
Ready to process requests.
From the above log, the problem seems to be unable to get the "Calling-Station-Id" value. Is this a freeradius configuration problem? And anyone know how to solve it?
on the account section of the radius config add
update request {
Called-Station-Id += &NAS-Port-Id
}
and in the post-auth section add
update reply {
Called-Station-Id += &NAS-Port-Id
}
I am using CAS + LDAP with Spring Security for user authentication for a Grails 2.2.3 app. However, I would also like to create a simple API with this application which will require a different authentication method. I would like to use Basic Authentication for this. However, adding basicAuth to my Config.groovy file is not working, and I am getting this error:
authentication.ProviderManager Authentication attempt using org.springframework.security.cas.authentication.CasAuthenticationProvider
www.BasicAuthenticationFilter Authentication request for user: grantmc failed: org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken
I know I'm using the correct credentials, so I'm not sure what the error is saying exactly or what I need to do to fix it. Does anyone have any ideas?
Here are the settings in resources.groovy:
initialDirContextFactory(DefaultSpringSecurityContextSource, "ldap://ldap.company.com:389") {
userDn = "CN=Admin,OU=Users,DC=company,DC=com"
password = "password"
}
ldapUserSearch(FilterBasedLdapUserSearch,
"OU=Users,DC=company,DC=com",
"employeeId={0}",
initialDirContextFactory) { }
ldapUserDetailsMapper(MyLdapUserDetailsContextMapper) { }
ldapAuthoritiesPopulator(DefaultLdapAuthoritiesPopulator,
initialDirContextFactory,
"ou=Groups,OU=Users,DC=company,DC=com") {
groupRoleAttribute = "cn"
groupSearchFilter = "member={0}"
rolePrefix = ""
searchSubtree = true
convertToUpperCase = true
ignorePartialResultException = true
}
userDetailsService(LdapUserDetailsService, ldapUserSearch, ldapAuthoritiesPopulator) {
userDetailsMapper = ref('ldapUserDetailsMapper')
}
And my settings in config.groovy:
grails.plugins.springsecurity.cas.serverUrlPrefix = 'https://cas.company.com/cas'
grails.plugins.springsecurity.cas.loginUri = "/login"
grails.plugins.springsecurity.cas.serviceUrl = "${grails.serverURL}/j_spring_cas_security_check"
grails.plugins.springsecurity.providerNames = ['casAuthenticationProvider']
grails.plugins.springsecurity.defaultTargetUrl = '/'
grails.plugins.springsecurity.alwaysUseDefault = false
grails.plugins.springsecurity.useBasicAuth = true
grails.plugins.springsecurity.basic.realmName = "API"
grails.plugins.springsecurity.filterChain.chainMap = [
'/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter',
'/**': 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter'
]
grails.plugins.springsecurity.securityConfigType = 'InterceptUrlMap'
grails.plugins.springsecurity.interceptUrlMap = [
'/api/**': ['IS_AUTHENTICATED_FULLY'],
'/**': ['IS_AUTHENTICATED_FULLY']
]