Reject certificate in use
Hello, I need to configure that if a client's certificate is in use, it cannot be used by another. I was looking at some examples on the web but it didn't work for me. If you can guide me, I appreciate it. Thank you.
On Nov 9, 2024, at 8:23 PM, Rodrigo Prieto <rodrigoprieto2019@gmail.com> wrote:
Hello, I need to configure that if a client's certificate is in use, it cannot be used by another. I was looking at some examples on the web but it didn't work for me. If you can guide me, I appreciate it.
First, define "who is using it", and "another system is using it". Once you know that information, the answer is relatively simple. This usually means *reading* the debug output. Think ab out what's there. How does the RADIUS server "know" that the certificate is used by machine A versus machine B? The answer is: by what's in the RADIUS packet. It's that simple. And, the information is in front of you... just read the debug output. In general, if you want to tie a certificate to a machine, you track the MAC address (Calling-Station-ID) against the certificate. This tracking is done in a database. Which database? Whatever one you're using, or you want to use. How to track it? Write policies to look up the Calling-Station-Id and certificate details in the database. Alan DeKok.
But how to store attributes to database? Is there any universal way to write some "logs" to database the way I want? Ex, I want to write Calling Station ID and Certificate thumbprint to database in post-auth, and read it back in auth or pre-auth to check. On 2024-11-10 15:13, Alan DeKok wrote:
On Nov 9, 2024, at 8:23 PM, Rodrigo Prieto <rodrigoprieto2019@gmail.com> wrote:
Hello, I need to configure that if a client's certificate is in use, it cannot be used by another. I was looking at some examples on the web but it didn't work for me. If you can guide me, I appreciate it. First, define "who is using it", and "another system is using it". Once you know that information, the answer is relatively simple.
This usually means *reading* the debug output. Think ab out what's there. How does the RADIUS server "know" that the certificate is used by machine A versus machine B?
The answer is: by what's in the RADIUS packet. It's that simple. And, the information is in front of you... just read the debug output.
In general, if you want to tie a certificate to a machine, you track the MAC address (Calling-Station-ID) against the certificate. This tracking is done in a database.
Which database? Whatever one you're using, or you want to use.
How to track it? Write policies to look up the Calling-Station-Id and certificate details in the database.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Nov 10, 2024, at 7:51 AM, Alexey D. Filimonov <alexey@filimonic.net> wrote:
But how to store attributes to database? Is there any universal way to write some "logs" to database the way I want?
You can run SQL statements "in line" in the configuration files: post-auth { ... %{sql:INSERT into .... } Then, just write an SQL statement.
Ex, I want to write Calling Station ID and Certificate thumbprint to database in post-auth, and read it back in auth or pre-auth to check.
If you're enforcing that a Calling-Station-ID is tied to a certificate, then you don't want to write it out in post-auth. Or, you only write it out the *first* time you see a certificate, and then enforce it after that. Alan DeKok.
Thanks for responding. I've been trying but I can't solve it. I am a novice user and there are things that escape me. I appreciate your help. El dom, 10 nov 2024 a las 9:58, Alan DeKok (<aland@deployingradius.com>) escribió:
On Nov 10, 2024, at 7:51 AM, Alexey D. Filimonov <alexey@filimonic.net> wrote:
But how to store attributes to database? Is there any universal way to write some "logs" to database the way I want?
You can run SQL statements "in line" in the configuration files:
post-auth { ... %{sql:INSERT into .... }
Then, just write an SQL statement.
Ex, I want to write Calling Station ID and Certificate thumbprint to database in post-auth, and read it back in auth or pre-auth to check.
If you're enforcing that a Calling-Station-ID is tied to a certificate, then you don't want to write it out in post-auth. Or, you only write it out the *first* time you see a certificate, and then enforce it after that.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Nov 11, 2024, at 3:40 AM, Rodrigo Prieto <rodrigoprieto2019@gmail.com> wrote:
Thanks for responding. I've been trying but I can't solve it. I am a novice user and there are things that escape me. I appreciate your help.
FreeRADIUS isn't something where you can hit a button and it does what you want. FreeRADIUS is more like a set of building blocks. You can build anything you want, but you have to put the pieces together yourself. You said you wanted to track who is using what certificate. This means using a database. FreeRADIUS doesn't include it's own database. Instead, it connects to any external database like redis, SQL, LDAP, etc. You need to write a database schema to store the data you want. You need to write queries to read and write the data. All of the documentation for how to do this is *database* documentation, and not *FreeRADIUS* documentation. So we're not going to explain here how to use SQL, LDAP, etc. You've got to go read that documentation. Once you have a schema and queries, you can just add the queries to the FreeRADIUS config. You then need to decide when / where to run the queries in FreeRADIUS. You can usually write down simple explanations as sentences: when the user logs in, use the Calling-Station-ID to check the database for certificate information if it isn't found, let them log in. And then before the server sends an Access-Accept, write the Calling-Station-ID and certificate information to the database. if the certificate information is found in the database, then compare the found information to the certificate. if the information doesn't match, reject the user. When you write down exactly what you want to do, the problem becomes much simpler to solve. It's not a huge unknown thing. Instead, it's broken down into a series of smaller problems, which are easier to solve. Alan DeKok.
Thanks for responding again. I know that it is not easy to configure any server in Linux. What I did was create a database and import schema.sql. mysql -u radius -p radius < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql When the client connects, it writes to the postauth table but when disconnecting and reconnecting, an error is output from the radcheck table. I'm stuck at that point. Maybe I have to create my own schema as you told me and stop using the freeradius schema? Thanks for the patience. El lun., 11 de noviembre de 2024 08:13, Alan DeKok < aland@deployingradius.com> escribió:
On Nov 11, 2024, at 3:40 AM, Rodrigo Prieto <rodrigoprieto2019@gmail.com> wrote:
Thanks for responding. I've been trying but I can't solve it. I am a
novice
user and there are things that escape me. I appreciate your help.
FreeRADIUS isn't something where you can hit a button and it does what you want. FreeRADIUS is more like a set of building blocks. You can build anything you want, but you have to put the pieces together yourself.
You said you wanted to track who is using what certificate. This means using a database. FreeRADIUS doesn't include it's own database. Instead, it connects to any external database like redis, SQL, LDAP, etc.
You need to write a database schema to store the data you want. You need to write queries to read and write the data. All of the documentation for how to do this is *database* documentation, and not *FreeRADIUS* documentation. So we're not going to explain here how to use SQL, LDAP, etc. You've got to go read that documentation.
Once you have a schema and queries, you can just add the queries to the FreeRADIUS config.
You then need to decide when / where to run the queries in FreeRADIUS. You can usually write down simple explanations as sentences:
when the user logs in, use the Calling-Station-ID to check the database for certificate information
if it isn't found, let them log in. And then before the server sends an Access-Accept, write the Calling-Station-ID and certificate information to the database.
if the certificate information is found in the database, then compare the found information to the certificate.
if the information doesn't match, reject the user.
When you write down exactly what you want to do, the problem becomes much simpler to solve. It's not a huge unknown thing. Instead, it's broken down into a series of smaller problems, which are easier to solve.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Nov 11, 2024, at 3:57 PM, Rodrigo Prieto <rodrigoprieto2019@gmail.com> wrote:
Thanks for responding again. I know that it is not easy to configure any server in Linux. What I did was create a database and import schema.sql. mysql -u radius -p radius < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql When the client connects, it writes to the postauth table but when disconnecting and reconnecting, an error is output from the radcheck table. I'm stuck at that point. Maybe I have to create my own schema as you told me and stop using the freeradius schema? Thanks for the patience.
Yes, you have to create your own schema, that's what I said in my last message. The default schema in FreeRADIUS does something quite different, and is *documented* as doing something else. Alan DeKok.
Hello, I was trying what you told me and it worked. Use the following configuration: /etc/freeradius/sites-avaibles/default post-auth { if (TLS-Client-Cert-Common-Name && Calling-Station-Id) { if ("%{sql:SELECT COUNT(*) FROM radius_clients WHERE cn='%{TLS-Client-Cert-Common-Name}'}" == "0") { update control { Tmp-String-0 := "%{sql:INSERT INTO radius_clients (cn, calling_station_id) VALUES ('%{TLS-Client-Cert-Common-Name}', '%{Calling-Station-Id}')}" } } else { if ("%{sql:SELECT calling_station_id FROM radius_clients WHERE cn='%{TLS-Client-Cert-Common-Name}'}" != "%{Calling-Station-Id}") { reject } } .... } /etc/freeradius/mods-available/sql sql { dialect = "mysql" driver = "rlm_sql_${dialect}" server = "localhost" login = "usuario_db" password = "" radius_db = "radius" } Several warnings appear that are not found in the SQL module because I only use it to connect to the server only. Below is an example but there are several warnings. (5) sql: WARNING: Cannot do check groups when group_membership_query is not set Other warnings I notice are the following: rlm_sql (sql): Opening additional connection (0), 1 of 10 pending slots used rlm_sql_mysql: Starting connect to MySQL server WARNING: MYSQL_OPT_RECONNECT is deprecated and will be removed in a future version. rlm_sql_mysql: Connected to database 'radius' on Localhost via UNIX socket, server version 8.0.39-0ubuntu0.24.04.2, protocol version 10 I was reading that mysql is not going to allow that form of reconnection. Is there any configuration I can do for that warning or does freeradius have to change something in its code? Thank you for giving me your knowledge. I learn a lot. El lun, 11 nov 2024 a las 18:05, Alan DeKok (<aland@deployingradius.com>) escribió:
On Nov 11, 2024, at 3:57 PM, Rodrigo Prieto <rodrigoprieto2019@gmail.com> wrote:
Thanks for responding again. I know that it is not easy to configure any server in Linux. What I did was create a database and import schema.sql. mysql -u radius -p radius < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql When the client connects, it writes to the postauth table but when disconnecting and reconnecting, an error is output from the radcheck table. I'm stuck at
that
point. Maybe I have to create my own schema as you told me and stop using the freeradius schema? Thanks for the patience.
Yes, you have to create your own schema, that's what I said in my last message.
The default schema in FreeRADIUS does something quite different, and is *documented* as doing something else.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Nov 13, 2024, at 1:51 AM, Rodrigo Prieto <rodrigoprieto2019@gmail.com> wrote:
Hello, I was trying what you told me and it worked. Use the following configuration:
That's good to hear.
Several warnings appear that are not found in the SQL module because I only use it to connect to the server only. Below is an example but there are several warnings.
Those are warnings, and can be ignored. They don't cause errors or the problem.
I was reading that mysql is not going to allow that form of reconnection. Is there any configuration I can do for that warning or does freeradius have to change something in its code?
We'll have to change the code.
Thank you for giving me your knowledge. I learn a lot.
You're welcome. Alan DeKok.
participants (3)
-
Alan DeKok -
Alexey D. Filimonov -
Rodrigo Prieto