Skip to content
Snippets Groups Projects
Commit 6fe07e00 authored by Sebastien Boutelier's avatar Sebastien Boutelier
Browse files

Envoi des logs autres que ceux des opérations (warnings, replications...) sur local5

Prise en charge des commandes UNBIND et ABANDON
parent e2869045
No related branches found
No related tags found
No related merge requests found
......@@ -6,13 +6,19 @@
Le programme parselog-ldap permet de construire des logs LDAP lisibles et exploitables. Il doit se lancer sur le serveur LDAP. Il ne peut pas recevoir les logs de plusieurs serveurs LDAP car il pourrait y avoir plusieurs fois le même numéro de connexion et donc des logs inconsistants.
Le programme prend en entrée un port sur lequel il va écouter en TCP et un couple IP/Port sur lequel il va envoyer en TCP les logs construits. Pour cela, il faudra passer en argument du programme ces paramètres:
Le programme prend en entrée un port sur lequel il va écouter en TCP et un couple IP/Port sur lequel il va envoyer en TCP les logs construits et sur local5 les logs qui ne sont pas des opérations. Pour cela, il faudra passer en argument du programme ces paramètres:
```
parselog-ldap --listen=8080 --loghost=172.26.66.74:4514
```
Il faudra ensuite indiquer au rsyslog du serveur LDAP d'envoyer les logs LDAP sur le démon, c'est à dire s'il écoute sur le port 8080 d'envoyer en TCP sur 127.0.0.1:8080. Celui-ci va en retour envoyer les logs sur le loghost indiqué en utilisant le protocole TCP.
Il faudra ensuite indiquer au rsyslog local de traiter les logs envoyés sur local5 et d'envoyer ceux du serveur LDAP sur le démon, c'est à dire s'il écoute sur le port 8080 d'envoyer en TCP sur 127.0.0.1:8080. Avec rsyslog, exemple d'un fichier /etc/rsyslog.d/ldap.conf:
```
local5.* -/var/log/ldap/ldap.log
local4.* @@127.0.0.1:8080
:programname, isequal, "slapd" stop
```
Le démon parselog-ldap ne doit pas tourner en tant que root, il faut donc lui créer un utilisateur sous lequel il sera exécuté.
......
......@@ -5,7 +5,6 @@ use std::env;
use regex::Regex;
use syslog::{Facility, Formatter3164};
use std::sync::OnceLock;
use gethostname::gethostname;
mod hashmap;
......@@ -14,6 +13,7 @@ static REGEXP_CLOSE: OnceLock<Regex> = OnceLock::new();
static REGEXP_CMD: OnceLock<Regex> = OnceLock::new();
static REGEXP_CONNECT: OnceLock<Regex> = OnceLock::new();
static REGEXP_LAUNCH: OnceLock<Regex> = OnceLock::new();
static REGEXP_OTHERLOG: OnceLock<Regex> = OnceLock::new();
static REGEXP_RESULT: OnceLock<Regex> = OnceLock::new();
fn help() {
......@@ -48,7 +48,6 @@ fn getloghost()->Result<String,String> {
process::exit(1);
}
fn com_accept(line: String){
let Some(caps) = REGEXP_CONNECT.get().expect("unitialized Regexp").captures(&line) else {
return;
......@@ -78,6 +77,7 @@ fn com_result(line: String){
let user : String;
match &caps["err"]{
"err=0" => err = "OK".to_string(),
"err=" => err = "OK".to_string(),
_ => err = "refused".to_string(),
}
match bind.as_str(){
......@@ -92,6 +92,10 @@ fn com_result(line: String){
if val1 == "\"\"" { return; }
linelog = format!("ID={} SRC={} BIND={} {} -> {}",con,ip,val1,cmd,err);
},
"UNBIND" => {
hashmap::set_val("bind",caps["con"].to_string(),"Anonymous".to_string());
return;
},
"SRCH" => {
linelog = format!("ID={} SRC={} BIND={} {} attr {} in {} with filter {} -> {} ({} answer)",con,ip,user,cmd,attr,val1,val2,err,nentries);
},
......@@ -152,15 +156,35 @@ fn com_default(line: String){
fn sendlog(line: String){
let formatter = Formatter3164 {
facility: Facility::LOG_USER,
hostname: Some(gethostname().into_string().unwrap()),
process: "ldap".into(),
hostname: None,
process: "sldapd".into(),
pid: 6666,
};
match syslog::tcp(formatter,&LOGHOST.get().unwrap_or(&"0".to_string()).to_string()) {
Err(e) => println!("impossible to connect to syslog: {:?}", e),
Ok(mut writer) => {
writer.info(line).expect("could not write error message");
writer.info(line).expect("could not write message");
}
}
}
fn sendotherlog(line: String){
let Some(caps) = REGEXP_OTHERLOG.get().expect("unitialized Regexp").captures(&line) else {
return;
};
let log = &caps["log"].to_string();
let formatter = Formatter3164 {
facility: Facility::LOG_LOCAL5,
hostname: None,
process: "slapd".into(),
pid: 6666,
};
match syslog::unix(formatter) {
Err(e) => println!("impossible to connect to syslog: {:?}", e),
Ok(mut writer) => {
writer.info(log).expect("could not write message");
}
}
}
......@@ -170,9 +194,12 @@ fn launch<R: BufRead>(reader: R) {
let line = l.unwrap();
//println!("LINE: {}",line);
let Some(caps) = REGEXP_LAUNCH.get().expect("unitialized Regexp").captures(&line) else {
sendotherlog(line.to_string());
return;
};
match &caps["command"]{
"ABANDON" =>com_closed(line.to_string()),
"do_abandon:" =>{},
"ACCEPT" =>com_accept(line.to_string()),
"closed" =>com_closed(line.to_string()),
"RESULT" =>com_result(line.to_string()),
......@@ -184,7 +211,9 @@ fn launch<R: BufRead>(reader: R) {
"MOD" =>create_log(line.to_string()),
"PASSMOD" =>create_log(line.to_string()),
"SRCH" =>create_log(line.to_string()),
_ =>com_default(line.to_string()),
"TLS" =>{},
"UNBIND" =>create_log(line.to_string()),
_ =>sendotherlog(line.to_string()),
}
}
}
......@@ -194,10 +223,11 @@ fn main() {
let _ = LOGHOST.set(loghost);
let port = getport().unwrap();
let _ = REGEXP_LAUNCH.set(Regex::new(r"^\S+ \S+ \S+ \S+ \S+ (?<con>\S+) (?<op>\S+) (?<command>\S+)").unwrap());
let _ = REGEXP_OTHERLOG.set(Regex::new(r"^\S+ \S+ \S+ \S+ \S+ (?<log>.+)").unwrap());
let _ = REGEXP_RESULT.set(Regex::new(r"^\S+ \S+ \S+ \S+ \S+ conn=(?<con>[0-9]+) op=(?<op>[0-9]+)( SEARCH)? RESULT \S+ (?<err>\S+)( nentries=(?<nentries>[0-9]+))?").unwrap());
let _ = REGEXP_CMD.set(Regex::new(r"^\S+ \S+ \S+ \S+ \S+ conn=(?<con>[0-9]+) op=(?<op>[0-9]+) (?<cmd>(ADD|DEL|BIND|CMP|MOD|PASSMOD|SRCH)) (?<v>[a-z]+)=(?<val1>\S+)( \S+ \S+)?( (attr|filter)=(?<val2>\S+))?").unwrap());
let _ = REGEXP_CONNECT.set(Regex::new(r"^\S+ \S+ \S+ \S+ \S+ conn=(?<con>[0-9]+) \S+ ACCEPT from IP=(?<ip>[0-9.:]+):[0-9]+").unwrap());
let _ = REGEXP_CLOSE.set(Regex::new(r"^\S+ \S+ \S+ \S+ \S+ conn=(?<con>[0-9]+) \S+ closed").unwrap());
let _ = REGEXP_CLOSE.set(Regex::new(r"^\S+ \S+ \S+ \S+ \S+ conn=(?<con>[0-9]+) \S+ (closed|ABANDON)").unwrap());
let s = format!("127.0.0.1:{}",port);
let listener = TcpListener::bind(s).unwrap();
for stream in listener.incoming() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment